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))
778static const char tdesc[] =
"DAHDI Telephony"
779#if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
781 #if defined(HAVE_PRI)
784 #if defined(HAVE_SS7)
785 #if defined(HAVE_PRI)
790 #if defined(HAVE_OPENR2)
791 #if defined(HAVE_PRI) || defined(HAVE_SS7)
799static const char config[] =
"chan_dahdi.conf";
802#define NUM_SPANS DAHDI_MAX_SPANS
807#define CHAN_PSEUDO -2
809#define CALLPROGRESS_PROGRESS 1
810#define CALLPROGRESS_FAX_OUTGOING 2
811#define CALLPROGRESS_FAX_INCOMING 4
812#define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
814#define NUM_CADENCE_MAX 25
821 { { 125, 125, 2000, 4000 } },
822 { { 250, 250, 500, 1000, 250, 250, 500, 4000 } },
823 { { 125, 125, 125, 125, 125, 4000 } },
824 { { 1000, 500, 2500, 5000 } },
841#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
842 (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
844#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) )
845#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) )
852#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
866#define REPORT_CHANNEL_ALARMS 1
867#define REPORT_SPAN_ALARMS 2
871static int pridebugfd = -1;
872static char pridebugfilename[1024] =
"";
906 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
915 i = DAHDI_IOMUX_SIGEVENT;
916 if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
918 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
926#define MASK_AVAIL (1 << 0)
927#define MASK_INUSE (1 << 1)
929#define CALLWAITING_SILENT_SAMPLES ((300 * 8) / READ_SIZE)
930#define CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE)
931#define CALLWAITING_SUPPRESS_SAMPLES ((100 * 8) / READ_SIZE)
932#define CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE)
933#define MIN_MS_SINCE_FLASH ((2000) )
934#define DEFAULT_RINGT ((8000 * 8) / READ_SIZE)
935#define DEFAULT_DIALTONE_DETECT_TIMEOUT ((10000 * 8) / READ_SIZE)
949static struct dahdi_ss7 linksets[
NUM_SPANS];
951static int cur_ss7type = -1;
952static int cur_slc = -1;
953static int cur_linkset = -1;
954static int cur_pointcode = -1;
955static int cur_cicbeginswith = -1;
956static int cur_adjpointcode = -1;
957static int cur_networkindicator = -1;
958static int cur_defaultdpc = -1;
962struct dahdi_mfcr2_conf {
963 openr2_variant_t variant;
965 int metering_pulse_timeout;
968#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
972#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
973 int dtmf_end_timeout;
975 signed int get_ani_first:2;
976#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
977 signed int skip_category_request:2;
979 unsigned int call_files:1;
980 unsigned int allow_collect_calls:1;
981 unsigned int charge_calls:1;
982 unsigned int accept_on_offer:1;
983 unsigned int forced_release:1;
984 unsigned int double_answer:1;
985 signed int immediate_accept:2;
986#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
987 signed int dtmf_dialing:2;
988 signed int dtmf_detection:2;
990 char logdir[OR2_MAX_PATH];
991 char r2proto_file[OR2_MAX_PATH];
992 openr2_log_level_t loglevel;
993 openr2_calling_party_category_t category;
1000 openr2_context_t *protocol_context;
1005 struct dahdi_mfcr2_conf
conf;
1008struct r2link_entry {
1009 struct dahdi_mfcr2 mfcr2;
1017static int r2links_count = 0;
1025 int mastertrunkgroup;
1032#if defined(HAVE_PRI_CCSS)
1034static const char dahdi_pri_cc_type[] =
"DAHDI/PRI";
1043#define POLARITY_IDLE 0
1044#define POLARITY_REV 1
1055#if defined(HAVE_PRI)
1064static struct dahdi_parms_pseudo {
1069} dahdi_pseudo_parms;
1085 struct dahdi_pri pri;
1088#if defined(HAVE_SS7)
1089 struct dahdi_ss7 ss7;
1093 struct dahdi_mfcr2_conf mfcr2;
1128 .nsf = PRI_NSF_NONE,
1129 .switchtype = PRI_SWITCH_NI2,
1130 .dialplan = PRI_UNKNOWN + 1,
1131 .localdialplan = PRI_NATIONAL_ISDN + 1,
1132 .nodetype = PRI_CPE,
1135#if defined(HAVE_PRI_CCSS)
1136 .cc_ptmp_recall_mode = 1,
1137 .cc_qsig_signaling_link_req = 1,
1138 .cc_qsig_signaling_link_rsp = 1,
1144 .internationalprefix =
"",
1145 .nationalprefix =
"",
1147 .privateprefix =
"",
1148 .unknownprefix =
"",
1150 .resetinterval = -1,
1153#if defined(HAVE_SS7)
1155 .called_nai = SS7_NAI_NATIONAL,
1156 .calling_nai = SS7_NAI_NATIONAL,
1157 .internationalprefix =
"",
1158 .nationalprefix =
"",
1159 .subscriberprefix =
"",
1160 .unknownprefix =
"",
1161 .networkroutedprefix =
""
1166 .variant = OR2_VAR_ITU,
1167 .mfback_timeout = -1,
1168 .metering_pulse_timeout = -1,
1171 .get_ani_first = -1,
1172#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
1173 .skip_category_request = -1,
1176 .allow_collect_calls = 0,
1178 .accept_on_offer = 1,
1179 .forced_release = 0,
1181 .immediate_accept = -1,
1182#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
1184 .dtmf_detection = -1,
1185 .dtmf_time_on = OR2_DEFAULT_DTMF_ON,
1186 .dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
1188#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
1189 .dtmf_end_timeout = -1,
1193 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
1194 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
1198 .context =
"default",
1203 .mohinterpret =
"default",
1206 .transfertobusy = 1,
1209 .ani_info_digits = 2,
1210 .ani_wink_time = 1000,
1211 .ani_timeout = 10000,
1215 .dahditrcallerid = 0,
1224 .echocancel.head.tap_length = 1,
1232#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1235 .polarityonanswerdelay = 600,
1239 .buf_policy = DAHDI_POLICY_IMMEDIATE,
1258 .ignore_failed_channels = 1,
1259 .smdi_port =
"/dev/ttyS0",
1268 const char *
data,
int *cause);
1289 .description =
tdesc,
1310#define GET_CHANNEL(p) ((p)->channel)
1367 return DAHDI_TONE_RINGTONE;
1369 return DAHDI_TONE_STUTTER;
1371 return DAHDI_TONE_CONGESTION;
1373 return DAHDI_TONE_DIALTONE;
1375 return DAHDI_TONE_DIALRECALL;
1377 return DAHDI_TONE_INFO;
1387 switch (analogsub) {
1416 struct doomed_pri *entry;
1422 ast_debug(4,
"Destroying span %d from doomed queue.\n",
1424 pri_destroy_span(entry->pri);
1443static void pri_queue_for_destruction(
struct sig_pri_span *pri)
1445 struct doomed_pri *entry;
1449 if (entry->pri == pri) {
1454 entry =
ast_calloc(
sizeof(
struct doomed_pri), 1);
1462 ast_debug(4,
"Queue span %d for destruction.\n", pri->
span);
1485 struct dahdi_dialoperation zo = {
1491 for (offset = 0; offset <
sizeof(zo.dialstr) - 1; ++offset) {
1498 if (offset >=
sizeof(zo.dialstr) - 3) {
1502 zo.dialstr[offset] =
'w';
1504 zo.dialstr[offset] =
'w';
1507 zo.dialstr[offset] = *pos++;
1511 ast_debug(1,
"Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL.\n",
1512 pvt->
channel, dial_str, zo.dialstr);
1563 struct pollfd poller;
1567 unsigned char buf[256];
1572 poller.events = POLLPRI | POLLIN;
1575 res = poll(&poller, 1, timeout);
1577 if (poller.revents & POLLPRI) {
1582 if (poller.revents & POLLIN) {
1594 if (analog_p->
ringt > 0) {
1595 if (!(--analog_p->
ringt)) {
1658 unsigned char buf[256];
1666 int checkaftercid = 0;
1667 const char *matched_context;
1671 if (ringdata ==
NULL) {
1672 ringdata = curRingData;
1680 for (receivedRingT = 0; receivedRingT <
RING_PATTERNS; receivedRingT++)
1681 ringdata[receivedRingT] = 0;
1685 ast_verb(3,
"Detecting post-CID distinctive ring\n");
1689 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1690 res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i);
1696 if (i & DAHDI_IOMUX_SIGEVENT) {
1699 if (res == DAHDI_EVENT_NOALARM) {
1702 }
else if (res == DAHDI_EVENT_RINGOFFHOOK) {
1704 ringdata[receivedRingT] = analog_p->
ringt;
1715 }
else if (i & DAHDI_IOMUX_READ) {
1718 if (
errno != ELAST) {
1725 if (analog_p->
ringt > 0) {
1726 if (!(--analog_p->
ringt)) {
1735 ast_verb(3,
"Detected ring pattern: %d,%d,%d\n", ringdata[0], ringdata[1], ringdata[2]);
1737 for (counter = 0; counter < 3; counter++) {
1741 ast_verb(3,
"Checking %d,%d,%d with +/- %d range\n",
1746 for (counter1 = 0; counter1 < 3; counter1++) {
1750 ast_verb(3,
"Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1751 ringdata[counter1]);
1753 }
else if (ring - range <= ringdata[counter1] && ringdata[counter1] <= ring + range) {
1754 ast_verb(3,
"Ring pattern %d is in range: %d to %d\n",
1755 ringdata[counter1], ring - range, ring + range);
1763 if (distMatches == 3) {
1766 ast_verb(3,
"Matched Distinctive Ring context %s\n", matched_context);
1772 if (strcmp(p->
context, matched_context) != 0) {
1860 ast_verb(3,
"CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
1936 ast_log(
LOG_ERROR,
"We used a sub other than SUB_REAL (incorrect assumption sir)\n");
1953 ast_debug(1,
"%s DTMF digit: 0x%02X '%c' on %s\n",
1963 struct dahdi_bufferinfo bi = {
1970 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
2008 ast_debug(1,
"Already in a fax extension, not redirecting\n");
2017 *dest = &p->
subs[idx].
f;
2047 if (!channel_string) {
2057 "DAHDIGroup: %llu\r\n"
2059 "DAHDIChannel: %s\r\n",
2080 "channel", dahdi_channel);
2104 snprintf(ch_name,
sizeof(ch_name),
"no-media (%d)", p->
channel);
2107 strcpy(ch_name,
"pseudo");
2110 snprintf(ch_name,
sizeof(ch_name),
"%d", p->
channel);
2124static void my_ami_channel_event(
void *pvt,
struct ast_channel *chan)
2184 return p->
subs[dahdi_sub].
dfd;
2227#if defined(HAVE_PRI) || defined(HAVE_SS7)
2228static void my_set_digital(
void *pvt,
int is_digital)
2236#if defined(HAVE_SS7)
2237static void my_set_inservice(
void *pvt,
int is_inservice)
2245#if defined(HAVE_SS7)
2246static void my_set_locallyblocked(
void *pvt,
int is_blocked)
2254#if defined(HAVE_SS7)
2255static void my_set_remotelyblocked(
void *pvt,
int is_blocked)
2368 p->
owner = new_owner;
2419 for (i = 0; i < 3; i++) {
2456 int needconf = needconference;
2563#if defined(HAVE_PRI) || defined(HAVE_SS7)
2564static int dahdi_setlaw(
int dfd,
int law)
2567 res = ioctl(dfd, DAHDI_SETLAW, &
law);
2574#if defined(HAVE_PRI)
2613 newlaw = DAHDI_LAW_ALAW;
2616 newlaw = DAHDI_LAW_MULAW;
2626#if defined(HAVE_PRI) || defined(HAVE_SS7)
2634static void my_pri_ss7_open_media(
void *p)
2645 res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
2652 res = dahdi_setlaw(dfd, pvt->
law);
2674#if defined(HAVE_PRI)
2685static void my_pri_dial_digits(
void *p,
const char *dial_string)
2687 char dial_str[DAHDI_MAX_DTMF_BUF];
2691 snprintf(dial_str,
sizeof(dial_str),
"T%s", dial_string);
2741 case DAHDI_EVENT_ONHOOK:
2744 case DAHDI_EVENT_RINGOFFHOOK:
2747 case DAHDI_EVENT_WINKFLASH:
2750 case DAHDI_EVENT_ALARM:
2753 case DAHDI_EVENT_NOALARM:
2756 case DAHDI_EVENT_DIALCOMPLETE:
2759 case DAHDI_EVENT_RINGERON:
2762 case DAHDI_EVENT_RINGEROFF:
2765 case DAHDI_EVENT_HOOKCOMPLETE:
2768 case DAHDI_EVENT_PULSE_START:
2771 case DAHDI_EVENT_POLARITY:
2774 case DAHDI_EVENT_RINGBEGIN:
2777 case DAHDI_EVENT_EC_DISABLED:
2780 case DAHDI_EVENT_REMOVED:
2783 case DAHDI_EVENT_NEONMWI_ACTIVE:
2786 case DAHDI_EVENT_NEONMWI_INACTIVE:
2789#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2790 case DAHDI_EVENT_TX_CED_DETECTED:
2793 case DAHDI_EVENT_RX_CED_DETECTED:
2796 case DAHDI_EVENT_EC_NLP_DISABLED:
2799 case DAHDI_EVENT_EC_NLP_ENABLED:
2803 case DAHDI_EVENT_PULSEDIGIT:
2806 case DAHDI_EVENT_DTMFDOWN:
2809 case DAHDI_EVENT_DTMFUP:
2813 switch(
event & 0xFFFF0000) {
2814 case DAHDI_EVENT_PULSEDIGIT:
2815 case DAHDI_EVENT_DTMFDOWN:
2816 case DAHDI_EVENT_DTMFUP:
2858 struct dahdi_params par;
2860 memset(&par, 0,
sizeof(par));
2867 par.rxisoffhook = 0;
2877 return (par.rxbits > -1) || par.rxisoffhook;
2880 return par.rxisoffhook;
2907 int func = DAHDI_FLASH;
2974 int x = DAHDI_START;
2989 ast_log(
LOG_ERROR,
"Trying to dial_digits '%s' on channel %d subchannel %u\n",
3016 if (ioctl(p->
subs[index].
dfd, DAHDI_DIALING, &x)) {
3017 ast_debug(1,
"DAHDI_DIALING ioctl failed!\n");
3030#if defined(HAVE_PRI)
3031static void my_pri_fixup_chans(
void *chan_old,
void *chan_new)
3038 if (new_chan->
owner) {
3045 new_chan->
dsp = old_chan->
dsp;
3059 new_chan->
law = old_chan->
law;
3064#if defined(HAVE_PRI)
3065static int sig_pri_tone_to_dahditone(
enum sig_pri_tone tone)
3069 return DAHDI_TONE_RINGTONE;
3071 return DAHDI_TONE_STUTTER;
3073 return DAHDI_TONE_CONGESTION;
3075 return DAHDI_TONE_DIALTONE;
3077 return DAHDI_TONE_DIALRECALL;
3079 return DAHDI_TONE_INFO;
3081 return DAHDI_TONE_BUSY;
3088#if defined(HAVE_PRI)
3089static void my_handle_dchan_exception(
struct sig_pri_span *pri,
int index)
3093 ioctl(pri->
fds[index], DAHDI_GETEVENT, &x);
3095 case DAHDI_EVENT_NONE:
3097 case DAHDI_EVENT_ALARM:
3098 case DAHDI_EVENT_NOALARM:
3110 case DAHDI_EVENT_ALARM:
3113 case DAHDI_EVENT_NOALARM:
3116 case DAHDI_EVENT_REMOVED:
3117 pri_queue_for_destruction(pri);
3125#if defined(HAVE_PRI)
3126static int my_pri_play_tone(
void *pvt,
enum sig_pri_tone tone)
3130 return tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, sig_pri_tone_to_dahditone(tone));
3134#if defined(HAVE_PRI) || defined(HAVE_SS7)
3143static void my_set_callerid(
void *pvt,
const struct ast_party_caller *caller)
3158 if (caller->
id.
tag) {
3163 sizeof(p->cid_ani));
3168#if defined(HAVE_PRI) || defined(HAVE_SS7)
3177static void my_set_dnid(
void *pvt,
const char *
dnid)
3185#if defined(HAVE_PRI)
3194static void my_set_rdnis(
void *pvt,
const char *
rdnis)
3202#if defined(HAVE_PRI)
3229static void my_pri_make_cc_dialstring(
void *priv,
char *
buf,
size_t buf_size)
3250 snprintf(
buf, buf_size,
"%s/i%d-",
args.tech, pvt->pri->span);
3253 if (isdigit(
args.group[0]) ||
args.group[0] ==
'i' || strchr(
args.group,
'!')) {
3260 snprintf(
buf, buf_size,
"%s/i%d-%s",
args.tech, pvt->pri->span,
args.group);
3264#if defined(HAVE_PRI)
3274static void dahdi_pri_update_span_devstate(
struct sig_pri_span *pri)
3277 unsigned num_b_chans;
3286 for (idx = pri->
numchans; idx--;) {
3310#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
3314 }
else if (!in_use) {
3316 }
else if (!pri->user_busy_threshold) {
3322 if (pri->threshold_devstate != new_state) {
3323 pri->threshold_devstate = new_state;
3330#if defined(HAVE_PRI)
3336static void my_module_ref(
void)
3342#if defined(HAVE_PRI)
3348static void my_module_unref(
void)
3354#if defined(HAVE_PRI)
3355#if defined(HAVE_PRI_CALL_WAITING)
3356static void my_pri_init_config(
void *priv,
struct sig_pri_span *pri);
3358static int dahdi_new_pri_nobch_channel(
struct sig_pri_span *pri);
3363 .play_tone = my_pri_play_tone,
3369 .new_ast_channel = my_new_pri_ast_channel,
3370 .fixup_chans = my_pri_fixup_chans,
3374 .set_digital = my_set_digital,
3375 .set_callerid = my_set_callerid,
3376 .set_dnid = my_set_dnid,
3377 .set_rdnis = my_set_rdnis,
3378 .new_nobch_intf = dahdi_new_pri_nobch_channel,
3379#if defined(HAVE_PRI_CALL_WAITING)
3380 .init_config = my_pri_init_config,
3383 .make_cc_dialstring = my_pri_make_cc_dialstring,
3384 .update_span_devstate = dahdi_pri_update_span_devstate,
3385 .module_ref = my_module_ref,
3386 .module_unref = my_module_unref,
3387 .dial_digits = my_pri_dial_digits,
3388 .open_media = my_pri_ss7_open_media,
3389 .ami_channel_event = my_ami_channel_event,
3390 .destroy_later = pri_queue_for_destruction,
3394#if defined(HAVE_SS7)
3403static void my_handle_link_exception(
struct sig_ss7_linkset *linkset,
int which)
3407 if (ioctl(linkset->
fds[which], DAHDI_GETEVENT, &
event)) {
3409 linkset->
span, which);
3413 case DAHDI_EVENT_NONE:
3415 case DAHDI_EVENT_ALARM:
3420 case DAHDI_EVENT_NOALARM:
3433#if defined(HAVE_SS7)
3434static void my_ss7_set_loopback(
void *pvt,
int enable)
3445#if defined(HAVE_SS7)
3465 if (linksets[idx].
ss7.ss7 ==
ss7) {
3466 return &linksets[idx].
ss7;
3473#if defined(HAVE_SS7)
3516 newlaw = DAHDI_LAW_ALAW;
3519 newlaw = DAHDI_LAW_MULAW;
3526#if defined(HAVE_SS7)
3527static int sig_ss7_tone_to_dahditone(
enum sig_ss7_tone tone)
3531 return DAHDI_TONE_RINGTONE;
3533 return DAHDI_TONE_STUTTER;
3535 return DAHDI_TONE_CONGESTION;
3537 return DAHDI_TONE_DIALTONE;
3539 return DAHDI_TONE_DIALRECALL;
3541 return DAHDI_TONE_INFO;
3543 return DAHDI_TONE_BUSY;
3550#if defined(HAVE_SS7)
3551static int my_ss7_play_tone(
void *pvt,
enum sig_ss7_tone tone)
3555 return tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, sig_ss7_tone_to_dahditone(tone));
3559#if defined(HAVE_SS7)
3567 .set_loopback = my_ss7_set_loopback,
3569 .new_ast_channel = my_new_ss7_ast_channel,
3570 .play_tone = my_ss7_play_tone,
3572 .handle_link_exception = my_handle_link_exception,
3576 .set_digital = my_set_digital,
3577 .set_inservice = my_set_inservice,
3578 .set_locallyblocked = my_set_locallyblocked,
3579 .set_remotelyblocked = my_set_remotelyblocked,
3580 .set_callerid = my_set_callerid,
3581 .set_dnid = my_set_dnid,
3582 .open_media = my_pri_ss7_open_media,
3583 .find_linkset = my_ss7_find_linkset,
3653#define gen_pvt_field_callback(type, field) \
3654 static type my_get_##field(void *pvt) \
3656 struct dahdi_pvt *p = pvt; \
3664#undef gen_pvt_field_callback
3755 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
3848#if defined(HAVE_PRI)
3863static void mfcr2_queue_for_destruction(
const struct dahdi_pvt *p)
3865 const struct dahdi_mfcr2 *r2link = p->mfcr2;
3866 struct r2link_entry *cur;
3869 if (r2link == &cur->mfcr2) {
3879static int dahdi_r2_answer(
struct dahdi_pvt *p)
3885#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
3887 int wants_double_answer =
ast_true(double_answer) ? 1 : 0;
3888 if (!double_answer) {
3891 res = openr2_chan_answer_call(p->r2chan);
3892 }
else if (wants_double_answer) {
3893 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
3895 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
3898 res = openr2_chan_answer_call(p->r2chan);
3906static openr2_calling_party_category_t dahdi_r2_get_channel_category(
struct ast_channel *
c)
3908 openr2_calling_party_category_t cat;
3912 ast_debug(1,
"No MFC/R2 category specified for chan %s, using default %s\n",
3914 return p->mfcr2_category;
3916 if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
3917 ast_log(
LOG_WARNING,
"Invalid category specified '%s' for chan %s, using default %s\n",
3918 catstr,
ast_channel_name(
c), openr2_proto_get_category_string(p->mfcr2_category));
3919 return p->mfcr2_category;
3921 ast_debug(1,
"Using category %s\n", catstr);
3925static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
3927 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3936 ast_log(
LOG_ERROR,
"Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
3946 p->mfcr2_ani_index =
'\0';
3947 p->mfcr2_dnis_index =
'\0';
3948 p->mfcr2_dnis_matched = 0;
3949 p->mfcr2_answer_pending = 0;
3950 p->mfcr2_call_accepted = 0;
3952 ast_verbose(
"New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
3955static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan,
int alarm)
3958 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3963 if (res == DAHDI_ALARM_NOTOPEN) {
3964 mfcr2_queue_for_destruction(p);
3973static void dahdi_r2_on_os_error(openr2_chan_t *r2chan,
int errorcode)
3975 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3977 ast_log(
LOG_ERROR,
"OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
3980 if (errorcode == ENODEV) {
3981 struct dahdi_mfcr2 *r2link = p->mfcr2;
3990static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
3992 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3993 ast_log(
LOG_ERROR,
"MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
4003static void dahdi_r2_disconnect_call(
struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
4005 if (openr2_chan_disconnect_call(p->r2chan, cause)) {
4006 ast_log(
LOG_NOTICE,
"Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n",
4007 p->
channel, openr2_proto_get_disconnect_string(cause));
4009 openr2_chan_set_idle(p->r2chan);
4016static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan,
const char *ani,
const char *dnis, openr2_calling_party_category_t category)
4022 ast_verbose(
"MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
4023 openr2_chan_get_number(r2chan), ani ? ani :
"(restricted)", dnis,
4024 openr2_proto_get_category_string(category));
4025 p = openr2_chan_get_client_data(r2chan);
4027 if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
4029 dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
4030 goto dahdi_r2_on_call_offered_cleanup;
4033 p->mfcr2_recvd_category = category;
4036 ast_debug(1,
"No CID allowed in configuration, CID is being cleared!\n");
4041 if (p->
immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
4042 ast_debug(1,
"Setting exten => s because of immediate or 0 DNIS configured\n");
4048 ast_log(
LOG_NOTICE,
"MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
4050 dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
4051 goto dahdi_r2_on_call_offered_cleanup;
4053 if (!p->mfcr2_accept_on_offer) {
4060 goto dahdi_r2_on_call_offered_cleanup;
4063 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
4064 }
else if (p->mfcr2_charge_calls) {
4065 ast_debug(1,
"Accepting MFC/R2 call with charge on chan %d\n", p->
channel);
4066 openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
4068 ast_debug(1,
"Accepting MFC/R2 call with no charge on chan %d\n", p->
channel);
4069 openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
4072dahdi_r2_on_call_offered_cleanup:
4076static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
4078 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4085static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
4091 p = openr2_chan_get_client_data(r2chan);
4093 p->mfcr2_call_accepted = 1;
4095 if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
4096 ast_verbose(
"MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
4101 if (!p->mfcr2_accept_on_offer) {
4102 openr2_chan_disable_read(r2chan);
4103 if (p->mfcr2_answer_pending) {
4104 ast_debug(1,
"Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
4107 goto dahdi_r2_on_call_accepted_cleanup;
4113 openr2_chan_disable_read(r2chan);
4114 goto dahdi_r2_on_call_accepted_cleanup;
4118 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
4119 goto dahdi_r2_on_call_accepted_cleanup;
4126 openr2_chan_disable_read(r2chan);
4128dahdi_r2_on_call_accepted_cleanup:
4132static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
4134 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4135 ast_verbose(
"MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan));
4139static void dahdi_r2_on_call_read(openr2_chan_t *r2chan,
const unsigned char *
buf,
int buflen)
4144static int dahdi_r2_cause_to_ast_cause(openr2_call_disconnect_cause_t cause)
4147 case OR2_CAUSE_BUSY_NUMBER:
4149 case OR2_CAUSE_NETWORK_CONGESTION:
4151 case OR2_CAUSE_OUT_OF_ORDER:
4153 case OR2_CAUSE_UNALLOCATED_NUMBER:
4155 case OR2_CAUSE_NO_ANSWER:
4157 case OR2_CAUSE_NORMAL_CLEARING:
4159 case OR2_CAUSE_UNSPECIFIED:
4165static void dahdi_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
4167 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4170 int datalen =
sizeof(*cause_code);
4172 ast_verbose(
"MFC/R2 call disconnected on channel %d\n", openr2_chan_get_number(r2chan));
4177 dahdi_r2_disconnect_call(p, OR2_CAUSE_NORMAL_CLEARING);
4181 snprintf(cause_str,
sizeof(cause_str),
"R2 DISCONNECT (%s)", openr2_proto_get_disconnect_string(cause));
4182 datalen += strlen(cause_str);
4184 memset(cause_code, 0, datalen);
4185 cause_code->
ast_cause = dahdi_r2_cause_to_ast_cause(cause);
4197 }
else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {
4200 case OR2_CAUSE_BUSY_NUMBER:
4203 case OR2_CAUSE_NETWORK_CONGESTION:
4204 case OR2_CAUSE_OUT_OF_ORDER:
4205 case OR2_CAUSE_UNALLOCATED_NUMBER:
4206 case OR2_CAUSE_NO_ANSWER:
4207 case OR2_CAUSE_UNSPECIFIED:
4208 case OR2_CAUSE_NORMAL_CLEARING:
4223static void dahdi_r2_write_log(openr2_log_level_t level,
char *logmessage)
4226 case OR2_LOG_NOTICE:
4229 case OR2_LOG_WARNING:
4235 case OR2_LOG_STACK_TRACE:
4236 case OR2_LOG_MF_TRACE:
4237 case OR2_LOG_CAS_TRACE:
4239 case OR2_LOG_EX_DEBUG:
4249static void dahdi_r2_on_line_blocked(openr2_chan_t *r2chan)
4251 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4255 ast_log(
LOG_NOTICE,
"Far end blocked on chan %d\n", openr2_chan_get_number(r2chan));
4258static void dahdi_r2_on_line_idle(openr2_chan_t *r2chan)
4260 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4264 ast_log(
LOG_NOTICE,
"Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan));
4267static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level,
const char *fmt, va_list ap)
4268 __attribute__((format (printf, 3, 0)));
4269static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level,
const char *fmt, va_list ap)
4271#define CONTEXT_TAG "Context - "
4273 char completemsg[
sizeof(
logmsg) * 2];
4275 snprintf(completemsg,
sizeof(completemsg), CONTEXT_TAG
"%s",
logmsg);
4276 dahdi_r2_write_log(level, completemsg);
4280static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level,
const char *fmt, va_list ap)
4281 __attribute__((format (printf, 3, 0)));
4282static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level,
const char *fmt, va_list ap)
4284#define CHAN_TAG "Chan "
4286 char completemsg[
sizeof(
logmsg) * 2];
4288 snprintf(completemsg,
sizeof(completemsg), CHAN_TAG
"%d - %s", openr2_chan_get_number(r2chan),
logmsg);
4289 dahdi_r2_write_log(level, completemsg);
4293static int dahdi_r2_on_dnis_digit_received(openr2_chan_t *r2chan,
char digit)
4295 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4302 p->mfcr2_dnis_index++;
4303 p->
exten[p->mfcr2_dnis_index] = 0;
4304 p->
rdnis[p->mfcr2_dnis_index] = 0;
4306 if ((p->mfcr2_dnis_matched ||
4315static void dahdi_r2_on_ani_digit_received(openr2_chan_t *r2chan,
char digit)
4317 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4320 p->mfcr2_ani_index++;
4321 p->
cid_num[p->mfcr2_ani_index] = 0;
4322 p->
cid_name[p->mfcr2_ani_index] = 0;
4325static void dahdi_r2_on_billing_pulse_received(openr2_chan_t *r2chan)
4327 ast_verbose(
"MFC/R2 billing pulse received on channel %d\n", openr2_chan_get_number(r2chan));
4330static openr2_event_interface_t dahdi_r2_event_iface = {
4331 .on_call_init = dahdi_r2_on_call_init,
4332 .on_call_offered = dahdi_r2_on_call_offered,
4333 .on_call_accepted = dahdi_r2_on_call_accepted,
4334 .on_call_answered = dahdi_r2_on_call_answered,
4335 .on_call_disconnect = dahdi_r2_on_call_disconnect,
4336 .on_call_end = dahdi_r2_on_call_end,
4337 .on_call_read = dahdi_r2_on_call_read,
4338 .on_hardware_alarm = dahdi_r2_on_hardware_alarm,
4339 .on_os_error = dahdi_r2_on_os_error,
4340 .on_protocol_error = dahdi_r2_on_protocol_error,
4341 .on_line_blocked = dahdi_r2_on_line_blocked,
4342 .on_line_idle = dahdi_r2_on_line_idle,
4344 .on_context_log = (openr2_handle_context_logging_func)dahdi_r2_on_context_log,
4345 .on_dnis_digit_received = dahdi_r2_on_dnis_digit_received,
4346 .on_ani_digit_received = dahdi_r2_on_ani_digit_received,
4348 .on_billing_pulse_received = dahdi_r2_on_billing_pulse_received
4351static inline int16_t dahdi_r2_alaw_to_linear(uint8_t sample)
4356static inline uint8_t dahdi_r2_linear_to_alaw(
int sample)
4361static openr2_transcoder_interface_t dahdi_r2_transcode_iface = {
4362 dahdi_r2_alaw_to_linear,
4363 dahdi_r2_linear_to_alaw
4404 for (
x = 0;
x < strlen(fn);
x++) {
4405 if (!isdigit(fn[
x])) {
4416 fn =
"/dev/dahdi/channel";
4418 fd = open(fn, O_RDWR | O_NONBLOCK);
4424 if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
4433 if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &
bs) == -1) {
4452 chan_pvt->
subs[sub_num].
dfd = -1;
4455#if defined(HAVE_PRI)
4456static void dahdi_close_pri_fd(
struct dahdi_pri *pri,
int fd_num)
4459 pri->pri.fds[fd_num] = -1;
4463#if defined(HAVE_SS7)
4464static void dahdi_close_ss7_fd(
struct dahdi_ss7 *ss7,
int fd_num)
4467 ss7->ss7.fds[fd_num] = -1;
4473 return ioctl(dfd, DAHDI_SETLINEAR, &linear);
4479 struct dahdi_bufferinfo bi;
4492 res = ioctl(p->
subs[x].
dfd, DAHDI_GET_BUFINFO, &bi);
4497 res = ioctl(p->
subs[x].
dfd, DAHDI_SET_BUFINFO, &bi);
4534 return DAHDI_TONE_DTMF_BASE + (
digit -
'0');
4536 return DAHDI_TONE_DTMF_A + (
digit -
'A');
4538 return DAHDI_TONE_DTMF_A + (
digit -
'a');
4539 else if (
digit ==
'*')
4540 return DAHDI_TONE_DTMF_s;
4541 else if (
digit ==
'#')
4542 return DAHDI_TONE_DTMF_p;
4581 char dial_str[] = {
'T',
digit,
'\0' };
4592 dtmf = DAHDI_FLUSH_WRITE;
4595 ast_log(
LOG_WARNING,
"Unable to flush the DAHDI write buffer to send DTMF on channel %d: %s\n",
4599 ast_debug(1,
"Channel %s started VLDTMF digit '%c'\n",
4634 ast_debug(1,
"Channel %s ending VLDTMF digit '%c'\n",
4660 "Hook Transition Complete",
4665 "Polarity Reversal",
4673 { DAHDI_ALARM_RED,
"Red Alarm" },
4674 { DAHDI_ALARM_YELLOW,
"Yellow Alarm" },
4675 { DAHDI_ALARM_BLUE,
"Blue Alarm" },
4676 { DAHDI_ALARM_RECOVER,
"Recovering" },
4677 { DAHDI_ALARM_LOOPBACK,
"Loopback" },
4678 { DAHDI_ALARM_NOTOPEN,
"Not Open" },
4679 { DAHDI_ALARM_NONE,
"None" },
4689 return alm ?
"Unknown Alarm" :
"No Alarm";
4694 static char buf[256];
4703 static char buf[256];
4706 return "E & M Immediate";
4708 return "E & M Wink";
4712 return "Feature Group D (DTMF)";
4714 return "Feature Group D (MF)";
4716 return "Feature Group D (MF) Tandem Access";
4718 return "Feature Group B (MF)";
4722 return "FGC/CAMA (Dialpulse)";
4724 return "FGC/CAMA (MF)";
4726 return "FXS Loopstart";
4728 return "FXS Groundstart";
4730 return "FXS Kewlstart";
4732 return "FXO Loopstart";
4734 return "FXO Groundstart";
4736 return "FXO Kewlstart";
4740 return "ISDN BRI Point to Point";
4742 return "ISDN BRI Point to MultiPoint";
4748 return "SF (Tone) Immediate";
4750 return "SF (Tone) Wink";
4752 return "SF (Tone) with Feature Group D (DTMF)";
4754 return "SF (Tone) with Feature Group D (MF)";
4756 return "SF (Tone) with Feature Group B (MF)";
4760 snprintf(
buf,
sizeof(
buf),
"Unknown signalling %d", sig);
4765#define sig2str dahdi_sig2str
4771 struct dahdi_confinfo zi;
4773 memset(&zi, 0,
sizeof(zi));
4776 if (slavechannel > 0) {
4778 zi.confmode = DAHDI_CONF_DIGITALMON;
4779 zi.confno = slavechannel;
4783 zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
4784 DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
4786 zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
4789 if ((zi.confno ==
c->curconf.confno) && (zi.confmode ==
c->curconf.confmode))
4793 if (ioctl(
c->dfd, DAHDI_SETCONF, &zi)) {
4794 ast_log(
LOG_WARNING,
"Failed to add %d to conference %d/%d: %s\n",
c->dfd, zi.confmode, zi.confno, strerror(
errno));
4797 if (slavechannel < 1) {
4801 ast_debug(1,
"Added %d to conference %d/%d\n",
c->dfd,
c->curconf.confmode,
c->curconf.confno);
4808 if ((p->
channel ==
c->curconf.confno) && (
c->curconf.confmode == DAHDI_CONF_DIGITALMON))
4811 if ((p->
confno > 0) && (p->
confno ==
c->curconf.confno) && (
c->curconf.confmode & DAHDI_CONF_TALKER))
4818 struct dahdi_confinfo zi;
4825 memset(&zi, 0,
sizeof(zi));
4826 if (ioctl(
c->dfd, DAHDI_SETCONF, &zi)) {
4827 ast_log(
LOG_WARNING,
"Failed to drop %d from conference %d/%d: %s\n",
c->dfd,
c->curconf.confmode,
c->curconf.confno, strerror(
errno));
4830 ast_debug(1,
"Removed %d from conference %d/%d\n",
c->dfd,
c->curconf.confmode,
c->curconf.confno);
4831 memcpy(&
c->curconf, &zi,
sizeof(
c->curconf));
4843 for (x = 0; x < 3; x++) {
4851 if (useslavenative) {
4870 else if (slave->
law != p->
law) {
4876 return useslavenative;
4884 struct dahdi_confinfo zi;
4886 memset(&zi, 0,
sizeof(zi));
4902 for (x = 0; x < 3; x++) {
4945 ast_debug(1,
"Updated conferencing on %d, with %d conference users\n", p->
channel, needconf);
4954 ast_debug(1,
"Echo cancellation already on\n");
4958 ast_debug(1,
"Echo cancellation isn't required on digital connection\n");
4962#if defined(HAVE_PRI) || defined(HAVE_SS7)
4964#if defined(HAVE_PRI)
4975#if defined(HAVE_SS7)
4984 "Unable to enable audio mode on channel %d (%s)\n",
5000 ast_debug(1,
"No echo cancellation requested\n");
5016 ast_debug(1,
"No echo training requested\n");
5025 struct dahdi_echocanparams ecp = { .tap_length = 0 };
5040 struct dahdi_hwgain hwgain;
5042 hwgain.newgain = gain * 10.0;
5043 hwgain.tx = tx_direction;
5044 return ioctl(fd, DAHDI_SET_HWGAIN, &hwgain) < 0;
5051 float shallow, steep;
5052 float max = SHRT_MAX;
5054 neg = (sample < 0 ? -1 : 1);
5056 shallow = neg*(
max-
max/drc)+(
float)sample/drc;
5057 if (fabsf(steep) < fabsf(shallow)) {
5068static void fill_txgain(
struct dahdi_gains *g,
float gain,
float drc,
int law)
5073 float linear_gain = pow(10.0, gain / 20.0);
5076 case DAHDI_LAW_ALAW:
5077 for (j = 0; j <
ARRAY_LEN(g->txgain); j++) {
5083 k = (float)k * linear_gain;
5086 }
else if (k < -32768) {
5095 case DAHDI_LAW_MULAW:
5096 for (j = 0; j <
ARRAY_LEN(g->txgain); j++) {
5102 k = (float)k * linear_gain;
5105 }
else if (k < -32768) {
5118static void fill_rxgain(
struct dahdi_gains *g,
float gain,
float drc,
int law)
5122 float linear_gain = pow(10.0, gain / 20.0);
5125 case DAHDI_LAW_ALAW:
5126 for (j = 0; j <
ARRAY_LEN(g->rxgain); j++) {
5132 k = (float)k * linear_gain;
5135 }
else if (k < -32768) {
5144 case DAHDI_LAW_MULAW:
5145 for (j = 0; j <
ARRAY_LEN(g->rxgain); j++) {
5151 k = (float)k * linear_gain;
5154 }
else if (k < -32768) {
5168 struct dahdi_gains g;
5171 memset(&g, 0,
sizeof(g));
5172 res = ioctl(fd, DAHDI_GETGAINS, &g);
5180 return ioctl(fd, DAHDI_SETGAINS, &g);
5185 struct dahdi_gains g;
5188 memset(&g, 0,
sizeof(g));
5189 res = ioctl(fd, DAHDI_GETGAINS, &g);
5197 return ioctl(fd, DAHDI_SETGAINS, &g);
5200static int set_actual_gain(
int fd,
float rxgain,
float txgain,
float rxdrc,
float txdrc,
int law)
5237 res = ioctl(fd, DAHDI_HOOK, &x);
5240 if (
errno == EINPROGRESS)
5254#if defined(HAVE_PRI) || defined(HAVE_SS7)
5256#if defined(HAVE_PRI)
5264#if defined(HAVE_SS7)
5288 struct dahdi_confinfo
c;
5301 memset(&
c, 0,
sizeof(
c));
5302 c.confmode = DAHDI_CONF_NORMAL;
5308 ast_debug(1,
"Disabled conferencing\n");
5322 ast_debug(1,
"Restored conferencing\n");
5355 ast_debug(6,
"MWI manual override active on channel %d: pretending that it should be %s\n",
5386 if (
errno == EAGAIN)
5465#if defined(HAVE_PRI)
5472 subaddr = strchr(p->
exten,
':');
5501 x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
5516 (p->
law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW);
5522#if defined(HAVE_SS7)
5554 openr2_calling_party_category_t chancat;
5573 chancat = dahdi_r2_get_channel_category(ast);
5574 callres = openr2_chan_make_call(p->r2chan, l, (
c + p->
stripmsd), chancat);
5575 if (-1 == callres) {
5580 p->mfcr2_call_accepted = 0;
5581 p->mfcr2_progress_sent = 0;
5655 }
else if (
iflist == pvt) {
5663 }
else if (
ifend == pvt) {
5674#if defined(HAVE_PRI)
5727#if defined(HAVE_PRI)
5765#if defined(HAVE_PRI)
5773static void dahdi_unlink_pri_pvt(
struct dahdi_pvt *pvt)
5784 for (idx = 0; idx <
pri->numchans; ++idx) {
5795#if defined(HAVE_SS7)
5803static void dahdi_unlink_ss7_pvt(
struct dahdi_pvt *pvt)
5814 for (idx = 0; idx <
ss7->numchans; ++idx) {
5825#if defined(HAVE_OPENR2)
5832static void dahdi_unlink_mfcr2_pvt(
struct dahdi_pvt *pvt)
5835 struct dahdi_mfcr2 *mfcr2;
5836 int should_destroy_link = 0;
5841 openr2_chan_disable_read(pvt->r2chan);
5845 for (idx = 0; idx < mfcr2->numchans; ++idx) {
5846 if (mfcr2->pvts[idx] == pvt) {
5847 ast_debug(1,
"Removing MFC/R2 channel %d from the mfcr2 link\n", pvt->
channel);
5848 mfcr2->pvts[idx] =
NULL;
5849 mfcr2->live_chans--;
5853 if (!mfcr2->live_chans) {
5854 ast_debug(1,
"MFC/R2 link is now empty\n");
5855 should_destroy_link = 1;
5859 if (should_destroy_link) {
5860 ast_debug(1,
"MFC/R2 link is now empty\n");
5861 mfcr2_queue_for_destruction(pvt);
5889#if defined(HAVE_PRI)
5890 dahdi_unlink_pri_pvt(p);
5892#if defined(HAVE_SS7)
5893 dahdi_unlink_ss7_pvt(p);
5895#if defined(HAVE_OPENR2)
5896 dahdi_unlink_mfcr2_pvt(p);
5904#if defined(HAVE_PRI)
5905 case DAHDI_IFLIST_NO_B_CHAN:
5907 dahdi_nobch_extract(p->pri, p);
5918#if defined(HAVE_PRI)
5923#if defined(HAVE_SS7)
5966 for (i = 0; i < 3; i++) {
5978#if defined(HAVE_PRI)
5994#if defined(HAVE_PRI_SERVICE_MESSAGES)
5996 char db_chan_name[20];
6001 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, p->
span, chan);
6002 if (!
ast_db_get(db_chan_name, SRVST_DBKEY, db_answer,
sizeof(db_answer))) {
6003 sscanf(db_answer,
"%1c:%30d", &
state, &why);
6013 ast_verb(3,
"Unregistered channel %d\n", chan);
6018#if defined(HAVE_PRI)
6021 if (!pris[
span].dchannels[0]) {
6037#if defined(HAVE_PRI)
6038static char *dahdi_send_keypad_facility_app =
"DAHDISendKeypadFacility";
6040static int dahdi_send_keypad_facility_exec(
struct ast_channel *chan,
const char *digits)
6046 ast_debug(1,
"No digit string sent to application!\n");
6053 ast_debug(1,
"Unable to find technology private\n");
6063#if defined(HAVE_PRI)
6064#if defined(HAVE_PRI_PROG_W_CAUSE)
6065static char *dahdi_send_callrerouting_facility_app =
"DAHDISendCallreroutingFacility";
6067static int dahdi_send_callrerouting_facility_exec(
struct ast_channel *chan,
const char *data)
6080 ast_debug(1,
"No data sent to application!\n");
6084 ast_debug(1,
"Only DAHDI technology accepted!\n");
6089 ast_debug(1,
"Unable to find technology private\n");
6096 ast_debug(1,
"callrerouting attempted on non-ISDN channel %s\n",
6105 ast_log(
LOG_WARNING,
"callrerouting facility requires at least destination number argument\n");
6110 ast_log(
LOG_WARNING,
"Callrerouting Facility without original called number argument\n");
6115 ast_log(
LOG_NOTICE,
"Callrerouting Facility without diversion reason argument, defaulting to unknown\n");
6134#if defined(HAVE_OPENR2)
6135static const char *
const dahdi_accept_r2_call_app =
"DAHDIAcceptR2Call";
6137static int dahdi_accept_r2_call_exec(
struct ast_channel *chan,
const char *data)
6140 openr2_call_mode_t accept_mode;
6141 int res, timeout, maxloops;
6150 ast_debug(1,
"No data sent to application!\n");
6155 ast_debug(1,
"Only DAHDI technology accepted!\n");
6161 ast_debug(1,
"Unable to find technology private!\n");
6169 ast_log(
LOG_WARNING,
"DAHDIAcceptR2Call requires 'yes' or 'no' for the charge parameter\n");
6174 if (!p->mfcr2 || !p->mfcr2call) {
6180 if (p->mfcr2_call_accepted) {
6185 accept_mode =
ast_true(
args.charge) ? OR2_CALL_WITH_CHARGE : OR2_CALL_NO_CHARGE;
6186 if (openr2_chan_accept_call(p->r2chan, accept_mode)) {
6197 while (maxloops > 0) {
6226 if (p->mfcr2_call_accepted) {
6228 ast_debug(1,
"Accepted MFC/R2 call!\n");
6239static openr2_call_disconnect_cause_t dahdi_ast_cause_to_r2_cause(
int cause)
6241 openr2_call_disconnect_cause_t r2cause = OR2_CAUSE_NORMAL_CLEARING;
6246 r2cause = OR2_CAUSE_BUSY_NUMBER;
6251 r2cause = OR2_CAUSE_NETWORK_CONGESTION;
6255 r2cause = OR2_CAUSE_UNALLOCATED_NUMBER;
6260 r2cause = OR2_CAUSE_OUT_OF_ORDER;
6265 r2cause = OR2_CAUSE_NO_ANSWER;
6269 r2cause = OR2_CAUSE_NORMAL_CLEARING;
6272 ast_debug(1,
"ast cause %d resulted in openr2 cause %d/%s\n",
6273 cause, r2cause, openr2_proto_get_disconnect_string(r2cause));
6282 struct dahdi_bufferinfo bi = {
6290 if ((bpres = ioctl(p->
subs[
SUB_REAL].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
6307 struct dahdi_params par;
6335#if defined(HAVE_PRI)
6398#if defined(HAVE_SS7)
6477 ast_debug(1,
"Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
6494 ast_debug(1,
"Normal call hung up with both three way call and a call waiting call in place?\n");
6497 ast_debug(1,
"We were flipped over to the callwait, moving back and not owning.\n");
6504 ast_debug(1,
"We were in the threeway and have a callwait still. Ditching the threeway.\n");
6510 ast_debug(1,
"Call was complete, setting owner to former third call\n");
6514 ast_debug(1,
"Call was incomplete, setting owner to NULL\n");
6533 ast_debug(1,
"Call was complete, setting owner to former third call\n");
6537 ast_debug(1,
"Call was incomplete, setting owner to NULL\n");
6598 if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
6601 if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) {
6602 dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE);
6605 int r2cause_user = r2causestr ? atoi(r2causestr) : 0;
6606 openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user)
6608 dahdi_r2_disconnect_call(p, r2cause);
6610 }
else if (p->mfcr2call) {
6636 memset(&par, 0,
sizeof(par));
6641 ast_debug(1,
"Hanging up channel %d, offhook = %d\n", p->
channel, par.rxisoffhook);
6644 if ((par.rxisoffhook) && (!(p->
radio || (p->
oprmode < 0))))
6737 ast_debug(1,
"Channel %d is no longer eligible for reorigination (went back on hook or became in use)\n", p->
channel);
6782#if defined(HAVE_PRI)
6787#if defined(HAVE_SS7)
6794 if (!p->mfcr2_call_accepted) {
6797 p->mfcr2_answer_pending = 1;
6798 if (p->mfcr2_charge_calls) {
6799 ast_debug(1,
"Accepting MFC/R2 call with charge before answering on chan %d\n", p->
channel);
6800 openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE);
6802 ast_debug(1,
"Accepting MFC/R2 call with no charge before answering on chan %d\n", p->
channel);
6803 openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE);
6839 int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
6860 if (!p || !data || (*datalen < 1)) {
6871 *cp = p->
tdd ? 1 : 0;
6885#if defined(HAVE_PRI)
6886#if defined(HAVE_PRI_CCSS)
6914 if (!p || !data || (datalen < 1)) {
6921 scp = (
signed char *) data;
6930 scp = (
signed char *) data;
6968 ast_debug(1,
"Set option TDD MODE, value: %s(%d) on %s\n",
6973 unsigned char mybuf[41000];
6975 int size, res, fd,
len;
6976 struct pollfd fds[1];
6979 memset(
buf, 0x7f,
sizeof(mybuf));
6995 fds[0].events = POLLPRI | POLLOUT;
6997 res = poll(fds, 1, -1);
7003 if (fds[0].revents & POLLPRI)
7005 if (!(fds[0].revents & POLLOUT)) {
7009 res = write(fd,
buf, size);
7011 if (res == -1)
return -1;
7035 ast_debug(1,
"Set option RELAX DTMF, value: %s(%d) on %s\n",
7040#if defined(HAVE_PRI)
7080 ast_debug(1,
"Set Operator Services mode, value: %d on %s/%s\n",
7133 if (!strcasecmp(data,
"rxgain")) {
7137 }
else if (!strcasecmp(data,
"txgain")) {
7141 }
else if (!strcasecmp(data,
"dahdi_channel")) {
7145 }
else if (!strcasecmp(data,
"dahdi_span")) {
7149 }
else if (!strcasecmp(data,
"dahdi_group")) {
7153 }
else if (!strcasecmp(data,
"dahdi_type")) {
7156#if defined(HAVE_OPENR2)
7161#if defined(HAVE_PRI)
7169#if defined(HAVE_SS7)
7180#if defined(HAVE_PRI)
7181#if defined(HAVE_PRI_REVERSE_CHARGE)
7182 }
else if (!strcasecmp(data,
"reversecharge")) {
7195#if defined(HAVE_PRI_SETUP_KEYPAD)
7196 }
else if (!strcasecmp(data,
"keypad_digits")) {
7210 }
else if (!strcasecmp(data,
"no_media_path")) {
7227 }
else if (!strcasecmp(data,
"dialmode")) {
7265 char policy_str[21] =
"";
7267 if ((res = sscanf(parse,
"%30d,%20s", num_buffers, policy_str)) != 2) {
7271 if (*num_buffers < 0) {
7275 if (!strcasecmp(policy_str,
"full")) {
7276 *policy = DAHDI_POLICY_WHEN_FULL;
7277 }
else if (!strcasecmp(policy_str,
"immediate")) {
7278 *policy = DAHDI_POLICY_IMMEDIATE;
7279#if defined(HAVE_DAHDI_HALF_FULL)
7280 }
else if (!strcasecmp(policy_str,
"half")) {
7281 *policy = DAHDI_POLICY_HALF_FULL;
7301 if (!strcasecmp(data,
"buffers")) {
7302 int num_bufs, policy;
7305 struct dahdi_bufferinfo bi = {
7306 .txbufpolicy = policy,
7307 .rxbufpolicy = policy,
7309 .numbufs = num_bufs,
7313 if ((bpres = ioctl(p->
subs[
SUB_REAL].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
7321 }
else if (!strcasecmp(data,
"echocan_mode")) {
7322 if (!strcasecmp(
value,
"on")) {
7326 }
else if (!strcasecmp(
value,
"off")) {
7330#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
7331 }
else if (!strcasecmp(
value,
"fax")) {
7342 }
else if (!strcasecmp(
value,
"voice")) {
7358 }
else if (!strcasecmp(data,
"dialmode")) {
7369 if (!strcasecmp(
value,
"pulse")) {
7371 }
else if (!strcasecmp(
value,
"dtmf") || !strcasecmp(
value,
"tone")) {
7373 }
else if (!strcasecmp(
value,
"none")) {
7375 }
else if (!strcasecmp(
value,
"both")) {
7382 }
else if (!strcasecmp(data,
"waitfordialtone")) {
7422 if (!slave || (master->
slaves[x] == slave)) {
7463 if (!slave || !master) {
7468 if (!master->
slaves[x]) {
7469 master->
slaves[x] = slave;
7492 if (p->
owner == oldchan) {
7495 for (x = 0; x < 3; x++) {
7505#if defined(HAVE_PRI)
7509#if defined(HAVE_SS7)
7578 ast_verb(3,
"TRANSFERRING %s to %s\n",
7603 struct dahdi_confinfo ci;
7607 memset(&ci, 0,
sizeof(ci));
7616 ast_verb(3,
"Avoiding 3-way call when in an external conference\n");
7630 struct dahdi_spaninfo zi;
7631 struct dahdi_params params;
7633 memset(&zi, 0,
sizeof(zi));
7634 zi.spanno = p->
span;
7637 if (zi.alarms != DAHDI_ALARM_NONE)
7645 memset(¶ms, 0,
sizeof(params));
7646 if ((res = ioctl(p->
subs[
SUB_REAL].
dfd, DAHDI_GET_PARAMS, ¶ms)) >= 0)
7647 return params.chan_alarms;
7651 return DAHDI_ALARM_NONE;
7659 ast_debug(1,
"%s DTMF digit: 0x%02X '%c' on %s\n",
7676 *dest = &p->
subs[idx].
f;
7680 ast_debug(1,
"Got some DTMF, but it's for the CAS\n");
7689 *dest = &p->
subs[idx].
f;
7696 struct dahdi_bufferinfo bi = {
7703 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
7741 ast_debug(1,
"Already in a fax extension, not redirecting\n");
7750 *dest = &p->
subs[idx].
f;
7760 "Alarm", alarm_txt);
7779 "Alarm", alarm_txt);
7789 const char *alarm_str;
7791#if defined(HAVE_PRI)
7832 p->
subs[idx].
f.
src =
"dahdi_handle_event";
7834 f = &p->
subs[idx].
f;
7844 if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) {
7845 p->
pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0;
7847#if defined(HAVE_PRI)
7865 if (res & DAHDI_EVENT_DTMFDOWN) {
7866 ast_debug(1,
"DTMF Down '%c'\n", res & 0xff);
7867#if defined(HAVE_PRI)
7882 return &p->
subs[idx].
f;
7886 case DAHDI_EVENT_EC_DISABLED:
7890#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
7891 case DAHDI_EVENT_TX_CED_DETECTED:
7892 ast_verb(3,
"Channel %d detected a CED tone towards the network.\n", p->
channel);
7894 case DAHDI_EVENT_RX_CED_DETECTED:
7895 ast_verb(3,
"Channel %d detected a CED tone from the network.\n", p->
channel);
7897 case DAHDI_EVENT_EC_NLP_DISABLED:
7898 ast_verb(3,
"Channel %d echo canceler disabled its NLP.\n", p->
channel);
7900 case DAHDI_EVENT_EC_NLP_ENABLED:
7901 ast_verb(3,
"Channel %d echo canceler enabled its NLP.\n", p->
channel);
7904 case DAHDI_EVENT_BITSCHANGED:
7910 openr2_chan_handle_cas(p->r2chan);
7916 case DAHDI_EVENT_PULSE_START:
7919 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
7921 case DAHDI_EVENT_DIALCOMPLETE:
7923#if defined(HAVE_PRI)
7928 if (ioctl(p->
subs[idx].
dfd, DAHDI_DIALING, &x) == -1) {
7929 ast_debug(1,
"DAHDI_DIALING ioctl failed on %s: %s\n",
7954 if (ioctl(p->
subs[idx].
dfd,DAHDI_DIALING,&x) == -1) {
7963 p->
dop.op = DAHDI_DIAL_OP_REPLACE;
7982 ast_debug(1,
"Done dialing, but waiting for progress detection before doing more...\n");
8007 case DAHDI_EVENT_ALARM:
8009#if defined(HAVE_PRI)
8014#if defined(HAVE_SS7)
8026 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
8032#if defined(HAVE_SS7)
8040 case DAHDI_EVENT_ONHOOK:
8074 ast_verb(3,
"Channel %d still has (callwait) call, ringing phone\n", p->
channel);
8089 unsigned int mssinceflash;
8100 if (p->
owner != ast) {
8110 ast_debug(1,
"Last flash was %u ms ago\n", mssinceflash);
8117 ast_debug(1,
"Looks like a bounced flash, hanging up both calls on %d\n", p->
channel);
8163 case DAHDI_EVENT_RINGOFFHOOK:
8193 int numchars = snprintf(p->
dop.dialstr,
sizeof(p->
dop.dialstr),
"M*0%s#",
c);
8194 if (numchars >=
sizeof(p->
dop.dialstr)) {
8201 if (strlen(p->
dop.dialstr) > 4) {
8206 p->
dop.dialstr[strlen(p->
dop.dialstr)-2] =
'\0';
8215 return &p->
subs[idx].
f;
8247 p->
dop.dialstr[0] =
'\0';
8250 ast_debug(1,
"Sent FXO deferred digit string: %s\n", p->
dop.dialstr);
8255 p->
dop.dialstr[0] =
'\0';
8259 return &p->
subs[idx].
f;
8266 return &p->
subs[idx].
f;
8279 res = tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, DAHDI_TONE_DIALTONE);
8294 ast_debug(1,
"Setting IDLE polarity due "
8295 "to ring. Old polarity was %d\n",
8338 case DAHDI_EVENT_RINGBEGIN:
8349 case DAHDI_EVENT_RINGERON:
8351 case DAHDI_EVENT_NOALARM:
8353#if defined(HAVE_PRI)
8358#if defined(HAVE_SS7)
8369 case DAHDI_EVENT_WINKFLASH:
8371 if (p->
radio)
break;
8375 struct dahdi_params par;
8377 memset(&par, 0,
sizeof(par));
8380 if (!par.rxisoffhook)
8398 ast_debug(1,
"Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
8462 ast_debug(1,
"Flash when call not up or ringing\n");
8493 res = tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, DAHDI_TONE_DIALRECALL);
8501 res = tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
8517 ast_debug(1,
"Got flash with three way call up, dropping last call on %d\n", p->
channel);
8535 ast_verb(3,
"Building conference call with %s and %s\n",
8585 snprintf(p->
dop.dialstr,
sizeof(p->
dop.dialstr),
"M*%d%s#",
8594 ast_log(
LOG_WARNING,
"Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
8611 p->
dop.dialstr[0] =
'\0';
8614 ast_debug(1,
"Sent deferred digit string: %s\n", p->
dop.dialstr);
8616 p->
dop.dialstr[0] =
'\0';
8622 case DAHDI_EVENT_HOOKCOMPLETE:
8640 p->
dop.dialstr[0] =
'\0';
8643 ast_debug(1,
"Sent deferred digit string: %s\n", p->
dop.dialstr);
8645 p->
dop.dialstr[0] =
'\0';
8646 p->
dop.op = DAHDI_DIAL_OP_REPLACE;
8656 ast_debug(1,
"Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->
channel);
8662 case DAHDI_EVENT_POLARITY:
8674 ast_debug(1,
"Answering on polarity switch!\n");
8689 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) );
8692 ast_debug(1,
"Polarity Reversal detected and now Hanging up on channel %d\n", p->
channel);
8703 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) );
8706 ast_debug(1,
"Dunno what to do with event %d on channel %d\n", res, p->
channel);
8708 return &p->
subs[idx].
f;
8730 p->
subs[idx].
f.
src =
"dahdi_exception";
8746 if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) &&
8747 (res != DAHDI_EVENT_HOOKCOMPLETE)) {
8748 ast_debug(1,
"Restoring owner of channel %d on event %d\n", p->
channel, res);
8756 case DAHDI_EVENT_ONHOOK:
8768 case DAHDI_EVENT_RINGOFFHOOK:
8776 case DAHDI_EVENT_HOOKCOMPLETE:
8777 case DAHDI_EVENT_RINGERON:
8778 case DAHDI_EVENT_RINGEROFF:
8781 case DAHDI_EVENT_WINKFLASH:
8788 if (usedindex > -1) {
8805 f = &p->
subs[idx].
f;
8811 if (ast != p->
owner) {
8815 f = &p->
subs[idx].
f;
8909 struct dahdi_params ps;
8911 memset(&ps, 0,
sizeof(ps));
8927 return &p->
subs[idx].
f;
8930 if (!(--p->
ringt)) {
8938 openr2_chan_process_event(p->r2chan);
8939 if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) {
8943 if (p->mfcr2_call_accepted &&
8944 !p->mfcr2_progress_sent &&
8946 ast_debug(1,
"Enqueuing progress frame after R2 accept in chan %d\n", p->
channel);
8948 p->mfcr2_progress_sent = 1;
8961 return &p->
subs[idx].
f;
8970 return &p->
subs[idx].
f;
8979 return &p->
subs[idx].
f;
8988 return &p->
subs[idx].
f;
8991 if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) {
9007 return &p->
subs[idx].
f;
9017 return &p->
subs[idx].
f;
9027 return &p->
subs[idx].
f;
9069 if (
errno == EAGAIN) {
9072 return &p->
subs[idx].
f;
9073 }
else if (
errno == ELAST) {
9115 return &p->
subs[idx].
f;
9123 ast_verb(3,
"CPE does not support Call Waiting Caller*ID.\n");
9180 ast_debug(1,
"Channel driver fax CNG detection timeout on %s\n",
9225 ast_debug(1,
"Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n",
9248 ast_debug(1,
"Got 10 samples of dialtone!\n");
9252 p->
dop.dialstr[0] =
'\0';
9257 ast_debug(1,
"Sent deferred digit string: %s\n", p->
dop.dialstr);
9259 p->
dop.dialstr[0] =
'\0';
9260 p->
dop.op = DAHDI_DIAL_OP_REPLACE;
9269 f = &p->
subs[idx].
f;
9321 res = write(fd,
buf, size);
9366 if (mssinceflash >= 1000) {
9384 ast_debug(5,
"Dropping frame since I'm still dialing on %s...\n",
9390 ast_debug(5,
"Dropping frame since there is no active owner on %s...\n",
9396 ast_debug(5,
"Dropping frame since I've still got a callerid spill on %s...\n",
9438 int func = DAHDI_FLASH;
9443#if defined(HAVE_PRI)
9449#if defined(HAVE_SS7)
9459 if (p->mfcr2 && !p->mfcr2_call_accepted) {
9468 switch (condition) {
9470 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_BUSY);
9473 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_RINGTONE);
9534 p->
dop.dialstr[0] =
'\0';
9547 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
9557#if defined(HAVE_PRI)
9572#if defined(HAVE_PRI)
9573 }
else if (i->pri) {
9575 y = ++i->pri->new_chan_seq;
9593 for (x = 0; x < 3; ++x) {
9631#if defined(HAVE_PRI)
9650 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));
9664#if defined(HAVE_PRI)
9672 if (law == DAHDI_LAW_ALAW) {
9682 ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW;
9717 x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
9718 if (ioctl(i->
subs[idx].
dfd, DAHDI_TONEDETECT, &x)) {
9736#if defined(HAVE_PRI) || defined(HAVE_SS7)
9770 ast_channel_parkinglot_set(tmp, i->
parkinglot);
9772 ast_channel_language_set(tmp, i->
language);
9799#if defined(HAVE_PRI) || defined(HAVE_SS7)
9828 dashptr = strrchr(device_name,
'-');
9835 for (v = i->
vars ; v ; v = v->
next)
9875 if (strchr(term,
c))
9887 j = DAHDI_IOMUX_SIGEVENT;
9889 if (ioctl(p->
subs[idx].
dfd,DAHDI_IOMUX,&j) == -1)
return(-1);
9891 if (j & DAHDI_IOMUX_SIGEVENT)
break;
9894 if (ioctl(p->
subs[idx].
dfd,DAHDI_GETEVENT,&j) == -1)
return(-1);
9934 return dahdichan->
dnd;
9939 ast_verb(3,
"%s DND on channel %d\n",
9940 flag?
"Enabled" :
"Disabled",
9948 int extlen = strlen(exten);
9954 if (extlen < strlen(pickupexten) && !strncmp(pickupexten, exten, extlen)) {
9958 if (exten[0] ==
'*' && extlen < 3) {
9979 unsigned char buf[256];
10000 const char *pickupexten;
10024 ast_log(
LOG_ERROR,
"Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
10027 pickupexten =
ast_strdupa(pickup_cfg->pickupexten);
10052 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10062 memset(dtmfbuf, 0,
sizeof(dtmfbuf));
10077 res =
my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf),
"*", 3000);
10087 if (res <= 0)
break;
10096 if ((p->
sig ==
SIG_FEATDMF) && (dtmfbuf[1] !=
'0') && (strlen(dtmfbuf) != 14))
10102 if (res <= 0)
break;
10110 res =
my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf),
"#", 3000);
10127 res =
my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf),
"*", 3000);
10134 dtmfbuf[
len] =
'\0';
10143 ast_debug(1,
"waitfordigit returned < 0...\n");
10147 dtmfbuf[
len++] = res;
10148 dtmfbuf[
len] =
'\0';
10160 }
else if (res < 0) {
10161 ast_debug(1,
"Got hung up before digits finished\n");
10176 if ((res > 0) && (strlen(anibuf) > 2)) {
10177 if (anibuf[strlen(anibuf) - 1] ==
'#')
10178 anibuf[strlen(anibuf) - 1] = 0;
10189 if (exten[0] ==
'*') {
10190 char *stringp=
NULL;
10194 s1 =
strsep(&stringp,
"*");
10195 s2 =
strsep(&stringp,
"*");
10208 if (exten[0] ==
'*') {
10209 char *stringp=
NULL;
10213 s1 =
strsep(&stringp,
"#");
10214 s2 =
strsep(&stringp,
"#");
10228 if (exten[0] ==
'*') {
10229 char *stringp=
NULL;
10233 s1 =
strsep(&stringp,
"#");
10234 s2 =
strsep(&stringp,
"#");
10235 if (s2 && (*(s2 + 1) ==
'0')) {
10245 if (exten[0] ==
'*') {
10246 char *stringp=
NULL;
10250 s1 =
strsep(&stringp,
"#");
10284 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10290 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_INFO);
10298 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10313 int is_exten_parking = 0;
10323 ast_debug(1,
"waitfordigit returned < 0...\n");
10324 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10328 ast_debug(1,
"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
10333 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10335 tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALTONE);
10346 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10350 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10352 memset(exten, 0,
sizeof(exten));
10353 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALTONE);
10357 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10376 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10385 }
else if (res == 0) {
10386 ast_debug(1,
"not enough digits (and no ambiguous match)...\n");
10387 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10391 }
else if (p->
callwaiting && !strcmp(exten,
"*70")) {
10395 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10401 ioctl(p->
subs[idx].
dfd,DAHDI_CONFDIAG,&
len);
10402 memset(exten, 0,
sizeof(exten));
10405 }
else if (!strcmp(exten, pickupexten)) {
10421 ast_debug(1,
"No call pickup possible...\n");
10422 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10433 }
else if (!p->
hidecallerid && !strcmp(exten,
"*67")) {
10441 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10447 memset(exten, 0,
sizeof(exten));
10449 }
else if (p->
callreturn && !strcmp(exten,
"*69")) {
10450 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10452 }
else if (!strcmp(exten,
"*78")) {
10455 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10457 memset(exten, 0,
sizeof(exten));
10459 }
else if (!strcmp(exten,
"*79")) {
10462 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10464 memset(exten, 0,
sizeof(exten));
10467 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10469 memset(exten, 0,
sizeof(exten));
10472 ast_verb(3,
"Cancelling call forwarding on channel %d\n", p->
channel);
10473 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10476 memset(exten, 0,
sizeof(exten));
10489 if (bridge_channel) {
10508 }
else if (p->
hidecallerid && !strcmp(exten,
"*82")) {
10513 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10519 memset(exten, 0,
sizeof(exten));
10521 }
else if (!strcmp(exten,
"*0")) {
10528 if (nbridge && bridged) {
10531 if (nbridge && pbridge &&
10535 int func = DAHDI_FLASH;
10537 p->
dop.dialstr[0] =
'\0';
10550 tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10552 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10570 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10580 if (smdi_msg !=
NULL) {
10583 if (smdi_msg->
type ==
'B')
10585 else if (smdi_msg->
type ==
'N')
10633 "Exiting simple switch\n");
10658 ast_debug(1,
"CID got string '%s'\n", dtmfbuf);
10671 struct timeval start;
10682 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10683 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
10689 if (i & DAHDI_IOMUX_SIGEVENT) {
10692 if (res == DAHDI_EVENT_NOALARM) {
10697 if (res == DAHDI_EVENT_RINGBEGIN) {
10705 }
else if (i & DAHDI_IOMUX_READ) {
10708 if (
errno != ELAST) {
10729 "Failed to decode CallerID on channel '%s'\n",
10734 else if (samples > (8000 * 10))
10758 "Exiting simple switch\n");
10779 for (receivedRingT = 0; receivedRingT <
ARRAY_LEN(curRingData); receivedRingT++)
10780 curRingData[receivedRingT] = 0;
10791 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10792 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
10798 if (i & DAHDI_IOMUX_SIGEVENT) {
10801 if (res == DAHDI_EVENT_NOALARM) {
10807 curRingData[receivedRingT] = p->
ringt;
10813 if (++receivedRingT ==
ARRAY_LEN(curRingData))
10815 }
else if (i & DAHDI_IOMUX_READ) {
10818 if (
errno != ELAST) {
10826 if (p->
ringt > 0) {
10827 if (!(--p->
ringt)) {
10835 ast_verb(3,
"Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
10836 for (counter = 0; counter < 3; counter++) {
10840 for (counter1 = 0; counter1 < 3; counter1++) {
10843 ast_verb(3,
"Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
10844 curRingData[counter1]);
10848 ast_verb(3,
"Ring pattern matched in range: %d to %d\n",
10855 if (distMatches == 3) {
10873 "state, but I have nothing to do. "
10874 "Terminating simple switch, should be "
10875 "restarted by the actual ring.\n",
10884 struct timeval start;
10897 "Exiting simple switch\n");
10921 ast_debug(1,
"CID is '%s', flags %d\n",
10940 for (receivedRingT = 0; receivedRingT <
ARRAY_LEN(curRingData); receivedRingT++)
10941 curRingData[receivedRingT] = 0;
10954 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10955 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
10961 if (i & DAHDI_IOMUX_SIGEVENT) {
10964 if (res == DAHDI_EVENT_NOALARM) {
10969 ast_debug(1,
"Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->
channel);
10978 curRingData[receivedRingT] = p->
ringt;
10984 if (++receivedRingT ==
ARRAY_LEN(curRingData))
10986 }
else if (i & DAHDI_IOMUX_READ) {
10989 if (
errno != ELAST) {
10997 if (p->
ringt > 0) {
10998 if (!(--p->
ringt)) {
11011 "Failed to decode CallerID on channel '%s'\n",
11016 else if (
samples > (8000 * 10))
11026 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
11027 curRingData[receivedRingT] = 0;
11030 ast_verb(3,
"Detecting post-CID distinctive ring\n");
11032 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
11033 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
11039 if (i & DAHDI_IOMUX_SIGEVENT) {
11042 if (res == DAHDI_EVENT_NOALARM) {
11048 curRingData[receivedRingT] = p->
ringt;
11054 if (++receivedRingT ==
ARRAY_LEN(curRingData))
11056 }
else if (i & DAHDI_IOMUX_READ) {
11059 if (
errno != ELAST) {
11067 if (p->
ringt > 0) {
11068 if (!(--p->
ringt)) {
11078 ast_verb(3,
"Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
11080 for (counter = 0; counter < 3; counter++) {
11084 ast_verb(3,
"Checking %d,%d,%d\n",
11089 for (counter1 = 0; counter1 < 3; counter1++) {
11092 ast_verb(3,
"Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
11093 curRingData[counter1]);
11098 ast_verb(3,
"Ring pattern matched in range: %d to %d\n",
11104 if (distMatches == 3) {
11151 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
11155 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
11181 for (x = 0; x <
len; x++)
11191 pthread_t threadid;
11196 unsigned int spill_done = 0;
11197 int spill_result = -1;
11200 goto quit_no_clean;
11208 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
11214 if (i & DAHDI_IOMUX_SIGEVENT) {
11217 int callid_created;
11225 case DAHDI_EVENT_NEONMWI_ACTIVE:
11226 case DAHDI_EVENT_NEONMWI_INACTIVE:
11227 case DAHDI_EVENT_NONE:
11228 case DAHDI_EVENT_BITSCHANGED:
11230 case DAHDI_EVENT_NOALARM:
11239 case DAHDI_EVENT_ALARM:
11277 goto quit_no_clean;
11279 }
else if (i & DAHDI_IOMUX_READ) {
11281 if (
errno != ELAST) {
11296 }
else if (spill_result) {
11306 if (samples > (8000 * 4))
11311 if (spill_result == 1) {
11348#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11350 if (pvt->mwisend_rpas) {
11353 }
else if (pvt->mwisend_fsk) {
11381 x = DAHDI_FLUSH_BOTH;
11385#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11386 if (pvt->mwisend_fsk) {
11391#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11399 struct timeval now;
11423#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11424 if (pvt->mwisend_fsk) {
11426 gettimeofday(&now,
NULL);
11430#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11438 if (0 < num_read) {
11491 case DAHDI_EVENT_RINGEROFF:
11508 case DAHDI_EVENT_RINGOFFHOOK:
11518 case DAHDI_EVENT_RINGERON:
11519 case DAHDI_EVENT_HOOKCOMPLETE:
11533 int destroyed_first = 0;
11534 int destroyed_last = 0;
11541 int x = DAHDI_FLASH;
11543 if (cur->
channel > destroyed_last) {
11544 destroyed_last = cur->
channel;
11546 if (destroyed_first < 1 || cur->
channel < destroyed_first) {
11547 destroyed_first = cur->
channel;
11558 if (destroyed_first > start || destroyed_last <
end) {
11559 ast_debug(1,
"Asked to destroy %d-%d, destroyed %d-%d,\n",
11560 start,
end, destroyed_first, destroyed_last);
11565static void dahdi_r2_destroy_nodev(
void)
11567 struct r2link_entry *cur;
11571 struct dahdi_mfcr2 *r2 = &cur->mfcr2;
11572 ast_debug(3,
"About to destroy %d DAHDI channels of MFC/R2 link.\n", r2->numchans);
11573 for (i = 0; i < r2->numchans; i++) {
11586 pthread_cancel(r2->r2master);
11587 pthread_join(r2->r2master,
NULL);
11589 openr2_context_delete(r2->protocol_context);
11619 ast_debug(1,
"channel range caps: %d - %d\n", start,
end);
11624 "channel range %d-%d is occupied\n",
11633 struct dahdi_pri *pri = pris + x;
11635 if (!pris[x].pri.pvts[0]) {
11639 int channo = pri->dchannels[i];
11644 if (!pri->pri.fds[i]) {
11647 if (channo >= start && channo <=
end) {
11649 "channel range %d-%d is occupied by span %d\n",
11650 start,
end, x + 1);
11658 !
conf.chan.cc_params) {
11663 conf.wanted_channels_start = start;
11666 conf.wanted_channels_end =
end;
11682 pthread_t threadid;
11685 int callid_created;
11690 case DAHDI_EVENT_NONE:
11691 case DAHDI_EVENT_BITSCHANGED:
11693 case DAHDI_EVENT_WINKFLASH:
11694 case DAHDI_EVENT_RINGOFFHOOK:
11696 if (i->
radio)
break;
11703 if (res && (
errno == EBUSY)) {
11717 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_RINGTONE);
11721 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
11730 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_STUTTER);
11732 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_DIALTONE);
11734 ast_log(
LOG_WARNING,
"Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->
channel);
11737 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
11780 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);
11797 case DAHDI_EVENT_NOALARM:
11799#if defined(HAVE_PRI)
11806#if defined(HAVE_SS7)
11817 case DAHDI_EVENT_ALARM:
11819#if defined(HAVE_PRI)
11826#if defined(HAVE_SS7)
11838 case DAHDI_EVENT_ONHOOK:
11884 case DAHDI_EVENT_POLARITY:
11898 ast_verb(2,
"Starting post polarity "
11899 "CID detection on channel %d\n",
11913 "polarity reversal on non-FXO (SIG_FXS) "
11914 "interface %d\n", i->
channel);
11917 case DAHDI_EVENT_REMOVED:
11919 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
11922 case DAHDI_EVENT_NEONMWI_ACTIVE:
11928 case DAHDI_EVENT_NEONMWI_INACTIVE:
11939 struct pollfd **pfds = arg;
11945 int count, res, res2, spoint, pollres=0;
11949 time_t thispass = 0, lastpass = 0;
11952 struct pollfd *pfds=
NULL;
11953 int lastalloc = -1;
11958 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,
NULL)) {
11964 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
11970 if (!pfds || (lastalloc !=
ifcount)) {
11997 pfds[count].events = POLLPRI;
11998 pfds[count].revents = 0;
12002 pfds[count].events |= POLLIN;
12010 pfds[count].events = POLLPRI;
12011 pfds[count].revents = 0;
12016 pfds[count].events |= POLLIN;
12027 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
NULL);
12028 pthread_testcancel();
12030 res = poll(pfds, count, 1000);
12031 pthread_testcancel();
12032 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
12045 lastpass = thispass;
12046 thispass = time(
NULL);
12057 if (thispass != lastpass) {
12064 && !
last->mwisendactive
12065 && (
last->sig & __DAHDI_SIG_FXO)
12078 res2 = ioctl(
last->subs[
SUB_REAL].dfd, DAHDI_VMWI, &res);
12081 ast_debug(3,
"Unable to control message waiting led on channel %d: %s\n",
last->channel, strerror(
errno));
12084 ast_debug(5,
"Initiating MWI FSK spill on channel %d\n",
last->channel);
12114 if (pollres & POLLIN) {
12130 pthread_attr_t attr;
12131 pthread_t threadid;
12134 pthread_attr_init(&attr);
12135 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
12140 memcpy(mtd->
buf,
buf, res);
12153 struct timeval now;
12161 gettimeofday(&now,
NULL);
12168 pthread_t threadid;
12203 if (pollres & POLLPRI) {
12230 ast_debug(1,
"Woah! Went back on hook before reoriginate could happen on channel %d\n", i->
channel);
12233 res = DAHDI_EVENT_RINGOFFHOOK;
12248 dahdi_r2_destroy_nodev();
12252 pthread_cleanup_pop(1);
12283#if defined(HAVE_PRI)
12284static int pri_resolve_span(
int *
span,
int channel,
int offset,
struct dahdi_spaninfo *si)
12289 trunkgroup = pris[*
span].mastertrunkgroup;
12304 }
else if (pris[*
span].mastertrunkgroup) {
12305 ast_log(
LOG_WARNING,
"Unable to use span %d implicitly since it is already part of trunk group %d\n", *
span, pris[*
span].mastertrunkgroup);
12308 if (si->totalchans == 31) {
12310 pris[*
span].dchannels[0] = 16 + offset;
12311 }
else if (si->totalchans == 24) {
12313 pris[*
span].dchannels[0] = 24 + offset;
12314 }
else if (si->totalchans == 3) {
12316 pris[*
span].dchannels[0] = 3 + offset;
12318 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);
12329#if defined(HAVE_PRI)
12330static int pri_create_trunkgroup(
int trunkgroup,
int *
channels)
12332 struct dahdi_spaninfo si;
12333 struct dahdi_params p;
12340 ast_log(
LOG_WARNING,
"Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
12347 memset(&si, 0,
sizeof(si));
12348 memset(&p, 0,
sizeof(p));
12349 fd = open(
"/dev/dahdi/channel", O_RDWR);
12355 if (ioctl(fd, DAHDI_SPECIFY, &x)) {
12360 if (ioctl(fd, DAHDI_GET_PARAMS, &p)) {
12365 if (ioctl(fd, DAHDI_SPANSTAT, &si)) {
12370 span = p.spanno - 1;
12376 if (pris[span].pri.
pvts[0]) {
12377 ast_log(
LOG_WARNING,
"Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
12382 pris[span].pri.trunkgroup = trunkgroup;
12385 pris[ospan].dchannels[y] =
channels[y];
12386 pris[span].pri.span = span + 1;
12393#if defined(HAVE_PRI)
12394static int pri_create_spanmap(
int span,
int trunkgroup,
int logicalspan)
12396 if (pris[span].mastertrunkgroup) {
12397 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);
12400 pris[span].mastertrunkgroup = trunkgroup;
12401 pris[span].prilogicalspan = logicalspan;
12406#if defined(HAVE_SS7)
12407static unsigned int parse_pointcode(
const char *pcstring)
12409 unsigned int code1, code2, code3;
12412 numvals = sscanf(pcstring,
"%30d-%30d-%30d", &code1, &code2, &code3);
12416 return (code1 << 16) | (code2 << 8) | code3;
12422#if defined(HAVE_SS7)
12423static struct dahdi_ss7 * ss7_resolve_linkset(
int linkset)
12425 if ((linkset < 0) || (linkset >=
NUM_SPANS))
12428 return &linksets[linkset - 1];
12433static void dahdi_r2_destroy_links(
void)
12435 struct r2link_entry *cur;
12440 ast_debug(3,
"MFC/R2 link #%d queued for destruction\n", cur->mfcr2.index);
12446 dahdi_r2_destroy_nodev();
12450#define R2_LINK_CAPACITY 30
12453 struct r2link_entry *cur =
NULL;
12461 if (memcmp(&
conf->mfcr2, &cur->mfcr2.conf,
sizeof(
conf->mfcr2))) {
12462 ast_debug(3,
"Need new R2 link because of: Configuration change\n");
12464 }
else if (cur->mfcr2.numchans == R2_LINK_CAPACITY) {
12465 ast_debug(3,
"Need new R2 link because of: Capacity (%d)\n", R2_LINK_CAPACITY);
12470 struct r2link_entry *tmp =
NULL;
12471 int new_idx = r2links_count + 1;
12473 for (i = 1; i <= r2links_count; i++) {
12476 if (i == tmp->mfcr2.index) {
12491 cur->mfcr2.index = new_idx;
12494 ast_debug(3,
"Created new R2 link #%d (now have %d)\n", new_idx, r2links_count);
12501static int dahdi_r2_set_context(
struct dahdi_mfcr2 *r2_link,
const struct dahdi_chan_conf *
conf)
12503 char tmplogdir[] =
"/tmp";
12504 char logdir[OR2_MAX_PATH];
12507 r2_link->protocol_context = openr2_context_new(
NULL, &dahdi_r2_event_iface,
12508 &dahdi_r2_transcode_iface,
conf->mfcr2.variant,
conf->mfcr2.max_ani,
12509 conf->mfcr2.max_dnis);
12510 if (!r2_link->protocol_context) {
12513 openr2_context_set_log_level(r2_link->protocol_context,
conf->mfcr2.loglevel);
12514 openr2_context_set_ani_first(r2_link->protocol_context,
conf->mfcr2.get_ani_first);
12515#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
12516 openr2_context_set_skip_category_request(r2_link->protocol_context,
conf->mfcr2.skip_category_request);
12518 openr2_context_set_mf_threshold(r2_link->protocol_context,
threshold);
12519 openr2_context_set_mf_back_timeout(r2_link->protocol_context,
conf->mfcr2.mfback_timeout);
12520 openr2_context_set_metering_pulse_timeout(r2_link->protocol_context,
conf->mfcr2.metering_pulse_timeout);
12521 openr2_context_set_double_answer(r2_link->protocol_context,
conf->mfcr2.double_answer);
12522 openr2_context_set_immediate_accept(r2_link->protocol_context,
conf->mfcr2.immediate_accept);
12523#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
12524 openr2_context_set_dtmf_dialing(r2_link->protocol_context,
conf->mfcr2.dtmf_dialing,
conf->mfcr2.dtmf_time_on,
conf->mfcr2.dtmf_time_off);
12525 openr2_context_set_dtmf_detection(r2_link->protocol_context,
conf->mfcr2.dtmf_detection);
12527#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
12528 openr2_context_set_dtmf_detection_end_timeout(r2_link->protocol_context,
conf->mfcr2.dtmf_end_timeout);
12531 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
12532 ast_log(
LOG_ERROR,
"Failed setting default MFC/R2 log directory %s\n", tmplogdir);
12536 if (snres >=
sizeof(logdir)) {
12537 ast_log(
LOG_ERROR,
"MFC/R2 logging directory truncated, using %s\n", tmplogdir);
12538 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
12539 ast_log(
LOG_ERROR,
"Failed setting default MFC/R2 log directory %s\n", tmplogdir);
12542 if (openr2_context_set_log_directory(r2_link->protocol_context, logdir)) {
12548 if (openr2_context_configure_from_advanced_file(r2_link->protocol_context,
conf->mfcr2.r2proto_file)) {
12549 ast_log(
LOG_ERROR,
"Failed to configure r2context from advanced configuration file %s\n",
conf->mfcr2.r2proto_file);
12553 memcpy(&r2_link->conf, &
conf->mfcr2,
sizeof(r2_link->conf));
12587 struct dahdi_bufferinfo bi;
12590#if defined(HAVE_PRI)
12596 struct dahdi_params p;
12597#if defined(HAVE_PRI)
12598 struct dahdi_spaninfo si;
12601#if defined(HAVE_SS7)
12621 if (!here && reloading != 1) {
12633 for (x = 0; x < 3; x++)
12640 int chan_sig =
conf->chan.sig;
12643 if (reloading && tmp->
vars) {
12653 snprintf(fn,
sizeof(fn),
"%d",
channel);
12668 memset(&p, 0,
sizeof(p));
12675 if (
conf->is_sig_auto)
12677 if (p.sigtype != (chan_sig & 0x3ffff)) {
12683 tmp->
law = p.curlaw;
12684 tmp->
span = p.spanno;
12685#if defined(HAVE_PRI)
12686 span = p.spanno - 1;
12691 tmp->
sig = chan_sig;
12702#if defined(HAVE_SS7)
12704 struct dahdi_ss7 *ss7;
12708 ast_log(
LOG_ERROR,
"Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(
errno));
12713 ss7 = ss7_resolve_linkset(cur_linkset);
12719 ss7->ss7.span = cur_linkset;
12720 if (cur_cicbeginswith < 0) {
12731 tmp->ss7 = &ss7->ss7;
12734 ss7_chan->
cic = cur_cicbeginswith++;
12737 ss7_chan->
dpc = cur_defaultdpc;
12739 ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan;
12741 ast_copy_string(ss7->ss7.internationalprefix,
conf->ss7.ss7.internationalprefix,
sizeof(ss7->ss7.internationalprefix));
12742 ast_copy_string(ss7->ss7.nationalprefix,
conf->ss7.ss7.nationalprefix,
sizeof(ss7->ss7.nationalprefix));
12743 ast_copy_string(ss7->ss7.subscriberprefix,
conf->ss7.ss7.subscriberprefix,
sizeof(ss7->ss7.subscriberprefix));
12744 ast_copy_string(ss7->ss7.unknownprefix,
conf->ss7.ss7.unknownprefix,
sizeof(ss7->ss7.unknownprefix));
12745 ast_copy_string(ss7->ss7.networkroutedprefix,
conf->ss7.ss7.networkroutedprefix,
sizeof(ss7->ss7.networkroutedprefix));
12747 ss7->ss7.called_nai =
conf->ss7.ss7.called_nai;
12748 ss7->ss7.calling_nai =
conf->ss7.ss7.calling_nai;
12753 struct dahdi_mfcr2 *r2_link;
12754 struct r2link_entry *r2_le = dahdi_r2_get_link(
conf);
12755 r2_link = &r2_le->mfcr2;
12761 if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link,
conf)) {
12766 if (r2_link->numchans ==
ARRAY_LEN(r2_link->pvts)) {
12771 r2_link->pvts[r2_link->numchans++] = tmp;
12772 tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context,
12775 if (!tmp->r2chan) {
12776 openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context);
12777 ast_log(
LOG_ERROR,
"Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err));
12781 r2_link->live_chans++;
12782 tmp->mfcr2 = r2_link;
12783 if (
conf->mfcr2.call_files) {
12784 openr2_chan_enable_call_files(tmp->r2chan);
12786 openr2_chan_set_client_data(tmp->r2chan, tmp);
12788 openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log);
12789 openr2_chan_set_log_level(tmp->r2chan,
conf->mfcr2.loglevel);
12790 tmp->mfcr2_category =
conf->mfcr2.category;
12791 tmp->mfcr2_charge_calls =
conf->mfcr2.charge_calls;
12792 tmp->mfcr2_allow_collect_calls =
conf->mfcr2.allow_collect_calls;
12793 tmp->mfcr2_forced_release =
conf->mfcr2.forced_release;
12794 tmp->mfcr2_accept_on_offer =
conf->mfcr2.accept_on_offer;
12795 tmp->mfcr2call = 0;
12796 tmp->mfcr2_dnis_index = 0;
12797 tmp->mfcr2_ani_index = 0;
12805 int myswitchtype = 0;
12809 ast_log(
LOG_ERROR,
"Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(
errno));
12814 ast_log(
LOG_ERROR,
"Channel %d does not lie on a span I know of (%d)\n", channel, span);
12825 tmp->logicalspan = pris[span].prilogicalspan;
12826 pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
12828 ast_log(
LOG_WARNING,
"Channel %d: Unable to find locate channel/trunk group!\n", channel);
12832 myswitchtype =
conf->pri.pri.switchtype;
12837 if (pris[x].dchannels[y] == tmp->
channel) {
12843 if (!matchesdchan) {
12844 if (pris[span].pri.
nodetype && (pris[span].pri.nodetype !=
conf->pri.pri.nodetype)) {
12849 if (pris[span].pri.
switchtype && (pris[span].pri.switchtype != myswitchtype)) {
12854 if ((pris[span].pri.
dialplan) && (pris[span].pri.dialplan !=
conf->pri.pri.dialplan)) {
12855 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));
12869 if (pris[span].pri.
minunused && (pris[span].pri.minunused !=
conf->pri.pri.minunused)) {
12870 ast_log(
LOG_ERROR,
"Span %d already has minunused of %d.\n", span + 1,
conf->pri.pri.minunused);
12874 if (pris[span].pri.
minidle && (pris[span].pri.minidle !=
conf->pri.pri.minidle)) {
12880 ast_log(
LOG_ERROR,
"Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
12886 pri_chan =
sig_pri_chan_new(tmp, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup);
12892 tmp->pri = &pris[span].pri;
12904 conf->chan.cc_params);
12906 pris[span].pri.sig = chan_sig;
12907 pris[span].pri.nodetype =
conf->pri.pri.nodetype;
12908 pris[span].pri.switchtype = myswitchtype;
12909 pris[span].pri.nsf =
conf->pri.pri.nsf;
12910 pris[span].pri.dialplan =
conf->pri.pri.dialplan;
12911 pris[span].pri.localdialplan =
conf->pri.pri.localdialplan;
12912 pris[span].pri.cpndialplan =
conf->pri.pri.cpndialplan;
12913 pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->
sig_pvt;
12914 pris[span].pri.minunused =
conf->pri.pri.minunused;
12915 pris[span].pri.minidle =
conf->pri.pri.minidle;
12916 pris[span].pri.overlapdial =
conf->pri.pri.overlapdial;
12917 pris[span].pri.qsigchannelmapping =
conf->pri.pri.qsigchannelmapping;
12918 pris[span].pri.discardremoteholdretrieval =
conf->pri.pri.discardremoteholdretrieval;
12919#if defined(HAVE_PRI_SERVICE_MESSAGES)
12920 pris[span].pri.enable_service_message_support =
conf->pri.pri.enable_service_message_support;
12922#ifdef HAVE_PRI_INBANDDISCONNECT
12923 pris[span].pri.inbanddisconnect =
conf->pri.pri.inbanddisconnect;
12925#if defined(HAVE_PRI_CALL_HOLD)
12926 pris[span].pri.hold_disconnect_transfer =
12927 conf->pri.pri.hold_disconnect_transfer;
12929#if defined(HAVE_PRI_CCSS)
12930 pris[span].pri.cc_ptmp_recall_mode =
12931 conf->pri.pri.cc_ptmp_recall_mode;
12932 pris[span].pri.cc_qsig_signaling_link_req =
12933 conf->pri.pri.cc_qsig_signaling_link_req;
12934 pris[span].pri.cc_qsig_signaling_link_rsp =
12935 conf->pri.pri.cc_qsig_signaling_link_rsp;
12937#if defined(HAVE_PRI_CALL_WAITING)
12938 pris[span].pri.max_call_waiting_calls =
12939 conf->pri.pri.max_call_waiting_calls;
12940 pris[span].pri.allow_call_waiting_calls =
12941 conf->pri.pri.allow_call_waiting_calls;
12943 pris[span].pri.transfer =
conf->chan.transfer;
12944 pris[span].pri.facilityenable =
conf->pri.pri.facilityenable;
12945#if defined(HAVE_PRI_L2_PERSISTENCE)
12946 pris[span].pri.l2_persistence =
conf->pri.pri.l2_persistence;
12948 pris[span].pri.colp_send =
conf->pri.pri.colp_send;
12949#if defined(HAVE_PRI_AOC_EVENTS)
12950 pris[span].pri.aoc_passthrough_flag =
conf->pri.pri.aoc_passthrough_flag;
12951 pris[span].pri.aoce_delayhangup =
conf->pri.pri.aoce_delayhangup;
12954 pris[span].pri.layer1_ignored =
conf->pri.pri.layer1_ignored;
12957 pris[span].pri.layer1_ignored = 0;
12959 pris[span].pri.append_msn_to_user_tag =
conf->pri.pri.append_msn_to_user_tag;
12960 pris[span].pri.inband_on_setup_ack =
conf->pri.pri.inband_on_setup_ack;
12961 pris[span].pri.inband_on_proceeding =
conf->pri.pri.inband_on_proceeding;
12962 ast_copy_string(pris[span].pri.initial_user_tag,
conf->chan.cid_tag,
sizeof(pris[span].pri.initial_user_tag));
12963 ast_copy_string(pris[span].pri.msn_list,
conf->pri.pri.msn_list,
sizeof(pris[span].pri.msn_list));
12964#if defined(HAVE_PRI_MWI)
12966 conf->pri.pri.mwi_mailboxes,
12967 sizeof(pris[span].pri.mwi_mailboxes));
12969 conf->pri.pri.mwi_vm_boxes,
12970 sizeof(pris[span].pri.mwi_vm_boxes));
12972 conf->pri.pri.mwi_vm_numbers,
12973 sizeof(pris[span].pri.mwi_vm_numbers));
12975 ast_copy_string(pris[span].pri.idledial,
conf->pri.pri.idledial,
sizeof(pris[span].pri.idledial));
12976 ast_copy_string(pris[span].pri.idleext,
conf->pri.pri.idleext,
sizeof(pris[span].pri.idleext));
12977 ast_copy_string(pris[span].pri.internationalprefix,
conf->pri.pri.internationalprefix,
sizeof(pris[span].pri.internationalprefix));
12978 ast_copy_string(pris[span].pri.nationalprefix,
conf->pri.pri.nationalprefix,
sizeof(pris[span].pri.nationalprefix));
12979 ast_copy_string(pris[span].pri.localprefix,
conf->pri.pri.localprefix,
sizeof(pris[span].pri.localprefix));
12980 ast_copy_string(pris[span].pri.privateprefix,
conf->pri.pri.privateprefix,
sizeof(pris[span].pri.privateprefix));
12981 ast_copy_string(pris[span].pri.unknownprefix,
conf->pri.pri.unknownprefix,
sizeof(pris[span].pri.unknownprefix));
12982 pris[span].pri.moh_signaling =
conf->pri.pri.moh_signaling;
12983 pris[span].pri.resetinterval =
conf->pri.pri.resetinterval;
12984#if defined(HAVE_PRI_DISPLAY_TEXT)
12985 pris[span].pri.display_flags_send =
conf->pri.pri.display_flags_send;
12986 pris[span].pri.display_flags_receive =
conf->pri.pri.display_flags_receive;
12988#if defined(HAVE_PRI_MCID)
12989 pris[span].pri.mcid_send =
conf->pri.pri.mcid_send;
12991 pris[span].pri.force_restart_unavailable_chans =
conf->pri.pri.force_restart_unavailable_chans;
12992#if defined(HAVE_PRI_DATETIME_SEND)
12993 pris[span].pri.datetime_send =
conf->pri.pri.datetime_send;
12996 for (x = 0; x < PRI_MAX_TIMERS; x++) {
12997 pris[span].pri.pritimers[x] =
conf->pri.pri.pritimers[x];
13000#if defined(HAVE_PRI_CALL_WAITING)
13002 pris[span].pri.ch_cfg.stripmsd =
conf->chan.stripmsd;
13003 pris[span].pri.ch_cfg.hidecallerid =
conf->chan.hidecallerid;
13004 pris[span].pri.ch_cfg.hidecalleridname =
conf->chan.hidecalleridname;
13005 pris[span].pri.ch_cfg.immediate =
conf->chan.immediate;
13006 pris[span].pri.ch_cfg.priexclusive =
conf->chan.priexclusive;
13007 pris[span].pri.ch_cfg.priindication_oob =
conf->chan.priindication_oob;
13008 pris[span].pri.ch_cfg.use_callerid =
conf->chan.use_callerid;
13009 pris[span].pri.ch_cfg.use_callingpres =
conf->chan.use_callingpres;
13010 ast_copy_string(pris[span].pri.ch_cfg.context,
conf->chan.context,
sizeof(pris[span].pri.ch_cfg.context));
13011 ast_copy_string(pris[span].pri.ch_cfg.mohinterpret,
conf->chan.mohinterpret,
sizeof(pris[span].pri.ch_cfg.mohinterpret));
13024 chan_sig = tmp->
sig;
13026 memset(&p, 0,
sizeof(p));
13031 switch (chan_sig) {
13055 p.channo = channel;
13059 p.debouncetime = 5;
13061 p.channo = channel;
13063 if (
conf->timing.prewinktime >= 0)
13064 p.prewinktime =
conf->timing.prewinktime;
13065 if (
conf->timing.preflashtime >= 0)
13066 p.preflashtime =
conf->timing.preflashtime;
13067 if (
conf->timing.winktime >= 0)
13068 p.winktime =
conf->timing.winktime;
13069 if (
conf->timing.flashtime >= 0)
13070 p.flashtime =
conf->timing.flashtime;
13071 if (
conf->timing.starttime >= 0)
13072 p.starttime =
conf->timing.starttime;
13073 if (
conf->timing.rxwinktime >= 0)
13074 p.rxwinktime =
conf->timing.rxwinktime;
13075 if (
conf->timing.rxflashtime >= 0)
13076 p.rxflashtime =
conf->timing.rxflashtime;
13077 if (
conf->timing.debouncetime >= 0)
13078 p.debouncetime =
conf->timing.debouncetime;
13093 memset(&bi, 0,
sizeof(bi));
13096 bi.txbufpolicy =
conf->chan.buf_policy;
13097 bi.rxbufpolicy =
conf->chan.buf_policy;
13098 bi.numbufs =
conf->chan.buf_no;
13122 if (chan_sig & __DAHDI_SIG_FXS) {
13163 if (
conf->chan.echocanbridged)
13164 ast_log(
LOG_NOTICE,
"echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
13205 ast_log(
LOG_ERROR,
"Invalid SMDI port specified, disabling SMDI support\n");
13233#if defined(HAVE_PRI)
13250#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
13251 tmp->mwisend_setting =
conf->chan.mwisend_setting;
13252 tmp->mwisend_fsk =
conf->chan.mwisend_fsk;
13253 tmp->mwisend_rpas =
conf->chan.mwisend_rpas;
13263 if (
conf->chan.vars) {
13265 for (v =
conf->chan.vars ; v ; v = v->
next) {
13269 tmp->
vars = tmpvar;
13296 switch (chan_sig) {
13308 if ((res =
get_alarms(tmp)) != DAHDI_ALARM_NONE) {
13310 switch (tmp->
sig) {
13316#if defined(HAVE_SS7)
13347 switch (tmp->
sig) {
13348#if defined(HAVE_PRI)
13351#if defined(HAVE_PRI_SERVICE_MESSAGES)
13354 char db_chan_name[20];
13361 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, tmp->
span, tmp->
channel);
13362 if (!
ast_db_get(db_chan_name, SRVST_DBKEY, db_answer,
sizeof(db_answer))) {
13366 if (tmp->pri->enable_service_message_support) {
13369 sscanf(db_answer,
"%1c:%30u", &
state, why);
13372 *why &= (SRVST_NEAREND | SRVST_FAREND);
13382#if defined(HAVE_SS7)
13397 switch (tmp->
sig) {
13398#if defined(HAVE_PRI)
13418#if defined(HAVE_SS7)
13473 switch (
conf->chan.cid_start) {
13492 if (chan_sig & __DAHDI_SIG_FXO) {
13493 memset(&p, 0,
sizeof(p));
13498#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
13499 res = ioctl(tmp->
subs[
SUB_REAL].
dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting);
13512#if defined(HAVE_PRI)
13518 dahdi_pseudo_parms.buf_no = tmp->
buf_no;
13519 dahdi_pseudo_parms.buf_policy = tmp->
buf_policy;
13520 dahdi_pseudo_parms.faxbuf_no = tmp->
faxbuf_no;
13525 if (tmp && !here) {
13534#if defined(HAVE_PRI)
13537 if (!p->pri || p->pri->
span != span) {
13540 if (!groupmatch && channelmatch == -1) {
13549 if ((p->
group & groupmatch) != groupmatch)
13555 if (channelmatch != -1) {
13556 if (p->
channel != channelmatch)
13559 *channelmatched = 1;
13576#if defined(HAVE_PRI)
13588#if defined(HAVE_SS7)
13605 if (p->mfcr2call) {
13618#if defined(HAVE_PRI)
13619#if defined(HAVE_PRI_CALL_WAITING)
13634 pvt->
stripmsd = pri->ch_cfg.stripmsd;
13637 pvt->
immediate = pri->ch_cfg.immediate;
13648#if defined(HAVE_PRI)
13661static int dahdi_new_pri_nobch_channel(
struct sig_pri_span *pri)
13668 struct dahdi_bufferinfo bi;
13673 for (pvt_idx = 0; pvt_idx < pri->
numchans; ++pvt_idx) {
13674 if (!pri->
pvts[pvt_idx]) {
13702 pvt->
buf_no = dahdi_pseudo_parms.buf_no;
13703 pvt->
buf_policy = dahdi_pseudo_parms.buf_policy;
13704 pvt->
faxbuf_no = dahdi_pseudo_parms.faxbuf_no;
13725 pri->
pvts[pvt_idx] = chan;
13729 ast_log(
LOG_ERROR,
"Unable to open no B channel interface pseudo channel: %s\n",
13734 memset(&bi, 0,
sizeof(bi));
13740 bi.numbufs = pvt->
buf_no;
13744 "Unable to set buffer policy on no B channel interface: %s\n",
13749 "Unable to check buffer policy on no B channel interface: %s\n",
13756 pvt->
channel = nobch_channel;
13760 dahdi_nobch_insert(pri, pvt);
13774 struct dahdi_bufferinfo bi;
13805 bi.numbufs = src->
buf_no;
13842 char *subdir =
NULL;
13886 memset(param, 0,
sizeof(*param));
13889 if (strchr(
args.group,
'!') !=
NULL) {
13891 while ((s = strchr(
prev,
'!')) !=
NULL) {
13895 *(
prev - 1) =
'\0';
13898 }
else if (
args.group[0] ==
'i') {
13900 res = sscanf(
args.group + 1,
"%30d", &x);
13908 s = strchr(
args.group,
'-');
13916 if (toupper(
args.group[0]) ==
'G' || toupper(
args.group[0])==
'R') {
13918 s =
args.group + 1;
13919 res = sscanf(s,
"%30d%1c%30d", &x, ¶m->
opt, ¶m->
cadence);
13926 if (toupper(
args.group[0]) ==
'G') {
13927 if (
args.group[0] ==
'G') {
13938 if (
args.group[0] ==
'R') {
13953 if (!strcasecmp(s,
"pseudo")) {
13958 res = sscanf(s,
"%30d%1c%30d", &x, ¶m->
opt, ¶m->
cadence);
13970 snprintf(path,
sizeof(path),
"/dev/dahdi/%s/%d",
13972 if (stat(path, &stbuf) < 0) {
13974 path, strerror(
errno));
13977 if (!S_ISCHR(stbuf.st_mode)) {
13988 if (param->
opt ==
'r' && res < 3) {
13998 const char *
data,
int *cause)
14004 int channelmatched = 0;
14005 int foundowner = 0;
14006 int groupmatched = 0;
14007#if defined(HAVE_PRI) || defined(HAVE_SS7)
14008 int transcapdigital = 0;
14025 while (p && !tmp) {
14041 if (p->mfcr2call) {
14043 ast_debug(1,
"Yay!, someone just beat us in the race for channel %d.\n", p->
channel);
14059 switch (start.
opt) {
14072#if defined(HAVE_PRI) || defined(HAVE_SS7)
14099#if defined(HAVE_SS7)
14108#if defined(HAVE_PRI)
14111#if defined(HAVE_PRI_CALL_WAITING)
14150 if (cause && !tmp) {
14151 if (callwait || (channelmatched && foundowner)) {
14153 }
else if (groupmatched) {
14179#if defined(HAVE_PRI)
14180 const char *device;
14186 if (*device !=
'I') {
14190 res = sscanf(device,
"I%30u", &span);
14191 if (res != 1 || !span ||
NUM_SPANS < span) {
14195 device = strchr(device,
'/');
14205#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
14207 if (!strcmp(device,
"congestion"))
14210 return pris[span - 1].pri.congestion_devstate;
14212#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
14213 else if (!strcmp(device,
"threshold")) {
14214 return pris[span - 1].pri.threshold_devstate;
14244 int groupmatched = 0;
14245 int channelmatched = 0;
14259 const char *monitor_type;
14269#if defined(HAVE_PRI)
14275 snprintf(full_device_name,
sizeof(full_device_name),
14276 "DAHDI/I%d/congestion", p->pri->
span);
14280#if defined(HAVE_PRI)
14285 snprintf(full_device_name,
sizeof(full_device_name),
"DAHDI/%s",
14293 dash = strrchr(full_device_name,
'-');
14298 snprintf(dialstring,
sizeof(dialstring),
"DAHDI/%s", dest);
14308#
if defined(HAVE_PRI)
14313 monitor_type, full_device_name, dialstring,
NULL);
14321 if (p == exitpvt) {
14329#if defined(HAVE_SS7)
14330static void dahdi_ss7_message(
struct ss7 *ss7,
char *s)
14336 if (linksets[i].ss7.ss7 == ss7) {
14346#if defined(HAVE_SS7)
14347static void dahdi_ss7_error(
struct ss7 *ss7,
char *s)
14353 if (linksets[i].ss7.ss7 == ss7) {
14363#if defined(HAVE_OPENR2)
14364static void *mfcr2_monitor(
void *data)
14366 struct dahdi_mfcr2 *mfcr2 = data;
14384 for (i = 0; i < mfcr2->numchans; i++) {
14385 pvt = mfcr2->pvts[i];
14389 openr2_chan_set_idle(pvt->r2chan);
14390 openr2_chan_handle_cas(pvt->r2chan);
14396 for (i = 0; i < mfcr2->numchans; i++) {
14397 pollers[i].revents = 0;
14398 pollers[i].events = 0;
14399 pvt = mfcr2->pvts[i];
14406 if (mfcr2->nodev) {
14409 if (!pvt->r2chan) {
14414 openr2_chan_enable_read(pvt->r2chan);
14415 pollers[i].events = POLLIN | POLLPRI;
14422 if (pollsize == 0) {
14424 ast_debug(1,
"Monitor thread going idle since everybody has an owner\n");
14427 poll(
NULL, 0, maxsleep);
14433 pthread_testcancel();
14434 res = poll(pollers, mfcr2->numchans, maxsleep);
14435 pthread_testcancel();
14436 if ((res < 0) && (
errno != EINTR)) {
14441 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
14442 for (i = 0; i < mfcr2->numchans; i++) {
14443 pvt = mfcr2->pvts[i];
14447 if (pollers[i].revents & POLLPRI || pollers[i].revents & POLLIN) {
14448 openr2_chan_process_event(pvt->r2chan);
14451 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
14458#if defined(HAVE_PRI)
14459static void dahdi_pri_message(
struct pri *pri,
char *s)
14465 int dchancount = 0;
14470 if (pris[x].pri.dchans[y]) {
14474 if (pris[x].pri.dchans[y] == pri) {
14485 if (1 < dchancount) {
14499 if (pridebugfd >= 0) {
14500 if (write(pridebugfd, s, strlen(s)) < 0) {
14509#if defined(HAVE_PRI)
14510static void dahdi_pri_error(
struct pri *pri,
char *s)
14516 int dchancount = 0;
14521 if (pris[x].pri.dchans[y]) {
14525 if (pris[x].pri.dchans[y] == pri) {
14536 if (1 < dchancount) {
14550 if (pridebugfd >= 0) {
14551 if (write(pridebugfd, s, strlen(s)) < 0) {
14560#if defined(HAVE_PRI)
14561static int prepare_pri(
struct dahdi_pri *pri)
14564 struct dahdi_params p;
14565 struct dahdi_bufferinfo bi;
14566 struct dahdi_spaninfo si;
14569 if (!pri->dchannels[i])
14571 if (pri->pri.fds[i] >= 0) {
14575 pri->pri.fds[i] = open(
"/dev/dahdi/channel", O_RDWR);
14576 if ((pri->pri.fds[i] < 0)) {
14578 pri->pri.fds[i], strerror(
errno));
14581 x = pri->dchannels[i];
14582 res = ioctl(pri->pri.fds[i], DAHDI_SPECIFY, &x);
14584 dahdi_close_pri_fd(pri, i);
14588 memset(&p, 0,
sizeof(p));
14589 res = ioctl(pri->pri.fds[i], DAHDI_GET_PARAMS, &p);
14591 dahdi_close_pri_fd(pri, i);
14595 if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) {
14596 dahdi_close_pri_fd(pri, i);
14600 memset(&si, 0,
sizeof(si));
14601 res = ioctl(pri->pri.fds[i], DAHDI_SPANSTAT, &si);
14603 dahdi_close_pri_fd(pri, i);
14611 memset(&bi, 0,
sizeof(bi));
14612 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
14613 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
14616 if (ioctl(pri->pri.fds[i], DAHDI_SET_BUFINFO, &bi)) {
14618 dahdi_close_pri_fd(pri, i);
14621 pri->pri.dchan_logical_span[i] = pris[p.spanno - 1].prilogicalspan;
14627#if defined(HAVE_PRI)
14628static char *complete_span_helper(
const char *line,
const char *
word,
int pos,
int state,
int rpos)
14636 for (which = span = 0; span <
NUM_SPANS; span++) {
14637 if (pris[span].pri.pri && ++which >
state) {
14648#if defined(HAVE_PRI)
14649static char *complete_span_4(
const char *line,
const char *
word,
int pos,
int state)
14651 return complete_span_helper(line,
word,pos,
state,3);
14655#if defined(HAVE_PRI)
14661 e->
command =
"pri set debug file";
14662 e->
usage =
"Usage: pri set debug file [output-file]\n"
14663 " Sends PRI debug output to the specified output file\n";
14676 ast_cli(
a->fd,
"Unable to open '%s' for writing\n",
a->argv[4]);
14682 if (pridebugfd >= 0)
14688 ast_cli(
a->fd,
"PRI debug output will be sent to '%s'\n",
a->argv[4]);
14693#if defined(HAVE_PRI)
14694static int action_pri_debug_file_set(
struct mansession *s,
const struct message *m)
14711 if (pridebugfd >= 0) {
14716 ast_copy_string(pridebugfilename, output_file,
sizeof(pridebugfilename));
14718 astman_send_ack(s, m,
"PRI debug output will now be sent to requested file.");
14724#if defined(HAVE_PRI)
14725static int action_pri_debug_file_unset(
struct mansession *s,
const struct message *m)
14729 if (pridebugfd >= 0) {
14742#if defined(HAVE_PRI)
14751 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";
14753 "Usage: pri set debug {<level>|on|off|hex|intense} span <span>\n"
14754 " Enables debugging on a given PRI span\n"
14755 " Level is a bitmap of the following values:\n"
14756 " 1 General debugging incl. state changes\n"
14757 " 2 Decoded Q.931 messages\n"
14758 " 4 Decoded Q.921 messages\n"
14759 " 8 Raw hex dumps of Q.921 frames\n"
14760 " on - equivalent to 3\n"
14761 " hex - equivalent to 8\n"
14762 " intense - equivalent to 15\n";
14765 return complete_span_4(
a->line,
a->word,
a->pos,
a->n);
14771 if (!strcasecmp(
a->argv[3],
"on")) {
14773 }
else if (!strcasecmp(
a->argv[3],
"off")) {
14775 }
else if (!strcasecmp(
a->argv[3],
"intense")) {
14777 }
else if (!strcasecmp(
a->argv[3],
"hex")) {
14780 level = atoi(
a->argv[3]);
14782 span = atoi(
a->argv[5]);
14783 if ((span < 1) || (span >
NUM_SPANS)) {
14784 ast_cli(
a->fd,
"Invalid span %s. Should be a number %d to %d\n",
a->argv[5], 1,
NUM_SPANS);
14787 if (!pris[span-1].pri.pri) {
14788 ast_cli(
a->fd,
"No PRI running on span %d\n", span);
14793 if (level & 2) debugmask |= PRI_DEBUG_Q931_DUMP;
14794 if (level & 4) debugmask |= PRI_DEBUG_Q921_DUMP;
14795 if (level & 8) debugmask |= PRI_DEBUG_Q921_RAW;
14799 if (pris[span - 1].pri.dchans[x]) {
14800 pri_set_debug(pris[span - 1].pri.dchans[x], debugmask);
14806 if (0 <= pridebugfd) {
14809 ast_cli(
a->fd,
"Disabled PRI debug output to file '%s'\n",
14814 pris[span - 1].pri.debug = (level) ? 1 : 0;
14815 ast_cli(
a->fd,
"%s debugging on span %d\n", (level) ?
"Enabled" :
"Disabled", span);
14820#if defined(HAVE_PRI)
14840 if (!strcasecmp(level,
"on")) {
14842 }
else if (!strcasecmp(level,
"off")) {
14844 }
else if (!strcasecmp(level,
"intense")) {
14846 }
else if (!strcasecmp(level,
"hex")) {
14849 if (sscanf(level,
"%30d", &level_val) != 1) {
14855 if (sscanf(span,
"%30d", &span_val) != 1) {
14859 if ((span_val < 1) || (span_val >
NUM_SPANS)) {
14861 char id_text[256] =
"";
14864 snprintf(id_text,
sizeof(id_text),
"ActionID: %s\r\n",
id);
14869 "Message: Invalid span '%s' - Should be a number from 1 to %d\r\n"
14877 if (!pris[span_val-1].pri.pri) {
14882 if (level_val & 1) {
14885 if (level_val & 2) {
14886 debugmask |= PRI_DEBUG_Q931_DUMP;
14888 if (level_val & 4) {
14889 debugmask |= PRI_DEBUG_Q921_DUMP;
14891 if (level_val & 8) {
14892 debugmask |= PRI_DEBUG_Q921_RAW;
14897 if (pris[span_val - 1].pri.dchans[x]) {
14898 pri_set_debug(pris[span_val - 1].pri.dchans[x], debugmask);
14902 pris[span_val - 1].pri.debug = (level_val) ? 1 : 0;
14909#if defined(HAVE_PRI)
14910#if defined(HAVE_PRI_SERVICE_MESSAGES)
14916 int x, y, fd =
a->fd;
14917 int interfaceid = 0;
14918 char db_chan_name[20], db_answer[15];
14920 struct dahdi_pri *pri;
14922 if (
a->argc < 5 ||
a->argc > 6)
14924 if (strchr(
a->argv[4],
':')) {
14925 if (sscanf(
a->argv[4],
"%30d:%30d", &trunkgroup, &channel) != 2)
14927 if ((trunkgroup < 1) || (channel < 1))
14931 if (pris[x].pri.trunkgroup == trunkgroup) {
14937 ast_cli(fd,
"No such trunk group %d\n", trunkgroup);
14941 channel = atoi(
a->argv[4]);
14944 interfaceid = atoi(
a->argv[5]);
14949 if (pris[x].dchannels[y] == channel) {
14951 if (pri->pri.enable_service_message_support) {
14953 pri_maintenance_service(pri->pri.pri, interfaceid, -1, changestatus);
14957 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n"
14958 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n");
14968 if (tmp->pri && tmp->
channel == channel) {
14971 if (!tmp->pri->enable_service_message_support) {
14974 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n"
14975 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n");
14978 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, tmp->
span, channel);
14980 switch(changestatus) {
14984 *why &= ~SRVST_NEAREND;
14986 snprintf(db_answer,
sizeof(db_answer),
"%s:%u", SRVST_TYPE_OOS, *why);
14987 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
14989 dahdi_pri_update_span_devstate(tmp->pri);
14996 *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);
14999 dahdi_pri_update_span_devstate(tmp->pri);
15007 pri_maintenance_bservice(tmp->pri->pri, tmp->
sig_pvt, changestatus);
15014 ast_cli(fd,
"Unable to find given channel %d, possibly not a PRI\n",
channel);
15022 e->
command =
"pri service enable channel";
15024 "Usage: pri service enable channel <channel> [<interface id>]\n"
15025 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n"
15026 " to restore a channel to service, with optional interface id\n"
15027 " as agreed upon with remote switch operator\n";
15032 return handle_pri_service_generic(e, cmd,
a, 0);
15039 e->
command =
"pri service disable channel";
15041 "Usage: pri service disable channel <chan num> [<interface id>]\n"
15042 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n"
15043 " to remove a channel from service, with optional interface id\n"
15044 " as agreed upon with remote switch operator\n";
15049 return handle_pri_service_generic(e, cmd,
a, 2);
15054#if defined(HAVE_PRI)
15061 e->
command =
"pri show channels";
15063 "Usage: pri show channels\n"
15064 " Displays PRI channel information such as the current mapping\n"
15065 " of DAHDI B channels to Asterisk channel names and which calls\n"
15066 " are on hold or call-waiting. Calls on hold or call-waiting\n"
15067 " are not associated with any B channel.\n";
15077 for (span = 0; span <
NUM_SPANS; ++span) {
15078 if (pris[span].
pri.
pri) {
15086#if defined(HAVE_PRI)
15093 e->
command =
"pri show spans";
15095 "Usage: pri show spans\n"
15096 " Displays PRI span information\n";
15105 for (span = 0; span <
NUM_SPANS; span++) {
15106 if (pris[span].
pri.
pri) {
15114#if defined(HAVE_PRI)
15115#define container_of(ptr, type, member) \
15116 ((type *)((char *)(ptr) - offsetof(type, member)))
15133 struct dahdi_pri* dahdi_pri;
15134 pthread_t master = pri->
master;
15139 ast_debug(2,
"About to destroy DAHDI channels of span %d.\n", pri->
span);
15140 for (i = 0; i < pri->
numchans; i++) {
15152 cancel_code = pthread_cancel(master);
15153 pthread_kill(master, SIGURG);
15155 "Waiting to join thread of span %d "
15156 "with pid=%p cancel_code=%d\n",
15157 pri->
span, (
void *)master, cancel_code);
15158 res = pthread_join(master,
NULL);
15167 ast_debug(4,
"closing pri_fd %d\n", i);
15168 dahdi_close_pri_fd(dahdi_pri, i);
15169 dahdi_pri->dchannels[i] = 0;
15175static char *handle_pri_destroy_span(
struct ast_cli_entry *e,
int cmd,
15184 e->
command =
"pri destroy span";
15186 "Usage: pri destroy span <span>\n"
15187 " Destroys D-channel of span and its B-channels.\n"
15188 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n";
15191 return complete_span_4(
a->line,
a->word,
a->pos,
a->n);
15197 res = sscanf(
a->argv[3],
"%30d", &
span);
15198 if ((res != 1) || span < 1 || span >
NUM_SPANS) {
15200 "Invalid span '%s'. Should be a number from %d to %d\n",
15210 pri_destroy_span(
pri);
15216#if defined(HAVE_PRI)
15223 e->
command =
"pri show span";
15225 "Usage: pri show span <span>\n"
15226 " Displays PRI Information on a given PRI span\n";
15229 return complete_span_4(
a->line,
a->word,
a->pos,
a->n);
15234 span = atoi(
a->argv[3]);
15236 ast_cli(
a->fd,
"Invalid span '%s'. Should be a number from %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
15250#if defined(HAVE_PRI)
15260 e->
command =
"pri show debug";
15262 "Usage: pri show debug\n"
15263 " Show the debug state of pri spans\n";
15272 if (pris[
span].
pri.dchans[x]) {
15274 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" );
15282 if (pridebugfd >= 0)
15283 ast_cli(
a->fd,
"Logging PRI debug to file %s\n", pridebugfilename);
15287 ast_cli(
a->fd,
"No PRI running\n");
15292#if defined(HAVE_PRI)
15297 e->
command =
"pri show version";
15299 "Usage: pri show version\n"
15300 "Show libpri version information\n";
15306 ast_cli(
a->fd,
"libpri version: %s\n", pri_get_version());
15312#if defined(HAVE_PRI)
15314 AST_CLI_DEFINE(handle_pri_debug,
"Enables PRI debugging on a span"),
15315#if defined(HAVE_PRI_SERVICE_MESSAGES)
15316 AST_CLI_DEFINE(handle_pri_service_enable_channel,
"Return a channel to service"),
15317 AST_CLI_DEFINE(handle_pri_service_disable_channel,
"Remove a channel from service"),
15319 AST_CLI_DEFINE(handle_pri_show_channels,
"Displays PRI channel information"),
15320 AST_CLI_DEFINE(handle_pri_show_spans,
"Displays PRI span information"),
15321 AST_CLI_DEFINE(handle_pri_show_span,
"Displays PRI span information"),
15323 AST_CLI_DEFINE(handle_pri_show_debug,
"Displays current PRI debug settings"),
15324 AST_CLI_DEFINE(handle_pri_set_debug_file,
"Sends PRI debug output to the specified file"),
15335 e->
command =
"mfcr2 show version";
15337 "Usage: mfcr2 show version\n"
15338 " Shows the version of the OpenR2 library being used.\n";
15343 ast_cli(
a->fd,
"OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision());
15349#define FORMAT "%4s %40s\n"
15351 int numvariants = 0;
15352 const openr2_variant_entry_t *variants;
15355 e->
command =
"mfcr2 show variants";
15357 "Usage: mfcr2 show variants\n"
15358 " Shows the list of MFC/R2 variants supported.\n";
15363 if (!(variants = openr2_proto_get_variant_list(&numvariants))) {
15364 ast_cli(
a->fd,
"Failed to get list of variants.\n");
15368 for (i = 0; i < numvariants; i++) {
15377#define FORMAT "%4s %4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n"
15378 int filtertype = 0;
15385 openr2_context_t *r2context;
15386 openr2_variant_t r2variant;
15389 e->
command =
"mfcr2 show channels [group|context]";
15391 "Usage: mfcr2 show channels [group <group> | context <context>]\n"
15392 " Shows the DAHDI channels configured with MFC/R2 signaling.\n";
15397 if (!((
a->argc == 3) || (
a->argc == 5))) {
15400 if (
a->argc == 5) {
15401 if (!strcasecmp(
a->argv[3],
"group")) {
15402 targetnum = atoi(
a->argv[4]);
15403 if ((targetnum < 0) || (targetnum > 63))
15405 targetnum = 1 << targetnum;
15407 }
else if (!strcasecmp(
a->argv[3],
"context")) {
15413 ast_cli(
a->fd,
FORMAT,
"Chan",
"Link#",
"Variant",
"Max ANI",
"Max DNIS",
"ANI First",
"Immediate Accept",
"Tx CAS",
"Rx CAS");
15420 switch(filtertype) {
15422 if (p->
group != targetnum) {
15427 if (strcasecmp(p->
context,
a->argv[4])) {
15435 r2context = openr2_chan_get_context(p->r2chan);
15436 r2variant = openr2_context_get_variant(r2context);
15437 snprintf(channo,
sizeof(channo),
"%d", p->
channel);
15438 snprintf(linkno,
sizeof(linkno),
"%d", p->mfcr2->index);
15439 snprintf(anino,
sizeof(anino),
"%d", openr2_context_get_max_ani(r2context));
15440 snprintf(dnisno,
sizeof(dnisno),
"%d", openr2_context_get_max_dnis(r2context));
15441 ast_cli(
a->fd,
FORMAT, channo, linkno, openr2_proto_get_variant_string(r2variant),
15442 anino, dnisno, openr2_context_get_ani_first(r2context) ?
"Yes" :
"No",
15443 openr2_context_get_immediate_accept(r2context) ?
"Yes" :
"No",
15444 openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan));
15455 char *toklevel =
NULL;
15456 char *saveptr =
NULL;
15457 char *logval =
NULL;
15458 openr2_log_level_t loglevel = OR2_LOG_NOTHING;
15459 openr2_log_level_t tmplevel = OR2_LOG_NOTHING;
15462 e->
command =
"mfcr2 set debug";
15464 "Usage: mfcr2 set debug <loglevel> <channel>\n"
15465 " Set a new logging level for the specified channel.\n"
15466 " If no channel is specified the logging level will be applied to all channels.\n";
15474 channo = (
a->argc == 5) ? atoi(
a->argv[4]) : -1;
15476 toklevel = strtok_r(logval,
",", &saveptr);
15477 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
15478 ast_cli(
a->fd,
"Invalid MFC/R2 logging level '%s'.\n",
a->argv[3]);
15480 }
else if (OR2_LOG_NOTHING == tmplevel) {
15481 loglevel = tmplevel;
15483 loglevel |= tmplevel;
15484 while ((toklevel = strtok_r(
NULL,
",", &saveptr))) {
15485 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
15486 ast_cli(
a->fd,
"Ignoring invalid logging level: '%s'.\n", toklevel);
15489 loglevel |= tmplevel;
15497 if ((channo != -1) && (p->
channel != channo )) {
15500 openr2_chan_set_log_level(p->r2chan, loglevel);
15501 if (channo != -1) {
15502 ast_cli(
a->fd,
"MFC/R2 debugging set to '%s' for channel %d.\n",
a->argv[3], p->
channel);
15506 if ((channo != -1) && !p) {
15507 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15509 if (channo == -1) {
15510 ast_cli(
a->fd,
"MFC/R2 debugging set to '%s' for all channels.\n",
a->argv[3]);
15522 e->
command =
"mfcr2 call files [on|off]";
15524 "Usage: mfcr2 call files [on|off] <channel>\n"
15525 " Enable call files creation on the specified channel.\n"
15526 " If no channel is specified call files creation policy will be applied to all channels.\n";
15534 channo = (
a->argc == 5) ? atoi(
a->argv[4]) : -1;
15540 if ((channo != -1) && (p->
channel != channo )) {
15544 openr2_chan_enable_call_files(p->r2chan);
15546 openr2_chan_disable_call_files(p->r2chan);
15548 if (channo != -1) {
15550 ast_cli(
a->fd,
"MFC/R2 call files enabled for channel %d.\n", p->
channel);
15552 ast_cli(
a->fd,
"MFC/R2 call files disabled for channel %d.\n", p->
channel);
15557 if ((channo != -1) && !p) {
15558 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15560 if (channo == -1) {
15562 ast_cli(
a->fd,
"MFC/R2 Call files enabled for all channels.\n");
15564 ast_cli(
a->fd,
"MFC/R2 Call files disabled for all channels.\n");
15577 e->
command =
"mfcr2 set idle";
15579 "Usage: mfcr2 set idle <channel>\n"
15580 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
15581 " Force the given channel into IDLE state.\n"
15582 " If no channel is specified, all channels will be set to IDLE.\n";
15587 channo = (
a->argc == 4) ? atoi(
a->argv[3]) : -1;
15593 if ((channo != -1) && (p->
channel != channo )) {
15596 openr2_chan_set_idle(p->r2chan);
15601 if (channo != -1) {
15605 if ((channo != -1) && !p) {
15606 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15618 e->
command =
"mfcr2 set blocked";
15620 "Usage: mfcr2 set blocked <channel>\n"
15621 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
15622 " Force the given channel into BLOCKED state.\n"
15623 " If no channel is specified, all channels will be set to BLOCKED.\n";
15628 channo = (
a->argc == 4) ? atoi(
a->argv[3]) : -1;
15634 if ((channo != -1) && (p->
channel != channo )) {
15637 openr2_chan_set_blocked(p->r2chan);
15641 if (channo != -1) {
15645 if ((channo != -1) && !p) {
15646 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15652static void mfcr2_show_links_of(
struct ast_cli_args *
a,
struct r2links *list_head,
const char *title)
15654#define FORMAT "%-5s %-10s %-15s %-10s %s\n"
15659 char live_chans_str[5];
15660 char channel_list[R2_LINK_CAPACITY * 4];
15661 struct r2link_entry *cur;
15663 ast_cli(
a->fd,
FORMAT,
"Index",
"Thread",
"Dahdi-Device",
"Channels",
"Channel-List");
15665 struct dahdi_mfcr2 *mfcr2 = &cur->mfcr2;
15666 const char *thread_status =
NULL;
15673 if (mfcr2->r2master == 0L) {
15674 thread_status =
"zero";
15676 thread_status =
"none";
15678 thread_status =
"created";
15680 snprintf(index,
sizeof(index),
"%d", mfcr2->index);
15681 snprintf(live_chans_str,
sizeof(live_chans_str),
"%d", mfcr2->live_chans);
15687 for (i = 0; i < mfcr2->numchans &&
len <
sizeof(channel_list) - 1; i++) {
15694 if (prev_channo && prev_channo == channo - 1) {
15695 prev_channo = channo;
15699 if (inside_range) {
15701 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
"-%d,%d", prev_channo, channo);
15703 }
else if (prev_channo) {
15705 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
",%d", channo);
15708 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
"%d", channo);
15710 prev_channo = channo;
15713 if (inside_range) {
15715 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
"-%d", channo);
15717 }
else if (prev_channo) {
15719 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
",%d", channo);
15725 (mfcr2->nodev) ?
"MISSING" :
"OK",
15738 e->
command =
"mfcr2 show links";
15740 "Usage: mfcr2 show links\n"
15741 " Shows the DAHDI MFC/R2 links.\n";
15746 if (
a->argc != 3) {
15749 mfcr2_show_links_of(
a, &r2links,
"Live links\n");
15750 mfcr2_show_links_of(
a, &nodev_r2links,
"Links to be removed (device missing)\n");
15757 int wanted_link_index;
15758 int found_link = 0;
15759 struct r2link_entry *cur =
NULL;
15763 e->
command =
"mfcr2 destroy link";
15765 "Usage: mfcr2 destroy link <index-number>\n"
15766 " Destroys D-channel of link and its B-channels.\n"
15767 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n";
15775 res = sscanf(
a->argv[3],
"%30d", &wanted_link_index);
15776 if ((res != 1) || wanted_link_index < 1) {
15778 "Invalid link index '%s'. Should be a positive number\n",
a->argv[3]);
15783 struct dahdi_mfcr2 *mfcr2 = &cur->mfcr2;
15784 if (wanted_link_index == mfcr2->index) {
15792 if (! found_link) {
15793 ast_cli(
a->fd,
"No link found with index %d.\n", wanted_link_index);
15800 AST_CLI_DEFINE(handle_mfcr2_version,
"Show OpenR2 library version"),
15801 AST_CLI_DEFINE(handle_mfcr2_show_variants,
"Show supported MFC/R2 variants"),
15802 AST_CLI_DEFINE(handle_mfcr2_show_channels,
"Show MFC/R2 channels"),
15804 AST_CLI_DEFINE(handle_mfcr2_set_debug,
"Set MFC/R2 channel logging level"),
15805 AST_CLI_DEFINE(handle_mfcr2_call_files,
"Enable/Disable MFC/R2 call files"),
15806 AST_CLI_DEFINE(handle_mfcr2_set_idle,
"Reset MFC/R2 channel forcing it to IDLE"),
15807 AST_CLI_DEFINE(handle_mfcr2_set_blocked,
"Reset MFC/R2 channel forcing it to BLOCKED"),
15808 AST_CLI_DEFINE(handle_mfcr2_destroy_link,
"Destroy given MFC/R2 link"),
15819 e->
command =
"dahdi destroy channels";
15821 "Usage: dahdi destroy channels <from_channel> [<to_channel>]\n"
15822 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n";
15827 if ((
a->argc < 4) ||
a->argc > 5) {
15830 start = atoi(
a->argv[3]);
15832 ast_cli(
a->fd,
"Invalid starting channel number %s.\n",
15836 if (
a->argc == 5) {
15837 end = atoi(
a->argv[4]);
15839 ast_cli(
a->fd,
"Invalid ending channel number %s.\n",
15849 "range end (%d) is smaller than range start (%d)\n",
15865 e->
command =
"dahdi create channels";
15866 e->
usage =
"Usage: dahdi create channels <from> [<to>] - a range of channels\n"
15867 " dahdi create channels new - add channels not yet created\n"
15868 "For ISDN and SS7 the range should include complete spans.\n";
15873 if ((
a->argc < 4) ||
a->argc > 5) {
15876 if (
a->argc == 4 && !strcmp(
a->argv[3],
"new")) {
15880 start = atoi(
a->argv[3]);
15882 ast_cli(
a->fd,
"Invalid starting channel number '%s'.\n",
15886 if (
a->argc == 5) {
15887 end = atoi(
a->argv[4]);
15889 ast_cli(
a->fd,
"Invalid ending channel number '%s'.\n",
15898 "range end (%d) is smaller than range start (%d)\n",
15936#if defined(HAVE_PRI) || defined(HAVE_SS7)
15943 ast_verb(1,
"Destroying channels and reloading DAHDI configuration.\n");
15945 ast_verb(4,
"Initial softhangup of all DAHDI channels complete.\n");
15947 dahdi_r2_destroy_links();
15950#if defined(HAVE_PRI)
15953 cancel_code = pthread_cancel(pris[i].pri.
master);
15954 pthread_kill(pris[i].pri.
master, SIGURG);
15955 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);
15957 ast_debug(4,
"Joined thread of span %d\n", i);
15962#if defined(HAVE_SS7)
15965 cancel_code = pthread_cancel(linksets[i].ss7.master);
15966 pthread_kill(linksets[i].ss7.master, SIGURG);
15967 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);
15968 pthread_join(linksets[i].ss7.master,
NULL);
15969 ast_debug(4,
"Joined thread of span %d\n", i);
15978 ast_debug(4,
"Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (
void *)
monitor_thread, cancel_code);
15980 ast_debug(4,
"Joined monitor thread\n");
15986 int x = DAHDI_FLASH;
16002 ast_verb(4,
"Final softhangup of all DAHDI channels complete.\n");
16012 dahdi_close_pri_fd(&(pris[i]), j);
16015 memset(pris, 0,
sizeof(pris));
16019 pri_set_error(dahdi_pri_error);
16020 pri_set_message(dahdi_pri_message);
16022#if defined(HAVE_SS7)
16025 dahdi_close_ss7_fd(&(linksets[i]), j);
16028 memset(linksets, 0,
sizeof(linksets));
16032 ss7_set_error(dahdi_ss7_error);
16033 ss7_set_message(dahdi_ss7_message);
16053 e->
command =
"dahdi restart";
16055 "Usage: dahdi restart\n"
16056 " Restarts the DAHDI channels: destroys them all and then\n"
16057 " re-reads them from chan_dahdi.conf.\n"
16058 " Note that this will STOP any running CALL on DAHDI channels.\n"
16084#define FORMAT "%7s %4d %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
16085#define FORMAT2 "%7s %4s %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
16087 int filtertype = 0;
16094 e->
command =
"dahdi show channels [group|context]";
16096 "Usage: dahdi show channels [ group <group> | context <context> ]\n"
16097 " Shows a list of available channels with optional filtering\n"
16098 " <group> must be a number between 0 and 63\n";
16106 if (!((
a->argc == 3) || (
a->argc == 5))) {
16110 if (
a->argc == 5) {
16111 if (!strcasecmp(
a->argv[3],
"group")) {
16112 targetnum = atoi(
a->argv[4]);
16113 if (63 < targetnum) {
16118 }
else if (!strcasecmp(
a->argv[3],
"context")) {
16123 ast_cli(
a->fd,
FORMAT2,
"Chan",
"Span",
"Signalling",
"Extension",
"Context",
"Language",
"MOH Interpret",
"Blocked",
"In Service",
"Alarms",
"Description");
16128 switch(filtertype) {
16130 if (!(tmp->
group & targetnum)) {
16135 if (strcasecmp(tmp->
context,
a->argv[4])) {
16144 snprintf(tmps,
sizeof(tmps),
"%d", tmp->
channel);
16152 blockstr[2] =
'\0';
16154 ast_cli(
a->fd,
FORMAT, tmps, tmp->
span,
sig2str(tmp->
sig), tmp->
exten, tmp->
context, tmp->
language, tmp->
mohinterpret, blockstr, tmp->
inservice ?
"Yes" :
"No",
16167 struct dahdi_confinfo ci;
16168 struct dahdi_params ps;
16175 e->
command =
"dahdi show channel";
16177 "Usage: dahdi show channel <chan num>\n"
16178 " Detailed information about a given channel\n";
16187 channel = atoi(
a->argv[3]);
16191 if (tmp->
channel == channel) {
16201#if defined(HAVE_PRI)
16202#if defined(HAVE_PRI_SUBADDR)
16211 for (v = tmp->
vars ; v ; v = v->
next)
16225 ast_cli(
a->fd,
"DSP: %s\n", tmp->
dsp ?
"yes" :
"no");
16228#if defined(BUSYDETECT_TONEONLY)
16229 ast_cli(
a->fd,
" Busy Detector Helper: BUSYDETECT_TONEONLY\n");
16230#elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
16231 ast_cli(
a->fd,
" Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n");
16233#ifdef BUSYDETECT_DEBUG
16234 ast_cli(
a->fd,
" Busy Detector Debug: Enabled\n");
16239 ast_cli(
a->fd,
"TDD: %s\n", tmp->
tdd ?
"yes" :
"no");
16246 snprintf(hwrxgain,
sizeof(hwrxgain),
"%.1f", tmp->
hwrxgain);
16251 snprintf(hwtxgain,
sizeof(hwtxgain),
"%.1f", tmp->
hwtxgain);
16255 ast_cli(
a->fd,
"HW Gains (RX/TX): %s/%s\n", hwrxgain, hwtxgain);
16257 ast_cli(
a->fd,
"Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->
rxdrc, tmp->
txdrc);
16259 ast_cli(
a->fd,
"Echo Cancellation:\n");
16279 char calldir[OR2_MAX_PATH];
16280 openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
16281 openr2_variant_t r2variant = openr2_context_get_variant(r2context);
16282 ast_cli(
a->fd,
"MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan));
16283 ast_cli(
a->fd,
"MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan));
16284 ast_cli(
a->fd,
"MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan));
16285 ast_cli(
a->fd,
"MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan));
16286 ast_cli(
a->fd,
"MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ?
"Yes" :
"No");
16287 ast_cli(
a->fd,
"MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant));
16288 ast_cli(
a->fd,
"MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context));
16289 ast_cli(
a->fd,
"MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
16290#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
16291 ast_cli(
a->fd,
"MFC/R2 DTMF Dialing: %s\n", openr2_context_get_dtmf_dialing(r2context,
NULL,
NULL) ?
"Yes" :
"No");
16292 ast_cli(
a->fd,
"MFC/R2 DTMF Detection: %s\n", openr2_context_get_dtmf_detection(r2context) ?
"Yes" :
"No");
16294 ast_cli(
a->fd,
"MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ?
"Yes" :
"No");
16295#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
16296 ast_cli(
a->fd,
"MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ?
"Yes" :
"No");
16298 ast_cli(
a->fd,
"MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ?
"Yes" :
"No");
16299 ast_cli(
a->fd,
"MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ?
"Yes" :
"No");
16300 ast_cli(
a->fd,
"MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ?
"Yes" :
"No");
16301 ast_cli(
a->fd,
"MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ?
"Yes" :
"No");
16302 ast_cli(
a->fd,
"MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ?
"Yes" :
"No");
16303 ast_cli(
a->fd,
"MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context));
16304 ast_cli(
a->fd,
"MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context));
16305 ast_cli(
a->fd,
"MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan));
16306 ast_cli(
a->fd,
"MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan));
16307 ast_cli(
a->fd,
"MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan));
16308 ast_cli(
a->fd,
"MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan));
16309 ast_cli(
a->fd,
"MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir,
sizeof(calldir)));
16312#if defined(HAVE_SS7)
16333 if (tmp->logicalspan)
16334 ast_cli(
a->fd,
"PRI Logical Span: %d\n", tmp->logicalspan);
16336 ast_cli(
a->fd,
"PRI Logical Span: Implicit\n");
16339 memset(&ci, 0,
sizeof(ci));
16342 memset(&ci, 0,
sizeof(ci));
16344 ast_cli(
a->fd,
"Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, (
unsigned)ci.confmode);
16347 ast_cli(
a->fd,
"Actual Confmute: %s\n", x ?
"Yes" :
"No");
16349 memset(&ps, 0,
sizeof(ps));
16353 ast_cli(
a->fd,
"Hookstate (FXS only): %s\n", ps.rxisoffhook ?
"Offhook" :
"Onhook");
16371 e->
command =
"dahdi show cadences";
16373 "Usage: dahdi show cadences\n"
16374 " Shows all cadences currently defined\n";
16381 char tmp[16], tmp2[64];
16382 snprintf(tmp,
sizeof(tmp),
"r%d: ", i + 1);
16385 for (j = 0; j < 16; j++) {
16386 if (
cadences[i].ringcadence[j] == 0)
16388 snprintf(tmp,
sizeof(tmp),
"%d",
cadences[i].ringcadence[j]);
16394 strncat(output,
",",
sizeof(output) - strlen(output) - 1);
16395 strncat(output, tmp2,
sizeof(output) - strlen(output) - 1);
16404 alarmstr[0] =
'\0';
16405 if (spaninfo->alarms > 0) {
16406 if (spaninfo->alarms & DAHDI_ALARM_BLUE) {
16407 strcat(alarmstr,
"BLU/");
16409 if (spaninfo->alarms & DAHDI_ALARM_YELLOW) {
16410 strcat(alarmstr,
"YEL/");
16412 if (spaninfo->alarms & DAHDI_ALARM_RED) {
16413 strcat(alarmstr,
"RED/");
16415 if (spaninfo->alarms & DAHDI_ALARM_LOOPBACK) {
16416 strcat(alarmstr,
"LB/");
16418 if (spaninfo->alarms & DAHDI_ALARM_RECOVER) {
16419 strcat(alarmstr,
"REC/");
16421 if (spaninfo->alarms & DAHDI_ALARM_NOTOPEN) {
16422 strcat(alarmstr,
"NOP/");
16424 if (!strlen(alarmstr)) {
16425 strcat(alarmstr,
"UUU/");
16427 if (strlen(alarmstr)) {
16429 alarmstr[strlen(alarmstr) - 1] =
'\0';
16432 if (spaninfo->numchans) {
16433 strcpy(alarmstr,
"OK");
16435 strcpy(alarmstr,
"UNCONFIGURED");
16443 #define FORMAT "%4d %-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"
16444 #define FORMAT2 "%4s %-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"
16450 struct dahdi_spaninfo s;
16454 e->
command =
"dahdi show status";
16456 "Usage: dahdi show status\n"
16457 " Shows a list of DAHDI cards with status\n";
16462 ctl = open(
"/dev/dahdi/ctl", O_RDWR);
16464 ast_cli(
a->fd,
"No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(
errno));
16467 ast_cli(
a->fd,
FORMAT2,
"Span",
"Description",
"Alarms",
"IRQ",
"bpviol",
"CRC",
"Framing",
"Coding",
"Options",
"LBO");
16469 for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
16471 res = ioctl(ctl, DAHDI_SPANSTAT, &s);
16476 ast_cli(
a->fd,
FORMAT, span, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count,
16477 s.lineconfig & DAHDI_CONFIG_D4 ?
"D4" :
16478 s.lineconfig & DAHDI_CONFIG_ESF ?
"ESF" :
16479 s.lineconfig & DAHDI_CONFIG_CCS ?
"CCS" :
16481 s.lineconfig & DAHDI_CONFIG_B8ZS ?
"B8ZS" :
16482 s.lineconfig & DAHDI_CONFIG_HDB3 ?
"HDB3" :
16483 s.lineconfig & DAHDI_CONFIG_AMI ?
"AMI" :
16485 s.lineconfig & DAHDI_CONFIG_CRC4 ?
16486 s.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"CRC4/YEL" :
"CRC4" :
16487 s.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"YEL" :
"",
16500 int pseudo_fd = -1;
16501 struct dahdi_versioninfo vi;
16505 e->
command =
"dahdi show version";
16507 "Usage: dahdi show version\n"
16508 " Shows the DAHDI version in use\n";
16513 if ((pseudo_fd = open(
"/dev/dahdi/ctl", O_RDONLY)) < 0) {
16514 ast_cli(
a->fd,
"Failed to open control file to get version.\n");
16518 strcpy(vi.version,
"Unknown");
16519 strcpy(vi.echo_canceller,
"Unknown");
16521 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi))
16522 ast_cli(
a->fd,
"Failed to get DAHDI version: %s\n", strerror(
errno));
16524 ast_cli(
a->fd,
"DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller);
16540 e->
command =
"dahdi set hwgain {rx|tx}";
16542 "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n"
16543 " Sets the hardware gain on a given channel and overrides the\n"
16544 " value provided at module loadtime. Changes take effect\n"
16545 " immediately whether the channel is in use or not.\n"
16547 " <rx|tx> which direction do you want to change (relative to our module)\n"
16548 " <chan num> is the channel number relative to the device\n"
16549 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"
16552 " * hwgain is only supportable by hardware with analog ports because\n"
16553 " hwgain works on the analog side of an analog-digital conversion.\n";
16562 if (!strcasecmp(
"rx",
a->argv[3]))
16564 else if (!strcasecmp(
"tx",
a->argv[3]))
16570 gain = atof(
a->argv[5]);
16583 ast_cli(
a->fd,
"Unable to set the hardware gain for channel %d: %s\n",
channel, strerror(
errno));
16587 ast_cli(
a->fd,
"Hardware %s gain set to %.1f dB on channel %d.\n",
16588 tx ?
"tx" :
"rx", gain,
channel);
16620 e->
command =
"dahdi set swgain {rx|tx}";
16622 "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n"
16623 " Sets the software gain on a given channel and overrides the\n"
16624 " value provided at module loadtime. Changes take effect\n"
16625 " immediately whether the channel is in use or not.\n"
16627 " <rx|tx> which direction do you want to change (relative to our module)\n"
16628 " <chan num> is the channel number relative to the device\n"
16629 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n";
16638 if (!strcasecmp(
"rx",
a->argv[3]))
16640 else if (!strcasecmp(
"tx",
a->argv[3]))
16646 gain = atof(
a->argv[5]);
16663 ast_cli(
a->fd,
"Unable to set the software gain for channel %d\n",
channel);
16668 ast_cli(
a->fd,
"Software %s gain set to %.2f dB on channel %d.\n",
16669 tx ?
"tx" :
"rx", gain,
channel);
16696 e->
command =
"dahdi set dnd";
16698 "Usage: dahdi set dnd <chan#> <on|off>\n"
16699 " Sets/resets DND (Do Not Disturb) mode on a channel.\n"
16700 " Changes take effect immediately.\n"
16701 " <chan num> is the channel number\n"
16702 " <on|off> Enable or disable DND mode?\n"
16712 if ((
channel = atoi(
a->argv[3])) <= 0) {
16713 ast_cli(
a->fd,
"Expected channel number, got '%s'\n",
a->argv[3]);
16722 ast_cli(
a->fd,
"Expected 'on' or 'off', got '%s'\n",
a->argv[4]);
16727 for (dahdi_chan =
iflist; dahdi_chan; dahdi_chan = dahdi_chan->
next) {
16754 e->
command =
"dahdi set mwi";
16756 "Usage: dahdi set mwi <chan#> <on|off|reset>\n"
16757 " Sets/unsets MWI (Message Waiting Indicator) manually on a channel.\n"
16758 " This may be used regardless of whether the channel is assigned any mailboxes.\n"
16759 " When active, this setting will override the voicemail status to set MWI.\n"
16760 " Once cleared, the voicemail status will resume control of MWI.\n"
16761 " Changes are queued for when the channel is idle and persist until cleared.\n"
16762 " <chan num> is the channel number\n"
16763 " <on|off|reset> Enable, disable, or reset Message Waiting Indicator override?\n"
16773 if ((
channel = atoi(
a->argv[3])) <= 0) {
16774 ast_cli(
a->fd,
"Expected channel number, got '%s'\n",
a->argv[3]);
16782 }
else if (!strcmp(
a->argv[4],
"reset")) {
16785 ast_cli(
a->fd,
"Expected 'on' or 'off' or 'reset', got '%s'\n",
a->argv[4]);
16790 for (dahdi_chan =
iflist; dahdi_chan; dahdi_chan = dahdi_chan->
next) {
16797 ast_cli(
a->fd,
"MWI '%s' queued for channel %d\n", on ?
"enable" :
"disable",
channel);
16875 if (sscanf(
channel,
"%30d", &chan_num) != 1) {
16894#define REQUIRE_FXO_SIG() \
16895 if (!(dahdip->sigtype & __DAHDI_SIG_FXO)) { \
16896 ast_log(LOG_WARNING, "DAHDI channel %d is not FXO signalled\n", p->channel); \
16905 if (!strcasecmp(property,
"owner")) {
16907 }
else if (!strcasecmp(property,
"callwait")) {
16909 }
else if (!strcasecmp(property,
"threeway")) {
16912 }
else if (!strcasecmp(property,
"polarity")) {
16915 }
else if (!strcasecmp(property,
"dnd")) {
16917 snprintf(buffer,
len,
"%d", analog_p->
dnd);
16918 }
else if (!strcasecmp(property,
"callforward")) {
16921 }
else if (!strcasecmp(property,
"lastexten")) {
16939 if (!strcasecmp(property,
"owner") || !strcasecmp(property,
"callwait") || !strcasecmp(property,
"threeway")) {
16943 }
else if (!strcasecmp(property,
"polarity")) {
16951 }
else if (!strcasecmp(property,
"dnd")) {
16955 }
else if (!strcasecmp(property,
"callforward")) {
16961 }
else if (!strcasecmp(property,
"lastexten")) {
16973#undef REQUIRE_FXO_SIG
16979 struct dahdi_params dahdip;
16995 int channo = atoi(
args.dahdichan);
17010 memset(&dahdip, 0,
sizeof(dahdip));
17038 .
name =
"DAHDI_CHANNEL",
17047 struct dahdi_params dahdip;
17053 memset(&dahdip, 0,
sizeof(dahdip));
17063 struct dahdi_params dahdip;
17069 memset(&dahdip, 0,
sizeof(dahdip));
17078 .
name =
"POLARITY",
17191 for (i = 0; i < strlen(
number); i++) {
17206 int dahdichanquery;
17208 if (!dahdichannel || sscanf(dahdichannel,
"%30d", &dahdichanquery) != 1) {
17210 dahdichanquery = -1;
17215 snprintf(idText,
sizeof(idText),
"ActionID: %s\r\n",
id);
17227 if (dahdichanquery > 0 && tmp->
channel != dahdichanquery)
17235 "Event: DAHDIShowChannels\r\n"
17236 "DAHDIChannel: %d\r\n"
17239 "AccountCode: %s\r\n"
17240 "Signalling: %s\r\n"
17241 "SignallingCode: %d\r\n"
17245 "Description: %s\r\n"
17255 dahdi_dnd(tmp, -1) ?
"Enabled" :
"Disabled",
17260 "Event: DAHDIShowChannels\r\n"
17261 "DAHDIChannel: %d\r\n"
17262 "Signalling: %s\r\n"
17263 "SignallingCode: %d\r\n"
17267 "Description: %s\r\n"
17272 dahdi_dnd(tmp, -1) ?
"Enabled" :
"Disabled",
17296 struct dahdi_spaninfo spaninfo;
17298 ctl = open(
"/dev/dahdi/ctl", O_RDWR);
17306 snprintf(idText,
sizeof(idText),
"ActionID: %s\r\n",
id);
17310 for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
17311 spaninfo.spanno = span;
17312 res = ioctl(ctl, DAHDI_SPANSTAT, &spaninfo);
17319 "Event: DAHDIShowStatus\r\n"
17321 "Description: %s\r\n"
17332 span, spaninfo.desc, alarmstr, spaninfo.irqmisses, spaninfo.bpvcount, spaninfo.crc4count,
17333 spaninfo.lineconfig & DAHDI_CONFIG_D4 ?
"D4" :
17334 spaninfo.lineconfig & DAHDI_CONFIG_ESF ?
"ESF" :
17335 spaninfo.lineconfig & DAHDI_CONFIG_CCS ?
"CCS" :
17337 spaninfo.lineconfig & DAHDI_CONFIG_B8ZS ?
"B8ZS" :
17338 spaninfo.lineconfig & DAHDI_CONFIG_HDB3 ?
"HDB3" :
17339 spaninfo.lineconfig & DAHDI_CONFIG_AMI ?
"AMI" :
17341 spaninfo.lineconfig & DAHDI_CONFIG_CRC4 ?
17342 spaninfo.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"CRC4/YEL" :
"CRC4" :
17343 spaninfo.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"YEL" :
"",
17355#if defined(HAVE_PRI)
17361 struct dahdi_pri *dspan;
17364 char action_id[256];
17365 const char *show_cmd =
"PRIShowSpans";
17369 span_query = atoi(span_str);
17375 snprintf(action_id,
sizeof(action_id),
"ActionID: %s\r\n",
id);
17377 action_id[0] =
'\0';
17383 for (idx = 0; idx <
ARRAY_LEN(pris); ++idx) {
17384 dspan = &pris[idx];
17387 if (0 < span_query && dspan->pri.span != span_query) {
17391 if (dspan->pri.pri) {
17404#if defined(HAVE_SS7)
17405static int linkset_addsigchan(
int sigchan)
17407 struct dahdi_ss7 *link;
17410 struct dahdi_params params;
17411 struct dahdi_bufferinfo bi;
17412 struct dahdi_spaninfo si;
17418 if (cur_ss7type < 0) {
17422 if (cur_pointcode < 0) {
17426 if (cur_adjpointcode < 0) {
17430 if (cur_defaultdpc < 0) {
17434 if (cur_networkindicator < 0) {
17438 link = ss7_resolve_linkset(cur_linkset);
17448 curfd = link->ss7.numsigchans;
17451 link->ss7.fds[curfd] = open(
"/dev/dahdi/channel", O_RDWR, 0600);
17452 if (link->ss7.fds[curfd] < 0) {
17457 if (ioctl(link->ss7.fds[curfd], DAHDI_SPECIFY, &sigchan) == -1) {
17458 dahdi_close_ss7_fd(link, curfd);
17465 memset(¶ms, 0,
sizeof(params));
17466 res = ioctl(link->ss7.fds[curfd], DAHDI_GET_PARAMS, ¶ms);
17468 dahdi_close_ss7_fd(link, curfd);
17469 ast_log(
LOG_ERROR,
"Unable to get parameters for sigchan %d (%s)\n", sigchan,
17473 if (params.sigtype != DAHDI_SIG_HDLCFCS
17474 && params.sigtype != DAHDI_SIG_HARDHDLC
17475 && params.sigtype != DAHDI_SIG_MTP2) {
17476 dahdi_close_ss7_fd(link, curfd);
17482 memset(&bi, 0,
sizeof(bi));
17483 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
17484 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
17487 if (ioctl(link->ss7.fds[curfd], DAHDI_SET_BUFINFO, &bi)) {
17488 ast_log(
LOG_ERROR,
"Unable to set appropriate buffering on channel %d: %s\n",
17489 sigchan, strerror(
errno));
17490 dahdi_close_ss7_fd(link, curfd);
17495 memset(&si, 0,
sizeof(si));
17496 res = ioctl(link->ss7.fds[curfd], DAHDI_SPANSTAT, &si);
17498 dahdi_close_ss7_fd(link, curfd);
17499 ast_log(
LOG_ERROR,
"Unable to get span state for sigchan %d (%s)\n", sigchan,
17504 (params.sigtype == DAHDI_SIG_MTP2)
17505 ? SS7_TRANSPORT_DAHDIMTP2
17506 : SS7_TRANSPORT_DAHDIDCHAN,
17507 si.
alarms, cur_networkindicator, cur_pointcode, cur_adjpointcode, cur_slc);
17509 dahdi_close_ss7_fd(link, curfd);
17513 ++link->ss7.numsigchans;
17519#if defined(HAVE_SS7)
17525 e->
command =
"ss7 set debug {on|off} linkset";
17527 "Usage: ss7 set debug {on|off} linkset <linkset>\n"
17528 " Enables debugging on a given SS7 linkset\n";
17538 span = atoi(
a->argv[5]);
17539 if ((span < 1) || (span >
NUM_SPANS)) {
17540 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number from %d to %d\n",
a->argv[5], 1,
NUM_SPANS);
17543 if (!linksets[span-1].ss7.ss7) {
17544 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", span);
17546 if (!strcasecmp(
a->argv[3],
"on")) {
17547 linksets[span - 1].ss7.debug = 1;
17549 ast_cli(
a->fd,
"Enabled debugging on linkset %d\n", span);
17551 linksets[span - 1].ss7.debug = 0;
17552 ss7_set_debug(linksets[span-1].ss7.ss7, 0);
17553 ast_cli(
a->fd,
"Disabled debugging on linkset %d\n", span);
17561#if defined(HAVE_SS7)
17571 e->
command =
"ss7 {block|unblock} cic";
17573 "Usage: ss7 {block|unblock} cic <linkset> <dpc> <CIC>\n"
17574 " Sends a remote {blocking|unblocking} request for the given CIC on the specified linkset\n";
17580 if (
a->argc == 6) {
17581 linkset = atoi(
a->argv[3]);
17586 if (!strcasecmp(
a->argv[1],
"block")) {
17588 }
else if (strcasecmp(
a->argv[1],
"unblock")) {
17592 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17593 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17597 if (!linksets[linkset-1].ss7.ss7) {
17598 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17602 cic = atoi(
a->argv[5]);
17604 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17608 dpc = atoi(
a->argv[4]);
17610 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17614 for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) {
17615 if (linksets[linkset-1].ss7.pvts[i] && linksets[linkset-1].ss7.pvts[i]->cic == cic && linksets[linkset-1].ss7.pvts[i]->dpc == dpc) {
17616 blocked = linksets[linkset-1].ss7.pvts[i]->locallyblocked;
17619 ast_cli(
a->fd,
"Unable to allocate new ss7call\n");
17621 ast_cli(
a->fd,
"Sent %sblocking request for linkset %d on CIC %d DPC %d\n", (do_block) ?
"" :
"un", linkset, cic, dpc);
17623 }
else if (!do_block && blocked) {
17624 ast_cli(
a->fd,
"CIC %d is hardware locally blocked!\n", cic);
17626 ast_cli(
a->fd,
"CIC %d %s locally blocked\n", cic, do_block ?
"already" :
"is not");
17632 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17637#if defined(HAVE_SS7)
17649 e->
command =
"ss7 {reset|block|unblock} linkset";
17651 "Usage: ss7 {reset|block|unblock} linkset <linkset number>\n"
17652 " Sends a remote {reset|blocking|unblocking} request for all CICs on the given linkset\n";
17658 if (
a->argc == 4) {
17659 linkset = atoi(
a->argv[3]);
17664 if (!strcasecmp(
a->argv[1],
"block")) {
17665 do_what = DO_BLOCK;
17666 }
else if (!strcasecmp(
a->argv[1],
"unblock")) {
17667 do_what = DO_UNBLOCK;
17668 }
else if (!strcasecmp(
a->argv[1],
"reset")) {
17669 do_what = DO_RESET;
17674 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17675 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17679 if (!linksets[linkset - 1].ss7.ss7) {
17680 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17684 for (i = 0; i < linksets[linkset - 1].ss7.numchans; i++) {
17686 if (linksets[linkset - 1].ss7.pvts[i]) {
17691 ast_cli(
a->fd,
"Sent remote %s request on CIC %d\n",
17692 (do_what == DO_BLOCK) ?
"blocking" :
"unblocking",
17693 linksets[linkset - 1].ss7.
pvts[i]->cic);
17698 linksets[linkset - 1].ss7.pvts[i]->cic,
17699 linksets[linkset - 1].ss7.pvts[i]->dpc)) {
17700 ast_cli(
a->fd,
"Sent reset request on CIC %d\n",
17701 linksets[linkset - 1].ss7.pvts[i]->cic);
17712#if defined(HAVE_SS7)
17715 int linkset, cic, range, chanpos;
17716 int i, dpc, orient = 0;
17718 unsigned char state[255];
17722 e->
command =
"ss7 {block|unblock} group";
17724 "Usage: ss7 {block|unblock} group <linkset> <dpc> <1st. CIC> <range> [H]\n"
17725 " Sends a remote {blocking|unblocking} request for CIC range on the specified linkset\n";
17731 if (
a->argc == 7 ||
a->argc == 8) {
17732 linkset = atoi(
a->argv[3]);
17737 if (!strcasecmp(
a->argv[1],
"block")) {
17739 }
else if (strcasecmp(
a->argv[1],
"unblock")) {
17743 if (
a->argc == 8) {
17744 if (!strcasecmp(
a->argv[7],
"H")) {
17751 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17752 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[4], 1,
NUM_SPANS);
17756 if (!linksets[linkset-1].ss7.ss7) {
17757 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17761 cic = atoi(
a->argv[5]);
17763 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17767 range = atoi(
a->argv[6]);
17769 if (range < 1 || range > (linksets[linkset - 1].ss7.type == SS7_ANSI ? 24 : 31)) {
17770 ast_cli(
a->fd,
"Invalid range specified!\n");
17774 dpc = atoi(
a->argv[4]);
17776 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17783 ast_cli(
a->fd,
"Invalid CIC/RANGE\n");
17788 for (i = 0; i <= range; ++i) {
17795 ast_cli(
a->fd,
"Unable allocate new ss7call\n");
17797 ast_cli(
a->fd,
"Sending remote%s %sblocking request linkset %d on CIC %d range %d\n",
17798 orient ?
" hardware" :
"", do_block ?
"" :
"un", linkset, cic, range);
17805 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
17811#if defined(HAVE_SS7)
17814 int linkset, cic, range;
17819 e->
command =
"ss7 reset group";
17821 "Usage: ss7 reset group <linkset> <dpc> <1st CIC> <range>\n"
17822 " Send a GRS for the given CIC range on the specified linkset\n";
17828 if (
a->argc == 7) {
17829 linkset = atoi(
a->argv[3]);
17834 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17835 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[4], 1,
NUM_SPANS);
17839 if (!linksets[linkset-1].ss7.ss7) {
17840 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17844 cic = atoi(
a->argv[5]);
17847 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17851 range = atoi(
a->argv[6]);
17852 if (range < 1 || range > (linksets[linkset - 1].ss7.type == SS7_ANSI ? 24 : 31)) {
17853 ast_cli(
a->fd,
"Invalid range specified!\n");
17857 dpc = atoi(
a->argv[4]);
17859 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17866 ast_cli(
a->fd,
"Invalid CIC/RANGE\n");
17871 ast_cli(
a->fd,
"Unable to allocate new ss7call\n");
17873 ast_cli(
a->fd,
"GRS sent ... \n");
17880 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
17886#if defined(HAVE_SS7)
17893 e->
command =
"ss7 show calls";
17895 "Usage: ss7 show calls <linkset>\n"
17896 " Show SS7 calls on the specified linkset\n";
17902 if (
a->argc == 4) {
17903 linkset = atoi(
a->argv[3]);
17908 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17909 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17913 if (!linksets[linkset-1].ss7.ss7) {
17914 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17919 isup_show_calls(linksets[linkset-1].ss7.ss7, &
ast_cli,
a->fd);
17926#if defined(HAVE_SS7)
17929 int linkset, cic, res;
17934 e->
command =
"ss7 reset cic";
17936 "Usage: ss7 reset cic <linkset> <dpc> <CIC>\n"
17937 " Send a RSC for the given CIC on the specified linkset\n";
17943 if (
a->argc == 6) {
17944 linkset = atoi(
a->argv[3]);
17949 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17950 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17954 if (!linksets[linkset-1].ss7.ss7) {
17955 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17959 cic = atoi(
a->argv[5]);
17962 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17966 dpc = atoi(
a->argv[4]);
17968 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17974 ast_cli(
a->fd,
"%s RSC for linkset %d on CIC %d DPC %d\n", res ?
"Sent" :
"Failed", linkset, cic, dpc);
17980#if defined(HAVE_SS7)
17985 unsigned int arg = 0;
17992 "Usage: ss7 mtp3 <linkset> <slc> coo|coa|cbd|cba|eco|eca|tfp|tfa|lin|lun|lia|lua|lid|lfu <arg>\n"
17993 " Send a NET MNG message\n"
17994 " WARNING!!! WARNING!!! We are not a STP, just for testing/development purposes\n";
18004 linkset = atoi(
a->argv[2]);
18005 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
18006 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[2], 1,
NUM_SPANS);
18009 if (!linksets[linkset-1].ss7.ss7) {
18010 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
18014 slc = atoi(
a->argv[3]);
18016 if (
a->argc == 6) {
18017 arg = atoi(
a->argv[5]);
18021 res = mtp3_net_mng(linksets[linkset-1].ss7.ss7, slc,
a->argv[4], arg);
18026 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
18035#if defined(HAVE_SS7)
18039 unsigned int slc = 0;
18043 e->
command =
"ss7 restart mtp3";
18045 "Usage: ss7 restart mtp3 <linkset> <slc>\n"
18056 linkset = atoi(
a->argv[3]);
18057 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
18058 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[2], 1,
NUM_SPANS);
18061 if (!linksets[linkset-1].ss7.ss7) {
18062 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
18066 slc = atoi(
a->argv[4]);
18069 mtp3_init_restart(linksets[linkset-1].ss7.ss7, slc);
18074 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
18081#if defined(HAVE_SS7)
18088 e->
command =
"ss7 show linkset";
18090 "Usage: ss7 show linkset <span>\n"
18091 " Shows the status of an SS7 linkset.\n";
18101 linkset = atoi(
a->argv[3]);
18102 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
18103 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
18106 ss7 = &linksets[linkset - 1].ss7;
18108 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
18114 ast_cli(
a->fd,
"SS7 calling nai: %i\n",
ss7->calling_nai);
18115 ast_cli(
a->fd,
"SS7 called nai: %i\n",
ss7->called_nai);
18116 ast_cli(
a->fd,
"SS7 nationalprefix: %s\n",
ss7->nationalprefix);
18117 ast_cli(
a->fd,
"SS7 internationalprefix: %s\n",
ss7->internationalprefix);
18118 ast_cli(
a->fd,
"SS7 unknownprefix: %s\n",
ss7->unknownprefix);
18119 ast_cli(
a->fd,
"SS7 networkroutedprefix: %s\n",
ss7->networkroutedprefix);
18120 ast_cli(
a->fd,
"SS7 subscriberprefix: %s\n",
ss7->subscriberprefix);
18127#if defined(HAVE_SS7)
18134 e->
command =
"ss7 show channels";
18136 "Usage: ss7 show channels\n"
18137 " Displays SS7 channel information at a glance.\n";
18143 if (
a->argc != 3) {
18148 for (linkset = 0; linkset <
NUM_SPANS; ++linkset) {
18149 if (linksets[linkset].
ss7.ss7) {
18157#if defined(HAVE_SS7)
18160#define FORMAT "%5s %5s %6s %12s %-12s\n"
18161#define FORMAT2 "%5i %5i %6i %12s %-12s\n"
18162 int i, linkset, dpc = 0;
18169 e->
command =
"ss7 show cics";
18171 "Usage: ss7 show cics <linkset> [dpc]\n"
18172 " Shows the cics of an SS7 linkset.\n";
18178 if (
a->argc < 4 ||
a->argc > 5) {
18182 linkset = atoi(
a->argv[3]);
18184 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
18185 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
18189 if (!linksets[linkset-1].
ss7.ss7) {
18190 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
18193 ss7 = &linksets[linkset-1].ss7;
18195 if (
a->argc == 5) {
18196 dpc = atoi(
a->argv[4]);
18198 ast_cli(
a->fd,
"Invalid DPC specified!\n");
18203 ast_cli(
a->fd,
FORMAT,
"CIC",
"DPC",
"DAHDI",
"STATE",
"BLOCKING");
18205 for (i = 0; i <
ss7->numchans; i++) {
18206 if (!dpc || (
ss7->pvts[i] &&
ss7->pvts[i]->dpc == dpc)) {
18214 state =
"NotInServ";
18220 strcpy(blocking,
"L:");
18222 strcat(blocking,
"M");
18224 strcat(blocking,
" ");
18228 strcat(blocking,
"H");
18230 strcat(blocking,
" ");
18233 strcpy(blocking,
" ");
18237 strcat(blocking,
" R:");
18239 strcat(blocking,
"M");
18241 strcat(blocking,
" ");
18245 strcat(blocking,
"H");
18247 strcat(blocking,
" ");
18261#if defined(HAVE_SS7)
18266 e->
command =
"ss7 show version";
18268 "Usage: ss7 show version\n"
18269 " Show the libss7 version\n";
18275 ast_cli(
a->fd,
"libss7 version: %s\n", ss7_get_version());
18281#if defined(HAVE_SS7)
18283 AST_CLI_DEFINE(handle_ss7_debug,
"Enables SS7 debugging on a linkset"),
18284 AST_CLI_DEFINE(handle_ss7_cic_blocking,
"Blocks/Unblocks the given CIC"),
18285 AST_CLI_DEFINE(handle_ss7_linkset_mng,
"Resets/Blocks/Unblocks all CICs on a linkset"),
18286 AST_CLI_DEFINE(handle_ss7_group_blocking,
"Blocks/Unblocks the given CIC range"),
18288 AST_CLI_DEFINE(handle_ss7_group_reset,
"Resets the given CIC range"),
18291 AST_CLI_DEFINE(handle_ss7_show_linkset,
"Shows the status of a linkset"),
18292 AST_CLI_DEFINE(handle_ss7_show_channels,
"Displays SS7 channel information"),
18299#if defined(HAVE_PRI)
18300#if defined(HAVE_PRI_CCSS)
18347#if defined(HAVE_PRI)
18348#if defined(HAVE_PRI_CCSS)
18360static void dahdi_pri_cc_agent_destructor(
struct ast_cc_agent *agent)
18369#if defined(HAVE_PRI)
18370#if defined(HAVE_PRI_CCSS)
18372 .
type = dahdi_pri_cc_type,
18373 .init = dahdi_pri_cc_agent_init,
18382 .destructor = dahdi_pri_cc_agent_destructor,
18387#if defined(HAVE_PRI)
18388#if defined(HAVE_PRI_CCSS)
18390 .
type = dahdi_pri_cc_type,
18404#if defined(HAVE_PRI) || defined(HAVE_SS7)
18411 pthread_cancel(pris[i].pri.
master);
18412 pthread_kill(pris[i].pri.
master, SIGURG);
18417#ifdef HAVE_PRI_PROG_W_CAUSE
18421#if defined(HAVE_SS7)
18424 pthread_cancel(linksets[i].ss7.
master);
18425 pthread_kill(linksets[i].ss7.
master, SIGURG);
18430#if defined(HAVE_OPENR2)
18431 dahdi_r2_destroy_links();
18448#if defined(HAVE_PRI)
18475#if defined(HAVE_PRI)
18481 dahdi_close_pri_fd(&(pris[i]), j);
18485#if defined(HAVE_PRI_CCSS)
18492#if defined(HAVE_SS7)
18498 dahdi_close_ss7_fd(&(linksets[i]), j);
18500 if (linksets[i].ss7.
ss7) {
18501 ss7_destroy(linksets[i].ss7.
ss7);
18502 linksets[i].ss7.ss7 =
NULL;
18518#if defined(HAVE_PRI) || defined(HAVE_SS7)
18525#if defined(HAVE_SS7)
18535 int x, start, finish;
18538 if ((
reload == 0) && (
conf->chan.sig < 0) && !
conf->is_sig_auto) {
18539 ast_log(
LOG_ERROR,
"Signalling must be specified before any channels are.\n");
18545 while ((chan =
strsep(&
c,
","))) {
18546 if (sscanf(chan,
"%30d-%30d", &start, &finish) == 2) {
18548 }
else if (sscanf(chan,
"%30d", &start)) {
18551 }
else if (!strcasecmp(chan,
"pseudo")) {
18557 if (finish < start) {
18564 for (x = start; x <= finish; x++) {
18565 if (
conf->wanted_channels_start &&
18566 (x < conf->wanted_channels_start ||
18567 x >
conf->wanted_channels_end)
18577 (
reload == 1) ?
"reconfigure" :
"register",
value);
18591#define MAX_CHANLIST_LEN 80
18596 char *
params[DAHDI_MAX_ECHOCANPARAMS + 1];
18597 unsigned int param_count;
18609 if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024))
18616 for (x = 1; x < param_count; x++) {
18623 ast_log(
LOG_WARNING,
"Invalid echocancel parameter supplied at line %u: '%s'\n", line, params[x]);
18628 ast_log(
LOG_WARNING,
"Invalid echocancel parameter supplied at line %u: '%s'\n", line, param.name);
18636 ast_log(
LOG_WARNING,
"Invalid echocancel parameter value supplied at line %u: '%s'\n", line, param.value);
18644#if defined(HAVE_PRI)
18645#if defined(HAVE_PRI_DISPLAY_TEXT)
18655static unsigned long dahdi_display_text_option(
const char *
value)
18665 opt_str =
strsep(&val_str,
",");
18674 if (!strcasecmp(opt_str,
"block")) {
18675 options |= PRI_DISPLAY_OPTION_BLOCK;
18676 }
else if (!strcasecmp(opt_str,
"name_initial")) {
18677 options |= PRI_DISPLAY_OPTION_NAME_INITIAL;
18678 }
else if (!strcasecmp(opt_str,
"name_update")) {
18679 options |= PRI_DISPLAY_OPTION_NAME_UPDATE;
18680 }
else if (!strcasecmp(opt_str,
"name")) {
18681 options |= (PRI_DISPLAY_OPTION_NAME_INITIAL | PRI_DISPLAY_OPTION_NAME_UPDATE);
18682 }
else if (!strcasecmp(opt_str,
"text")) {
18683 options |= PRI_DISPLAY_OPTION_TEXT;
18691#if defined(HAVE_PRI)
18692#if defined(HAVE_PRI_DATETIME_SEND)
18702static int dahdi_datetime_send_option(
const char *
value)
18706 option = PRI_DATE_TIME_SEND_DEFAULT;
18709 option = PRI_DATE_TIME_SEND_NO;
18710 }
else if (!strcasecmp(
value,
"date")) {
18711 option = PRI_DATE_TIME_SEND_DATE;
18712 }
else if (!strcasecmp(
value,
"date_hh")) {
18713 option = PRI_DATE_TIME_SEND_DATE_HH;
18714 }
else if (!strcasecmp(
value,
"date_hhmm")) {
18715 option = PRI_DATE_TIME_SEND_DATE_HHMM;
18716 }
else if (!strcasecmp(
value,
"date_hhmmss")) {
18717 option = PRI_DATE_TIME_SEND_DATE_HHMMSS;
18726#define PROC_DAHDI_OPT_NOCHAN (1 << 0)
18728#define PROC_DAHDI_OPT_NOWARN (1 << 1)
18732 int count_pattern = 0;
18738 if (!sscanf(v->
value,
"%30d", &norval) && count_pattern == 0) {
18739 ast_log(
LOG_ERROR,
"busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->
lineno);
18743 busy_cadence->
pattern[count_pattern] = norval;
18746 if (count_pattern == 4) {
18750 temp = strchr(v->
value,
',');
18751 if (temp ==
NULL) {
18754 v->
value = temp + 1;
18756 busy_cadence->
length = count_pattern;
18758 if (count_pattern % 2 != 0) {
18760 ast_log(
LOG_ERROR,
"busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->
lineno);
18774 for (; v; v = v->
next) {
18779 if (!strcasecmp(v->
name,
"channel") || !strcasecmp(v->
name,
"channels")) {
18793 }
else if (!strcasecmp(v->
name,
"ignore_failed_channels")) {
18795 }
else if (!strcasecmp(v->
name,
"buffers")) {
18801 }
else if (!strcasecmp(v->
name,
"faxbuffers")) {
18805 }
else if (!strcasecmp(v->
name,
"dahdichan")) {
18808 }
else if (!strcasecmp(v->
name,
"usedistinctiveringdetection")) {
18810 }
else if (!strcasecmp(v->
name,
"distinctiveringaftercid")) {
18812 }
else if (!strcasecmp(v->
name,
"dring1context")) {
18814 }
else if (!strcasecmp(v->
name,
"dring2context")) {
18816 }
else if (!strcasecmp(v->
name,
"dring3context")) {
18818 }
else if (!strcasecmp(v->
name,
"dring1range")) {
18820 }
else if (!strcasecmp(v->
name,
"dring2range")) {
18822 }
else if (!strcasecmp(v->
name,
"dring3range")) {
18824 }
else if (!strcasecmp(v->
name,
"dring1")) {
18826 }
else if (!strcasecmp(v->
name,
"dring2")) {
18828 }
else if (!strcasecmp(v->
name,
"dring3")) {
18830 }
else if (!strcasecmp(v->
name,
"usecallerid")) {
18832 }
else if (!strcasecmp(v->
name,
"cidsignalling")) {
18833 if (!strcasecmp(v->
value,
"bell"))
18835 else if (!strcasecmp(v->
value,
"v23"))
18837 else if (!strcasecmp(v->
value,
"dtmf"))
18839 else if (!strcasecmp(v->
value,
"smdi"))
18841 else if (!strcasecmp(v->
value,
"v23_jp"))
18845 }
else if (!strcasecmp(v->
name,
"cidstart")) {
18846 if (!strcasecmp(v->
value,
"ring"))
18848 else if (!strcasecmp(v->
value,
"polarity_in"))
18850 else if (!strcasecmp(v->
value,
"polarity"))
18852 else if (!strcasecmp(v->
value,
"dtmf"))
18856 }
else if (!strcasecmp(v->
name,
"threewaycalling")) {
18858 }
else if (!strcasecmp(v->
name,
"threewaysilenthold")) {
18860 }
else if (!strcasecmp(v->
name,
"cancallforward")) {
18862 }
else if (!strcasecmp(v->
name,
"relaxdtmf")) {
18867 }
else if (!strcasecmp(v->
name,
"mailbox")) {
18869 }
else if (!strcasecmp(v->
name,
"description")) {
18871 }
else if (!strcasecmp(v->
name,
"adsi")) {
18873 }
else if (!strcasecmp(v->
name,
"usesmdi")) {
18875 }
else if (!strcasecmp(v->
name,
"smdiport")) {
18877 }
else if (!strcasecmp(v->
name,
"transfer")) {
18879 }
else if (!strcasecmp(v->
name,
"canpark")) {
18881 }
else if (!strcasecmp(v->
name,
"echocancelwhenbridged")) {
18883 }
else if (!strcasecmp(v->
name,
"busydetect")) {
18885 }
else if (!strcasecmp(v->
name,
"busycount")) {
18887 }
else if (!strcasecmp(v->
name,
"busypattern")) {
18889 }
else if (!strcasecmp(v->
name,
"calledsubscriberheld")) {
18891 }
else if (!strcasecmp(v->
name,
"lastnumredial")) {
18893 }
else if (!strcasecmp(v->
name,
"callprogress")) {
18897 }
else if (!strcasecmp(v->
name,
"waitfordialtone")) {
18899 }
else if (!strcasecmp(v->
name,
"dialtone_detect")) {
18900 if (!strcasecmp(v->
value,
"always")) {
18909 }
else if (!strcasecmp(v->
name,
"faxdetect")) {
18911 if (!strcasecmp(v->
value,
"incoming")) {
18913 }
else if (!strcasecmp(v->
value,
"outgoing")) {
18917 }
else if (!strcasecmp(v->
name,
"faxdetect_timeout")) {
18921 }
else if (!strcasecmp(v->
name,
"firstdigit_timeout")) {
18926 }
else if (!strcasecmp(v->
name,
"interdigit_timeout")) {
18931 }
else if (!strcasecmp(v->
name,
"matchdigit_timeout")) {
18936 }
else if (!strcasecmp(v->
name,
"echocancel")) {
18938 }
else if (!strcasecmp(v->
name,
"echotraining")) {
18939 if (sscanf(v->
value,
"%30d", &y) == 1) {
18940 if ((y < 10) || (y > 4000)) {
18949 }
else if (!strcasecmp(v->
name,
"hidecallerid")) {
18951 }
else if (!strcasecmp(v->
name,
"hidecalleridname")) {
18953 }
else if (!strcasecmp(v->
name,
"pulsedial")) {
18955 }
else if (!strcasecmp(v->
name,
"callreturn")) {
18957 }
else if (!strcasecmp(v->
name,
"callwaiting")) {
18959 }
else if (!strcasecmp(v->
name,
"callwaitingcallerid")) {
18961 }
else if (!strcasecmp(v->
name,
"callwaitingdeluxe")) {
18963 }
else if (!strcasecmp(v->
name,
"context")) {
18965 }
else if (!strcasecmp(v->
name,
"language")) {
18967 }
else if (!strcasecmp(v->
name,
"progzone")) {
18969 }
else if (!strcasecmp(v->
name,
"mohinterpret")
18970 ||!strcasecmp(v->
name,
"musiconhold") || !strcasecmp(v->
name,
"musicclass")) {
18972 }
else if (!strcasecmp(v->
name,
"mohsuggest")) {
18974 }
else if (!strcasecmp(v->
name,
"parkinglot")) {
18976 }
else if (!strcasecmp(v->
name,
"stripmsd")) {
18977 ast_log(
LOG_NOTICE,
"Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->
name);
18979 }
else if (!strcasecmp(v->
name,
"jitterbuffers")) {
18981 }
else if (!strcasecmp(v->
name,
"group")) {
18983 }
else if (!strcasecmp(v->
name,
"callgroup")) {
18987 if (!strcasecmp(v->
value,
"none"))
18991 }
else if (!strcasecmp(v->
name,
"pickupgroup")) {
18995 if (!strcasecmp(v->
value,
"none"))
18999 }
else if (!strcasecmp(v->
name,
"namedcallgroup")) {
19001 ast_log(
LOG_WARNING,
"Only FXO signalled channels may belong to a named call group\n");
19004 }
else if (!strcasecmp(v->
name,
"namedpickupgroup")) {
19006 ast_log(
LOG_WARNING,
"Only FXO signalled channels may belong to a named pickup group\n");
19009 }
else if (!strcasecmp(v->
name,
"setvar")) {
19011 char *varval =
NULL;
19013 char varname[strlen(v->
value) + 1];
19014 strcpy(varname, v->
value);
19015 if ((varval = strchr(varname,
'='))) {
19025 }
else if (!strcasecmp(v->
name,
"immediate")) {
19027 }
else if (!strcasecmp(v->
name,
"immediatering")) {
19029 }
else if (!strcasecmp(v->
name,
"transfertobusy")) {
19031 }
else if (!strcasecmp(v->
name,
"dialmode")) {
19032 if (!strcasecmp(v->
value,
"pulse")) {
19034 }
else if (!strcasecmp(v->
value,
"dtmf") || !strcasecmp(v->
value,
"tone")) {
19036 }
else if (!strcasecmp(v->
value,
"none")) {
19041 }
else if (!strcasecmp(v->
name,
"mwimonitor")) {
19058 }
else if (!strcasecmp(v->
name,
"hwrxgain")) {
19060 if (strcasecmp(v->
value,
"disabled")) {
19067 }
else if (!strcasecmp(v->
name,
"hwtxgain")) {
19069 if (strcasecmp(v->
value,
"disabled")) {
19076 }
else if (!strcasecmp(v->
name,
"cid_rxgain")) {
19080 }
else if (!strcasecmp(v->
name,
"rxgain")) {
19084 }
else if (!strcasecmp(v->
name,
"txgain")) {
19088 }
else if (!strcasecmp(v->
name,
"txdrc")) {
19092 }
else if (!strcasecmp(v->
name,
"rxdrc")) {
19096 }
else if (!strcasecmp(v->
name,
"tonezone")) {
19100 }
else if (!strcasecmp(v->
name,
"callerid")) {
19101 if (!strcasecmp(v->
value,
"asreceived")) {
19107 }
else if (!strcasecmp(v->
name,
"fullname")) {
19109 }
else if (!strcasecmp(v->
name,
"cid_number")) {
19111 }
else if (!strcasecmp(v->
name,
"cid_tag")) {
19113 }
else if (!strcasecmp(v->
name,
"useincomingcalleridondahditransfer")) {
19115 }
else if (!strcasecmp(v->
name,
"restrictcid")) {
19117 }
else if (!strcasecmp(v->
name,
"usecallingpres")) {
19119 }
else if (!strcasecmp(v->
name,
"accountcode")) {
19121 }
else if (!strcasecmp(v->
name,
"amaflags")) {
19127 }
else if (!strcasecmp(v->
name,
"polarityonanswerdelay")) {
19129 }
else if (!strcasecmp(v->
name,
"answeronpolarityswitch")) {
19131 }
else if (!strcasecmp(v->
name,
"ani_info_digits")) {
19133 }
else if (!strcasecmp(v->
name,
"ani_wink_time")) {
19135 }
else if (!strcasecmp(v->
name,
"ani_timeout")) {
19137 }
else if (!strcasecmp(v->
name,
"hanguponpolarityswitch")) {
19139 }
else if (!strcasecmp(v->
name,
"autoreoriginate")) {
19141 }
else if (!strcasecmp(v->
name,
"sendcalleridafter")) {
19143 }
else if (!strcasecmp(v->
name,
"mwimonitornotify")) {
19147 }
else if (!strcasecmp(v->
name,
"mwisendtype")) {
19148#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
19149 if (!strcasecmp(v->
value,
"rpas")) {
19156 memset(&confp->
chan.mwisend_setting, 0,
sizeof(confp->
chan.mwisend_setting));
19158 confp->
chan.mwisend_fsk = 0;
19160 confp->
chan.mwisend_fsk = 1;
19163 confp->
chan.mwisend_rpas = 1;
19165 confp->
chan.mwisend_rpas = 0;
19168 confp->
chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV;
19171 confp->
chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC;
19174 confp->
chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC;
19177 }
else if (
reload != 1) {
19178 if (!strcasecmp(v->
name,
"signalling") || !strcasecmp(v->
name,
"signaling")) {
19186 if (!strcasecmp(v->
value,
"em")) {
19188 }
else if (!strcasecmp(v->
value,
"em_e1")) {
19190 }
else if (!strcasecmp(v->
value,
"em_w")) {
19192 }
else if (!strcasecmp(v->
value,
"fxs_ls")) {
19194 }
else if (!strcasecmp(v->
value,
"fxs_gs")) {
19196 }
else if (!strcasecmp(v->
value,
"fxs_ks")) {
19198 }
else if (!strcasecmp(v->
value,
"fxo_ls")) {
19200 }
else if (!strcasecmp(v->
value,
"fxo_gs")) {
19202 }
else if (!strcasecmp(v->
value,
"fxo_ks")) {
19204 }
else if (!strcasecmp(v->
value,
"fxs_rx")) {
19207 }
else if (!strcasecmp(v->
value,
"fxo_rx")) {
19210 }
else if (!strcasecmp(v->
value,
"fxs_tx")) {
19213 }
else if (!strcasecmp(v->
value,
"fxo_tx")) {
19216 }
else if (!strcasecmp(v->
value,
"em_rx")) {
19219 }
else if (!strcasecmp(v->
value,
"em_tx")) {
19222 }
else if (!strcasecmp(v->
value,
"em_rxtx")) {
19225 }
else if (!strcasecmp(v->
value,
"em_txrx")) {
19228 }
else if (!strcasecmp(v->
value,
"sf")) {
19230 }
else if (!strcasecmp(v->
value,
"sf_w")) {
19232 }
else if (!strcasecmp(v->
value,
"sf_featd")) {
19234 }
else if (!strcasecmp(v->
value,
"sf_featdmf")) {
19236 }
else if (!strcasecmp(v->
value,
"sf_featb")) {
19238 }
else if (!strcasecmp(v->
value,
"sf")) {
19240 }
else if (!strcasecmp(v->
value,
"sf_rx")) {
19243 }
else if (!strcasecmp(v->
value,
"sf_tx")) {
19246 }
else if (!strcasecmp(v->
value,
"sf_rxtx")) {
19249 }
else if (!strcasecmp(v->
value,
"sf_txrx")) {
19252 }
else if (!strcasecmp(v->
value,
"featd")) {
19254 }
else if (!strcasecmp(v->
value,
"featdmf")) {
19256 }
else if (!strcasecmp(v->
value,
"featdmf_ta")) {
19258 }
else if (!strcasecmp(v->
value,
"e911")) {
19260 }
else if (!strcasecmp(v->
value,
"fgccama")) {
19262 }
else if (!strcasecmp(v->
value,
"fgccamamf")) {
19264 }
else if (!strcasecmp(v->
value,
"featb")) {
19267 }
else if (!strcasecmp(v->
value,
"pri_net")) {
19269 confp->pri.pri.nodetype = PRI_NETWORK;
19270 }
else if (!strcasecmp(v->
value,
"pri_cpe")) {
19272 confp->pri.pri.nodetype = PRI_CPE;
19273 }
else if (!strcasecmp(v->
value,
"bri_cpe")) {
19275 confp->pri.pri.nodetype = PRI_CPE;
19276 }
else if (!strcasecmp(v->
value,
"bri_net")) {
19278 confp->pri.pri.nodetype = PRI_NETWORK;
19279 }
else if (!strcasecmp(v->
value,
"bri_cpe_ptmp")) {
19281 confp->pri.pri.nodetype = PRI_CPE;
19282 }
else if (!strcasecmp(v->
value,
"bri_net_ptmp")) {
19283#if defined(HAVE_PRI_CALL_HOLD)
19285 confp->pri.pri.nodetype = PRI_NETWORK;
19287 ast_log(
LOG_WARNING,
"How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->
lineno);
19290#if defined(HAVE_SS7)
19291 }
else if (!strcasecmp(v->
value,
"ss7")) {
19295 }
else if (!strcasecmp(v->
value,
"mfcr2")) {
19298 }
else if (!strcasecmp(v->
value,
"auto")) {
19306 }
else if (!strcasecmp(v->
name,
"outsignalling") || !strcasecmp(v->
name,
"outsignaling")) {
19307 if (!strcasecmp(v->
value,
"em")) {
19309 }
else if (!strcasecmp(v->
value,
"em_e1")) {
19311 }
else if (!strcasecmp(v->
value,
"em_w")) {
19313 }
else if (!strcasecmp(v->
value,
"sf")) {
19315 }
else if (!strcasecmp(v->
value,
"sf_w")) {
19317 }
else if (!strcasecmp(v->
value,
"sf_featd")) {
19319 }
else if (!strcasecmp(v->
value,
"sf_featdmf")) {
19321 }
else if (!strcasecmp(v->
value,
"sf_featb")) {
19323 }
else if (!strcasecmp(v->
value,
"sf")) {
19325 }
else if (!strcasecmp(v->
value,
"featd")) {
19327 }
else if (!strcasecmp(v->
value,
"featdmf")) {
19329 }
else if (!strcasecmp(v->
value,
"featdmf_ta")) {
19331 }
else if (!strcasecmp(v->
value,
"e911")) {
19333 }
else if (!strcasecmp(v->
value,
"fgccama")) {
19335 }
else if (!strcasecmp(v->
value,
"fgccamamf")) {
19337 }
else if (!strcasecmp(v->
value,
"featb")) {
19343 }
else if (!strcasecmp(v->
name,
"pridialplan")) {
19344 if (!strcasecmp(v->
value,
"national")) {
19345 confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1;
19346 }
else if (!strcasecmp(v->
value,
"unknown")) {
19347 confp->pri.pri.dialplan = PRI_UNKNOWN + 1;
19348 }
else if (!strcasecmp(v->
value,
"private")) {
19349 confp->pri.pri.dialplan = PRI_PRIVATE + 1;
19350 }
else if (!strcasecmp(v->
value,
"international")) {
19351 confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
19352 }
else if (!strcasecmp(v->
value,
"local")) {
19353 confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1;
19354 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19355 confp->pri.pri.dialplan = -1;
19356 }
else if (!strcasecmp(v->
value,
"redundant")) {
19357 confp->pri.pri.dialplan = -2;
19361 }
else if (!strcasecmp(v->
name,
"prilocaldialplan")) {
19362 if (!strcasecmp(v->
value,
"national")) {
19363 confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1;
19364 }
else if (!strcasecmp(v->
value,
"unknown")) {
19365 confp->pri.pri.localdialplan = PRI_UNKNOWN + 1;
19366 }
else if (!strcasecmp(v->
value,
"private")) {
19367 confp->pri.pri.localdialplan = PRI_PRIVATE + 1;
19368 }
else if (!strcasecmp(v->
value,
"international")) {
19369 confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
19370 }
else if (!strcasecmp(v->
value,
"local")) {
19371 confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1;
19372 }
else if (!strcasecmp(v->
value,
"from_channel")) {
19373 confp->pri.pri.localdialplan = 0;
19374 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19375 confp->pri.pri.localdialplan = -1;
19376 }
else if (!strcasecmp(v->
value,
"redundant")) {
19377 confp->pri.pri.localdialplan = -2;
19381 }
else if (!strcasecmp(v->
name,
"pricpndialplan")) {
19382 if (!strcasecmp(v->
value,
"national")) {
19383 confp->pri.pri.cpndialplan = PRI_NATIONAL_ISDN + 1;
19384 }
else if (!strcasecmp(v->
value,
"unknown")) {
19385 confp->pri.pri.cpndialplan = PRI_UNKNOWN + 1;
19386 }
else if (!strcasecmp(v->
value,
"private")) {
19387 confp->pri.pri.cpndialplan = PRI_PRIVATE + 1;
19388 }
else if (!strcasecmp(v->
value,
"international")) {
19389 confp->pri.pri.cpndialplan = PRI_INTERNATIONAL_ISDN + 1;
19390 }
else if (!strcasecmp(v->
value,
"local")) {
19391 confp->pri.pri.cpndialplan = PRI_LOCAL_ISDN + 1;
19392 }
else if (!strcasecmp(v->
value,
"from_channel")) {
19393 confp->pri.pri.cpndialplan = 0;
19394 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19395 confp->pri.pri.cpndialplan = -1;
19396 }
else if (!strcasecmp(v->
value,
"redundant")) {
19397 confp->pri.pri.cpndialplan = -2;
19401 }
else if (!strcasecmp(v->
name,
"switchtype")) {
19402 if (!strcasecmp(v->
value,
"national"))
19403 confp->pri.pri.switchtype = PRI_SWITCH_NI2;
19404 else if (!strcasecmp(v->
value,
"ni1"))
19405 confp->pri.pri.switchtype = PRI_SWITCH_NI1;
19406 else if (!strcasecmp(v->
value,
"dms100"))
19407 confp->pri.pri.switchtype = PRI_SWITCH_DMS100;
19408 else if (!strcasecmp(v->
value,
"4ess"))
19409 confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS;
19410 else if (!strcasecmp(v->
value,
"5ess"))
19411 confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E;
19412 else if (!strcasecmp(v->
value,
"euroisdn"))
19413 confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1;
19414 else if (!strcasecmp(v->
value,
"qsig"))
19415 confp->pri.pri.switchtype = PRI_SWITCH_QSIG;
19420 }
else if (!strcasecmp(v->
name,
"msn")) {
19422 sizeof(confp->pri.pri.msn_list));
19423 }
else if (!strcasecmp(v->
name,
"nsf")) {
19424 if (!strcasecmp(v->
value,
"sdn"))
19425 confp->pri.pri.nsf = PRI_NSF_SDN;
19426 else if (!strcasecmp(v->
value,
"megacom"))
19427 confp->pri.pri.nsf = PRI_NSF_MEGACOM;
19428 else if (!strcasecmp(v->
value,
"tollfreemegacom"))
19429 confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;
19430 else if (!strcasecmp(v->
value,
"accunet"))
19431 confp->pri.pri.nsf = PRI_NSF_ACCUNET;
19432 else if (!strcasecmp(v->
value,
"none"))
19433 confp->pri.pri.nsf = PRI_NSF_NONE;
19436 confp->pri.pri.nsf = PRI_NSF_NONE;
19438 }
else if (!strcasecmp(v->
name,
"priindication")) {
19439 if (!strcasecmp(v->
value,
"outofband"))
19441 else if (!strcasecmp(v->
value,
"inband"))
19444 ast_log(
LOG_WARNING,
"'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n",
19446 }
else if (!strcasecmp(v->
name,
"priexclusive")) {
19448 }
else if (!strcasecmp(v->
name,
"internationalprefix")) {
19449 ast_copy_string(confp->pri.pri.internationalprefix, v->
value,
sizeof(confp->pri.pri.internationalprefix));
19450 }
else if (!strcasecmp(v->
name,
"nationalprefix")) {
19451 ast_copy_string(confp->pri.pri.nationalprefix, v->
value,
sizeof(confp->pri.pri.nationalprefix));
19452 }
else if (!strcasecmp(v->
name,
"localprefix")) {
19454 }
else if (!strcasecmp(v->
name,
"privateprefix")) {
19455 ast_copy_string(confp->pri.pri.privateprefix, v->
value,
sizeof(confp->pri.pri.privateprefix));
19456 }
else if (!strcasecmp(v->
name,
"unknownprefix")) {
19457 ast_copy_string(confp->pri.pri.unknownprefix, v->
value,
sizeof(confp->pri.pri.unknownprefix));
19458 }
else if (!strcasecmp(v->
name,
"resetinterval")) {
19459 if (!strcasecmp(v->
value,
"never"))
19460 confp->pri.pri.resetinterval = -1;
19461 else if (atoi(v->
value) >= 60)
19462 confp->pri.pri.resetinterval = atoi(v->
value);
19464 ast_log(
LOG_WARNING,
"'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n",
19466 }
else if (!strcasecmp(v->
name,
"force_restart_unavailable_chans")) {
19467 confp->pri.pri.force_restart_unavailable_chans =
ast_true(v->
value);
19468 }
else if (!strcasecmp(v->
name,
"minunused")) {
19469 confp->pri.pri.minunused = atoi(v->
value);
19470 }
else if (!strcasecmp(v->
name,
"minidle")) {
19471 confp->pri.pri.minidle = atoi(v->
value);
19472 }
else if (!strcasecmp(v->
name,
"idleext")) {
19474 }
else if (!strcasecmp(v->
name,
"idledial")) {
19476 }
else if (!strcasecmp(v->
name,
"overlapdial")) {
19479 }
else if (!strcasecmp(v->
value,
"incoming")) {
19481 }
else if (!strcasecmp(v->
value,
"outgoing")) {
19488#ifdef HAVE_PRI_PROG_W_CAUSE
19489 }
else if (!strcasecmp(v->
name,
"qsigchannelmapping")) {
19490 if (!strcasecmp(v->
value,
"logical")) {
19492 }
else if (!strcasecmp(v->
value,
"physical")) {
19498 }
else if (!strcasecmp(v->
name,
"discardremoteholdretrieval")) {
19499 confp->pri.pri.discardremoteholdretrieval =
ast_true(v->
value);
19500#if defined(HAVE_PRI_SERVICE_MESSAGES)
19501 }
else if (!strcasecmp(v->
name,
"service_message_support")) {
19503 if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS
19504 || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E
19505 || confp->pri.pri.switchtype == PRI_SWITCH_NI2) &&
ast_true(v->
value)) {
19506 confp->pri.pri.enable_service_message_support = 1;
19508 confp->pri.pri.enable_service_message_support = 0;
19511#ifdef HAVE_PRI_INBANDDISCONNECT
19512 }
else if (!strcasecmp(v->
name,
"inbanddisconnect")) {
19515 }
else if (!strcasecmp(v->
name,
"pritimer")) {
19516#ifdef PRI_GETSET_TIMERS
19527 timeridx = pri_timer2idx(timerc);
19529 if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) {
19531 "'%s' is not a valid ISDN timer at line %d.\n", timerc,
19533 }
else if (!
timer) {
19535 "'%s' is not a valid value for ISDN timer '%s' at line %d.\n",
19538 confp->pri.pri.pritimers[timeridx] =
timer;
19542 "'%s' is not a valid ISDN timer configuration string at line %d.\n",
19546 }
else if (!strcasecmp(v->
name,
"facilityenable")) {
19548#if defined(HAVE_PRI_AOC_EVENTS)
19549 }
else if (!strcasecmp(v->
name,
"aoc_enable")) {
19550 confp->pri.pri.aoc_passthrough_flag = 0;
19551 if (strchr(v->
value,
's') || strchr(v->
value,
'S')) {
19554 if (strchr(v->
value,
'd') || strchr(v->
value,
'D')) {
19557 if (strchr(v->
value,
'e') || strchr(v->
value,
'E')) {
19560 }
else if (!strcasecmp(v->
name,
"aoce_delayhangup")) {
19563#if defined(HAVE_PRI_CALL_HOLD)
19564 }
else if (!strcasecmp(v->
name,
"hold_disconnect_transfer")) {
19565 confp->pri.pri.hold_disconnect_transfer =
ast_true(v->
value);
19567 }
else if (!strcasecmp(v->
name,
"moh_signaling")
19568 || !strcasecmp(v->
name,
"moh_signalling")) {
19569 if (!strcasecmp(v->
value,
"moh")) {
19571 }
else if (!strcasecmp(v->
value,
"notify")) {
19573#if defined(HAVE_PRI_CALL_HOLD)
19574 }
else if (!strcasecmp(v->
value,
"hold")) {
19575 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_HOLD;
19580#if defined(HAVE_PRI_CCSS)
19581 }
else if (!strcasecmp(v->
name,
"cc_ptmp_recall_mode")) {
19582 if (!strcasecmp(v->
value,
"global")) {
19583 confp->pri.pri.cc_ptmp_recall_mode = 0;
19584 }
else if (!strcasecmp(v->
value,
"specific")) {
19585 confp->pri.pri.cc_ptmp_recall_mode = 1;
19587 confp->pri.pri.cc_ptmp_recall_mode = 1;
19589 }
else if (!strcasecmp(v->
name,
"cc_qsig_signaling_link_req")) {
19590 if (!strcasecmp(v->
value,
"release")) {
19591 confp->pri.pri.cc_qsig_signaling_link_req = 0;
19592 }
else if (!strcasecmp(v->
value,
"retain")) {
19593 confp->pri.pri.cc_qsig_signaling_link_req = 1;
19594 }
else if (!strcasecmp(v->
value,
"do_not_care")) {
19595 confp->pri.pri.cc_qsig_signaling_link_req = 2;
19597 confp->pri.pri.cc_qsig_signaling_link_req = 1;
19599 }
else if (!strcasecmp(v->
name,
"cc_qsig_signaling_link_rsp")) {
19600 if (!strcasecmp(v->
value,
"release")) {
19601 confp->pri.pri.cc_qsig_signaling_link_rsp = 0;
19602 }
else if (!strcasecmp(v->
value,
"retain")) {
19603 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;
19605 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;
19608#if defined(HAVE_PRI_CALL_WAITING)
19609 }
else if (!strcasecmp(v->
name,
"max_call_waiting_calls")) {
19610 confp->pri.pri.max_call_waiting_calls = atoi(v->
value);
19611 if (confp->pri.pri.max_call_waiting_calls < 0) {
19613 confp->pri.pri.max_call_waiting_calls = 0;
19615 }
else if (!strcasecmp(v->
name,
"allow_call_waiting_calls")) {
19616 confp->pri.pri.allow_call_waiting_calls =
ast_true(v->
value);
19618#if defined(HAVE_PRI_MWI)
19619 }
else if (!strcasecmp(v->
name,
"mwi_mailboxes")) {
19621 sizeof(confp->pri.pri.mwi_mailboxes));
19622 }
else if (!strcasecmp(v->
name,
"mwi_vm_boxes")) {
19624 sizeof(confp->pri.pri.mwi_vm_boxes));
19625 }
else if (!strcasecmp(v->
name,
"mwi_vm_numbers")) {
19627 sizeof(confp->pri.pri.mwi_vm_numbers));
19629 }
else if (!strcasecmp(v->
name,
"append_msn_to_cid_tag")) {
19630 confp->pri.pri.append_msn_to_user_tag =
ast_true(v->
value);
19631 }
else if (!strcasecmp(v->
name,
"inband_on_setup_ack")) {
19633 }
else if (!strcasecmp(v->
name,
"inband_on_proceeding")) {
19635#if defined(HAVE_PRI_DISPLAY_TEXT)
19636 }
else if (!strcasecmp(v->
name,
"display_send")) {
19637 confp->pri.pri.display_flags_send = dahdi_display_text_option(v->
value);
19638 }
else if (!strcasecmp(v->
name,
"display_receive")) {
19639 confp->pri.pri.display_flags_receive = dahdi_display_text_option(v->
value);
19641#if defined(HAVE_PRI_MCID)
19642 }
else if (!strcasecmp(v->
name,
"mcid_send")) {
19645#if defined(HAVE_PRI_DATETIME_SEND)
19646 }
else if (!strcasecmp(v->
name,
"datetime_send")) {
19647 confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->
value);
19649 }
else if (!strcasecmp(v->
name,
"layer1_presence")) {
19650 if (!strcasecmp(v->
value,
"required")) {
19651 confp->pri.pri.layer1_ignored = 0;
19652 }
else if (!strcasecmp(v->
value,
"ignore")) {
19653 confp->pri.pri.layer1_ignored = 1;
19656 confp->pri.pri.layer1_ignored = 0;
19658#if defined(HAVE_PRI_L2_PERSISTENCE)
19659 }
else if (!strcasecmp(v->
name,
"layer2_persistence")) {
19660 if (!strcasecmp(v->
value,
"keep_up")) {
19661 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_KEEP_UP;
19662 }
else if (!strcasecmp(v->
value,
"leave_down")) {
19663 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN;
19665 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_DEFAULT;
19668 }
else if (!strcasecmp(v->
name,
"colp_send")) {
19669 if (!strcasecmp(v->
value,
"block")) {
19671 }
else if (!strcasecmp(v->
value,
"connect")) {
19673 }
else if (!strcasecmp(v->
value,
"update")) {
19679#if defined(HAVE_SS7)
19680 }
else if (!strcasecmp(v->
name,
"ss7type")) {
19681 if (!strcasecmp(v->
value,
"itu")) {
19682 cur_ss7type = SS7_ITU;
19683 }
else if (!strcasecmp(v->
value,
"ansi")) {
19684 cur_ss7type = SS7_ANSI;
19688 }
else if (!strcasecmp(v->
name,
"slc")) {
19689 cur_slc = atoi(v->
value);
19690 }
else if (!strcasecmp(v->
name,
"linkset")) {
19691 cur_linkset = atoi(v->
value);
19692 }
else if (!strcasecmp(v->
name,
"pointcode")) {
19693 cur_pointcode = parse_pointcode(v->
value);
19694 }
else if (!strcasecmp(v->
name,
"adjpointcode")) {
19695 cur_adjpointcode = parse_pointcode(v->
value);
19696 }
else if (!strcasecmp(v->
name,
"defaultdpc")) {
19697 cur_defaultdpc = parse_pointcode(v->
value);
19698 }
else if (!strcasecmp(v->
name,
"cicbeginswith")) {
19699 cur_cicbeginswith = atoi(v->
value);
19700 }
else if (!strcasecmp(v->
name,
"networkindicator")) {
19701 if (!strcasecmp(v->
value,
"national")) {
19702 cur_networkindicator = SS7_NI_NAT;
19703 }
else if (!strcasecmp(v->
value,
"national_spare")) {
19704 cur_networkindicator = SS7_NI_NAT_SPARE;
19705 }
else if (!strcasecmp(v->
value,
"international")) {
19706 cur_networkindicator = SS7_NI_INT;
19707 }
else if (!strcasecmp(v->
value,
"international_spare")) {
19708 cur_networkindicator = SS7_NI_INT_SPARE;
19710 cur_networkindicator = -1;
19712 }
else if (!strcasecmp(v->
name,
"ss7_internationalprefix")) {
19713 ast_copy_string(confp->ss7.ss7.internationalprefix, v->
value,
sizeof(confp->ss7.ss7.internationalprefix));
19714 }
else if (!strcasecmp(v->
name,
"ss7_nationalprefix")) {
19715 ast_copy_string(confp->ss7.ss7.nationalprefix, v->
value,
sizeof(confp->ss7.ss7.nationalprefix));
19716 }
else if (!strcasecmp(v->
name,
"ss7_subscriberprefix")) {
19717 ast_copy_string(confp->ss7.ss7.subscriberprefix, v->
value,
sizeof(confp->ss7.ss7.subscriberprefix));
19718 }
else if (!strcasecmp(v->
name,
"ss7_unknownprefix")) {
19719 ast_copy_string(confp->ss7.ss7.unknownprefix, v->
value,
sizeof(confp->ss7.ss7.unknownprefix));
19720 }
else if (!strcasecmp(v->
name,
"ss7_networkroutedprefix")) {
19721 ast_copy_string(confp->ss7.ss7.networkroutedprefix, v->
value,
sizeof(confp->ss7.ss7.networkroutedprefix));
19722 }
else if (!strcasecmp(v->
name,
"ss7_called_nai")) {
19723 if (!strcasecmp(v->
value,
"national")) {
19724 confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL;
19725 }
else if (!strcasecmp(v->
value,
"international")) {
19726 confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL;
19727 }
else if (!strcasecmp(v->
value,
"subscriber")) {
19728 confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER;
19729 }
else if (!strcasecmp(v->
value,
"unknown")) {
19730 confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN;
19731 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19736 }
else if (!strcasecmp(v->
name,
"ss7_calling_nai")) {
19737 if (!strcasecmp(v->
value,
"national")) {
19738 confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL;
19739 }
else if (!strcasecmp(v->
value,
"international")) {
19740 confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL;
19741 }
else if (!strcasecmp(v->
value,
"subscriber")) {
19742 confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER;
19743 }
else if (!strcasecmp(v->
value,
"unknown")) {
19744 confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN;
19745 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19750 }
else if (!strcasecmp(v->
name,
"sigchan")) {
19752 sigchan = atoi(v->
value);
19753 res = linkset_addsigchan(sigchan);
19757 }
else if (!strcasecmp(v->
name,
"ss7_explicitacm")) {
19758 struct dahdi_ss7 *link;
19759 link = ss7_resolve_linkset(cur_linkset);
19767 link->ss7.flags &= ~LINKSET_FLAG_EXPLICITACM;
19769 }
else if (!strcasecmp(v->
name,
"ss7_autoacm")) {
19770 struct dahdi_ss7 *link;
19771 link = ss7_resolve_linkset(cur_linkset);
19779 link->ss7.flags &= ~LINKSET_FLAG_AUTOACM;
19781 }
else if (!strcasecmp(v->
name,
"ss7_initialhwblo")) {
19782 struct dahdi_ss7 *link;
19783 link = ss7_resolve_linkset(cur_linkset);
19791 link->ss7.flags &= ~LINKSET_FLAG_INITIALHWBLO;
19793 }
else if (!strcasecmp(v->
name,
"ss7_use_echocontrol")) {
19794 struct dahdi_ss7 *link;
19795 link = ss7_resolve_linkset(cur_linkset);
19803 link->ss7.flags &= ~LINKSET_FLAG_USEECHOCONTROL;
19805 }
else if (!strcasecmp(v->
name,
"ss7_default_echocontrol")) {
19806 struct dahdi_ss7 *link;
19807 link = ss7_resolve_linkset(cur_linkset);
19815 link->ss7.flags &= ~LINKSET_FLAG_DEFAULTECHOCONTROL;
19817 }
else if (!strncasecmp(v->
name,
"isup_timer.", 11)) {
19818 struct dahdi_ss7 *link;
19819 link = ss7_resolve_linkset(cur_linkset);
19824 if (!link->ss7.ss7) {
19826 }
else if (!ss7_set_isup_timer(link->ss7.ss7, strstr(v->
name,
".") + 1, atoi(v->
value))) {
19829 }
else if (!strncasecmp(v->
name,
"mtp3_timer.", 11)) {
19830 struct dahdi_ss7 *link;
19831 link = ss7_resolve_linkset(cur_linkset);
19836 if (!link->ss7.ss7) {
19838 }
else if (!ss7_set_mtp3_timer(link->ss7.ss7, strstr(v->
name,
".") + 1, atoi(v->
value))) {
19841 }
else if (!strcasecmp(v->
name,
"inr_if_no_calling")) {
19842 struct dahdi_ss7 *link;
19843 link = ss7_resolve_linkset(cur_linkset);
19848 if (!link->ss7.ss7) {
19851 ss7_set_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
19853 ss7_clear_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
19855 }
else if (!strcasecmp(v->
name,
"non_isdn_access")) {
19856 struct dahdi_ss7 *link;
19857 link = ss7_resolve_linkset(cur_linkset);
19862 if (!link->ss7.ss7) {
19865 ss7_clear_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
19867 ss7_set_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
19869 }
else if (!strcasecmp(v->
name,
"sls_shift")) {
19870 struct dahdi_ss7 *link;
19871 int sls_shift = atoi(v->
value);
19873 if (sls_shift < 0 || sls_shift > 7) {
19878 link = ss7_resolve_linkset(cur_linkset);
19883 if (!link->ss7.ss7) {
19886 ss7_set_sls_shift(link->ss7.ss7, sls_shift);
19888 }
else if (!strcasecmp(v->
name,
"cause_location")) {
19889 struct dahdi_ss7 *link;
19890 int cause_location = atoi(v->
value);
19892 if (cause_location < 0 || cause_location > 15) {
19893 ast_log(
LOG_ERROR,
"Invalid cause_location value. Must be between 0 and 15\n");
19896 link = ss7_resolve_linkset(cur_linkset);
19901 if (!link->ss7.ss7) {
19904 ss7_set_cause_location(link->ss7.ss7, cause_location);
19908 }
else if (!strcasecmp(v->
name,
"mfcr2_advanced_protocol_file")) {
19910 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);
19911 }
else if (!strcasecmp(v->
name,
"mfcr2_logdir")) {
19913 }
else if (!strcasecmp(v->
name,
"mfcr2_variant")) {
19914 confp->mfcr2.variant = openr2_proto_get_variant(v->
value);
19915 if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) {
19917 confp->mfcr2.variant = OR2_VAR_ITU;
19919 }
else if (!strcasecmp(v->
name,
"mfcr2_mfback_timeout")) {
19920 confp->mfcr2.mfback_timeout = atoi(v->
value);
19921 if (!confp->mfcr2.mfback_timeout) {
19922 ast_log(
LOG_WARNING,
"MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
19923 confp->mfcr2.mfback_timeout = -1;
19924 }
else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) {
19925 ast_log(
LOG_WARNING,
"MF timeout less than 500ms is not recommended, you have been warned!\n");
19927 }
else if (!strcasecmp(v->
name,
"mfcr2_metering_pulse_timeout")) {
19928 confp->mfcr2.metering_pulse_timeout = atoi(v->
value);
19929 if (confp->mfcr2.metering_pulse_timeout > 500) {
19930 ast_log(
LOG_WARNING,
"Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n");
19932#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
19933 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_detection")) {
19935 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_dialing")) {
19937 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_time_on")) {
19938 confp->mfcr2.dtmf_time_on = atoi(v->
value);
19939 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_time_off")) {
19940 confp->mfcr2.dtmf_time_off = atoi(v->
value);
19942#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
19943 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_end_timeout")) {
19944 confp->mfcr2.dtmf_end_timeout = atoi(v->
value);
19946 }
else if (!strcasecmp(v->
name,
"mfcr2_get_ani_first")) {
19948 }
else if (!strcasecmp(v->
name,
"mfcr2_double_answer")) {
19950 }
else if (!strcasecmp(v->
name,
"mfcr2_charge_calls")) {
19952 }
else if (!strcasecmp(v->
name,
"mfcr2_accept_on_offer")) {
19954 }
else if (!strcasecmp(v->
name,
"mfcr2_allow_collect_calls")) {
19955 confp->mfcr2.allow_collect_calls =
ast_true(v->
value) ? 1 : 0;
19956 }
else if (!strcasecmp(v->
name,
"mfcr2_forced_release")) {
19958 }
else if (!strcasecmp(v->
name,
"mfcr2_immediate_accept")) {
19959 confp->mfcr2.immediate_accept =
ast_true(v->
value) ? 1 : 0;
19960#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
19961 }
else if (!strcasecmp(v->
name,
"mfcr2_skip_category")) {
19962 confp->mfcr2.skip_category_request =
ast_true(v->
value) ? 1 : 0;
19964 }
else if (!strcasecmp(v->
name,
"mfcr2_call_files")) {
19966 }
else if (!strcasecmp(v->
name,
"mfcr2_max_ani")) {
19967 confp->mfcr2.max_ani = atoi(v->
value);
19971 }
else if (!strcasecmp(v->
name,
"mfcr2_max_dnis")) {
19972 confp->mfcr2.max_dnis = atoi(v->
value);
19976 }
else if (!strcasecmp(v->
name,
"mfcr2_category")) {
19977 confp->mfcr2.category = openr2_proto_get_category(v->
value);
19978 if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) {
19979 confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
19980 ast_log(
LOG_WARNING,
"Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n",
19983 }
else if (!strcasecmp(v->
name,
"mfcr2_logging")) {
19984 openr2_log_level_t tmplevel;
19991 clevel =
strsep(&logval,
",");
19992 if (-1 == (tmplevel = openr2_log_get_level(clevel))) {
19996 confp->mfcr2.loglevel |= tmplevel;
19999 }
else if (!strcasecmp(v->
name,
"cadence")) {
20001 int element_count,
c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
20003 struct dahdi_ring_cadence new_cadence;
20004 int cid_location = -1;
20005 int firstcadencepos = 0;
20006 char original_args[80];
20007 int cadence_is_ok = 1;
20011 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]);
20014 if (element_count % 2 == 1) {
20015 ast_log(
LOG_ERROR,
"Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->
lineno);
20025 for (i = 0; i < element_count; i++) {
20027 ast_log(
LOG_ERROR,
"Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->
lineno);
20030 }
else if (
c[i] < 0) {
20033 if (cid_location == -1) {
20042 if (firstcadencepos == 0) {
20043 firstcadencepos = i;
20046 ast_log(
LOG_ERROR,
"First cadence position specified twice: %s at line %d.\n", original_args, v->
lineno);
20055 for (i = 0; i < 16; i++) {
20056 new_cadence.ringcadence[i] =
c[i];
20059 if (cadence_is_ok) {
20061 if (element_count < 2) {
20064 if (cid_location == -1) {
20069 cid_location = (cid_location + 1) / 2;
20084 }
else if (!strcasecmp(v->
name,
"ringtimeout")) {
20086 }
else if (!strcasecmp(v->
name,
"prewink")) {
20088 }
else if (!strcasecmp(v->
name,
"preflash")) {
20090 }
else if (!strcasecmp(v->
name,
"wink")) {
20092 }
else if (!strcasecmp(v->
name,
"flash")) {
20094 }
else if (!strcasecmp(v->
name,
"start")) {
20096 }
else if (!strcasecmp(v->
name,
"rxwink")) {
20098 }
else if (!strcasecmp(v->
name,
"rxflash")) {
20100 }
else if (!strcasecmp(v->
name,
"debounce")) {
20102 }
else if (!strcasecmp(v->
name,
"toneduration")) {
20106 struct dahdi_dialparams dps;
20108 ctlfd = open(
"/dev/dahdi/ctl", O_RDWR);
20114 toneduration = atoi(v->
value);
20115 if (toneduration > -1) {
20116 memset(&dps, 0,
sizeof(dps));
20118 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
20119 res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps);
20127 }
else if (!strcasecmp(v->
name,
"defaultcic")) {
20129 }
else if (!strcasecmp(v->
name,
"defaultozz")) {
20131 }
else if (!strcasecmp(v->
name,
"mwilevel")) {
20133 }
else if (!strcasecmp(v->
name,
"dtmfcidlevel")) {
20135 }
else if (!strcasecmp(v->
name,
"reportalarms")) {
20136 if (!strcasecmp(v->
value,
"all"))
20138 if (!strcasecmp(v->
value,
"none"))
20140 else if (!strcasecmp(v->
value,
"channels"))
20142 else if (!strcasecmp(v->
value,
"spans"))
20154 "Dahdichan '%s' failure ignored: ignore_failed_channels.\n",
20172 for (tmp =
iflist, y=-1; tmp; tmp = tmp->
next) {
20190 if (
conf.chan.cc_params) {
20196 ast_verb(3,
"Automatically generated pseudo channel\n");
20260 static int had_cfg_before = 1;
20263 have_cfg_now = !!cfg;
20266 if (had_cfg_before) {
20277 have_cfg_now = !!cfg;
20279 if (had_cfg_before) {
20298 had_cfg_before = have_cfg_now;
20307 if (!strcasecmp(v->
name,
"trunkgroup")) {
20308 trunkgroup = atoi(v->
value);
20309 if (trunkgroup > 0) {
20310 if ((
c = strchr(v->
value,
','))) {
20312 memset(dchannels, 0,
sizeof(dchannels));
20314 dchannels[i] = atoi(
c + 1);
20315 if (dchannels[i] < 0) {
20316 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);
20319 c = strchr(
c + 1,
',');
20322 if (pri_create_trunkgroup(trunkgroup, dchannels)) {
20323 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);
20325 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");
20327 ast_log(
LOG_WARNING,
"Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->
lineno);
20329 ast_log(
LOG_WARNING,
"Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->
lineno);
20331 ast_log(
LOG_WARNING,
"Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->
lineno);
20332 }
else if (!strcasecmp(v->
name,
"spanmap")) {
20333 spanno = atoi(v->
value);
20335 if ((
c = strchr(v->
value,
','))) {
20336 trunkgroup = atoi(
c + 1);
20337 if (trunkgroup > 0) {
20338 if ((
c = strchr(
c + 1,
',')))
20339 logicalspan = atoi(
c + 1);
20342 if (logicalspan >= 0) {
20343 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
20344 ast_log(
LOG_WARNING,
"Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
20346 ast_verb(2,
"Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
20348 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);
20382 if (!strcasecmp(cat,
"general") ||
20383 !strcasecmp(cat,
"trunkgroups") ||
20384 !strcasecmp(cat,
"globals") ||
20385 !strcasecmp(cat,
"channels")) {
20412 if (pris[x].pri.
pvts[0] &&
20414 prepare_pri(pris + x);
20419 ast_verb(2,
"Starting D-Channel on span %d\n", x + 1);
20424#if defined(HAVE_SS7)
20428 if (linksets[x].ss7.
ss7) {
20433 ast_verb(2,
"Starting SS7 linkset on span %d\n", x + 1);
20440 struct r2link_entry *cur;
20444 struct dahdi_mfcr2 *r2 = &cur->mfcr2;
20447 ast_log(
LOG_ERROR,
"Unable to start R2 monitor on channel group %d\n", x + 1);
20450 ast_verb(2,
"Starting R2 monitor on channel group %d\n", x + 1);
20504#if defined(HAVE_PRI) || defined(HAVE_SS7)
20525 memset(pris, 0,
sizeof(pris));
20529 pri_set_error(dahdi_pri_error);
20530 pri_set_message(dahdi_pri_message);
20532#ifdef HAVE_PRI_PROG_W_CAUSE
20535#if defined(HAVE_PRI_CCSS)
20543#
if defined(HAVE_PRI_CCSS)
20553#if defined(HAVE_SS7)
20554 memset(linksets, 0,
sizeof(linksets));
20558 ss7_set_error(dahdi_ss7_error);
20559 ss7_set_message(dahdi_ss7_message);
20578#if defined(HAVE_SS7)
20599#if defined(HAVE_PRI)
20613#define END_SILENCE_LEN 400
20614#define HEADER_MS 50
20615#define TRAILER_MS 5
20616#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
20617#define ASCII_BYTES_PER_CHAR 80
20619 unsigned char *
buf,*mybuf;
20621 struct pollfd fds[1];
20622 int size,res,fd,
len,x;
20644 if ((!p->
tdd) && (!p->
mate)) {
20645#if defined(HAVE_PRI)
20646#if defined(HAVE_PRI_DISPLAY_TEXT)
20671 for (x = 0;
text[x]; x++) {
20699 fds[0].events = POLLOUT | POLLPRI;
20700 fds[0].revents = 0;
20701 res = poll(fds, 1, -1);
20707 if (fds[0].revents & POLLPRI) {
20711 if (!(fds[0].revents & POLLOUT)) {
20715 res = write(fd,
buf, size);
20754 .
requires =
"ccss",
20755 .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 struct @120 alarms[]
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)
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
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 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)
Defi