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
673#define SMDI_MD_WAIT_TIMEOUT 1500
676"0 db (CSU)/0-133 feet (DSX-1)",
677"133-266 feet (DSX-1)",
678"266-399 feet (DSX-1)",
679"399-533 feet (DSX-1)",
680"533-655 feet (DSX-1)",
692 .resync_threshold = 1000,
710#define DEFAULT_CIDRINGS 1
712#define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? ast_format_alaw : ast_format_ulaw)
716#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))
718static const char tdesc[] =
"DAHDI Telephony"
719#if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
721 #if defined(HAVE_PRI)
724 #if defined(HAVE_SS7)
725 #if defined(HAVE_PRI)
730 #if defined(HAVE_OPENR2)
731 #if defined(HAVE_PRI) || defined(HAVE_SS7)
739static const char config[] =
"chan_dahdi.conf";
742#define NUM_SPANS DAHDI_MAX_SPANS
747#define CHAN_PSEUDO -2
749#define CALLPROGRESS_PROGRESS 1
750#define CALLPROGRESS_FAX_OUTGOING 2
751#define CALLPROGRESS_FAX_INCOMING 4
752#define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
754#define NUM_CADENCE_MAX 25
761 { { 125, 125, 2000, 4000 } },
762 { { 250, 250, 500, 1000, 250, 250, 500, 4000 } },
763 { { 125, 125, 125, 125, 125, 4000 } },
764 { { 1000, 500, 2500, 5000 } },
781#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
782 (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
784#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) )
785#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) )
792#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
806#define REPORT_CHANNEL_ALARMS 1
807#define REPORT_SPAN_ALARMS 2
811static int pridebugfd = -1;
812static char pridebugfilename[1024] =
"";
846 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
855 i = DAHDI_IOMUX_SIGEVENT;
856 if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
858 if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
866#define MASK_AVAIL (1 << 0)
867#define MASK_INUSE (1 << 1)
869#define CALLWAITING_SILENT_SAMPLES ((300 * 8) / READ_SIZE)
870#define CALLWAITING_REPEAT_SAMPLES ((10000 * 8) / READ_SIZE)
871#define CALLWAITING_SUPPRESS_SAMPLES ((100 * 8) / READ_SIZE)
872#define CIDCW_EXPIRE_SAMPLES ((500 * 8) / READ_SIZE)
873#define MIN_MS_SINCE_FLASH ((2000) )
874#define DEFAULT_RINGT ((8000 * 8) / READ_SIZE)
875#define DEFAULT_DIALTONE_DETECT_TIMEOUT ((10000 * 8) / READ_SIZE)
889static struct dahdi_ss7 linksets[
NUM_SPANS];
891static int cur_ss7type = -1;
892static int cur_slc = -1;
893static int cur_linkset = -1;
894static int cur_pointcode = -1;
895static int cur_cicbeginswith = -1;
896static int cur_adjpointcode = -1;
897static int cur_networkindicator = -1;
898static int cur_defaultdpc = -1;
902struct dahdi_mfcr2_conf {
903 openr2_variant_t variant;
905 int metering_pulse_timeout;
908#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
912#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
913 int dtmf_end_timeout;
915 signed int get_ani_first:2;
916#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
917 signed int skip_category_request:2;
919 unsigned int call_files:1;
920 unsigned int allow_collect_calls:1;
921 unsigned int charge_calls:1;
922 unsigned int accept_on_offer:1;
923 unsigned int forced_release:1;
924 unsigned int double_answer:1;
925 signed int immediate_accept:2;
926#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
927 signed int dtmf_dialing:2;
928 signed int dtmf_detection:2;
930 char logdir[OR2_MAX_PATH];
931 char r2proto_file[OR2_MAX_PATH];
932 openr2_log_level_t loglevel;
933 openr2_calling_party_category_t category;
940 openr2_context_t *protocol_context;
945 struct dahdi_mfcr2_conf
conf;
949 struct dahdi_mfcr2 mfcr2;
957static int r2links_count = 0;
965 int mastertrunkgroup;
972#if defined(HAVE_PRI_CCSS)
974static const char dahdi_pri_cc_type[] =
"DAHDI/PRI";
983#define POLARITY_IDLE 0
984#define POLARITY_REV 1
1004static struct dahdi_parms_pseudo {
1009} dahdi_pseudo_parms;
1025 struct dahdi_pri pri;
1028#if defined(HAVE_SS7)
1029 struct dahdi_ss7 ss7;
1033 struct dahdi_mfcr2_conf mfcr2;
1068 .nsf = PRI_NSF_NONE,
1069 .switchtype = PRI_SWITCH_NI2,
1070 .dialplan = PRI_UNKNOWN + 1,
1071 .localdialplan = PRI_NATIONAL_ISDN + 1,
1072 .nodetype = PRI_CPE,
1075#if defined(HAVE_PRI_CCSS)
1076 .cc_ptmp_recall_mode = 1,
1077 .cc_qsig_signaling_link_req = 1,
1078 .cc_qsig_signaling_link_rsp = 1,
1084 .internationalprefix =
"",
1085 .nationalprefix =
"",
1087 .privateprefix =
"",
1088 .unknownprefix =
"",
1090 .resetinterval = -1,
1093#if defined(HAVE_SS7)
1095 .called_nai = SS7_NAI_NATIONAL,
1096 .calling_nai = SS7_NAI_NATIONAL,
1097 .internationalprefix =
"",
1098 .nationalprefix =
"",
1099 .subscriberprefix =
"",
1100 .unknownprefix =
"",
1101 .networkroutedprefix =
""
1106 .variant = OR2_VAR_ITU,
1107 .mfback_timeout = -1,
1108 .metering_pulse_timeout = -1,
1111 .get_ani_first = -1,
1112#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
1113 .skip_category_request = -1,
1116 .allow_collect_calls = 0,
1118 .accept_on_offer = 1,
1119 .forced_release = 0,
1121 .immediate_accept = -1,
1122#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
1124 .dtmf_detection = -1,
1125 .dtmf_time_on = OR2_DEFAULT_DTMF_ON,
1126 .dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
1128#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
1129 .dtmf_end_timeout = -1,
1133 .loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
1134 .category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
1138 .context =
"default",
1143 .mohinterpret =
"default",
1146 .transfertobusy = 1,
1149 .ani_info_digits = 2,
1150 .ani_wink_time = 1000,
1151 .ani_timeout = 10000,
1155 .dahditrcallerid = 0,
1164 .echocancel.head.tap_length = 1,
1172#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1175 .polarityonanswerdelay = 600,
1179 .buf_policy = DAHDI_POLICY_IMMEDIATE,
1198 .ignore_failed_channels = 1,
1199 .smdi_port =
"/dev/ttyS0",
1208 const char *
data,
int *cause);
1229 .description =
tdesc,
1250#define GET_CHANNEL(p) ((p)->channel)
1307 return DAHDI_TONE_RINGTONE;
1309 return DAHDI_TONE_STUTTER;
1311 return DAHDI_TONE_CONGESTION;
1313 return DAHDI_TONE_DIALTONE;
1315 return DAHDI_TONE_DIALRECALL;
1317 return DAHDI_TONE_INFO;
1327 switch (analogsub) {
1356 struct doomed_pri *entry;
1362 ast_debug(4,
"Destroying span %d from doomed queue.\n",
1364 pri_destroy_span(entry->pri);
1383static void pri_queue_for_destruction(
struct sig_pri_span *pri)
1385 struct doomed_pri *entry;
1389 if (entry->pri == pri) {
1394 entry =
ast_calloc(
sizeof(
struct doomed_pri), 1);
1402 ast_debug(4,
"Queue span %d for destruction.\n", pri->
span);
1425 struct dahdi_dialoperation zo = {
1431 for (offset = 0; offset <
sizeof(zo.dialstr) - 1; ++offset) {
1438 if (offset >=
sizeof(zo.dialstr) - 3) {
1442 zo.dialstr[offset] =
'w';
1444 zo.dialstr[offset] =
'w';
1447 zo.dialstr[offset] = *pos++;
1451 ast_debug(1,
"Channel %d: Dial str '%s' expanded to '%s' sent to DAHDI_DIAL.\n",
1452 pvt->
channel, dial_str, zo.dialstr);
1503 struct pollfd poller;
1507 unsigned char buf[256];
1512 poller.events = POLLPRI | POLLIN;
1515 res = poll(&poller, 1, timeout);
1517 if (poller.revents & POLLPRI) {
1522 if (poller.revents & POLLIN) {
1534 if (analog_p->
ringt > 0) {
1535 if (!(--analog_p->
ringt)) {
1598 unsigned char buf[256];
1606 int checkaftercid = 0;
1607 const char *matched_context;
1611 if (ringdata ==
NULL) {
1612 ringdata = curRingData;
1620 for (receivedRingT = 0; receivedRingT <
RING_PATTERNS; receivedRingT++)
1621 ringdata[receivedRingT] = 0;
1625 ast_verb(3,
"Detecting post-CID distinctive ring\n");
1629 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1630 res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i);
1636 if (i & DAHDI_IOMUX_SIGEVENT) {
1639 if (res == DAHDI_EVENT_NOALARM) {
1642 }
else if (res == DAHDI_EVENT_RINGOFFHOOK) {
1644 ringdata[receivedRingT] = analog_p->
ringt;
1655 }
else if (i & DAHDI_IOMUX_READ) {
1658 if (
errno != ELAST) {
1665 if (analog_p->
ringt > 0) {
1666 if (!(--analog_p->
ringt)) {
1675 ast_verb(3,
"Detected ring pattern: %d,%d,%d\n", ringdata[0], ringdata[1], ringdata[2]);
1677 for (counter = 0; counter < 3; counter++) {
1681 ast_verb(3,
"Checking %d,%d,%d with +/- %d range\n",
1686 for (counter1 = 0; counter1 < 3; counter1++) {
1690 ast_verb(3,
"Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1691 ringdata[counter1]);
1693 }
else if (ring - range <= ringdata[counter1] && ringdata[counter1] <= ring + range) {
1694 ast_verb(3,
"Ring pattern %d is in range: %d to %d\n",
1695 ringdata[counter1], ring - range, ring + range);
1703 if (distMatches == 3) {
1706 ast_verb(3,
"Matched Distinctive Ring context %s\n", matched_context);
1712 if (strcmp(p->
context, matched_context) != 0) {
1800 ast_verb(3,
"CPE supports Call Waiting Caller*ID. Sending '%s/%s'\n",
1876 ast_log(
LOG_ERROR,
"We used a sub other than SUB_REAL (incorrect assumption sir)\n");
1893 ast_debug(1,
"%s DTMF digit: 0x%02X '%c' on %s\n",
1903 struct dahdi_bufferinfo bi = {
1910 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
1948 ast_debug(1,
"Already in a fax extension, not redirecting\n");
1957 *dest = &p->
subs[idx].
f;
1987 if (!channel_string) {
1997 "DAHDIGroup: %llu\r\n"
1999 "DAHDIChannel: %s\r\n",
2020 "channel", dahdi_channel);
2044 snprintf(ch_name,
sizeof(ch_name),
"no-media (%d)", p->
channel);
2047 strcpy(ch_name,
"pseudo");
2050 snprintf(ch_name,
sizeof(ch_name),
"%d", p->
channel);
2064static void my_ami_channel_event(
void *pvt,
struct ast_channel *chan)
2124 return p->
subs[dahdi_sub].
dfd;
2167#if defined(HAVE_PRI) || defined(HAVE_SS7)
2168static void my_set_digital(
void *pvt,
int is_digital)
2176#if defined(HAVE_SS7)
2177static void my_set_inservice(
void *pvt,
int is_inservice)
2185#if defined(HAVE_SS7)
2186static void my_set_locallyblocked(
void *pvt,
int is_blocked)
2194#if defined(HAVE_SS7)
2195static void my_set_remotelyblocked(
void *pvt,
int is_blocked)
2308 p->
owner = new_owner;
2359 for (i = 0; i < 3; i++) {
2396 int needconf = needconference;
2503#if defined(HAVE_PRI) || defined(HAVE_SS7)
2504static int dahdi_setlaw(
int dfd,
int law)
2507 res = ioctl(dfd, DAHDI_SETLAW, &
law);
2514#if defined(HAVE_PRI)
2553 newlaw = DAHDI_LAW_ALAW;
2556 newlaw = DAHDI_LAW_MULAW;
2566#if defined(HAVE_PRI) || defined(HAVE_SS7)
2574static void my_pri_ss7_open_media(
void *p)
2585 res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
2592 res = dahdi_setlaw(dfd, pvt->
law);
2614#if defined(HAVE_PRI)
2625static void my_pri_dial_digits(
void *p,
const char *dial_string)
2627 char dial_str[DAHDI_MAX_DTMF_BUF];
2631 snprintf(dial_str,
sizeof(dial_str),
"T%s", dial_string);
2681 case DAHDI_EVENT_ONHOOK:
2684 case DAHDI_EVENT_RINGOFFHOOK:
2687 case DAHDI_EVENT_WINKFLASH:
2690 case DAHDI_EVENT_ALARM:
2693 case DAHDI_EVENT_NOALARM:
2696 case DAHDI_EVENT_DIALCOMPLETE:
2699 case DAHDI_EVENT_RINGERON:
2702 case DAHDI_EVENT_RINGEROFF:
2705 case DAHDI_EVENT_HOOKCOMPLETE:
2708 case DAHDI_EVENT_PULSE_START:
2711 case DAHDI_EVENT_POLARITY:
2714 case DAHDI_EVENT_RINGBEGIN:
2717 case DAHDI_EVENT_EC_DISABLED:
2720 case DAHDI_EVENT_REMOVED:
2723 case DAHDI_EVENT_NEONMWI_ACTIVE:
2726 case DAHDI_EVENT_NEONMWI_INACTIVE:
2729#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2730 case DAHDI_EVENT_TX_CED_DETECTED:
2733 case DAHDI_EVENT_RX_CED_DETECTED:
2736 case DAHDI_EVENT_EC_NLP_DISABLED:
2739 case DAHDI_EVENT_EC_NLP_ENABLED:
2743 case DAHDI_EVENT_PULSEDIGIT:
2746 case DAHDI_EVENT_DTMFDOWN:
2749 case DAHDI_EVENT_DTMFUP:
2753 switch(
event & 0xFFFF0000) {
2754 case DAHDI_EVENT_PULSEDIGIT:
2755 case DAHDI_EVENT_DTMFDOWN:
2756 case DAHDI_EVENT_DTMFUP:
2798 struct dahdi_params par;
2800 memset(&par, 0,
sizeof(par));
2807 par.rxisoffhook = 0;
2817 return (par.rxbits > -1) || par.rxisoffhook;
2820 return par.rxisoffhook;
2847 int func = DAHDI_FLASH;
2915 struct dahdi_params dahdip;
2923 memset(&dahdip, 0,
sizeof(dahdip));
2930 if (!(dahdip.sigtype & __DAHDI_SIG_FXO)) {
2953 snprintf(buffer, buflen,
"%d", pvt->
polarity);
2968 if (!strcasecmp(
value,
"idle")) {
2970 }
else if (!strcasecmp(
value,
"reverse")) {
2994 int x = DAHDI_START;
3009 ast_log(
LOG_ERROR,
"Trying to dial_digits '%s' on channel %d subchannel %u\n",
3036 if (ioctl(p->
subs[index].
dfd, DAHDI_DIALING, &x)) {
3037 ast_debug(1,
"DAHDI_DIALING ioctl failed!\n");
3050#if defined(HAVE_PRI)
3051static void my_pri_fixup_chans(
void *chan_old,
void *chan_new)
3058 if (new_chan->
owner) {
3065 new_chan->
dsp = old_chan->
dsp;
3079 new_chan->
law = old_chan->
law;
3084#if defined(HAVE_PRI)
3085static int sig_pri_tone_to_dahditone(
enum sig_pri_tone tone)
3089 return DAHDI_TONE_RINGTONE;
3091 return DAHDI_TONE_STUTTER;
3093 return DAHDI_TONE_CONGESTION;
3095 return DAHDI_TONE_DIALTONE;
3097 return DAHDI_TONE_DIALRECALL;
3099 return DAHDI_TONE_INFO;
3101 return DAHDI_TONE_BUSY;
3108#if defined(HAVE_PRI)
3109static void my_handle_dchan_exception(
struct sig_pri_span *pri,
int index)
3113 ioctl(pri->
fds[index], DAHDI_GETEVENT, &x);
3115 case DAHDI_EVENT_NONE:
3117 case DAHDI_EVENT_ALARM:
3118 case DAHDI_EVENT_NOALARM:
3130 case DAHDI_EVENT_ALARM:
3133 case DAHDI_EVENT_NOALARM:
3136 case DAHDI_EVENT_REMOVED:
3137 pri_queue_for_destruction(pri);
3145#if defined(HAVE_PRI)
3146static int my_pri_play_tone(
void *pvt,
enum sig_pri_tone tone)
3150 return tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, sig_pri_tone_to_dahditone(tone));
3154#if defined(HAVE_PRI) || defined(HAVE_SS7)
3163static void my_set_callerid(
void *pvt,
const struct ast_party_caller *caller)
3178 if (caller->
id.
tag) {
3183 sizeof(p->cid_ani));
3188#if defined(HAVE_PRI) || defined(HAVE_SS7)
3197static void my_set_dnid(
void *pvt,
const char *
dnid)
3205#if defined(HAVE_PRI)
3214static void my_set_rdnis(
void *pvt,
const char *
rdnis)
3222#if defined(HAVE_PRI)
3249static void my_pri_make_cc_dialstring(
void *priv,
char *
buf,
size_t buf_size)
3270 snprintf(
buf, buf_size,
"%s/i%d-",
args.tech, pvt->pri->span);
3273 if (isdigit(
args.group[0]) ||
args.group[0] ==
'i' || strchr(
args.group,
'!')) {
3280 snprintf(
buf, buf_size,
"%s/i%d-%s",
args.tech, pvt->pri->span,
args.group);
3284#if defined(HAVE_PRI)
3294static void dahdi_pri_update_span_devstate(
struct sig_pri_span *pri)
3297 unsigned num_b_chans;
3306 for (idx = pri->
numchans; idx--;) {
3330#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
3334 }
else if (!in_use) {
3336 }
else if (!pri->user_busy_threshold) {
3342 if (pri->threshold_devstate != new_state) {
3343 pri->threshold_devstate = new_state;
3350#if defined(HAVE_PRI)
3356static void my_module_ref(
void)
3362#if defined(HAVE_PRI)
3368static void my_module_unref(
void)
3374#if defined(HAVE_PRI)
3375#if defined(HAVE_PRI_CALL_WAITING)
3376static void my_pri_init_config(
void *priv,
struct sig_pri_span *pri);
3378static int dahdi_new_pri_nobch_channel(
struct sig_pri_span *pri);
3383 .play_tone = my_pri_play_tone,
3389 .new_ast_channel = my_new_pri_ast_channel,
3390 .fixup_chans = my_pri_fixup_chans,
3394 .set_digital = my_set_digital,
3395 .set_callerid = my_set_callerid,
3396 .set_dnid = my_set_dnid,
3397 .set_rdnis = my_set_rdnis,
3398 .new_nobch_intf = dahdi_new_pri_nobch_channel,
3399#if defined(HAVE_PRI_CALL_WAITING)
3400 .init_config = my_pri_init_config,
3403 .make_cc_dialstring = my_pri_make_cc_dialstring,
3404 .update_span_devstate = dahdi_pri_update_span_devstate,
3405 .module_ref = my_module_ref,
3406 .module_unref = my_module_unref,
3407 .dial_digits = my_pri_dial_digits,
3408 .open_media = my_pri_ss7_open_media,
3409 .ami_channel_event = my_ami_channel_event,
3410 .destroy_later = pri_queue_for_destruction,
3414#if defined(HAVE_SS7)
3423static void my_handle_link_exception(
struct sig_ss7_linkset *linkset,
int which)
3427 if (ioctl(linkset->
fds[which], DAHDI_GETEVENT, &
event)) {
3429 linkset->
span, which);
3433 case DAHDI_EVENT_NONE:
3435 case DAHDI_EVENT_ALARM:
3440 case DAHDI_EVENT_NOALARM:
3453#if defined(HAVE_SS7)
3454static void my_ss7_set_loopback(
void *pvt,
int enable)
3465#if defined(HAVE_SS7)
3485 if (linksets[idx].
ss7.ss7 ==
ss7) {
3486 return &linksets[idx].ss7;
3493#if defined(HAVE_SS7)
3536 newlaw = DAHDI_LAW_ALAW;
3539 newlaw = DAHDI_LAW_MULAW;
3546#if defined(HAVE_SS7)
3547static int sig_ss7_tone_to_dahditone(
enum sig_ss7_tone tone)
3551 return DAHDI_TONE_RINGTONE;
3553 return DAHDI_TONE_STUTTER;
3555 return DAHDI_TONE_CONGESTION;
3557 return DAHDI_TONE_DIALTONE;
3559 return DAHDI_TONE_DIALRECALL;
3561 return DAHDI_TONE_INFO;
3563 return DAHDI_TONE_BUSY;
3570#if defined(HAVE_SS7)
3571static int my_ss7_play_tone(
void *pvt,
enum sig_ss7_tone tone)
3575 return tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, sig_ss7_tone_to_dahditone(tone));
3579#if defined(HAVE_SS7)
3587 .set_loopback = my_ss7_set_loopback,
3589 .new_ast_channel = my_new_ss7_ast_channel,
3590 .play_tone = my_ss7_play_tone,
3592 .handle_link_exception = my_handle_link_exception,
3596 .set_digital = my_set_digital,
3597 .set_inservice = my_set_inservice,
3598 .set_locallyblocked = my_set_locallyblocked,
3599 .set_remotelyblocked = my_set_remotelyblocked,
3600 .set_callerid = my_set_callerid,
3601 .set_dnid = my_set_dnid,
3602 .open_media = my_pri_ss7_open_media,
3603 .find_linkset = my_ss7_find_linkset,
3673#define gen_pvt_field_callback(type, field) \
3674 static type my_get_##field(void *pvt) \
3676 struct dahdi_pvt *p = pvt; \
3684#undef gen_pvt_field_callback
3754 .get_firstdigit_timeout = my_get_firstdigit_timeout,
3755 .get_matchdigit_timeout = my_get_matchdigit_timeout,
3756 .get_interdigit_timeout = my_get_interdigit_timeout,
3775 "Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
3868#if defined(HAVE_PRI)
3883static void mfcr2_queue_for_destruction(
const struct dahdi_pvt *p)
3885 const struct dahdi_mfcr2 *r2link = p->mfcr2;
3886 struct r2link_entry *cur;
3889 if (r2link == &cur->mfcr2) {
3899static int dahdi_r2_answer(
struct dahdi_pvt *p)
3905#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
3907 int wants_double_answer =
ast_true(double_answer) ? 1 : 0;
3908 if (!double_answer) {
3911 res = openr2_chan_answer_call(p->r2chan);
3912 }
else if (wants_double_answer) {
3913 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
3915 res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
3918 res = openr2_chan_answer_call(p->r2chan);
3926static openr2_calling_party_category_t dahdi_r2_get_channel_category(
struct ast_channel *
c)
3928 openr2_calling_party_category_t cat;
3932 ast_debug(1,
"No MFC/R2 category specified for chan %s, using default %s\n",
3934 return p->mfcr2_category;
3936 if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
3937 ast_log(
LOG_WARNING,
"Invalid category specified '%s' for chan %s, using default %s\n",
3938 catstr,
ast_channel_name(
c), openr2_proto_get_category_string(p->mfcr2_category));
3939 return p->mfcr2_category;
3941 ast_debug(1,
"Using category %s\n", catstr);
3945static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
3947 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3956 ast_log(
LOG_ERROR,
"Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
3966 p->mfcr2_ani_index =
'\0';
3967 p->mfcr2_dnis_index =
'\0';
3968 p->mfcr2_dnis_matched = 0;
3969 p->mfcr2_answer_pending = 0;
3970 p->mfcr2_call_accepted = 0;
3972 ast_verbose(
"New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
3975static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan,
int alarm)
3978 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3983 if (res == DAHDI_ALARM_NOTOPEN) {
3984 mfcr2_queue_for_destruction(p);
3993static void dahdi_r2_on_os_error(openr2_chan_t *r2chan,
int errorcode)
3995 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3997 ast_log(
LOG_ERROR,
"OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
4000 if (errorcode == ENODEV) {
4001 struct dahdi_mfcr2 *r2link = p->mfcr2;
4010static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
4012 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4013 ast_log(
LOG_ERROR,
"MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
4023static void dahdi_r2_disconnect_call(
struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
4025 if (openr2_chan_disconnect_call(p->r2chan, cause)) {
4026 ast_log(
LOG_NOTICE,
"Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n",
4027 p->
channel, openr2_proto_get_disconnect_string(cause));
4029 openr2_chan_set_idle(p->r2chan);
4036static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan,
const char *ani,
const char *dnis, openr2_calling_party_category_t category)
4042 ast_verbose(
"MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
4043 openr2_chan_get_number(r2chan), ani ? ani :
"(restricted)", dnis,
4044 openr2_proto_get_category_string(category));
4045 p = openr2_chan_get_client_data(r2chan);
4047 if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
4049 dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
4050 goto dahdi_r2_on_call_offered_cleanup;
4053 p->mfcr2_recvd_category = category;
4056 ast_debug(1,
"No CID allowed in configuration, CID is being cleared!\n");
4061 if (p->
immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
4062 ast_debug(1,
"Setting exten => s because of immediate or 0 DNIS configured\n");
4068 ast_log(
LOG_NOTICE,
"MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
4070 dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
4071 goto dahdi_r2_on_call_offered_cleanup;
4073 if (!p->mfcr2_accept_on_offer) {
4080 goto dahdi_r2_on_call_offered_cleanup;
4083 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
4084 }
else if (p->mfcr2_charge_calls) {
4085 ast_debug(1,
"Accepting MFC/R2 call with charge on chan %d\n", p->
channel);
4086 openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
4088 ast_debug(1,
"Accepting MFC/R2 call with no charge on chan %d\n", p->
channel);
4089 openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
4092dahdi_r2_on_call_offered_cleanup:
4096static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
4098 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4105static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
4111 p = openr2_chan_get_client_data(r2chan);
4113 p->mfcr2_call_accepted = 1;
4115 if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
4116 ast_verbose(
"MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
4121 if (!p->mfcr2_accept_on_offer) {
4122 openr2_chan_disable_read(r2chan);
4123 if (p->mfcr2_answer_pending) {
4124 ast_debug(1,
"Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
4127 goto dahdi_r2_on_call_accepted_cleanup;
4133 openr2_chan_disable_read(r2chan);
4134 goto dahdi_r2_on_call_accepted_cleanup;
4138 dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
4139 goto dahdi_r2_on_call_accepted_cleanup;
4146 openr2_chan_disable_read(r2chan);
4148dahdi_r2_on_call_accepted_cleanup:
4152static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
4154 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4155 ast_verbose(
"MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan));
4159static void dahdi_r2_on_call_read(openr2_chan_t *r2chan,
const unsigned char *
buf,
int buflen)
4164static int dahdi_r2_cause_to_ast_cause(openr2_call_disconnect_cause_t cause)
4167 case OR2_CAUSE_BUSY_NUMBER:
4169 case OR2_CAUSE_NETWORK_CONGESTION:
4171 case OR2_CAUSE_OUT_OF_ORDER:
4173 case OR2_CAUSE_UNALLOCATED_NUMBER:
4175 case OR2_CAUSE_NO_ANSWER:
4177 case OR2_CAUSE_NORMAL_CLEARING:
4179 case OR2_CAUSE_UNSPECIFIED:
4185static void dahdi_r2_on_call_disconnect(openr2_chan_t *r2chan, openr2_call_disconnect_cause_t cause)
4187 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4190 int datalen =
sizeof(*cause_code);
4192 ast_verbose(
"MFC/R2 call disconnected on channel %d\n", openr2_chan_get_number(r2chan));
4197 dahdi_r2_disconnect_call(p, OR2_CAUSE_NORMAL_CLEARING);
4201 snprintf(cause_str,
sizeof(cause_str),
"R2 DISCONNECT (%s)", openr2_proto_get_disconnect_string(cause));
4202 datalen += strlen(cause_str);
4204 memset(cause_code, 0, datalen);
4205 cause_code->
ast_cause = dahdi_r2_cause_to_ast_cause(cause);
4217 }
else if (openr2_chan_get_direction(r2chan) == OR2_DIR_FORWARD) {
4220 case OR2_CAUSE_BUSY_NUMBER:
4223 case OR2_CAUSE_NETWORK_CONGESTION:
4224 case OR2_CAUSE_OUT_OF_ORDER:
4225 case OR2_CAUSE_UNALLOCATED_NUMBER:
4226 case OR2_CAUSE_NO_ANSWER:
4227 case OR2_CAUSE_UNSPECIFIED:
4228 case OR2_CAUSE_NORMAL_CLEARING:
4243static void dahdi_r2_write_log(openr2_log_level_t level,
char *logmessage)
4246 case OR2_LOG_NOTICE:
4249 case OR2_LOG_WARNING:
4255 case OR2_LOG_STACK_TRACE:
4256 case OR2_LOG_MF_TRACE:
4257 case OR2_LOG_CAS_TRACE:
4259 case OR2_LOG_EX_DEBUG:
4269static void dahdi_r2_on_line_blocked(openr2_chan_t *r2chan)
4271 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4275 ast_log(
LOG_NOTICE,
"Far end blocked on chan %d\n", openr2_chan_get_number(r2chan));
4278static void dahdi_r2_on_line_idle(openr2_chan_t *r2chan)
4280 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4284 ast_log(
LOG_NOTICE,
"Far end unblocked on chan %d\n", openr2_chan_get_number(r2chan));
4287static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level,
const char *fmt, va_list ap)
4288 __attribute__((format (printf, 3, 0)));
4289static void dahdi_r2_on_context_log(openr2_context_t *r2context, openr2_log_level_t level,
const char *fmt, va_list ap)
4291#define CONTEXT_TAG "Context - "
4293 char completemsg[
sizeof(
logmsg) * 2];
4295 snprintf(completemsg,
sizeof(completemsg), CONTEXT_TAG
"%s",
logmsg);
4296 dahdi_r2_write_log(level, completemsg);
4300static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level,
const char *fmt, va_list ap)
4301 __attribute__((format (printf, 3, 0)));
4302static void dahdi_r2_on_chan_log(openr2_chan_t *r2chan, openr2_log_level_t level,
const char *fmt, va_list ap)
4304#define CHAN_TAG "Chan "
4306 char completemsg[
sizeof(
logmsg) * 2];
4308 snprintf(completemsg,
sizeof(completemsg), CHAN_TAG
"%d - %s", openr2_chan_get_number(r2chan),
logmsg);
4309 dahdi_r2_write_log(level, completemsg);
4313static int dahdi_r2_on_dnis_digit_received(openr2_chan_t *r2chan,
char digit)
4315 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4322 p->mfcr2_dnis_index++;
4323 p->
exten[p->mfcr2_dnis_index] = 0;
4324 p->
rdnis[p->mfcr2_dnis_index] = 0;
4326 if ((p->mfcr2_dnis_matched ||
4335static void dahdi_r2_on_ani_digit_received(openr2_chan_t *r2chan,
char digit)
4337 struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4340 p->mfcr2_ani_index++;
4341 p->
cid_num[p->mfcr2_ani_index] = 0;
4342 p->
cid_name[p->mfcr2_ani_index] = 0;
4345static void dahdi_r2_on_billing_pulse_received(openr2_chan_t *r2chan)
4347 ast_verbose(
"MFC/R2 billing pulse received on channel %d\n", openr2_chan_get_number(r2chan));
4350static openr2_event_interface_t dahdi_r2_event_iface = {
4351 .on_call_init = dahdi_r2_on_call_init,
4352 .on_call_offered = dahdi_r2_on_call_offered,
4353 .on_call_accepted = dahdi_r2_on_call_accepted,
4354 .on_call_answered = dahdi_r2_on_call_answered,
4355 .on_call_disconnect = dahdi_r2_on_call_disconnect,
4356 .on_call_end = dahdi_r2_on_call_end,
4357 .on_call_read = dahdi_r2_on_call_read,
4358 .on_hardware_alarm = dahdi_r2_on_hardware_alarm,
4359 .on_os_error = dahdi_r2_on_os_error,
4360 .on_protocol_error = dahdi_r2_on_protocol_error,
4361 .on_line_blocked = dahdi_r2_on_line_blocked,
4362 .on_line_idle = dahdi_r2_on_line_idle,
4364 .on_context_log = (openr2_handle_context_logging_func)dahdi_r2_on_context_log,
4365 .on_dnis_digit_received = dahdi_r2_on_dnis_digit_received,
4366 .on_ani_digit_received = dahdi_r2_on_ani_digit_received,
4368 .on_billing_pulse_received = dahdi_r2_on_billing_pulse_received
4371static inline int16_t dahdi_r2_alaw_to_linear(uint8_t sample)
4376static inline uint8_t dahdi_r2_linear_to_alaw(
int sample)
4381static openr2_transcoder_interface_t dahdi_r2_transcode_iface = {
4382 dahdi_r2_alaw_to_linear,
4383 dahdi_r2_linear_to_alaw
4424 for (
x = 0;
x < strlen(fn);
x++) {
4425 if (!isdigit(fn[
x])) {
4436 fn =
"/dev/dahdi/channel";
4438 fd = open(fn, O_RDWR | O_NONBLOCK);
4444 if (ioctl(fd, DAHDI_SPECIFY, &chan)) {
4453 if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &
bs) == -1) {
4472 chan_pvt->
subs[sub_num].
dfd = -1;
4475#if defined(HAVE_PRI)
4476static void dahdi_close_pri_fd(
struct dahdi_pri *pri,
int fd_num)
4479 pri->pri.fds[fd_num] = -1;
4483#if defined(HAVE_SS7)
4484static void dahdi_close_ss7_fd(
struct dahdi_ss7 *ss7,
int fd_num)
4487 ss7->ss7.fds[fd_num] = -1;
4493 return ioctl(dfd, DAHDI_SETLINEAR, &linear);
4499 struct dahdi_bufferinfo bi;
4512 res = ioctl(p->
subs[x].
dfd, DAHDI_GET_BUFINFO, &bi);
4517 res = ioctl(p->
subs[x].
dfd, DAHDI_SET_BUFINFO, &bi);
4554 return DAHDI_TONE_DTMF_BASE + (
digit -
'0');
4556 return DAHDI_TONE_DTMF_A + (
digit -
'A');
4558 return DAHDI_TONE_DTMF_A + (
digit -
'a');
4559 else if (
digit ==
'*')
4560 return DAHDI_TONE_DTMF_s;
4561 else if (
digit ==
'#')
4562 return DAHDI_TONE_DTMF_p;
4601 char dial_str[] = {
'T',
digit,
'\0' };
4612 dtmf = DAHDI_FLUSH_WRITE;
4615 ast_log(
LOG_WARNING,
"Unable to flush the DAHDI write buffer to send DTMF on channel %d: %s\n",
4619 ast_debug(1,
"Channel %s started VLDTMF digit '%c'\n",
4654 ast_debug(1,
"Channel %s ending VLDTMF digit '%c'\n",
4680 "Hook Transition Complete",
4685 "Polarity Reversal",
4693 { DAHDI_ALARM_RED,
"Red Alarm" },
4694 { DAHDI_ALARM_YELLOW,
"Yellow Alarm" },
4695 { DAHDI_ALARM_BLUE,
"Blue Alarm" },
4696 { DAHDI_ALARM_RECOVER,
"Recovering" },
4697 { DAHDI_ALARM_LOOPBACK,
"Loopback" },
4698 { DAHDI_ALARM_NOTOPEN,
"Not Open" },
4699 { DAHDI_ALARM_NONE,
"None" },
4709 return alm ?
"Unknown Alarm" :
"No Alarm";
4714 static char buf[256];
4723 static char buf[256];
4726 return "E & M Immediate";
4728 return "E & M Wink";
4732 return "Feature Group D (DTMF)";
4734 return "Feature Group D (MF)";
4736 return "Feature Group D (MF) Tandem Access";
4738 return "Feature Group B (MF)";
4742 return "FGC/CAMA (Dialpulse)";
4744 return "FGC/CAMA (MF)";
4746 return "FXS Loopstart";
4748 return "FXS Groundstart";
4750 return "FXS Kewlstart";
4752 return "FXO Loopstart";
4754 return "FXO Groundstart";
4756 return "FXO Kewlstart";
4760 return "ISDN BRI Point to Point";
4762 return "ISDN BRI Point to MultiPoint";
4768 return "SF (Tone) Immediate";
4770 return "SF (Tone) Wink";
4772 return "SF (Tone) with Feature Group D (DTMF)";
4774 return "SF (Tone) with Feature Group D (MF)";
4776 return "SF (Tone) with Feature Group B (MF)";
4780 snprintf(
buf,
sizeof(
buf),
"Unknown signalling %d", sig);
4785#define sig2str dahdi_sig2str
4791 struct dahdi_confinfo zi;
4793 memset(&zi, 0,
sizeof(zi));
4796 if (slavechannel > 0) {
4798 zi.confmode = DAHDI_CONF_DIGITALMON;
4799 zi.confno = slavechannel;
4803 zi.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER |
4804 DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER;
4806 zi.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
4809 if ((zi.confno ==
c->curconf.confno) && (zi.confmode ==
c->curconf.confmode))
4813 if (ioctl(
c->dfd, DAHDI_SETCONF, &zi)) {
4814 ast_log(
LOG_WARNING,
"Failed to add %d to conference %d/%d: %s\n",
c->dfd, zi.confmode, zi.confno, strerror(
errno));
4817 if (slavechannel < 1) {
4821 ast_debug(1,
"Added %d to conference %d/%d\n",
c->dfd,
c->curconf.confmode,
c->curconf.confno);
4828 if ((p->
channel ==
c->curconf.confno) && (
c->curconf.confmode == DAHDI_CONF_DIGITALMON))
4831 if ((p->
confno > 0) && (p->
confno ==
c->curconf.confno) && (
c->curconf.confmode & DAHDI_CONF_TALKER))
4838 struct dahdi_confinfo zi;
4845 memset(&zi, 0,
sizeof(zi));
4846 if (ioctl(
c->dfd, DAHDI_SETCONF, &zi)) {
4847 ast_log(
LOG_WARNING,
"Failed to drop %d from conference %d/%d: %s\n",
c->dfd,
c->curconf.confmode,
c->curconf.confno, strerror(
errno));
4850 ast_debug(1,
"Removed %d from conference %d/%d\n",
c->dfd,
c->curconf.confmode,
c->curconf.confno);
4851 memcpy(&
c->curconf, &zi,
sizeof(
c->curconf));
4863 for (x = 0; x < 3; x++) {
4871 if (useslavenative) {
4890 else if (slave->
law != p->
law) {
4896 return useslavenative;
4904 struct dahdi_confinfo zi;
4906 memset(&zi, 0,
sizeof(zi));
4922 for (x = 0; x < 3; x++) {
4965 ast_debug(1,
"Updated conferencing on %d, with %d conference users\n", p->
channel, needconf);
4974 ast_debug(1,
"Echo cancellation already on\n");
4978 ast_debug(1,
"Echo cancellation isn't required on digital connection\n");
4982#if defined(HAVE_PRI) || defined(HAVE_SS7)
4984#if defined(HAVE_PRI)
4995#if defined(HAVE_SS7)
5004 "Unable to enable audio mode on channel %d (%s)\n",
5020 ast_debug(1,
"No echo cancellation requested\n");
5036 ast_debug(1,
"No echo training requested\n");
5045 struct dahdi_echocanparams ecp = { .tap_length = 0 };
5060 struct dahdi_hwgain hwgain;
5062 hwgain.newgain = gain * 10.0;
5063 hwgain.tx = tx_direction;
5064 return ioctl(fd, DAHDI_SET_HWGAIN, &hwgain) < 0;
5071 float shallow, steep;
5072 float max = SHRT_MAX;
5074 neg = (sample < 0 ? -1 : 1);
5076 shallow = neg*(
max-
max/drc)+(
float)sample/drc;
5077 if (fabsf(steep) < fabsf(shallow)) {
5088static void fill_txgain(
struct dahdi_gains *g,
float gain,
float drc,
int law)
5093 float linear_gain = pow(10.0, gain / 20.0);
5096 case DAHDI_LAW_ALAW:
5097 for (j = 0; j <
ARRAY_LEN(g->txgain); j++) {
5103 k = (float)k * linear_gain;
5106 }
else if (k < -32768) {
5115 case DAHDI_LAW_MULAW:
5116 for (j = 0; j <
ARRAY_LEN(g->txgain); j++) {
5122 k = (float)k * linear_gain;
5125 }
else if (k < -32768) {
5138static void fill_rxgain(
struct dahdi_gains *g,
float gain,
float drc,
int law)
5142 float linear_gain = pow(10.0, gain / 20.0);
5145 case DAHDI_LAW_ALAW:
5146 for (j = 0; j <
ARRAY_LEN(g->rxgain); j++) {
5152 k = (float)k * linear_gain;
5155 }
else if (k < -32768) {
5164 case DAHDI_LAW_MULAW:
5165 for (j = 0; j <
ARRAY_LEN(g->rxgain); j++) {
5171 k = (float)k * linear_gain;
5174 }
else if (k < -32768) {
5188 struct dahdi_gains g;
5191 memset(&g, 0,
sizeof(g));
5192 res = ioctl(fd, DAHDI_GETGAINS, &g);
5200 return ioctl(fd, DAHDI_SETGAINS, &g);
5205 struct dahdi_gains g;
5208 memset(&g, 0,
sizeof(g));
5209 res = ioctl(fd, DAHDI_GETGAINS, &g);
5217 return ioctl(fd, DAHDI_SETGAINS, &g);
5220static int set_actual_gain(
int fd,
float rxgain,
float txgain,
float rxdrc,
float txdrc,
int law)
5257 res = ioctl(fd, DAHDI_HOOK, &x);
5260 if (
errno == EINPROGRESS)
5274#if defined(HAVE_PRI) || defined(HAVE_SS7)
5276#if defined(HAVE_PRI)
5284#if defined(HAVE_SS7)
5308 struct dahdi_confinfo
c;
5321 memset(&
c, 0,
sizeof(
c));
5322 c.confmode = DAHDI_CONF_NORMAL;
5328 ast_debug(1,
"Disabled conferencing\n");
5342 ast_debug(1,
"Restored conferencing\n");
5375 ast_debug(6,
"MWI manual override active on channel %d: pretending that it should be %s\n",
5406 if (
errno == EAGAIN)
5485#if defined(HAVE_PRI)
5492 subaddr = strchr(p->
exten,
':');
5521 x = DAHDI_FLUSH_READ | DAHDI_FLUSH_WRITE;
5536 (p->
law == DAHDI_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW);
5542#if defined(HAVE_SS7)
5574 openr2_calling_party_category_t chancat;
5593 chancat = dahdi_r2_get_channel_category(ast);
5594 callres = openr2_chan_make_call(p->r2chan, l, (
c + p->
stripmsd), chancat);
5595 if (-1 == callres) {
5600 p->mfcr2_call_accepted = 0;
5601 p->mfcr2_progress_sent = 0;
5675 }
else if (
iflist == pvt) {
5683 }
else if (
ifend == pvt) {
5694#if defined(HAVE_PRI)
5747#if defined(HAVE_PRI)
5785#if defined(HAVE_PRI)
5793static void dahdi_unlink_pri_pvt(
struct dahdi_pvt *pvt)
5804 for (idx = 0; idx <
pri->numchans; ++idx) {
5815#if defined(HAVE_SS7)
5823static void dahdi_unlink_ss7_pvt(
struct dahdi_pvt *pvt)
5834 for (idx = 0; idx <
ss7->numchans; ++idx) {
5845#if defined(HAVE_OPENR2)
5852static void dahdi_unlink_mfcr2_pvt(
struct dahdi_pvt *pvt)
5855 struct dahdi_mfcr2 *mfcr2;
5856 int should_destroy_link = 0;
5861 openr2_chan_disable_read(pvt->r2chan);
5865 for (idx = 0; idx < mfcr2->numchans; ++idx) {
5866 if (mfcr2->pvts[idx] == pvt) {
5867 ast_debug(1,
"Removing MFC/R2 channel %d from the mfcr2 link\n", pvt->
channel);
5868 mfcr2->pvts[idx] =
NULL;
5869 mfcr2->live_chans--;
5873 if (!mfcr2->live_chans) {
5874 ast_debug(1,
"MFC/R2 link is now empty\n");
5875 should_destroy_link = 1;
5879 if (should_destroy_link) {
5880 ast_debug(1,
"MFC/R2 link is now empty\n");
5881 mfcr2_queue_for_destruction(pvt);
5909#if defined(HAVE_PRI)
5910 dahdi_unlink_pri_pvt(p);
5912#if defined(HAVE_SS7)
5913 dahdi_unlink_ss7_pvt(p);
5915#if defined(HAVE_OPENR2)
5916 dahdi_unlink_mfcr2_pvt(p);
5924#if defined(HAVE_PRI)
5925 case DAHDI_IFLIST_NO_B_CHAN:
5927 dahdi_nobch_extract(p->pri, p);
5938#if defined(HAVE_PRI)
5943#if defined(HAVE_SS7)
5986 for (i = 0; i < 3; i++) {
5998#if defined(HAVE_PRI)
6014#if defined(HAVE_PRI_SERVICE_MESSAGES)
6016 char db_chan_name[20];
6021 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, p->
span, chan);
6022 if (!
ast_db_get(db_chan_name, SRVST_DBKEY, db_answer,
sizeof(db_answer))) {
6023 sscanf(db_answer,
"%1c:%30d", &
state, &why);
6033 ast_verb(3,
"Unregistered channel %d\n", chan);
6038#if defined(HAVE_PRI)
6041 if (!pris[
span].dchannels[0]) {
6057#if defined(HAVE_PRI)
6058static char *dahdi_send_keypad_facility_app =
"DAHDISendKeypadFacility";
6060static int dahdi_send_keypad_facility_exec(
struct ast_channel *chan,
const char *digits)
6066 ast_debug(1,
"No digit string sent to application!\n");
6073 ast_debug(1,
"Unable to find technology private\n");
6083#if defined(HAVE_PRI)
6084#if defined(HAVE_PRI_PROG_W_CAUSE)
6085static char *dahdi_send_callrerouting_facility_app =
"DAHDISendCallreroutingFacility";
6087static int dahdi_send_callrerouting_facility_exec(
struct ast_channel *chan,
const char *data)
6100 ast_debug(1,
"No data sent to application!\n");
6104 ast_debug(1,
"Only DAHDI technology accepted!\n");
6109 ast_debug(1,
"Unable to find technology private\n");
6116 ast_debug(1,
"callrerouting attempted on non-ISDN channel %s\n",
6125 ast_log(
LOG_WARNING,
"callrerouting facility requires at least destination number argument\n");
6130 ast_log(
LOG_WARNING,
"Callrerouting Facility without original called number argument\n");
6135 ast_log(
LOG_NOTICE,
"Callrerouting Facility without diversion reason argument, defaulting to unknown\n");
6154#if defined(HAVE_OPENR2)
6155static const char *
const dahdi_accept_r2_call_app =
"DAHDIAcceptR2Call";
6157static int dahdi_accept_r2_call_exec(
struct ast_channel *chan,
const char *data)
6160 openr2_call_mode_t accept_mode;
6161 int res, timeout, maxloops;
6170 ast_debug(1,
"No data sent to application!\n");
6175 ast_debug(1,
"Only DAHDI technology accepted!\n");
6181 ast_debug(1,
"Unable to find technology private!\n");
6189 ast_log(
LOG_WARNING,
"DAHDIAcceptR2Call requires 'yes' or 'no' for the charge parameter\n");
6194 if (!p->mfcr2 || !p->mfcr2call) {
6200 if (p->mfcr2_call_accepted) {
6205 accept_mode =
ast_true(
args.charge) ? OR2_CALL_WITH_CHARGE : OR2_CALL_NO_CHARGE;
6206 if (openr2_chan_accept_call(p->r2chan, accept_mode)) {
6217 while (maxloops > 0) {
6246 if (p->mfcr2_call_accepted) {
6248 ast_debug(1,
"Accepted MFC/R2 call!\n");
6259static openr2_call_disconnect_cause_t dahdi_ast_cause_to_r2_cause(
int cause)
6261 openr2_call_disconnect_cause_t r2cause = OR2_CAUSE_NORMAL_CLEARING;
6266 r2cause = OR2_CAUSE_BUSY_NUMBER;
6271 r2cause = OR2_CAUSE_NETWORK_CONGESTION;
6275 r2cause = OR2_CAUSE_UNALLOCATED_NUMBER;
6280 r2cause = OR2_CAUSE_OUT_OF_ORDER;
6285 r2cause = OR2_CAUSE_NO_ANSWER;
6289 r2cause = OR2_CAUSE_NORMAL_CLEARING;
6292 ast_debug(1,
"ast cause %d resulted in openr2 cause %d/%s\n",
6293 cause, r2cause, openr2_proto_get_disconnect_string(r2cause));
6302 struct dahdi_bufferinfo bi = {
6310 if ((bpres = ioctl(p->
subs[
SUB_REAL].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
6327 struct dahdi_params par;
6355#if defined(HAVE_PRI)
6418#if defined(HAVE_SS7)
6497 ast_debug(1,
"Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
6514 ast_debug(1,
"Normal call hung up with both three way call and a call waiting call in place?\n");
6517 ast_debug(1,
"We were flipped over to the callwait, moving back and not owning.\n");
6524 ast_debug(1,
"We were in the threeway and have a callwait still. Ditching the threeway.\n");
6530 ast_debug(1,
"Call was complete, setting owner to former third call\n");
6534 ast_debug(1,
"Call was incomplete, setting owner to NULL\n");
6553 ast_debug(1,
"Call was complete, setting owner to former third call\n");
6557 ast_debug(1,
"Call was incomplete, setting owner to NULL\n");
6618 if (p->mfcr2 && p->mfcr2call && openr2_chan_get_direction(p->r2chan) != OR2_DIR_STOPPED) {
6621 if (openr2_chan_get_direction(p->r2chan) == OR2_DIR_BACKWARD && p->mfcr2_forced_release) {
6622 dahdi_r2_disconnect_call(p, OR2_CAUSE_FORCED_RELEASE);
6625 int r2cause_user = r2causestr ? atoi(r2causestr) : 0;
6626 openr2_call_disconnect_cause_t r2cause = r2cause_user ? dahdi_ast_cause_to_r2_cause(r2cause_user)
6628 dahdi_r2_disconnect_call(p, r2cause);
6630 }
else if (p->mfcr2call) {
6656 memset(&par, 0,
sizeof(par));
6661 ast_debug(1,
"Hanging up channel %d, offhook = %d\n", p->
channel, par.rxisoffhook);
6664 if ((par.rxisoffhook) && (!(p->
radio || (p->
oprmode < 0))))
6747 ast_debug(1,
"Channel %d is no longer eligible for reorigination (went back on hook or became in use)\n", p->
channel);
6792#if defined(HAVE_PRI)
6797#if defined(HAVE_SS7)
6804 if (!p->mfcr2_call_accepted) {
6807 p->mfcr2_answer_pending = 1;
6808 if (p->mfcr2_charge_calls) {
6809 ast_debug(1,
"Accepting MFC/R2 call with charge before answering on chan %d\n", p->
channel);
6810 openr2_chan_accept_call(p->r2chan, OR2_CALL_WITH_CHARGE);
6812 ast_debug(1,
"Accepting MFC/R2 call with no charge before answering on chan %d\n", p->
channel);
6813 openr2_chan_accept_call(p->r2chan, OR2_CALL_NO_CHARGE);
6849 int val = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
6870 if (!p || !data || (*datalen < 1)) {
6881 *cp = p->
tdd ? 1 : 0;
6895#if defined(HAVE_PRI)
6896#if defined(HAVE_PRI_CCSS)
6924 if (!p || !data || (datalen < 1)) {
6931 scp = (
signed char *) data;
6940 scp = (
signed char *) data;
6978 ast_debug(1,
"Set option TDD MODE, value: %s(%d) on %s\n",
6983 unsigned char mybuf[41000];
6985 int size, res, fd,
len;
6986 struct pollfd fds[1];
6989 memset(
buf, 0x7f,
sizeof(mybuf));
7005 fds[0].events = POLLPRI | POLLOUT;
7007 res = poll(fds, 1, -1);
7013 if (fds[0].revents & POLLPRI)
7015 if (!(fds[0].revents & POLLOUT)) {
7019 res = write(fd,
buf, size);
7021 if (res == -1)
return -1;
7045 ast_debug(1,
"Set option RELAX DTMF, value: %s(%d) on %s\n",
7050#if defined(HAVE_PRI)
7090 ast_debug(1,
"Set Operator Services mode, value: %d on %s/%s\n",
7143 if (!strcasecmp(data,
"rxgain")) {
7147 }
else if (!strcasecmp(data,
"txgain")) {
7151 }
else if (!strcasecmp(data,
"dahdi_channel")) {
7155 }
else if (!strcasecmp(data,
"dahdi_span")) {
7159 }
else if (!strcasecmp(data,
"dahdi_group")) {
7163 }
else if (!strcasecmp(data,
"dahdi_type")) {
7166#if defined(HAVE_OPENR2)
7171#if defined(HAVE_PRI)
7179#if defined(HAVE_SS7)
7190#if defined(HAVE_PRI)
7191#if defined(HAVE_PRI_REVERSE_CHARGE)
7192 }
else if (!strcasecmp(data,
"reversecharge")) {
7205#if defined(HAVE_PRI_SETUP_KEYPAD)
7206 }
else if (!strcasecmp(data,
"keypad_digits")) {
7220 }
else if (!strcasecmp(data,
"no_media_path")) {
7237 }
else if (!strcasecmp(data,
"dialmode")) {
7275 char policy_str[21] =
"";
7277 if ((res = sscanf(parse,
"%30d,%20s", num_buffers, policy_str)) != 2) {
7281 if (*num_buffers < 0) {
7285 if (!strcasecmp(policy_str,
"full")) {
7286 *policy = DAHDI_POLICY_WHEN_FULL;
7287 }
else if (!strcasecmp(policy_str,
"immediate")) {
7288 *policy = DAHDI_POLICY_IMMEDIATE;
7289#if defined(HAVE_DAHDI_HALF_FULL)
7290 }
else if (!strcasecmp(policy_str,
"half")) {
7291 *policy = DAHDI_POLICY_HALF_FULL;
7311 if (!strcasecmp(data,
"buffers")) {
7312 int num_bufs, policy;
7315 struct dahdi_bufferinfo bi = {
7316 .txbufpolicy = policy,
7317 .rxbufpolicy = policy,
7319 .numbufs = num_bufs,
7323 if ((bpres = ioctl(p->
subs[
SUB_REAL].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
7331 }
else if (!strcasecmp(data,
"echocan_mode")) {
7332 if (!strcasecmp(
value,
"on")) {
7336 }
else if (!strcasecmp(
value,
"off")) {
7340#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
7341 }
else if (!strcasecmp(
value,
"fax")) {
7352 }
else if (!strcasecmp(
value,
"voice")) {
7368 }
else if (!strcasecmp(data,
"dialmode")) {
7379 if (!strcasecmp(
value,
"pulse")) {
7381 }
else if (!strcasecmp(
value,
"dtmf") || !strcasecmp(
value,
"tone")) {
7383 }
else if (!strcasecmp(
value,
"none")) {
7385 }
else if (!strcasecmp(
value,
"both")) {
7392 }
else if (!strcasecmp(data,
"waitfordialtone")) {
7432 if (!slave || (master->
slaves[x] == slave)) {
7473 if (!slave || !master) {
7478 if (!master->
slaves[x]) {
7479 master->
slaves[x] = slave;
7502 if (p->
owner == oldchan) {
7505 for (x = 0; x < 3; x++) {
7515#if defined(HAVE_PRI)
7519#if defined(HAVE_SS7)
7588 ast_verb(3,
"TRANSFERRING %s to %s\n",
7613 struct dahdi_confinfo ci;
7617 memset(&ci, 0,
sizeof(ci));
7626 ast_verb(3,
"Avoiding 3-way call when in an external conference\n");
7640 struct dahdi_spaninfo zi;
7641 struct dahdi_params params;
7643 memset(&zi, 0,
sizeof(zi));
7644 zi.spanno = p->
span;
7647 if (zi.alarms != DAHDI_ALARM_NONE)
7655 memset(¶ms, 0,
sizeof(params));
7656 if ((res = ioctl(p->
subs[
SUB_REAL].
dfd, DAHDI_GET_PARAMS, ¶ms)) >= 0)
7657 return params.chan_alarms;
7661 return DAHDI_ALARM_NONE;
7669 ast_debug(1,
"%s DTMF digit: 0x%02X '%c' on %s\n",
7686 *dest = &p->
subs[idx].
f;
7690 ast_debug(1,
"Got some DTMF, but it's for the CAS\n");
7699 *dest = &p->
subs[idx].
f;
7706 struct dahdi_bufferinfo bi = {
7713 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
7751 ast_debug(1,
"Already in a fax extension, not redirecting\n");
7760 *dest = &p->
subs[idx].
f;
7770 "Alarm", alarm_txt);
7789 "Alarm", alarm_txt);
7799 const char *alarm_str;
7801#if defined(HAVE_PRI)
7842 p->
subs[idx].
f.
src =
"dahdi_handle_event";
7844 f = &p->
subs[idx].
f;
7854 if (res & (DAHDI_EVENT_PULSEDIGIT | DAHDI_EVENT_DTMFUP)) {
7855 p->
pulsedial = (res & DAHDI_EVENT_PULSEDIGIT) ? 1 : 0;
7857#if defined(HAVE_PRI)
7875 if (res & DAHDI_EVENT_DTMFDOWN) {
7876 ast_debug(1,
"DTMF Down '%c'\n", res & 0xff);
7877#if defined(HAVE_PRI)
7892 return &p->
subs[idx].
f;
7896 case DAHDI_EVENT_EC_DISABLED:
7900#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
7901 case DAHDI_EVENT_TX_CED_DETECTED:
7902 ast_verb(3,
"Channel %d detected a CED tone towards the network.\n", p->
channel);
7904 case DAHDI_EVENT_RX_CED_DETECTED:
7905 ast_verb(3,
"Channel %d detected a CED tone from the network.\n", p->
channel);
7907 case DAHDI_EVENT_EC_NLP_DISABLED:
7908 ast_verb(3,
"Channel %d echo canceler disabled its NLP.\n", p->
channel);
7910 case DAHDI_EVENT_EC_NLP_ENABLED:
7911 ast_verb(3,
"Channel %d echo canceler enabled its NLP.\n", p->
channel);
7914 case DAHDI_EVENT_BITSCHANGED:
7920 openr2_chan_handle_cas(p->r2chan);
7926 case DAHDI_EVENT_PULSE_START:
7929 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
7931 case DAHDI_EVENT_DIALCOMPLETE:
7933#if defined(HAVE_PRI)
7938 if (ioctl(p->
subs[idx].
dfd, DAHDI_DIALING, &x) == -1) {
7939 ast_debug(1,
"DAHDI_DIALING ioctl failed on %s: %s\n",
7964 if (ioctl(p->
subs[idx].
dfd,DAHDI_DIALING,&x) == -1) {
7973 p->
dop.op = DAHDI_DIAL_OP_REPLACE;
7992 ast_debug(1,
"Done dialing, but waiting for progress detection before doing more...\n");
8017 case DAHDI_EVENT_ALARM:
8019#if defined(HAVE_PRI)
8024#if defined(HAVE_SS7)
8036 if (!p->pri || !p->pri->pri || pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
8042#if defined(HAVE_SS7)
8050 case DAHDI_EVENT_ONHOOK:
8084 ast_verb(3,
"Channel %d still has (callwait) call, ringing phone\n", p->
channel);
8099 unsigned int mssinceflash;
8110 if (p->
owner != ast) {
8120 ast_debug(1,
"Last flash was %u ms ago\n", mssinceflash);
8127 ast_debug(1,
"Looks like a bounced flash, hanging up both calls on %d\n", p->
channel);
8173 case DAHDI_EVENT_RINGOFFHOOK:
8203 int numchars = snprintf(p->
dop.dialstr,
sizeof(p->
dop.dialstr),
"M*0%s#",
c);
8204 if (numchars >=
sizeof(p->
dop.dialstr)) {
8211 if (strlen(p->
dop.dialstr) > 4) {
8216 p->
dop.dialstr[strlen(p->
dop.dialstr)-2] =
'\0';
8225 return &p->
subs[idx].
f;
8257 p->
dop.dialstr[0] =
'\0';
8260 ast_debug(1,
"Sent FXO deferred digit string: %s\n", p->
dop.dialstr);
8265 p->
dop.dialstr[0] =
'\0';
8269 return &p->
subs[idx].
f;
8276 return &p->
subs[idx].
f;
8289 res = tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, DAHDI_TONE_DIALTONE);
8304 ast_debug(1,
"Setting IDLE polarity due "
8305 "to ring. Old polarity was %d\n",
8348 case DAHDI_EVENT_RINGBEGIN:
8359 case DAHDI_EVENT_RINGERON:
8361 case DAHDI_EVENT_NOALARM:
8363#if defined(HAVE_PRI)
8368#if defined(HAVE_SS7)
8379 case DAHDI_EVENT_WINKFLASH:
8381 if (p->
radio)
break;
8385 struct dahdi_params par;
8387 memset(&par, 0,
sizeof(par));
8390 if (!par.rxisoffhook)
8408 ast_debug(1,
"Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
8472 ast_debug(1,
"Flash when call not up or ringing\n");
8503 res = tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, DAHDI_TONE_DIALRECALL);
8511 res = tone_zone_play_tone(p->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
8527 ast_debug(1,
"Got flash with three way call up, dropping last call on %d\n", p->
channel);
8545 ast_verb(3,
"Building conference call with %s and %s\n",
8595 snprintf(p->
dop.dialstr,
sizeof(p->
dop.dialstr),
"M*%d%s#",
8604 ast_log(
LOG_WARNING,
"Received unexpected wink on channel of type SIG_FEATDMF_TA\n");
8621 p->
dop.dialstr[0] =
'\0';
8624 ast_debug(1,
"Sent deferred digit string: %s\n", p->
dop.dialstr);
8626 p->
dop.dialstr[0] =
'\0';
8632 case DAHDI_EVENT_HOOKCOMPLETE:
8650 p->
dop.dialstr[0] =
'\0';
8653 ast_debug(1,
"Sent deferred digit string: %s\n", p->
dop.dialstr);
8655 p->
dop.dialstr[0] =
'\0';
8656 p->
dop.op = DAHDI_DIAL_OP_REPLACE;
8666 ast_debug(1,
"Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->
channel);
8672 case DAHDI_EVENT_POLARITY:
8684 ast_debug(1,
"Answering on polarity switch!\n");
8699 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) );
8702 ast_debug(1,
"Polarity Reversal detected and now Hanging up on channel %d\n", p->
channel);
8713 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) );
8716 ast_debug(1,
"Dunno what to do with event %d on channel %d\n", res, p->
channel);
8718 return &p->
subs[idx].
f;
8740 p->
subs[idx].
f.
src =
"dahdi_exception";
8756 if ((res != DAHDI_EVENT_RINGEROFF) && (res != DAHDI_EVENT_RINGERON) &&
8757 (res != DAHDI_EVENT_HOOKCOMPLETE)) {
8758 ast_debug(1,
"Restoring owner of channel %d on event %d\n", p->
channel, res);
8766 case DAHDI_EVENT_ONHOOK:
8778 case DAHDI_EVENT_RINGOFFHOOK:
8786 case DAHDI_EVENT_HOOKCOMPLETE:
8787 case DAHDI_EVENT_RINGERON:
8788 case DAHDI_EVENT_RINGEROFF:
8791 case DAHDI_EVENT_WINKFLASH:
8798 if (usedindex > -1) {
8815 f = &p->
subs[idx].
f;
8821 if (ast != p->
owner) {
8825 f = &p->
subs[idx].
f;
8919 struct dahdi_params ps;
8921 memset(&ps, 0,
sizeof(ps));
8937 return &p->
subs[idx].
f;
8940 if (!(--p->
ringt)) {
8948 openr2_chan_process_event(p->r2chan);
8949 if (OR2_DIR_FORWARD == openr2_chan_get_direction(p->r2chan)) {
8953 if (p->mfcr2_call_accepted &&
8954 !p->mfcr2_progress_sent &&
8956 ast_debug(1,
"Enqueuing progress frame after R2 accept in chan %d\n", p->
channel);
8958 p->mfcr2_progress_sent = 1;
8971 return &p->
subs[idx].
f;
8980 return &p->
subs[idx].
f;
8989 return &p->
subs[idx].
f;
8998 return &p->
subs[idx].
f;
9001 if (p->mfcr2 && openr2_chan_get_read_enabled(p->r2chan)) {
9017 return &p->
subs[idx].
f;
9027 return &p->
subs[idx].
f;
9037 return &p->
subs[idx].
f;
9079 if (
errno == EAGAIN) {
9082 return &p->
subs[idx].
f;
9083 }
else if (
errno == ELAST) {
9125 return &p->
subs[idx].
f;
9133 ast_verb(3,
"CPE does not support Call Waiting Caller*ID.\n");
9190 ast_debug(1,
"Channel driver fax CNG detection timeout on %s\n",
9235 ast_debug(1,
"Absorbing inband %s DTMF digit: 0x%02X '%c' on %s\n",
9258 ast_debug(1,
"Got 10 samples of dialtone!\n");
9262 p->
dop.dialstr[0] =
'\0';
9267 ast_debug(1,
"Sent deferred digit string: %s\n", p->
dop.dialstr);
9269 p->
dop.dialstr[0] =
'\0';
9270 p->
dop.op = DAHDI_DIAL_OP_REPLACE;
9279 f = &p->
subs[idx].
f;
9330 res = write(fd,
buf, size);
9373 ast_debug(5,
"Dropping frame since I'm still dialing on %s...\n",
9379 ast_debug(5,
"Dropping frame since there is no active owner on %s...\n",
9385 ast_debug(5,
"Dropping frame since I've still got a callerid spill on %s...\n",
9427 int func = DAHDI_FLASH;
9432#if defined(HAVE_PRI)
9438#if defined(HAVE_SS7)
9448 if (p->mfcr2 && !p->mfcr2_call_accepted) {
9457 switch (condition) {
9459 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_BUSY);
9462 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_RINGTONE);
9523 p->
dop.dialstr[0] =
'\0';
9536 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
9546#if defined(HAVE_PRI)
9561#if defined(HAVE_PRI)
9562 }
else if (i->pri) {
9564 y = ++i->pri->new_chan_seq;
9582 for (x = 0; x < 3; ++x) {
9620#if defined(HAVE_PRI)
9639 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));
9653#if defined(HAVE_PRI)
9661 if (law == DAHDI_LAW_ALAW) {
9671 ? DAHDI_LAW_ALAW : DAHDI_LAW_MULAW;
9706 x = DAHDI_TONEDETECT_ON | DAHDI_TONEDETECT_MUTE;
9707 if (ioctl(i->
subs[idx].
dfd, DAHDI_TONEDETECT, &x)) {
9725#if defined(HAVE_PRI) || defined(HAVE_SS7)
9759 ast_channel_parkinglot_set(tmp, i->
parkinglot);
9761 ast_channel_language_set(tmp, i->
language);
9788#if defined(HAVE_PRI) || defined(HAVE_SS7)
9817 dashptr = strrchr(device_name,
'-');
9824 for (v = i->
vars ; v ; v = v->
next)
9864 if (strchr(term,
c))
9876 j = DAHDI_IOMUX_SIGEVENT;
9878 if (ioctl(p->
subs[idx].
dfd,DAHDI_IOMUX,&j) == -1)
return(-1);
9880 if (j & DAHDI_IOMUX_SIGEVENT)
break;
9883 if (ioctl(p->
subs[idx].
dfd,DAHDI_GETEVENT,&j) == -1)
return(-1);
9923 return dahdichan->
dnd;
9928 ast_verb(3,
"%s DND on channel %d\n",
9929 flag?
"Enabled" :
"Disabled",
9937 int extlen = strlen(exten);
9943 if (extlen < strlen(pickupexten) && !strncmp(pickupexten, exten, extlen)) {
9947 if (exten[0] ==
'*' && extlen < 3) {
9968 unsigned char buf[256];
9989 const char *pickupexten;
10013 ast_log(
LOG_ERROR,
"Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
10016 pickupexten =
ast_strdupa(pickup_cfg->pickupexten);
10041 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10051 memset(dtmfbuf, 0,
sizeof(dtmfbuf));
10066 res =
my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf),
"*", 3000);
10076 if (res <= 0)
break;
10085 if ((p->
sig ==
SIG_FEATDMF) && (dtmfbuf[1] !=
'0') && (strlen(dtmfbuf) != 14))
10091 if (res <= 0)
break;
10099 res =
my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf),
"#", 3000);
10116 res =
my_getsigstr(chan, dtmfbuf + strlen(dtmfbuf),
"*", 3000);
10123 dtmfbuf[
len] =
'\0';
10132 ast_debug(1,
"waitfordigit returned < 0...\n");
10136 dtmfbuf[
len++] = res;
10137 dtmfbuf[
len] =
'\0';
10149 }
else if (res < 0) {
10150 ast_debug(1,
"Got hung up before digits finished\n");
10165 if ((res > 0) && (strlen(anibuf) > 2)) {
10166 if (anibuf[strlen(anibuf) - 1] ==
'#')
10167 anibuf[strlen(anibuf) - 1] = 0;
10178 if (exten[0] ==
'*') {
10179 char *stringp=
NULL;
10183 s1 =
strsep(&stringp,
"*");
10184 s2 =
strsep(&stringp,
"*");
10197 if (exten[0] ==
'*') {
10198 char *stringp=
NULL;
10202 s1 =
strsep(&stringp,
"#");
10203 s2 =
strsep(&stringp,
"#");
10217 if (exten[0] ==
'*') {
10218 char *stringp=
NULL;
10222 s1 =
strsep(&stringp,
"#");
10223 s2 =
strsep(&stringp,
"#");
10224 if (s2 && (*(s2 + 1) ==
'0')) {
10234 if (exten[0] ==
'*') {
10235 char *stringp=
NULL;
10239 s1 =
strsep(&stringp,
"#");
10273 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10279 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_INFO);
10287 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10302 int is_exten_parking = 0;
10312 ast_debug(1,
"waitfordigit returned < 0...\n");
10313 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10317 ast_debug(1,
"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
10322 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10324 tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALTONE);
10335 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10339 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10341 memset(exten, 0,
sizeof(exten));
10342 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALTONE);
10346 res = tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10365 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10374 }
else if (res == 0) {
10375 ast_debug(1,
"not enough digits (and no ambiguous match)...\n");
10376 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10380 }
else if (p->
callwaiting && !strcmp(exten,
"*70")) {
10384 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10390 ioctl(p->
subs[idx].
dfd,DAHDI_CONFDIAG,&
len);
10391 memset(exten, 0,
sizeof(exten));
10394 }
else if (!strcmp(exten, pickupexten)) {
10410 ast_debug(1,
"No call pickup possible...\n");
10411 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10422 }
else if (!p->
hidecallerid && !strcmp(exten,
"*67")) {
10430 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10436 memset(exten, 0,
sizeof(exten));
10438 }
else if (p->
callreturn && !strcmp(exten,
"*69")) {
10439 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10441 }
else if (!strcmp(exten,
"*78")) {
10444 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10446 memset(exten, 0,
sizeof(exten));
10448 }
else if (!strcmp(exten,
"*79")) {
10451 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10453 memset(exten, 0,
sizeof(exten));
10456 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10458 memset(exten, 0,
sizeof(exten));
10461 ast_verb(3,
"Cancelling call forwarding on channel %d\n", p->
channel);
10462 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10465 memset(exten, 0,
sizeof(exten));
10478 if (bridge_channel) {
10497 }
else if (p->
hidecallerid && !strcmp(exten,
"*82")) {
10502 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_DIALRECALL);
10508 memset(exten, 0,
sizeof(exten));
10510 }
else if (!strcmp(exten,
"*0")) {
10517 if (nbridge && bridged) {
10520 if (nbridge && pbridge &&
10524 int func = DAHDI_FLASH;
10526 p->
dop.dialstr[0] =
'\0';
10539 tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
10541 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10559 tone_zone_play_tone(p->
subs[idx].
dfd, -1);
10569 if (smdi_msg !=
NULL) {
10572 if (smdi_msg->
type ==
'B')
10574 else if (smdi_msg->
type ==
'N')
10622 "Exiting simple switch\n");
10647 ast_debug(1,
"CID got string '%s'\n", dtmfbuf);
10660 struct timeval start;
10671 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10672 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
10678 if (i & DAHDI_IOMUX_SIGEVENT) {
10681 if (res == DAHDI_EVENT_NOALARM) {
10686 if (res == DAHDI_EVENT_RINGBEGIN) {
10694 }
else if (i & DAHDI_IOMUX_READ) {
10697 if (
errno != ELAST) {
10718 "Failed to decode CallerID on channel '%s'\n",
10723 else if (samples > (8000 * 10))
10747 "Exiting simple switch\n");
10768 for (receivedRingT = 0; receivedRingT <
ARRAY_LEN(curRingData); receivedRingT++)
10769 curRingData[receivedRingT] = 0;
10780 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10781 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
10787 if (i & DAHDI_IOMUX_SIGEVENT) {
10790 if (res == DAHDI_EVENT_NOALARM) {
10796 curRingData[receivedRingT] = p->
ringt;
10802 if (++receivedRingT ==
ARRAY_LEN(curRingData))
10804 }
else if (i & DAHDI_IOMUX_READ) {
10807 if (
errno != ELAST) {
10815 if (p->
ringt > 0) {
10816 if (!(--p->
ringt)) {
10824 ast_verb(3,
"Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
10825 for (counter = 0; counter < 3; counter++) {
10829 for (counter1 = 0; counter1 < 3; counter1++) {
10832 ast_verb(3,
"Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
10833 curRingData[counter1]);
10837 ast_verb(3,
"Ring pattern matched in range: %d to %d\n",
10844 if (distMatches == 3) {
10862 "state, but I have nothing to do. "
10863 "Terminating simple switch, should be "
10864 "restarted by the actual ring.\n",
10873 struct timeval start;
10886 "Exiting simple switch\n");
10910 ast_debug(1,
"CID is '%s', flags %d\n",
10929 for (receivedRingT = 0; receivedRingT <
ARRAY_LEN(curRingData); receivedRingT++)
10930 curRingData[receivedRingT] = 0;
10943 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
10944 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
10950 if (i & DAHDI_IOMUX_SIGEVENT) {
10953 if (res == DAHDI_EVENT_NOALARM) {
10958 ast_debug(1,
"Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->
channel);
10967 curRingData[receivedRingT] = p->
ringt;
10973 if (++receivedRingT ==
ARRAY_LEN(curRingData))
10975 }
else if (i & DAHDI_IOMUX_READ) {
10978 if (
errno != ELAST) {
10986 if (p->
ringt > 0) {
10987 if (!(--p->
ringt)) {
11000 "Failed to decode CallerID on channel '%s'\n",
11005 else if (
samples > (8000 * 10))
11015 for (receivedRingT = 0; receivedRingT < 3; receivedRingT++) {
11016 curRingData[receivedRingT] = 0;
11019 ast_verb(3,
"Detecting post-CID distinctive ring\n");
11021 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
11022 if ((res = ioctl(p->
subs[idx].
dfd, DAHDI_IOMUX, &i))) {
11028 if (i & DAHDI_IOMUX_SIGEVENT) {
11031 if (res == DAHDI_EVENT_NOALARM) {
11037 curRingData[receivedRingT] = p->
ringt;
11043 if (++receivedRingT ==
ARRAY_LEN(curRingData))
11045 }
else if (i & DAHDI_IOMUX_READ) {
11048 if (
errno != ELAST) {
11056 if (p->
ringt > 0) {
11057 if (!(--p->
ringt)) {
11067 ast_verb(3,
"Detected ring pattern: %d,%d,%d\n",curRingData[0],curRingData[1],curRingData[2]);
11069 for (counter = 0; counter < 3; counter++) {
11073 ast_verb(3,
"Checking %d,%d,%d\n",
11078 for (counter1 = 0; counter1 < 3; counter1++) {
11081 ast_verb(3,
"Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
11082 curRingData[counter1]);
11087 ast_verb(3,
"Ring pattern matched in range: %d to %d\n",
11093 if (distMatches == 3) {
11140 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
11144 res = tone_zone_play_tone(p->
subs[idx].
dfd, DAHDI_TONE_CONGESTION);
11170 for (x = 0; x <
len; x++)
11180 pthread_t threadid;
11185 unsigned int spill_done = 0;
11186 int spill_result = -1;
11189 goto quit_no_clean;
11197 i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
11203 if (i & DAHDI_IOMUX_SIGEVENT) {
11206 int callid_created;
11214 case DAHDI_EVENT_NEONMWI_ACTIVE:
11215 case DAHDI_EVENT_NEONMWI_INACTIVE:
11216 case DAHDI_EVENT_NONE:
11217 case DAHDI_EVENT_BITSCHANGED:
11219 case DAHDI_EVENT_NOALARM:
11228 case DAHDI_EVENT_ALARM:
11266 goto quit_no_clean;
11268 }
else if (i & DAHDI_IOMUX_READ) {
11270 if (
errno != ELAST) {
11285 }
else if (spill_result) {
11295 if (samples > (8000 * 4))
11300 if (spill_result == 1) {
11337#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11339 if (pvt->mwisend_rpas) {
11342 }
else if (pvt->mwisend_fsk) {
11370 x = DAHDI_FLUSH_BOTH;
11374#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11375 if (pvt->mwisend_fsk) {
11380#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11388 struct timeval now;
11412#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11413 if (pvt->mwisend_fsk) {
11415 gettimeofday(&now,
NULL);
11419#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
11427 if (0 < num_read) {
11480 case DAHDI_EVENT_RINGEROFF:
11497 case DAHDI_EVENT_RINGOFFHOOK:
11507 case DAHDI_EVENT_RINGERON:
11508 case DAHDI_EVENT_HOOKCOMPLETE:
11522 int destroyed_first = 0;
11523 int destroyed_last = 0;
11530 int x = DAHDI_FLASH;
11532 if (cur->
channel > destroyed_last) {
11533 destroyed_last = cur->
channel;
11535 if (destroyed_first < 1 || cur->
channel < destroyed_first) {
11536 destroyed_first = cur->
channel;
11547 if (destroyed_first > start || destroyed_last <
end) {
11548 ast_debug(1,
"Asked to destroy %d-%d, destroyed %d-%d,\n",
11549 start,
end, destroyed_first, destroyed_last);
11554static void dahdi_r2_destroy_nodev(
void)
11556 struct r2link_entry *cur;
11560 struct dahdi_mfcr2 *r2 = &cur->mfcr2;
11561 ast_debug(3,
"About to destroy %d DAHDI channels of MFC/R2 link.\n", r2->numchans);
11562 for (i = 0; i < r2->numchans; i++) {
11575 pthread_cancel(r2->r2master);
11576 pthread_join(r2->r2master,
NULL);
11578 openr2_context_delete(r2->protocol_context);
11608 ast_debug(1,
"channel range caps: %d - %d\n", start,
end);
11613 "channel range %d-%d is occupied\n",
11622 struct dahdi_pri *pri = pris + x;
11624 if (!pris[x].pri.pvts[0]) {
11628 int channo = pri->dchannels[i];
11633 if (!pri->pri.fds[i]) {
11636 if (channo >= start && channo <=
end) {
11638 "channel range %d-%d is occupied by span %d\n",
11639 start,
end, x + 1);
11647 !
conf.chan.cc_params) {
11652 conf.wanted_channels_start = start;
11655 conf.wanted_channels_end =
end;
11671 pthread_t threadid;
11674 int callid_created;
11679 case DAHDI_EVENT_NONE:
11680 case DAHDI_EVENT_BITSCHANGED:
11682 case DAHDI_EVENT_WINKFLASH:
11683 case DAHDI_EVENT_RINGOFFHOOK:
11685 if (i->
radio)
break;
11692 if (res && (
errno == EBUSY)) {
11706 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_RINGTONE);
11710 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
11719 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_STUTTER);
11721 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_DIALTONE);
11723 ast_log(
LOG_WARNING,
"Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->
channel);
11726 res = tone_zone_play_tone(i->
subs[
SUB_REAL].
dfd, DAHDI_TONE_CONGESTION);
11769 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);
11786 case DAHDI_EVENT_NOALARM:
11788#if defined(HAVE_PRI)
11795#if defined(HAVE_SS7)
11806 case DAHDI_EVENT_ALARM:
11808#if defined(HAVE_PRI)
11815#if defined(HAVE_SS7)
11827 case DAHDI_EVENT_ONHOOK:
11873 case DAHDI_EVENT_POLARITY:
11887 ast_verb(2,
"Starting post polarity "
11888 "CID detection on channel %d\n",
11902 "polarity reversal on non-FXO (SIG_FXS) "
11903 "interface %d\n", i->
channel);
11906 case DAHDI_EVENT_REMOVED:
11908 "Got DAHDI_EVENT_REMOVED. Destroying channel %d\n",
11911 case DAHDI_EVENT_NEONMWI_ACTIVE:
11917 case DAHDI_EVENT_NEONMWI_INACTIVE:
11928 struct pollfd **pfds = arg;
11934 int count, res, res2, spoint, pollres=0;
11938 time_t thispass = 0, lastpass = 0;
11941 struct pollfd *pfds=
NULL;
11942 int lastalloc = -1;
11947 if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,
NULL)) {
11953 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
11959 if (!pfds || (lastalloc !=
ifcount)) {
11986 pfds[count].events = POLLPRI;
11987 pfds[count].revents = 0;
11991 pfds[count].events |= POLLIN;
11999 pfds[count].events = POLLPRI;
12000 pfds[count].revents = 0;
12005 pfds[count].events |= POLLIN;
12016 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
NULL);
12017 pthread_testcancel();
12019 res = poll(pfds, count, 1000);
12020 pthread_testcancel();
12021 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
12034 lastpass = thispass;
12035 thispass = time(
NULL);
12046 if (thispass != lastpass) {
12053 && !
last->mwisendactive
12054 && (
last->sig & __DAHDI_SIG_FXO)
12067 res2 = ioctl(
last->subs[
SUB_REAL].dfd, DAHDI_VMWI, &res);
12070 ast_debug(3,
"Unable to control message waiting led on channel %d: %s\n",
last->channel, strerror(
errno));
12073 ast_debug(5,
"Initiating MWI FSK spill on channel %d\n",
last->channel);
12103 if (pollres & POLLIN) {
12119 pthread_attr_t attr;
12120 pthread_t threadid;
12123 pthread_attr_init(&attr);
12124 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
12129 memcpy(mtd->
buf,
buf, res);
12142 struct timeval now;
12150 gettimeofday(&now,
NULL);
12157 pthread_t threadid;
12192 if (pollres & POLLPRI) {
12219 ast_debug(1,
"Woah! Went back on hook before reoriginate could happen on channel %d\n", i->
channel);
12222 res = DAHDI_EVENT_RINGOFFHOOK;
12237 dahdi_r2_destroy_nodev();
12241 pthread_cleanup_pop(1);
12272#if defined(HAVE_PRI)
12273static int pri_resolve_span(
int *
span,
int channel,
int offset,
struct dahdi_spaninfo *si)
12278 trunkgroup = pris[*
span].mastertrunkgroup;
12293 }
else if (pris[*
span].mastertrunkgroup) {
12294 ast_log(
LOG_WARNING,
"Unable to use span %d implicitly since it is already part of trunk group %d\n", *
span, pris[*
span].mastertrunkgroup);
12297 if (si->totalchans == 31) {
12299 pris[*
span].dchannels[0] = 16 + offset;
12300 }
else if (si->totalchans == 24) {
12302 pris[*
span].dchannels[0] = 24 + offset;
12303 }
else if (si->totalchans == 3) {
12305 pris[*
span].dchannels[0] = 3 + offset;
12307 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);
12318#if defined(HAVE_PRI)
12319static int pri_create_trunkgroup(
int trunkgroup,
int *
channels)
12321 struct dahdi_spaninfo si;
12322 struct dahdi_params p;
12329 ast_log(
LOG_WARNING,
"Trunk group %d already exists on span %d, Primary d-channel %d\n", trunkgroup, x + 1, pris[x].dchannels[0]);
12336 memset(&si, 0,
sizeof(si));
12337 memset(&p, 0,
sizeof(p));
12338 fd = open(
"/dev/dahdi/channel", O_RDWR);
12344 if (ioctl(fd, DAHDI_SPECIFY, &x)) {
12349 if (ioctl(fd, DAHDI_GET_PARAMS, &p)) {
12354 if (ioctl(fd, DAHDI_SPANSTAT, &si)) {
12359 span = p.spanno - 1;
12365 if (pris[span].pri.
pvts[0]) {
12366 ast_log(
LOG_WARNING,
"Span %d is already provisioned with channels (implicit PRI maybe?)\n", span + 1);
12371 pris[span].pri.trunkgroup = trunkgroup;
12374 pris[ospan].dchannels[y] =
channels[y];
12375 pris[span].pri.span = span + 1;
12382#if defined(HAVE_PRI)
12383static int pri_create_spanmap(
int span,
int trunkgroup,
int logicalspan)
12385 if (pris[span].mastertrunkgroup) {
12386 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);
12389 pris[span].mastertrunkgroup = trunkgroup;
12390 pris[span].prilogicalspan = logicalspan;
12395#if defined(HAVE_SS7)
12396static unsigned int parse_pointcode(
const char *pcstring)
12398 unsigned int code1, code2, code3;
12401 numvals = sscanf(pcstring,
"%30d-%30d-%30d", &code1, &code2, &code3);
12405 return (code1 << 16) | (code2 << 8) | code3;
12411#if defined(HAVE_SS7)
12412static struct dahdi_ss7 * ss7_resolve_linkset(
int linkset)
12414 if ((linkset < 0) || (linkset >=
NUM_SPANS))
12417 return &linksets[linkset - 1];
12422static void dahdi_r2_destroy_links(
void)
12424 struct r2link_entry *cur;
12429 ast_debug(3,
"MFC/R2 link #%d queued for destruction\n", cur->mfcr2.index);
12435 dahdi_r2_destroy_nodev();
12439#define R2_LINK_CAPACITY 30
12442 struct r2link_entry *cur =
NULL;
12450 if (memcmp(&
conf->mfcr2, &cur->mfcr2.conf,
sizeof(
conf->mfcr2))) {
12451 ast_debug(3,
"Need new R2 link because of: Configuration change\n");
12453 }
else if (cur->mfcr2.numchans == R2_LINK_CAPACITY) {
12454 ast_debug(3,
"Need new R2 link because of: Capacity (%d)\n", R2_LINK_CAPACITY);
12459 struct r2link_entry *tmp =
NULL;
12460 int new_idx = r2links_count + 1;
12462 for (i = 1; i <= r2links_count; i++) {
12465 if (i == tmp->mfcr2.index) {
12480 cur->mfcr2.index = new_idx;
12483 ast_debug(3,
"Created new R2 link #%d (now have %d)\n", new_idx, r2links_count);
12490static int dahdi_r2_set_context(
struct dahdi_mfcr2 *r2_link,
const struct dahdi_chan_conf *
conf)
12492 char tmplogdir[] =
"/tmp";
12493 char logdir[OR2_MAX_PATH];
12496 r2_link->protocol_context = openr2_context_new(
NULL, &dahdi_r2_event_iface,
12497 &dahdi_r2_transcode_iface,
conf->mfcr2.variant,
conf->mfcr2.max_ani,
12498 conf->mfcr2.max_dnis);
12499 if (!r2_link->protocol_context) {
12502 openr2_context_set_log_level(r2_link->protocol_context,
conf->mfcr2.loglevel);
12503 openr2_context_set_ani_first(r2_link->protocol_context,
conf->mfcr2.get_ani_first);
12504#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
12505 openr2_context_set_skip_category_request(r2_link->protocol_context,
conf->mfcr2.skip_category_request);
12507 openr2_context_set_mf_threshold(r2_link->protocol_context,
threshold);
12508 openr2_context_set_mf_back_timeout(r2_link->protocol_context,
conf->mfcr2.mfback_timeout);
12509 openr2_context_set_metering_pulse_timeout(r2_link->protocol_context,
conf->mfcr2.metering_pulse_timeout);
12510 openr2_context_set_double_answer(r2_link->protocol_context,
conf->mfcr2.double_answer);
12511 openr2_context_set_immediate_accept(r2_link->protocol_context,
conf->mfcr2.immediate_accept);
12512#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
12513 openr2_context_set_dtmf_dialing(r2_link->protocol_context,
conf->mfcr2.dtmf_dialing,
conf->mfcr2.dtmf_time_on,
conf->mfcr2.dtmf_time_off);
12514 openr2_context_set_dtmf_detection(r2_link->protocol_context,
conf->mfcr2.dtmf_detection);
12516#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
12517 openr2_context_set_dtmf_detection_end_timeout(r2_link->protocol_context,
conf->mfcr2.dtmf_end_timeout);
12520 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
12521 ast_log(
LOG_ERROR,
"Failed setting default MFC/R2 log directory %s\n", tmplogdir);
12525 if (snres >=
sizeof(logdir)) {
12526 ast_log(
LOG_ERROR,
"MFC/R2 logging directory truncated, using %s\n", tmplogdir);
12527 if (openr2_context_set_log_directory(r2_link->protocol_context, tmplogdir)) {
12528 ast_log(
LOG_ERROR,
"Failed setting default MFC/R2 log directory %s\n", tmplogdir);
12531 if (openr2_context_set_log_directory(r2_link->protocol_context, logdir)) {
12537 if (openr2_context_configure_from_advanced_file(r2_link->protocol_context,
conf->mfcr2.r2proto_file)) {
12538 ast_log(
LOG_ERROR,
"Failed to configure r2context from advanced configuration file %s\n",
conf->mfcr2.r2proto_file);
12542 memcpy(&r2_link->conf, &
conf->mfcr2,
sizeof(r2_link->conf));
12576 struct dahdi_bufferinfo bi;
12579#if defined(HAVE_PRI)
12585 struct dahdi_params p;
12586#if defined(HAVE_PRI)
12587 struct dahdi_spaninfo si;
12590#if defined(HAVE_SS7)
12610 if (!here && reloading != 1) {
12622 for (x = 0; x < 3; x++)
12629 int chan_sig =
conf->chan.sig;
12632 if (reloading && tmp->
vars) {
12642 snprintf(fn,
sizeof(fn),
"%d",
channel);
12657 memset(&p, 0,
sizeof(p));
12664 if (
conf->is_sig_auto)
12666 if (p.sigtype != (chan_sig & 0x3ffff)) {
12672 tmp->
law = p.curlaw;
12673 tmp->
span = p.spanno;
12674#if defined(HAVE_PRI)
12675 span = p.spanno - 1;
12680 tmp->
sig = chan_sig;
12691#if defined(HAVE_SS7)
12693 struct dahdi_ss7 *ss7;
12697 ast_log(
LOG_ERROR,
"Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(
errno));
12702 ss7 = ss7_resolve_linkset(cur_linkset);
12708 ss7->ss7.span = cur_linkset;
12709 if (cur_cicbeginswith < 0) {
12720 tmp->ss7 = &ss7->ss7;
12723 ss7_chan->
cic = cur_cicbeginswith++;
12726 ss7_chan->
dpc = cur_defaultdpc;
12728 ss7->ss7.pvts[ss7->ss7.numchans++] = ss7_chan;
12730 ast_copy_string(ss7->ss7.internationalprefix,
conf->ss7.ss7.internationalprefix,
sizeof(ss7->ss7.internationalprefix));
12731 ast_copy_string(ss7->ss7.nationalprefix,
conf->ss7.ss7.nationalprefix,
sizeof(ss7->ss7.nationalprefix));
12732 ast_copy_string(ss7->ss7.subscriberprefix,
conf->ss7.ss7.subscriberprefix,
sizeof(ss7->ss7.subscriberprefix));
12733 ast_copy_string(ss7->ss7.unknownprefix,
conf->ss7.ss7.unknownprefix,
sizeof(ss7->ss7.unknownprefix));
12734 ast_copy_string(ss7->ss7.networkroutedprefix,
conf->ss7.ss7.networkroutedprefix,
sizeof(ss7->ss7.networkroutedprefix));
12736 ss7->ss7.called_nai =
conf->ss7.ss7.called_nai;
12737 ss7->ss7.calling_nai =
conf->ss7.ss7.calling_nai;
12742 struct dahdi_mfcr2 *r2_link;
12743 struct r2link_entry *r2_le = dahdi_r2_get_link(
conf);
12744 r2_link = &r2_le->mfcr2;
12750 if (!r2_link->protocol_context && dahdi_r2_set_context(r2_link,
conf)) {
12755 if (r2_link->numchans ==
ARRAY_LEN(r2_link->pvts)) {
12760 r2_link->pvts[r2_link->numchans++] = tmp;
12761 tmp->r2chan = openr2_chan_new_from_fd(r2_link->protocol_context,
12764 if (!tmp->r2chan) {
12765 openr2_liberr_t err = openr2_context_get_last_error(r2_link->protocol_context);
12766 ast_log(
LOG_ERROR,
"Cannot create OpenR2 channel: %s\n", openr2_context_error_string(err));
12770 r2_link->live_chans++;
12771 tmp->mfcr2 = r2_link;
12772 if (
conf->mfcr2.call_files) {
12773 openr2_chan_enable_call_files(tmp->r2chan);
12775 openr2_chan_set_client_data(tmp->r2chan, tmp);
12777 openr2_chan_set_logging_func(tmp->r2chan, (openr2_logging_func_t)dahdi_r2_on_chan_log);
12778 openr2_chan_set_log_level(tmp->r2chan,
conf->mfcr2.loglevel);
12779 tmp->mfcr2_category =
conf->mfcr2.category;
12780 tmp->mfcr2_charge_calls =
conf->mfcr2.charge_calls;
12781 tmp->mfcr2_allow_collect_calls =
conf->mfcr2.allow_collect_calls;
12782 tmp->mfcr2_forced_release =
conf->mfcr2.forced_release;
12783 tmp->mfcr2_accept_on_offer =
conf->mfcr2.accept_on_offer;
12784 tmp->mfcr2call = 0;
12785 tmp->mfcr2_dnis_index = 0;
12786 tmp->mfcr2_ani_index = 0;
12794 int myswitchtype = 0;
12798 ast_log(
LOG_ERROR,
"Unable to set clear mode on clear channel %d of span %d: %s\n", channel, p.spanno, strerror(
errno));
12803 ast_log(
LOG_ERROR,
"Channel %d does not lie on a span I know of (%d)\n", channel, span);
12814 tmp->logicalspan = pris[span].prilogicalspan;
12815 pri_resolve_span(&span, channel, (channel - p.chanpos), &si);
12817 ast_log(
LOG_WARNING,
"Channel %d: Unable to find locate channel/trunk group!\n", channel);
12821 myswitchtype =
conf->pri.pri.switchtype;
12826 if (pris[x].dchannels[y] == tmp->
channel) {
12832 if (!matchesdchan) {
12833 if (pris[span].pri.
nodetype && (pris[span].pri.nodetype !=
conf->pri.pri.nodetype)) {
12838 if (pris[span].pri.
switchtype && (pris[span].pri.switchtype != myswitchtype)) {
12843 if ((pris[span].pri.
dialplan) && (pris[span].pri.dialplan !=
conf->pri.pri.dialplan)) {
12844 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));
12858 if (pris[span].pri.
minunused && (pris[span].pri.minunused !=
conf->pri.pri.minunused)) {
12859 ast_log(
LOG_ERROR,
"Span %d already has minunused of %d.\n", span + 1,
conf->pri.pri.minunused);
12863 if (pris[span].pri.
minidle && (pris[span].pri.minidle !=
conf->pri.pri.minidle)) {
12869 ast_log(
LOG_ERROR,
"Unable to add channel %d: Too many channels in trunk group %d!\n", channel,
12875 pri_chan =
sig_pri_chan_new(tmp, &pris[span].pri, tmp->logicalspan, p.chanpos, pris[span].mastertrunkgroup);
12881 tmp->pri = &pris[span].pri;
12893 conf->chan.cc_params);
12895 pris[span].pri.sig = chan_sig;
12896 pris[span].pri.nodetype =
conf->pri.pri.nodetype;
12897 pris[span].pri.switchtype = myswitchtype;
12898 pris[span].pri.nsf =
conf->pri.pri.nsf;
12899 pris[span].pri.dialplan =
conf->pri.pri.dialplan;
12900 pris[span].pri.localdialplan =
conf->pri.pri.localdialplan;
12901 pris[span].pri.cpndialplan =
conf->pri.pri.cpndialplan;
12902 pris[span].pri.pvts[pris[span].pri.numchans++] = tmp->
sig_pvt;
12903 pris[span].pri.minunused =
conf->pri.pri.minunused;
12904 pris[span].pri.minidle =
conf->pri.pri.minidle;
12905 pris[span].pri.overlapdial =
conf->pri.pri.overlapdial;
12906 pris[span].pri.qsigchannelmapping =
conf->pri.pri.qsigchannelmapping;
12907 pris[span].pri.discardremoteholdretrieval =
conf->pri.pri.discardremoteholdretrieval;
12908#if defined(HAVE_PRI_SERVICE_MESSAGES)
12909 pris[span].pri.enable_service_message_support =
conf->pri.pri.enable_service_message_support;
12911#ifdef HAVE_PRI_INBANDDISCONNECT
12912 pris[span].pri.inbanddisconnect =
conf->pri.pri.inbanddisconnect;
12914#if defined(HAVE_PRI_CALL_HOLD)
12915 pris[span].pri.hold_disconnect_transfer =
12916 conf->pri.pri.hold_disconnect_transfer;
12918#if defined(HAVE_PRI_CCSS)
12919 pris[span].pri.cc_ptmp_recall_mode =
12920 conf->pri.pri.cc_ptmp_recall_mode;
12921 pris[span].pri.cc_qsig_signaling_link_req =
12922 conf->pri.pri.cc_qsig_signaling_link_req;
12923 pris[span].pri.cc_qsig_signaling_link_rsp =
12924 conf->pri.pri.cc_qsig_signaling_link_rsp;
12926#if defined(HAVE_PRI_CALL_WAITING)
12927 pris[span].pri.max_call_waiting_calls =
12928 conf->pri.pri.max_call_waiting_calls;
12929 pris[span].pri.allow_call_waiting_calls =
12930 conf->pri.pri.allow_call_waiting_calls;
12932 pris[span].pri.transfer =
conf->chan.transfer;
12933 pris[span].pri.facilityenable =
conf->pri.pri.facilityenable;
12934#if defined(HAVE_PRI_L2_PERSISTENCE)
12935 pris[span].pri.l2_persistence =
conf->pri.pri.l2_persistence;
12937 pris[span].pri.colp_send =
conf->pri.pri.colp_send;
12938#if defined(HAVE_PRI_AOC_EVENTS)
12939 pris[span].pri.aoc_passthrough_flag =
conf->pri.pri.aoc_passthrough_flag;
12940 pris[span].pri.aoce_delayhangup =
conf->pri.pri.aoce_delayhangup;
12943 pris[span].pri.layer1_ignored =
conf->pri.pri.layer1_ignored;
12946 pris[span].pri.layer1_ignored = 0;
12948 pris[span].pri.append_msn_to_user_tag =
conf->pri.pri.append_msn_to_user_tag;
12949 pris[span].pri.inband_on_setup_ack =
conf->pri.pri.inband_on_setup_ack;
12950 pris[span].pri.inband_on_proceeding =
conf->pri.pri.inband_on_proceeding;
12951 ast_copy_string(pris[span].pri.initial_user_tag,
conf->chan.cid_tag,
sizeof(pris[span].pri.initial_user_tag));
12952 ast_copy_string(pris[span].pri.msn_list,
conf->pri.pri.msn_list,
sizeof(pris[span].pri.msn_list));
12953#if defined(HAVE_PRI_MWI)
12955 conf->pri.pri.mwi_mailboxes,
12956 sizeof(pris[span].pri.mwi_mailboxes));
12958 conf->pri.pri.mwi_vm_boxes,
12959 sizeof(pris[span].pri.mwi_vm_boxes));
12961 conf->pri.pri.mwi_vm_numbers,
12962 sizeof(pris[span].pri.mwi_vm_numbers));
12964 ast_copy_string(pris[span].pri.idledial,
conf->pri.pri.idledial,
sizeof(pris[span].pri.idledial));
12965 ast_copy_string(pris[span].pri.idleext,
conf->pri.pri.idleext,
sizeof(pris[span].pri.idleext));
12966 ast_copy_string(pris[span].pri.internationalprefix,
conf->pri.pri.internationalprefix,
sizeof(pris[span].pri.internationalprefix));
12967 ast_copy_string(pris[span].pri.nationalprefix,
conf->pri.pri.nationalprefix,
sizeof(pris[span].pri.nationalprefix));
12968 ast_copy_string(pris[span].pri.localprefix,
conf->pri.pri.localprefix,
sizeof(pris[span].pri.localprefix));
12969 ast_copy_string(pris[span].pri.privateprefix,
conf->pri.pri.privateprefix,
sizeof(pris[span].pri.privateprefix));
12970 ast_copy_string(pris[span].pri.unknownprefix,
conf->pri.pri.unknownprefix,
sizeof(pris[span].pri.unknownprefix));
12971 pris[span].pri.moh_signaling =
conf->pri.pri.moh_signaling;
12972 pris[span].pri.resetinterval =
conf->pri.pri.resetinterval;
12973#if defined(HAVE_PRI_DISPLAY_TEXT)
12974 pris[span].pri.display_flags_send =
conf->pri.pri.display_flags_send;
12975 pris[span].pri.display_flags_receive =
conf->pri.pri.display_flags_receive;
12977#if defined(HAVE_PRI_MCID)
12978 pris[span].pri.mcid_send =
conf->pri.pri.mcid_send;
12980 pris[span].pri.force_restart_unavailable_chans =
conf->pri.pri.force_restart_unavailable_chans;
12981#if defined(HAVE_PRI_DATETIME_SEND)
12982 pris[span].pri.datetime_send =
conf->pri.pri.datetime_send;
12985 for (x = 0; x < PRI_MAX_TIMERS; x++) {
12986 pris[span].pri.pritimers[x] =
conf->pri.pri.pritimers[x];
12989#if defined(HAVE_PRI_CALL_WAITING)
12991 pris[span].pri.ch_cfg.stripmsd =
conf->chan.stripmsd;
12992 pris[span].pri.ch_cfg.hidecallerid =
conf->chan.hidecallerid;
12993 pris[span].pri.ch_cfg.hidecalleridname =
conf->chan.hidecalleridname;
12994 pris[span].pri.ch_cfg.immediate =
conf->chan.immediate;
12995 pris[span].pri.ch_cfg.priexclusive =
conf->chan.priexclusive;
12996 pris[span].pri.ch_cfg.priindication_oob =
conf->chan.priindication_oob;
12997 pris[span].pri.ch_cfg.use_callerid =
conf->chan.use_callerid;
12998 pris[span].pri.ch_cfg.use_callingpres =
conf->chan.use_callingpres;
12999 ast_copy_string(pris[span].pri.ch_cfg.context,
conf->chan.context,
sizeof(pris[span].pri.ch_cfg.context));
13000 ast_copy_string(pris[span].pri.ch_cfg.mohinterpret,
conf->chan.mohinterpret,
sizeof(pris[span].pri.ch_cfg.mohinterpret));
13013 chan_sig = tmp->
sig;
13015 memset(&p, 0,
sizeof(p));
13020 switch (chan_sig) {
13044 p.channo = channel;
13048 p.debouncetime = 5;
13050 p.channo = channel;
13052 if (
conf->timing.prewinktime >= 0)
13053 p.prewinktime =
conf->timing.prewinktime;
13054 if (
conf->timing.preflashtime >= 0)
13055 p.preflashtime =
conf->timing.preflashtime;
13056 if (
conf->timing.winktime >= 0)
13057 p.winktime =
conf->timing.winktime;
13058 if (
conf->timing.flashtime >= 0)
13059 p.flashtime =
conf->timing.flashtime;
13060 if (
conf->timing.starttime >= 0)
13061 p.starttime =
conf->timing.starttime;
13062 if (
conf->timing.rxwinktime >= 0)
13063 p.rxwinktime =
conf->timing.rxwinktime;
13064 if (
conf->timing.rxflashtime >= 0)
13065 p.rxflashtime =
conf->timing.rxflashtime;
13066 if (
conf->timing.debouncetime >= 0)
13067 p.debouncetime =
conf->timing.debouncetime;
13082 memset(&bi, 0,
sizeof(bi));
13085 bi.txbufpolicy =
conf->chan.buf_policy;
13086 bi.rxbufpolicy =
conf->chan.buf_policy;
13087 bi.numbufs =
conf->chan.buf_no;
13111 if (chan_sig & __DAHDI_SIG_FXS) {
13151 if (
conf->chan.echocanbridged)
13152 ast_log(
LOG_NOTICE,
"echocancelwhenbridged requires echocancel to be enabled; ignoring\n");
13193 ast_log(
LOG_ERROR,
"Invalid SMDI port specified, disabling SMDI support\n");
13221#if defined(HAVE_PRI)
13238#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
13239 tmp->mwisend_setting =
conf->chan.mwisend_setting;
13240 tmp->mwisend_fsk =
conf->chan.mwisend_fsk;
13241 tmp->mwisend_rpas =
conf->chan.mwisend_rpas;
13251 if (
conf->chan.vars) {
13253 for (v =
conf->chan.vars ; v ; v = v->
next) {
13257 tmp->
vars = tmpvar;
13284 switch (chan_sig) {
13296 if ((res =
get_alarms(tmp)) != DAHDI_ALARM_NONE) {
13298 switch (tmp->
sig) {
13304#if defined(HAVE_SS7)
13335 switch (tmp->
sig) {
13336#if defined(HAVE_PRI)
13339#if defined(HAVE_PRI_SERVICE_MESSAGES)
13342 char db_chan_name[20];
13349 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, tmp->
span, tmp->
channel);
13350 if (!
ast_db_get(db_chan_name, SRVST_DBKEY, db_answer,
sizeof(db_answer))) {
13354 if (tmp->pri->enable_service_message_support) {
13357 sscanf(db_answer,
"%1c:%30u", &
state, why);
13360 *why &= (SRVST_NEAREND | SRVST_FAREND);
13370#if defined(HAVE_SS7)
13385 switch (tmp->
sig) {
13386#if defined(HAVE_PRI)
13406#if defined(HAVE_SS7)
13461 switch (
conf->chan.cid_start) {
13479 if (chan_sig & __DAHDI_SIG_FXO) {
13480 memset(&p, 0,
sizeof(p));
13485#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
13486 res = ioctl(tmp->
subs[
SUB_REAL].
dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting);
13499#if defined(HAVE_PRI)
13505 dahdi_pseudo_parms.buf_no = tmp->
buf_no;
13506 dahdi_pseudo_parms.buf_policy = tmp->
buf_policy;
13507 dahdi_pseudo_parms.faxbuf_no = tmp->
faxbuf_no;
13512 if (tmp && !here) {
13521#if defined(HAVE_PRI)
13524 if (!p->pri || p->pri->
span != span) {
13527 if (!groupmatch && channelmatch == -1) {
13536 if ((p->
group & groupmatch) != groupmatch)
13542 if (channelmatch != -1) {
13543 if (p->
channel != channelmatch)
13546 *channelmatched = 1;
13563#if defined(HAVE_PRI)
13575#if defined(HAVE_SS7)
13592 if (p->mfcr2call) {
13605#if defined(HAVE_PRI)
13606#if defined(HAVE_PRI_CALL_WAITING)
13621 pvt->
stripmsd = pri->ch_cfg.stripmsd;
13624 pvt->
immediate = pri->ch_cfg.immediate;
13635#if defined(HAVE_PRI)
13648static int dahdi_new_pri_nobch_channel(
struct sig_pri_span *pri)
13655 struct dahdi_bufferinfo bi;
13660 for (pvt_idx = 0; pvt_idx < pri->
numchans; ++pvt_idx) {
13661 if (!pri->
pvts[pvt_idx]) {
13689 pvt->
buf_no = dahdi_pseudo_parms.buf_no;
13690 pvt->
buf_policy = dahdi_pseudo_parms.buf_policy;
13691 pvt->
faxbuf_no = dahdi_pseudo_parms.faxbuf_no;
13712 pri->
pvts[pvt_idx] = chan;
13716 ast_log(
LOG_ERROR,
"Unable to open no B channel interface pseudo channel: %s\n",
13721 memset(&bi, 0,
sizeof(bi));
13727 bi.numbufs = pvt->
buf_no;
13731 "Unable to set buffer policy on no B channel interface: %s\n",
13736 "Unable to check buffer policy on no B channel interface: %s\n",
13743 pvt->
channel = nobch_channel;
13747 dahdi_nobch_insert(pri, pvt);
13761 struct dahdi_bufferinfo bi;
13792 bi.numbufs = src->
buf_no;
13829 char *subdir =
NULL;
13873 memset(param, 0,
sizeof(*param));
13876 if (strchr(
args.group,
'!') !=
NULL) {
13878 while ((s = strchr(
prev,
'!')) !=
NULL) {
13882 *(
prev - 1) =
'\0';
13883 subdir =
args.group;
13885 }
else if (
args.group[0] ==
'i') {
13887 res = sscanf(
args.group + 1,
"%30d", &x);
13895 s = strchr(
args.group,
'-');
13900 args.group = s + 1;
13903 if (toupper(
args.group[0]) ==
'G' || toupper(
args.group[0])==
'R') {
13905 s =
args.group + 1;
13906 res = sscanf(s,
"%30d%1c%30d", &x, ¶m->
opt, ¶m->
cadence);
13913 if (toupper(
args.group[0]) ==
'G') {
13914 if (
args.group[0] ==
'G') {
13925 if (
args.group[0] ==
'R') {
13940 if (!strcasecmp(s,
"pseudo")) {
13945 res = sscanf(s,
"%30d%1c%30d", &x, ¶m->
opt, ¶m->
cadence);
13957 snprintf(path,
sizeof(path),
"/dev/dahdi/%s/%d",
13959 if (stat(path, &stbuf) < 0) {
13961 path, strerror(
errno));
13964 if (!S_ISCHR(stbuf.st_mode)) {
13975 if (param->
opt ==
'r' && res < 3) {
13985 const char *
data,
int *cause)
13991 int channelmatched = 0;
13992 int foundowner = 0;
13993 int groupmatched = 0;
13994#if defined(HAVE_PRI) || defined(HAVE_SS7)
13995 int transcapdigital = 0;
14012 while (p && !tmp) {
14028 if (p->mfcr2call) {
14030 ast_debug(1,
"Yay!, someone just beat us in the race for channel %d.\n", p->
channel);
14046 switch (start.
opt) {
14059#if defined(HAVE_PRI) || defined(HAVE_SS7)
14086#if defined(HAVE_SS7)
14095#if defined(HAVE_PRI)
14098#if defined(HAVE_PRI_CALL_WAITING)
14137 if (cause && !tmp) {
14138 if (callwait || (channelmatched && foundowner)) {
14140 }
else if (groupmatched) {
14166#if defined(HAVE_PRI)
14167 const char *device;
14173 if (*device !=
'I') {
14177 res = sscanf(device,
"I%30u", &span);
14178 if (res != 1 || !span ||
NUM_SPANS < span) {
14182 device = strchr(device,
'/');
14192#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
14194 if (!strcmp(device,
"congestion"))
14197 return pris[span - 1].pri.congestion_devstate;
14199#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
14200 else if (!strcmp(device,
"threshold")) {
14201 return pris[span - 1].pri.threshold_devstate;
14231 int groupmatched = 0;
14232 int channelmatched = 0;
14246 const char *monitor_type;
14256#if defined(HAVE_PRI)
14262 snprintf(full_device_name,
sizeof(full_device_name),
14263 "DAHDI/I%d/congestion", p->pri->
span);
14267#if defined(HAVE_PRI)
14272 snprintf(full_device_name,
sizeof(full_device_name),
"DAHDI/%s",
14280 dash = strrchr(full_device_name,
'-');
14285 snprintf(dialstring,
sizeof(dialstring),
"DAHDI/%s", dest);
14295#
if defined(HAVE_PRI)
14300 monitor_type, full_device_name, dialstring,
NULL);
14308 if (p == exitpvt) {
14316#if defined(HAVE_SS7)
14317static void dahdi_ss7_message(
struct ss7 *ss7,
char *s)
14323 if (linksets[i].ss7.ss7 == ss7) {
14333#if defined(HAVE_SS7)
14334static void dahdi_ss7_error(
struct ss7 *ss7,
char *s)
14340 if (linksets[i].ss7.ss7 == ss7) {
14350#if defined(HAVE_OPENR2)
14351static void *mfcr2_monitor(
void *data)
14353 struct dahdi_mfcr2 *mfcr2 = data;
14371 for (i = 0; i < mfcr2->numchans; i++) {
14372 pvt = mfcr2->pvts[i];
14376 openr2_chan_set_idle(pvt->r2chan);
14377 openr2_chan_handle_cas(pvt->r2chan);
14383 for (i = 0; i < mfcr2->numchans; i++) {
14384 pollers[i].revents = 0;
14385 pollers[i].events = 0;
14386 pvt = mfcr2->pvts[i];
14393 if (mfcr2->nodev) {
14396 if (!pvt->r2chan) {
14401 openr2_chan_enable_read(pvt->r2chan);
14402 pollers[i].events = POLLIN | POLLPRI;
14409 if (pollsize == 0) {
14411 ast_debug(1,
"Monitor thread going idle since everybody has an owner\n");
14414 poll(
NULL, 0, maxsleep);
14420 pthread_testcancel();
14421 res = poll(pollers, mfcr2->numchans, maxsleep);
14422 pthread_testcancel();
14423 if ((res < 0) && (
errno != EINTR)) {
14428 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
14429 for (i = 0; i < mfcr2->numchans; i++) {
14430 pvt = mfcr2->pvts[i];
14434 if (pollers[i].revents & POLLPRI || pollers[i].revents & POLLIN) {
14435 openr2_chan_process_event(pvt->r2chan);
14438 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
14445#if defined(HAVE_PRI)
14446static void dahdi_pri_message(
struct pri *pri,
char *s)
14452 int dchancount = 0;
14457 if (pris[x].pri.dchans[y]) {
14461 if (pris[x].pri.dchans[y] == pri) {
14472 if (1 < dchancount) {
14486 if (pridebugfd >= 0) {
14487 if (write(pridebugfd, s, strlen(s)) < 0) {
14496#if defined(HAVE_PRI)
14497static void dahdi_pri_error(
struct pri *pri,
char *s)
14503 int dchancount = 0;
14508 if (pris[x].pri.dchans[y]) {
14512 if (pris[x].pri.dchans[y] == pri) {
14523 if (1 < dchancount) {
14537 if (pridebugfd >= 0) {
14538 if (write(pridebugfd, s, strlen(s)) < 0) {
14547#if defined(HAVE_PRI)
14548static int prepare_pri(
struct dahdi_pri *pri)
14551 struct dahdi_params p;
14552 struct dahdi_bufferinfo bi;
14553 struct dahdi_spaninfo si;
14556 if (!pri->dchannels[i])
14558 if (pri->pri.fds[i] >= 0) {
14562 pri->pri.fds[i] = open(
"/dev/dahdi/channel", O_RDWR);
14563 if ((pri->pri.fds[i] < 0)) {
14565 pri->pri.fds[i], strerror(
errno));
14568 x = pri->dchannels[i];
14569 res = ioctl(pri->pri.fds[i], DAHDI_SPECIFY, &x);
14571 dahdi_close_pri_fd(pri, i);
14575 memset(&p, 0,
sizeof(p));
14576 res = ioctl(pri->pri.fds[i], DAHDI_GET_PARAMS, &p);
14578 dahdi_close_pri_fd(pri, i);
14582 if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC)) {
14583 dahdi_close_pri_fd(pri, i);
14587 memset(&si, 0,
sizeof(si));
14588 res = ioctl(pri->pri.fds[i], DAHDI_SPANSTAT, &si);
14590 dahdi_close_pri_fd(pri, i);
14598 memset(&bi, 0,
sizeof(bi));
14599 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
14600 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
14603 if (ioctl(pri->pri.fds[i], DAHDI_SET_BUFINFO, &bi)) {
14605 dahdi_close_pri_fd(pri, i);
14608 pri->pri.dchan_logical_span[i] = pris[p.spanno - 1].prilogicalspan;
14614#if defined(HAVE_PRI)
14615static char *complete_span_helper(
const char *line,
const char *
word,
int pos,
int state,
int rpos)
14623 for (which = span = 0; span <
NUM_SPANS; span++) {
14624 if (pris[span].pri.pri && ++which >
state) {
14635#if defined(HAVE_PRI)
14636static char *complete_span_4(
const char *line,
const char *
word,
int pos,
int state)
14638 return complete_span_helper(line,
word,pos,
state,3);
14642#if defined(HAVE_PRI)
14648 e->
command =
"pri set debug file";
14649 e->
usage =
"Usage: pri set debug file [output-file]\n"
14650 " Sends PRI debug output to the specified output file\n";
14663 ast_cli(
a->fd,
"Unable to open '%s' for writing\n",
a->argv[4]);
14669 if (pridebugfd >= 0)
14675 ast_cli(
a->fd,
"PRI debug output will be sent to '%s'\n",
a->argv[4]);
14680#if defined(HAVE_PRI)
14681static int action_pri_debug_file_set(
struct mansession *s,
const struct message *m)
14698 if (pridebugfd >= 0) {
14703 ast_copy_string(pridebugfilename, output_file,
sizeof(pridebugfilename));
14705 astman_send_ack(s, m,
"PRI debug output will now be sent to requested file.");
14711#if defined(HAVE_PRI)
14712static int action_pri_debug_file_unset(
struct mansession *s,
const struct message *m)
14716 if (pridebugfd >= 0) {
14729#if defined(HAVE_PRI)
14738 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";
14740 "Usage: pri set debug {<level>|on|off|hex|intense} span <span>\n"
14741 " Enables debugging on a given PRI span\n"
14742 " Level is a bitmap of the following values:\n"
14743 " 1 General debugging incl. state changes\n"
14744 " 2 Decoded Q.931 messages\n"
14745 " 4 Decoded Q.921 messages\n"
14746 " 8 Raw hex dumps of Q.921 frames\n"
14747 " on - equivalent to 3\n"
14748 " hex - equivalent to 8\n"
14749 " intense - equivalent to 15\n";
14752 return complete_span_4(
a->line,
a->word,
a->pos,
a->n);
14758 if (!strcasecmp(
a->argv[3],
"on")) {
14760 }
else if (!strcasecmp(
a->argv[3],
"off")) {
14762 }
else if (!strcasecmp(
a->argv[3],
"intense")) {
14764 }
else if (!strcasecmp(
a->argv[3],
"hex")) {
14767 level = atoi(
a->argv[3]);
14769 span = atoi(
a->argv[5]);
14770 if ((span < 1) || (span >
NUM_SPANS)) {
14771 ast_cli(
a->fd,
"Invalid span %s. Should be a number %d to %d\n",
a->argv[5], 1,
NUM_SPANS);
14774 if (!pris[span-1].pri.pri) {
14775 ast_cli(
a->fd,
"No PRI running on span %d\n", span);
14780 if (level & 2) debugmask |= PRI_DEBUG_Q931_DUMP;
14781 if (level & 4) debugmask |= PRI_DEBUG_Q921_DUMP;
14782 if (level & 8) debugmask |= PRI_DEBUG_Q921_RAW;
14786 if (pris[span - 1].pri.dchans[x]) {
14787 pri_set_debug(pris[span - 1].pri.dchans[x], debugmask);
14793 if (0 <= pridebugfd) {
14796 ast_cli(
a->fd,
"Disabled PRI debug output to file '%s'\n",
14801 pris[span - 1].pri.debug = (level) ? 1 : 0;
14802 ast_cli(
a->fd,
"%s debugging on span %d\n", (level) ?
"Enabled" :
"Disabled", span);
14807#if defined(HAVE_PRI)
14827 if (!strcasecmp(level,
"on")) {
14829 }
else if (!strcasecmp(level,
"off")) {
14831 }
else if (!strcasecmp(level,
"intense")) {
14833 }
else if (!strcasecmp(level,
"hex")) {
14836 if (sscanf(level,
"%30d", &level_val) != 1) {
14842 if (sscanf(span,
"%30d", &span_val) != 1) {
14846 if ((span_val < 1) || (span_val >
NUM_SPANS)) {
14848 char id_text[256] =
"";
14851 snprintf(id_text,
sizeof(id_text),
"ActionID: %s\r\n",
id);
14856 "Message: Invalid span '%s' - Should be a number from 1 to %d\r\n"
14864 if (!pris[span_val-1].pri.pri) {
14869 if (level_val & 1) {
14872 if (level_val & 2) {
14873 debugmask |= PRI_DEBUG_Q931_DUMP;
14875 if (level_val & 4) {
14876 debugmask |= PRI_DEBUG_Q921_DUMP;
14878 if (level_val & 8) {
14879 debugmask |= PRI_DEBUG_Q921_RAW;
14884 if (pris[span_val - 1].pri.dchans[x]) {
14885 pri_set_debug(pris[span_val - 1].pri.dchans[x], debugmask);
14889 pris[span_val - 1].pri.debug = (level_val) ? 1 : 0;
14896#if defined(HAVE_PRI)
14897#if defined(HAVE_PRI_SERVICE_MESSAGES)
14903 int x, y, fd =
a->fd;
14904 int interfaceid = 0;
14905 char db_chan_name[20], db_answer[15];
14907 struct dahdi_pri *pri;
14909 if (
a->argc < 5 ||
a->argc > 6)
14911 if (strchr(
a->argv[4],
':')) {
14912 if (sscanf(
a->argv[4],
"%30d:%30d", &trunkgroup, &channel) != 2)
14914 if ((trunkgroup < 1) || (channel < 1))
14918 if (pris[x].pri.trunkgroup == trunkgroup) {
14924 ast_cli(fd,
"No such trunk group %d\n", trunkgroup);
14928 channel = atoi(
a->argv[4]);
14931 interfaceid = atoi(
a->argv[5]);
14936 if (pris[x].dchannels[y] == channel) {
14938 if (pri->pri.enable_service_message_support) {
14940 pri_maintenance_service(pri->pri.pri, interfaceid, -1, changestatus);
14944 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n"
14945 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n");
14955 if (tmp->pri && tmp->
channel == channel) {
14958 if (!tmp->pri->enable_service_message_support) {
14961 "\n\tThis operation has not been enabled in chan_dahdi.conf, set 'service_message_support=yes' to use this operation.\n"
14962 "\tNote only 4ESS, 5ESS, and NI2 switch types are supported.\n\n");
14965 snprintf(db_chan_name,
sizeof(db_chan_name),
"%s/%d:%d", dahdi_db, tmp->
span, channel);
14967 switch(changestatus) {
14971 *why &= ~SRVST_NEAREND;
14973 snprintf(db_answer,
sizeof(db_answer),
"%s:%u", SRVST_TYPE_OOS, *why);
14974 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
14976 dahdi_pri_update_span_devstate(tmp->pri);
14983 *why |= SRVST_NEAREND;
14984 snprintf(db_answer,
sizeof(db_answer),
"%s:%u", SRVST_TYPE_OOS, *why);
14985 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
14986 dahdi_pri_update_span_devstate(tmp->pri);
14994 pri_maintenance_bservice(tmp->pri->pri, tmp->
sig_pvt, changestatus);
15001 ast_cli(fd,
"Unable to find given channel %d, possibly not a PRI\n",
channel);
15009 e->
command =
"pri service enable channel";
15011 "Usage: pri service enable channel <channel> [<interface id>]\n"
15012 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n"
15013 " to restore a channel to service, with optional interface id\n"
15014 " as agreed upon with remote switch operator\n";
15019 return handle_pri_service_generic(e, cmd,
a, 0);
15026 e->
command =
"pri service disable channel";
15028 "Usage: pri service disable channel <chan num> [<interface id>]\n"
15029 " Send an AT&T / NFAS / CCS ANSI T1.607 maintenance message\n"
15030 " to remove a channel from service, with optional interface id\n"
15031 " as agreed upon with remote switch operator\n";
15036 return handle_pri_service_generic(e, cmd,
a, 2);
15041#if defined(HAVE_PRI)
15048 e->
command =
"pri show channels";
15050 "Usage: pri show channels\n"
15051 " Displays PRI channel information such as the current mapping\n"
15052 " of DAHDI B channels to Asterisk channel names and which calls\n"
15053 " are on hold or call-waiting. Calls on hold or call-waiting\n"
15054 " are not associated with any B channel.\n";
15064 for (span = 0; span <
NUM_SPANS; ++span) {
15065 if (pris[span].
pri.
pri) {
15073#if defined(HAVE_PRI)
15080 e->
command =
"pri show spans";
15082 "Usage: pri show spans\n"
15083 " Displays PRI span information\n";
15092 for (span = 0; span <
NUM_SPANS; span++) {
15093 if (pris[span].
pri.
pri) {
15101#if defined(HAVE_PRI)
15102#define container_of(ptr, type, member) \
15103 ((type *)((char *)(ptr) - offsetof(type, member)))
15120 struct dahdi_pri* dahdi_pri;
15121 pthread_t master = pri->
master;
15126 ast_debug(2,
"About to destroy DAHDI channels of span %d.\n", pri->
span);
15127 for (i = 0; i < pri->
numchans; i++) {
15139 cancel_code = pthread_cancel(master);
15140 pthread_kill(master, SIGURG);
15142 "Waiting to join thread of span %d "
15143 "with pid=%p cancel_code=%d\n",
15144 pri->
span, (
void *)master, cancel_code);
15145 res = pthread_join(master,
NULL);
15154 ast_debug(4,
"closing pri_fd %d\n", i);
15155 dahdi_close_pri_fd(dahdi_pri, i);
15156 dahdi_pri->dchannels[i] = 0;
15162static char *handle_pri_destroy_span(
struct ast_cli_entry *e,
int cmd,
15171 e->
command =
"pri destroy span";
15173 "Usage: pri destroy span <span>\n"
15174 " Destroys D-channel of span and its B-channels.\n"
15175 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n";
15178 return complete_span_4(
a->line,
a->word,
a->pos,
a->n);
15184 res = sscanf(
a->argv[3],
"%30d", &
span);
15185 if ((res != 1) || span < 1 || span >
NUM_SPANS) {
15187 "Invalid span '%s'. Should be a number from %d to %d\n",
15197 pri_destroy_span(
pri);
15203#if defined(HAVE_PRI)
15210 e->
command =
"pri show span";
15212 "Usage: pri show span <span>\n"
15213 " Displays PRI Information on a given PRI span\n";
15216 return complete_span_4(
a->line,
a->word,
a->pos,
a->n);
15221 span = atoi(
a->argv[3]);
15223 ast_cli(
a->fd,
"Invalid span '%s'. Should be a number from %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
15237#if defined(HAVE_PRI)
15247 e->
command =
"pri show debug";
15249 "Usage: pri show debug\n"
15250 " Show the debug state of pri spans\n";
15259 if (pris[
span].
pri.dchans[x]) {
15261 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" );
15269 if (pridebugfd >= 0)
15270 ast_cli(
a->fd,
"Logging PRI debug to file %s\n", pridebugfilename);
15274 ast_cli(
a->fd,
"No PRI running\n");
15279#if defined(HAVE_PRI)
15284 e->
command =
"pri show version";
15286 "Usage: pri show version\n"
15287 "Show libpri version information\n";
15293 ast_cli(
a->fd,
"libpri version: %s\n", pri_get_version());
15299#if defined(HAVE_PRI)
15301 AST_CLI_DEFINE(handle_pri_debug,
"Enables PRI debugging on a span"),
15302#if defined(HAVE_PRI_SERVICE_MESSAGES)
15303 AST_CLI_DEFINE(handle_pri_service_enable_channel,
"Return a channel to service"),
15304 AST_CLI_DEFINE(handle_pri_service_disable_channel,
"Remove a channel from service"),
15306 AST_CLI_DEFINE(handle_pri_show_channels,
"Displays PRI channel information"),
15307 AST_CLI_DEFINE(handle_pri_show_spans,
"Displays PRI span information"),
15308 AST_CLI_DEFINE(handle_pri_show_span,
"Displays PRI span information"),
15310 AST_CLI_DEFINE(handle_pri_show_debug,
"Displays current PRI debug settings"),
15311 AST_CLI_DEFINE(handle_pri_set_debug_file,
"Sends PRI debug output to the specified file"),
15322 e->
command =
"mfcr2 show version";
15324 "Usage: mfcr2 show version\n"
15325 " Shows the version of the OpenR2 library being used.\n";
15330 ast_cli(
a->fd,
"OpenR2 version: %s, revision: %s\n", openr2_get_version(), openr2_get_revision());
15336#define FORMAT "%4s %40s\n"
15338 int numvariants = 0;
15339 const openr2_variant_entry_t *variants;
15342 e->
command =
"mfcr2 show variants";
15344 "Usage: mfcr2 show variants\n"
15345 " Shows the list of MFC/R2 variants supported.\n";
15350 if (!(variants = openr2_proto_get_variant_list(&numvariants))) {
15351 ast_cli(
a->fd,
"Failed to get list of variants.\n");
15355 for (i = 0; i < numvariants; i++) {
15364#define FORMAT "%4s %4s %-7.7s %-7.7s %-8.8s %-9.9s %-16.16s %-8.8s %-8.8s\n"
15365 int filtertype = 0;
15372 openr2_context_t *r2context;
15373 openr2_variant_t r2variant;
15376 e->
command =
"mfcr2 show channels [group|context]";
15378 "Usage: mfcr2 show channels [group <group> | context <context>]\n"
15379 " Shows the DAHDI channels configured with MFC/R2 signaling.\n";
15384 if (!((
a->argc == 3) || (
a->argc == 5))) {
15387 if (
a->argc == 5) {
15388 if (!strcasecmp(
a->argv[3],
"group")) {
15389 targetnum = atoi(
a->argv[4]);
15390 if ((targetnum < 0) || (targetnum > 63))
15392 targetnum = 1 << targetnum;
15394 }
else if (!strcasecmp(
a->argv[3],
"context")) {
15400 ast_cli(
a->fd,
FORMAT,
"Chan",
"Link#",
"Variant",
"Max ANI",
"Max DNIS",
"ANI First",
"Immediate Accept",
"Tx CAS",
"Rx CAS");
15407 switch(filtertype) {
15409 if (p->
group != targetnum) {
15414 if (strcasecmp(p->
context,
a->argv[4])) {
15422 r2context = openr2_chan_get_context(p->r2chan);
15423 r2variant = openr2_context_get_variant(r2context);
15424 snprintf(channo,
sizeof(channo),
"%d", p->
channel);
15425 snprintf(linkno,
sizeof(linkno),
"%d", p->mfcr2->index);
15426 snprintf(anino,
sizeof(anino),
"%d", openr2_context_get_max_ani(r2context));
15427 snprintf(dnisno,
sizeof(dnisno),
"%d", openr2_context_get_max_dnis(r2context));
15428 ast_cli(
a->fd,
FORMAT, channo, linkno, openr2_proto_get_variant_string(r2variant),
15429 anino, dnisno, openr2_context_get_ani_first(r2context) ?
"Yes" :
"No",
15430 openr2_context_get_immediate_accept(r2context) ?
"Yes" :
"No",
15431 openr2_chan_get_tx_cas_string(p->r2chan), openr2_chan_get_rx_cas_string(p->r2chan));
15442 char *toklevel =
NULL;
15443 char *saveptr =
NULL;
15444 char *logval =
NULL;
15445 openr2_log_level_t loglevel = OR2_LOG_NOTHING;
15446 openr2_log_level_t tmplevel = OR2_LOG_NOTHING;
15449 e->
command =
"mfcr2 set debug";
15451 "Usage: mfcr2 set debug <loglevel> <channel>\n"
15452 " Set a new logging level for the specified channel.\n"
15453 " If no channel is specified the logging level will be applied to all channels.\n";
15461 channo = (
a->argc == 5) ? atoi(
a->argv[4]) : -1;
15463 toklevel = strtok_r(logval,
",", &saveptr);
15464 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
15465 ast_cli(
a->fd,
"Invalid MFC/R2 logging level '%s'.\n",
a->argv[3]);
15467 }
else if (OR2_LOG_NOTHING == tmplevel) {
15468 loglevel = tmplevel;
15470 loglevel |= tmplevel;
15471 while ((toklevel = strtok_r(
NULL,
",", &saveptr))) {
15472 if (-1 == (tmplevel = openr2_log_get_level(toklevel))) {
15473 ast_cli(
a->fd,
"Ignoring invalid logging level: '%s'.\n", toklevel);
15476 loglevel |= tmplevel;
15484 if ((channo != -1) && (p->
channel != channo )) {
15487 openr2_chan_set_log_level(p->r2chan, loglevel);
15488 if (channo != -1) {
15489 ast_cli(
a->fd,
"MFC/R2 debugging set to '%s' for channel %d.\n",
a->argv[3], p->
channel);
15493 if ((channo != -1) && !p) {
15494 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15496 if (channo == -1) {
15497 ast_cli(
a->fd,
"MFC/R2 debugging set to '%s' for all channels.\n",
a->argv[3]);
15509 e->
command =
"mfcr2 call files [on|off]";
15511 "Usage: mfcr2 call files [on|off] <channel>\n"
15512 " Enable call files creation on the specified channel.\n"
15513 " If no channel is specified call files creation policy will be applied to all channels.\n";
15521 channo = (
a->argc == 5) ? atoi(
a->argv[4]) : -1;
15527 if ((channo != -1) && (p->
channel != channo )) {
15531 openr2_chan_enable_call_files(p->r2chan);
15533 openr2_chan_disable_call_files(p->r2chan);
15535 if (channo != -1) {
15537 ast_cli(
a->fd,
"MFC/R2 call files enabled for channel %d.\n", p->
channel);
15539 ast_cli(
a->fd,
"MFC/R2 call files disabled for channel %d.\n", p->
channel);
15544 if ((channo != -1) && !p) {
15545 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15547 if (channo == -1) {
15549 ast_cli(
a->fd,
"MFC/R2 Call files enabled for all channels.\n");
15551 ast_cli(
a->fd,
"MFC/R2 Call files disabled for all channels.\n");
15564 e->
command =
"mfcr2 set idle";
15566 "Usage: mfcr2 set idle <channel>\n"
15567 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
15568 " Force the given channel into IDLE state.\n"
15569 " If no channel is specified, all channels will be set to IDLE.\n";
15574 channo = (
a->argc == 4) ? atoi(
a->argv[3]) : -1;
15580 if ((channo != -1) && (p->
channel != channo )) {
15583 openr2_chan_set_idle(p->r2chan);
15588 if (channo != -1) {
15592 if ((channo != -1) && !p) {
15593 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15605 e->
command =
"mfcr2 set blocked";
15607 "Usage: mfcr2 set blocked <channel>\n"
15608 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n"
15609 " Force the given channel into BLOCKED state.\n"
15610 " If no channel is specified, all channels will be set to BLOCKED.\n";
15615 channo = (
a->argc == 4) ? atoi(
a->argv[3]) : -1;
15621 if ((channo != -1) && (p->
channel != channo )) {
15624 openr2_chan_set_blocked(p->r2chan);
15628 if (channo != -1) {
15632 if ((channo != -1) && !p) {
15633 ast_cli(
a->fd,
"MFC/R2 channel %d not found.\n", channo);
15639static void mfcr2_show_links_of(
struct ast_cli_args *
a,
struct r2links *list_head,
const char *title)
15641#define FORMAT "%-5s %-10s %-15s %-10s %s\n"
15646 char live_chans_str[5];
15647 char channel_list[R2_LINK_CAPACITY * 4];
15648 struct r2link_entry *cur;
15650 ast_cli(
a->fd,
FORMAT,
"Index",
"Thread",
"Dahdi-Device",
"Channels",
"Channel-List");
15652 struct dahdi_mfcr2 *mfcr2 = &cur->mfcr2;
15653 const char *thread_status =
NULL;
15660 if (mfcr2->r2master == 0L) {
15661 thread_status =
"zero";
15663 thread_status =
"none";
15665 thread_status =
"created";
15667 snprintf(index,
sizeof(index),
"%d", mfcr2->index);
15668 snprintf(live_chans_str,
sizeof(live_chans_str),
"%d", mfcr2->live_chans);
15674 for (i = 0; i < mfcr2->numchans &&
len <
sizeof(channel_list) - 1; i++) {
15681 if (prev_channo && prev_channo == channo - 1) {
15682 prev_channo = channo;
15686 if (inside_range) {
15688 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
"-%d,%d", prev_channo, channo);
15690 }
else if (prev_channo) {
15692 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
",%d", channo);
15695 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
"%d", channo);
15697 prev_channo = channo;
15700 if (inside_range) {
15702 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
"-%d", channo);
15704 }
else if (prev_channo) {
15706 len += snprintf(channel_list +
len,
sizeof(channel_list) -
len - 1,
",%d", channo);
15712 (mfcr2->nodev) ?
"MISSING" :
"OK",
15725 e->
command =
"mfcr2 show links";
15727 "Usage: mfcr2 show links\n"
15728 " Shows the DAHDI MFC/R2 links.\n";
15733 if (
a->argc != 3) {
15736 mfcr2_show_links_of(
a, &r2links,
"Live links\n");
15737 mfcr2_show_links_of(
a, &nodev_r2links,
"Links to be removed (device missing)\n");
15744 int wanted_link_index;
15745 int found_link = 0;
15746 struct r2link_entry *cur =
NULL;
15750 e->
command =
"mfcr2 destroy link";
15752 "Usage: mfcr2 destroy link <index-number>\n"
15753 " Destroys D-channel of link and its B-channels.\n"
15754 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.\n";
15762 res = sscanf(
a->argv[3],
"%30d", &wanted_link_index);
15763 if ((res != 1) || wanted_link_index < 1) {
15765 "Invalid link index '%s'. Should be a positive number\n",
a->argv[3]);
15770 struct dahdi_mfcr2 *mfcr2 = &cur->mfcr2;
15771 if (wanted_link_index == mfcr2->index) {
15779 if (! found_link) {
15780 ast_cli(
a->fd,
"No link found with index %d.\n", wanted_link_index);
15787 AST_CLI_DEFINE(handle_mfcr2_version,
"Show OpenR2 library version"),
15788 AST_CLI_DEFINE(handle_mfcr2_show_variants,
"Show supported MFC/R2 variants"),
15789 AST_CLI_DEFINE(handle_mfcr2_show_channels,
"Show MFC/R2 channels"),
15791 AST_CLI_DEFINE(handle_mfcr2_set_debug,
"Set MFC/R2 channel logging level"),
15792 AST_CLI_DEFINE(handle_mfcr2_call_files,
"Enable/Disable MFC/R2 call files"),
15793 AST_CLI_DEFINE(handle_mfcr2_set_idle,
"Reset MFC/R2 channel forcing it to IDLE"),
15794 AST_CLI_DEFINE(handle_mfcr2_set_blocked,
"Reset MFC/R2 channel forcing it to BLOCKED"),
15795 AST_CLI_DEFINE(handle_mfcr2_destroy_link,
"Destroy given MFC/R2 link"),
15806 e->
command =
"dahdi destroy channels";
15808 "Usage: dahdi destroy channels <from_channel> [<to_channel>]\n"
15809 " DON'T USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING. Immediately removes a given channel, whether it is in use or not\n";
15814 if ((
a->argc < 4) ||
a->argc > 5) {
15817 start = atoi(
a->argv[3]);
15819 ast_cli(
a->fd,
"Invalid starting channel number %s.\n",
15823 if (
a->argc == 5) {
15824 end = atoi(
a->argv[4]);
15826 ast_cli(
a->fd,
"Invalid ending channel number %s.\n",
15836 "range end (%d) is smaller than range start (%d)\n",
15852 e->
command =
"dahdi create channels";
15853 e->
usage =
"Usage: dahdi create channels <from> [<to>] - a range of channels\n"
15854 " dahdi create channels new - add channels not yet created\n"
15855 "For ISDN and SS7 the range should include complete spans.\n";
15860 if ((
a->argc < 4) ||
a->argc > 5) {
15863 if (
a->argc == 4 && !strcmp(
a->argv[3],
"new")) {
15867 start = atoi(
a->argv[3]);
15869 ast_cli(
a->fd,
"Invalid starting channel number '%s'.\n",
15873 if (
a->argc == 5) {
15874 end = atoi(
a->argv[4]);
15876 ast_cli(
a->fd,
"Invalid ending channel number '%s'.\n",
15885 "range end (%d) is smaller than range start (%d)\n",
15923#if defined(HAVE_PRI) || defined(HAVE_SS7)
15930 ast_verb(1,
"Destroying channels and reloading DAHDI configuration.\n");
15932 ast_verb(4,
"Initial softhangup of all DAHDI channels complete.\n");
15934 dahdi_r2_destroy_links();
15937#if defined(HAVE_PRI)
15940 cancel_code = pthread_cancel(pris[i].pri.
master);
15941 pthread_kill(pris[i].pri.
master, SIGURG);
15942 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);
15944 ast_debug(4,
"Joined thread of span %d\n", i);
15949#if defined(HAVE_SS7)
15952 cancel_code = pthread_cancel(linksets[i].ss7.master);
15953 pthread_kill(linksets[i].ss7.master, SIGURG);
15954 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);
15955 pthread_join(linksets[i].ss7.master,
NULL);
15956 ast_debug(4,
"Joined thread of span %d\n", i);
15965 ast_debug(4,
"Waiting to join monitor thread with pid=%p, cancel_code=%d\n", (
void *)
monitor_thread, cancel_code);
15967 ast_debug(4,
"Joined monitor thread\n");
15973 int x = DAHDI_FLASH;
15989 ast_verb(4,
"Final softhangup of all DAHDI channels complete.\n");
15999 dahdi_close_pri_fd(&(pris[i]), j);
16002 memset(pris, 0,
sizeof(pris));
16006 pri_set_error(dahdi_pri_error);
16007 pri_set_message(dahdi_pri_message);
16009#if defined(HAVE_SS7)
16012 dahdi_close_ss7_fd(&(linksets[i]), j);
16015 memset(linksets, 0,
sizeof(linksets));
16019 ss7_set_error(dahdi_ss7_error);
16020 ss7_set_message(dahdi_ss7_message);
16040 e->
command =
"dahdi restart";
16042 "Usage: dahdi restart\n"
16043 " Restarts the DAHDI channels: destroys them all and then\n"
16044 " re-reads them from chan_dahdi.conf.\n"
16045 " Note that this will STOP any running CALL on DAHDI channels.\n"
16071#define FORMAT "%7s %4d %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
16072#define FORMAT2 "%7s %4s %-20.20s %-10.10s %-15.15s %-8.8s %-20.20s %-10.10s %-10.10s %-12.12s %-32.32s\n"
16074 int filtertype = 0;
16081 e->
command =
"dahdi show channels [group|context]";
16083 "Usage: dahdi show channels [ group <group> | context <context> ]\n"
16084 " Shows a list of available channels with optional filtering\n"
16085 " <group> must be a number between 0 and 63\n";
16093 if (!((
a->argc == 3) || (
a->argc == 5))) {
16097 if (
a->argc == 5) {
16098 if (!strcasecmp(
a->argv[3],
"group")) {
16099 targetnum = atoi(
a->argv[4]);
16100 if (63 < targetnum) {
16105 }
else if (!strcasecmp(
a->argv[3],
"context")) {
16110 ast_cli(
a->fd,
FORMAT2,
"Chan",
"Span",
"Signalling",
"Extension",
"Context",
"Language",
"MOH Interpret",
"Blocked",
"In Service",
"Alarms",
"Description");
16115 switch(filtertype) {
16117 if (!(tmp->
group & targetnum)) {
16122 if (strcasecmp(tmp->
context,
a->argv[4])) {
16131 snprintf(tmps,
sizeof(tmps),
"%d", tmp->
channel);
16139 blockstr[2] =
'\0';
16141 ast_cli(
a->fd,
FORMAT, tmps, tmp->
span,
sig2str(tmp->
sig), tmp->
exten, tmp->
context, tmp->
language, tmp->
mohinterpret, blockstr, tmp->
inservice ?
"Yes" :
"No",
16154 struct dahdi_confinfo ci;
16155 struct dahdi_params ps;
16162 e->
command =
"dahdi show channel";
16164 "Usage: dahdi show channel <chan num>\n"
16165 " Detailed information about a given channel\n";
16174 channel = atoi(
a->argv[3]);
16178 if (tmp->
channel == channel) {
16188#if defined(HAVE_PRI)
16189#if defined(HAVE_PRI_SUBADDR)
16198 for (v = tmp->
vars ; v ; v = v->
next)
16212 ast_cli(
a->fd,
"DSP: %s\n", tmp->
dsp ?
"yes" :
"no");
16215#if defined(BUSYDETECT_TONEONLY)
16216 ast_cli(
a->fd,
" Busy Detector Helper: BUSYDETECT_TONEONLY\n");
16217#elif defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
16218 ast_cli(
a->fd,
" Busy Detector Helper: BUSYDETECT_COMPARE_TONE_AND_SILENCE\n");
16220#ifdef BUSYDETECT_DEBUG
16221 ast_cli(
a->fd,
" Busy Detector Debug: Enabled\n");
16226 ast_cli(
a->fd,
"TDD: %s\n", tmp->
tdd ?
"yes" :
"no");
16233 snprintf(hwrxgain,
sizeof(hwrxgain),
"%.1f", tmp->
hwrxgain);
16238 snprintf(hwtxgain,
sizeof(hwtxgain),
"%.1f", tmp->
hwtxgain);
16242 ast_cli(
a->fd,
"HW Gains (RX/TX): %s/%s\n", hwrxgain, hwtxgain);
16244 ast_cli(
a->fd,
"Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->
rxdrc, tmp->
txdrc);
16246 ast_cli(
a->fd,
"Echo Cancellation:\n");
16266 char calldir[OR2_MAX_PATH];
16267 openr2_context_t *r2context = openr2_chan_get_context(tmp->r2chan);
16268 openr2_variant_t r2variant = openr2_context_get_variant(r2context);
16269 ast_cli(
a->fd,
"MFC/R2 MF State: %s\n", openr2_chan_get_mf_state_string(tmp->r2chan));
16270 ast_cli(
a->fd,
"MFC/R2 MF Group: %s\n", openr2_chan_get_mf_group_string(tmp->r2chan));
16271 ast_cli(
a->fd,
"MFC/R2 State: %s\n", openr2_chan_get_r2_state_string(tmp->r2chan));
16272 ast_cli(
a->fd,
"MFC/R2 Call State: %s\n", openr2_chan_get_call_state_string(tmp->r2chan));
16273 ast_cli(
a->fd,
"MFC/R2 Call Files Enabled: %s\n", openr2_chan_get_call_files_enabled(tmp->r2chan) ?
"Yes" :
"No");
16274 ast_cli(
a->fd,
"MFC/R2 Variant: %s\n", openr2_proto_get_variant_string(r2variant));
16275 ast_cli(
a->fd,
"MFC/R2 Max ANI: %d\n", openr2_context_get_max_ani(r2context));
16276 ast_cli(
a->fd,
"MFC/R2 Max DNIS: %d\n", openr2_context_get_max_dnis(r2context));
16277#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
16278 ast_cli(
a->fd,
"MFC/R2 DTMF Dialing: %s\n", openr2_context_get_dtmf_dialing(r2context,
NULL,
NULL) ?
"Yes" :
"No");
16279 ast_cli(
a->fd,
"MFC/R2 DTMF Detection: %s\n", openr2_context_get_dtmf_detection(r2context) ?
"Yes" :
"No");
16281 ast_cli(
a->fd,
"MFC/R2 Get ANI First: %s\n", openr2_context_get_ani_first(r2context) ?
"Yes" :
"No");
16282#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
16283 ast_cli(
a->fd,
"MFC/R2 Skip Category Request: %s\n", openr2_context_get_skip_category_request(r2context) ?
"Yes" :
"No");
16285 ast_cli(
a->fd,
"MFC/R2 Immediate Accept: %s\n", openr2_context_get_immediate_accept(r2context) ?
"Yes" :
"No");
16286 ast_cli(
a->fd,
"MFC/R2 Accept on Offer: %s\n", tmp->mfcr2_accept_on_offer ?
"Yes" :
"No");
16287 ast_cli(
a->fd,
"MFC/R2 Charge Calls: %s\n", tmp->mfcr2_charge_calls ?
"Yes" :
"No");
16288 ast_cli(
a->fd,
"MFC/R2 Allow Collect Calls: %s\n", tmp->mfcr2_allow_collect_calls ?
"Yes" :
"No");
16289 ast_cli(
a->fd,
"MFC/R2 Forced Release: %s\n", tmp->mfcr2_forced_release ?
"Yes" :
"No");
16290 ast_cli(
a->fd,
"MFC/R2 MF Back Timeout: %dms\n", openr2_context_get_mf_back_timeout(r2context));
16291 ast_cli(
a->fd,
"MFC/R2 R2 Metering Pulse Timeout: %dms\n", openr2_context_get_metering_pulse_timeout(r2context));
16292 ast_cli(
a->fd,
"MFC/R2 Rx CAS: %s\n", openr2_chan_get_rx_cas_string(tmp->r2chan));
16293 ast_cli(
a->fd,
"MFC/R2 Tx CAS: %s\n", openr2_chan_get_tx_cas_string(tmp->r2chan));
16294 ast_cli(
a->fd,
"MFC/R2 MF Tx Signal: %d\n", openr2_chan_get_tx_mf_signal(tmp->r2chan));
16295 ast_cli(
a->fd,
"MFC/R2 MF Rx Signal: %d\n", openr2_chan_get_rx_mf_signal(tmp->r2chan));
16296 ast_cli(
a->fd,
"MFC/R2 Call Files Directory: %s\n", openr2_context_get_log_directory(r2context, calldir,
sizeof(calldir)));
16299#if defined(HAVE_SS7)
16320 if (tmp->logicalspan)
16321 ast_cli(
a->fd,
"PRI Logical Span: %d\n", tmp->logicalspan);
16323 ast_cli(
a->fd,
"PRI Logical Span: Implicit\n");
16326 memset(&ci, 0,
sizeof(ci));
16329 memset(&ci, 0,
sizeof(ci));
16331 ast_cli(
a->fd,
"Actual Confinfo: Num/%d, Mode/0x%04x\n", ci.confno, (
unsigned)ci.confmode);
16334 ast_cli(
a->fd,
"Actual Confmute: %s\n", x ?
"Yes" :
"No");
16336 memset(&ps, 0,
sizeof(ps));
16340 ast_cli(
a->fd,
"Hookstate (FXS only): %s\n", ps.rxisoffhook ?
"Offhook" :
"Onhook");
16358 e->
command =
"dahdi show cadences";
16360 "Usage: dahdi show cadences\n"
16361 " Shows all cadences currently defined\n";
16368 char tmp[16], tmp2[64];
16369 snprintf(tmp,
sizeof(tmp),
"r%d: ", i + 1);
16372 for (j = 0; j < 16; j++) {
16373 if (
cadences[i].ringcadence[j] == 0)
16375 snprintf(tmp,
sizeof(tmp),
"%d",
cadences[i].ringcadence[j]);
16381 strncat(output,
",",
sizeof(output) - strlen(output) - 1);
16382 strncat(output, tmp2,
sizeof(output) - strlen(output) - 1);
16391 alarmstr[0] =
'\0';
16392 if (spaninfo->alarms > 0) {
16393 if (spaninfo->alarms & DAHDI_ALARM_BLUE) {
16394 strcat(alarmstr,
"BLU/");
16396 if (spaninfo->alarms & DAHDI_ALARM_YELLOW) {
16397 strcat(alarmstr,
"YEL/");
16399 if (spaninfo->alarms & DAHDI_ALARM_RED) {
16400 strcat(alarmstr,
"RED/");
16402 if (spaninfo->alarms & DAHDI_ALARM_LOOPBACK) {
16403 strcat(alarmstr,
"LB/");
16405 if (spaninfo->alarms & DAHDI_ALARM_RECOVER) {
16406 strcat(alarmstr,
"REC/");
16408 if (spaninfo->alarms & DAHDI_ALARM_NOTOPEN) {
16409 strcat(alarmstr,
"NOP/");
16411 if (!strlen(alarmstr)) {
16412 strcat(alarmstr,
"UUU/");
16414 if (strlen(alarmstr)) {
16416 alarmstr[strlen(alarmstr) - 1] =
'\0';
16419 if (spaninfo->numchans) {
16420 strcpy(alarmstr,
"OK");
16422 strcpy(alarmstr,
"UNCONFIGURED");
16430 #define FORMAT "%4d %-40.40s %-7.7s %-6d %-6d %-6d %-3.3s %-4.4s %-8.8s %s\n"
16431 #define FORMAT2 "%4s %-40.40s %-7.7s %-6.6s %-6.6s %-6.6s %-3.3s %-4.4s %-8.8s %s\n"
16437 struct dahdi_spaninfo s;
16441 e->
command =
"dahdi show status";
16443 "Usage: dahdi show status\n"
16444 " Shows a list of DAHDI cards with status\n";
16449 ctl = open(
"/dev/dahdi/ctl", O_RDWR);
16451 ast_cli(
a->fd,
"No DAHDI found. Unable to open /dev/dahdi/ctl: %s\n", strerror(
errno));
16454 ast_cli(
a->fd,
FORMAT2,
"Span",
"Description",
"Alarms",
"IRQ",
"bpviol",
"CRC",
"Framing",
"Coding",
"Options",
"LBO");
16456 for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
16458 res = ioctl(ctl, DAHDI_SPANSTAT, &s);
16463 ast_cli(
a->fd,
FORMAT, span, s.desc, alarmstr, s.irqmisses, s.bpvcount, s.crc4count,
16464 s.lineconfig & DAHDI_CONFIG_D4 ?
"D4" :
16465 s.lineconfig & DAHDI_CONFIG_ESF ?
"ESF" :
16466 s.lineconfig & DAHDI_CONFIG_CCS ?
"CCS" :
16468 s.lineconfig & DAHDI_CONFIG_B8ZS ?
"B8ZS" :
16469 s.lineconfig & DAHDI_CONFIG_HDB3 ?
"HDB3" :
16470 s.lineconfig & DAHDI_CONFIG_AMI ?
"AMI" :
16472 s.lineconfig & DAHDI_CONFIG_CRC4 ?
16473 s.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"CRC4/YEL" :
"CRC4" :
16474 s.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"YEL" :
"",
16487 int pseudo_fd = -1;
16488 struct dahdi_versioninfo vi;
16492 e->
command =
"dahdi show version";
16494 "Usage: dahdi show version\n"
16495 " Shows the DAHDI version in use\n";
16500 if ((pseudo_fd = open(
"/dev/dahdi/ctl", O_RDONLY)) < 0) {
16501 ast_cli(
a->fd,
"Failed to open control file to get version.\n");
16505 strcpy(vi.version,
"Unknown");
16506 strcpy(vi.echo_canceller,
"Unknown");
16508 if (ioctl(pseudo_fd, DAHDI_GETVERSION, &vi))
16509 ast_cli(
a->fd,
"Failed to get DAHDI version: %s\n", strerror(
errno));
16511 ast_cli(
a->fd,
"DAHDI Version: %s Echo Canceller: %s\n", vi.version, vi.echo_canceller);
16527 e->
command =
"dahdi set hwgain {rx|tx}";
16529 "Usage: dahdi set hwgain <rx|tx> <chan#> <gain>\n"
16530 " Sets the hardware gain on a given channel and overrides the\n"
16531 " value provided at module loadtime. Changes take effect\n"
16532 " immediately whether the channel is in use or not.\n"
16534 " <rx|tx> which direction do you want to change (relative to our module)\n"
16535 " <chan num> is the channel number relative to the device\n"
16536 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n"
16539 " * hwgain is only supportable by hardware with analog ports because\n"
16540 " hwgain works on the analog side of an analog-digital conversion.\n";
16549 if (!strcasecmp(
"rx",
a->argv[3]))
16551 else if (!strcasecmp(
"tx",
a->argv[3]))
16557 gain = atof(
a->argv[5]);
16570 ast_cli(
a->fd,
"Unable to set the hardware gain for channel %d: %s\n",
channel, strerror(
errno));
16574 ast_cli(
a->fd,
"Hardware %s gain set to %.1f dB on channel %d.\n",
16575 tx ?
"tx" :
"rx", gain,
channel);
16607 e->
command =
"dahdi set swgain {rx|tx}";
16609 "Usage: dahdi set swgain <rx|tx> <chan#> <gain>\n"
16610 " Sets the software gain on a given channel and overrides the\n"
16611 " value provided at module loadtime. Changes take effect\n"
16612 " immediately whether the channel is in use or not.\n"
16614 " <rx|tx> which direction do you want to change (relative to our module)\n"
16615 " <chan num> is the channel number relative to the device\n"
16616 " <gain> is the gain in dB (e.g. -3.5 for -3.5dB)\n";
16625 if (!strcasecmp(
"rx",
a->argv[3]))
16627 else if (!strcasecmp(
"tx",
a->argv[3]))
16633 gain = atof(
a->argv[5]);
16650 ast_cli(
a->fd,
"Unable to set the software gain for channel %d\n",
channel);
16655 ast_cli(
a->fd,
"Software %s gain set to %.2f dB on channel %d.\n",
16656 tx ?
"tx" :
"rx", gain,
channel);
16683 e->
command =
"dahdi set dnd";
16685 "Usage: dahdi set dnd <chan#> <on|off>\n"
16686 " Sets/resets DND (Do Not Disturb) mode on a channel.\n"
16687 " Changes take effect immediately.\n"
16688 " <chan num> is the channel number\n"
16689 " <on|off> Enable or disable DND mode?\n"
16699 if ((
channel = atoi(
a->argv[3])) <= 0) {
16700 ast_cli(
a->fd,
"Expected channel number, got '%s'\n",
a->argv[3]);
16709 ast_cli(
a->fd,
"Expected 'on' or 'off', got '%s'\n",
a->argv[4]);
16714 for (dahdi_chan =
iflist; dahdi_chan; dahdi_chan = dahdi_chan->
next) {
16741 e->
command =
"dahdi set mwi";
16743 "Usage: dahdi set mwi <chan#> <on|off|reset>\n"
16744 " Sets/unsets MWI (Message Waiting Indicator) manually on a channel.\n"
16745 " This may be used regardless of whether the channel is assigned any mailboxes.\n"
16746 " When active, this setting will override the voicemail status to set MWI.\n"
16747 " Once cleared, the voicemail status will resume control of MWI.\n"
16748 " Changes are queued for when the channel is idle and persist until cleared.\n"
16749 " <chan num> is the channel number\n"
16750 " <on|off|reset> Enable, disable, or reset Message Waiting Indicator override?\n"
16760 if ((
channel = atoi(
a->argv[3])) <= 0) {
16761 ast_cli(
a->fd,
"Expected channel number, got '%s'\n",
a->argv[3]);
16769 }
else if (!strcmp(
a->argv[4],
"reset")) {
16772 ast_cli(
a->fd,
"Expected 'on' or 'off' or 'reset', got '%s'\n",
a->argv[4]);
16777 for (dahdi_chan =
iflist; dahdi_chan; dahdi_chan = dahdi_chan->
next) {
16784 ast_cli(
a->fd,
"MWI '%s' queued for channel %d\n", on ?
"enable" :
"disable",
channel);
16862 if (sscanf(
channel,
"%30d", &chan_num) != 1) {
16978 for (i = 0; i < strlen(
number); i++) {
16993 int dahdichanquery;
16995 if (!dahdichannel || sscanf(dahdichannel,
"%30d", &dahdichanquery) != 1) {
16997 dahdichanquery = -1;
17002 snprintf(idText,
sizeof(idText),
"ActionID: %s\r\n",
id);
17014 if (dahdichanquery > 0 && tmp->
channel != dahdichanquery)
17022 "Event: DAHDIShowChannels\r\n"
17023 "DAHDIChannel: %d\r\n"
17026 "AccountCode: %s\r\n"
17027 "Signalling: %s\r\n"
17028 "SignallingCode: %d\r\n"
17032 "Description: %s\r\n"
17042 dahdi_dnd(tmp, -1) ?
"Enabled" :
"Disabled",
17047 "Event: DAHDIShowChannels\r\n"
17048 "DAHDIChannel: %d\r\n"
17049 "Signalling: %s\r\n"
17050 "SignallingCode: %d\r\n"
17054 "Description: %s\r\n"
17059 dahdi_dnd(tmp, -1) ?
"Enabled" :
"Disabled",
17083 struct dahdi_spaninfo spaninfo;
17085 ctl = open(
"/dev/dahdi/ctl", O_RDWR);
17093 snprintf(idText,
sizeof(idText),
"ActionID: %s\r\n",
id);
17097 for (span = 1; span < DAHDI_MAX_SPANS; ++span) {
17098 spaninfo.spanno = span;
17099 res = ioctl(ctl, DAHDI_SPANSTAT, &spaninfo);
17106 "Event: DAHDIShowStatus\r\n"
17108 "Description: %s\r\n"
17119 span, spaninfo.desc, alarmstr, spaninfo.irqmisses, spaninfo.bpvcount, spaninfo.crc4count,
17120 spaninfo.lineconfig & DAHDI_CONFIG_D4 ?
"D4" :
17121 spaninfo.lineconfig & DAHDI_CONFIG_ESF ?
"ESF" :
17122 spaninfo.lineconfig & DAHDI_CONFIG_CCS ?
"CCS" :
17124 spaninfo.lineconfig & DAHDI_CONFIG_B8ZS ?
"B8ZS" :
17125 spaninfo.lineconfig & DAHDI_CONFIG_HDB3 ?
"HDB3" :
17126 spaninfo.lineconfig & DAHDI_CONFIG_AMI ?
"AMI" :
17128 spaninfo.lineconfig & DAHDI_CONFIG_CRC4 ?
17129 spaninfo.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"CRC4/YEL" :
"CRC4" :
17130 spaninfo.lineconfig & DAHDI_CONFIG_NOTOPEN ?
"YEL" :
"",
17142#if defined(HAVE_PRI)
17148 struct dahdi_pri *dspan;
17151 char action_id[256];
17152 const char *show_cmd =
"PRIShowSpans";
17156 span_query = atoi(span_str);
17162 snprintf(action_id,
sizeof(action_id),
"ActionID: %s\r\n",
id);
17164 action_id[0] =
'\0';
17170 for (idx = 0; idx <
ARRAY_LEN(pris); ++idx) {
17171 dspan = &pris[idx];
17174 if (0 < span_query && dspan->pri.span != span_query) {
17178 if (dspan->pri.pri) {
17191#if defined(HAVE_SS7)
17192static int linkset_addsigchan(
int sigchan)
17194 struct dahdi_ss7 *link;
17197 struct dahdi_params params;
17198 struct dahdi_bufferinfo bi;
17199 struct dahdi_spaninfo si;
17205 if (cur_ss7type < 0) {
17209 if (cur_pointcode < 0) {
17213 if (cur_adjpointcode < 0) {
17217 if (cur_defaultdpc < 0) {
17221 if (cur_networkindicator < 0) {
17225 link = ss7_resolve_linkset(cur_linkset);
17235 curfd = link->ss7.numsigchans;
17238 link->ss7.fds[curfd] = open(
"/dev/dahdi/channel", O_RDWR, 0600);
17239 if (link->ss7.fds[curfd] < 0) {
17244 if (ioctl(link->ss7.fds[curfd], DAHDI_SPECIFY, &sigchan) == -1) {
17245 dahdi_close_ss7_fd(link, curfd);
17252 memset(¶ms, 0,
sizeof(params));
17253 res = ioctl(link->ss7.fds[curfd], DAHDI_GET_PARAMS, ¶ms);
17255 dahdi_close_ss7_fd(link, curfd);
17256 ast_log(
LOG_ERROR,
"Unable to get parameters for sigchan %d (%s)\n", sigchan,
17260 if (params.sigtype != DAHDI_SIG_HDLCFCS
17261 && params.sigtype != DAHDI_SIG_HARDHDLC
17262 && params.sigtype != DAHDI_SIG_MTP2) {
17263 dahdi_close_ss7_fd(link, curfd);
17269 memset(&bi, 0,
sizeof(bi));
17270 bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
17271 bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
17274 if (ioctl(link->ss7.fds[curfd], DAHDI_SET_BUFINFO, &bi)) {
17275 ast_log(
LOG_ERROR,
"Unable to set appropriate buffering on channel %d: %s\n",
17276 sigchan, strerror(
errno));
17277 dahdi_close_ss7_fd(link, curfd);
17282 memset(&si, 0,
sizeof(si));
17283 res = ioctl(link->ss7.fds[curfd], DAHDI_SPANSTAT, &si);
17285 dahdi_close_ss7_fd(link, curfd);
17286 ast_log(
LOG_ERROR,
"Unable to get span state for sigchan %d (%s)\n", sigchan,
17291 (params.sigtype == DAHDI_SIG_MTP2)
17292 ? SS7_TRANSPORT_DAHDIMTP2
17293 : SS7_TRANSPORT_DAHDIDCHAN,
17294 si.alarms, cur_networkindicator, cur_pointcode, cur_adjpointcode, cur_slc);
17296 dahdi_close_ss7_fd(link, curfd);
17300 ++link->ss7.numsigchans;
17306#if defined(HAVE_SS7)
17312 e->
command =
"ss7 set debug {on|off} linkset";
17314 "Usage: ss7 set debug {on|off} linkset <linkset>\n"
17315 " Enables debugging on a given SS7 linkset\n";
17325 span = atoi(
a->argv[5]);
17326 if ((span < 1) || (span >
NUM_SPANS)) {
17327 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number from %d to %d\n",
a->argv[5], 1,
NUM_SPANS);
17330 if (!linksets[span-1].ss7.ss7) {
17331 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", span);
17333 if (!strcasecmp(
a->argv[3],
"on")) {
17334 linksets[span - 1].ss7.debug = 1;
17336 ast_cli(
a->fd,
"Enabled debugging on linkset %d\n", span);
17338 linksets[span - 1].ss7.debug = 0;
17339 ss7_set_debug(linksets[span-1].ss7.ss7, 0);
17340 ast_cli(
a->fd,
"Disabled debugging on linkset %d\n", span);
17348#if defined(HAVE_SS7)
17358 e->
command =
"ss7 {block|unblock} cic";
17360 "Usage: ss7 {block|unblock} cic <linkset> <dpc> <CIC>\n"
17361 " Sends a remote {blocking|unblocking} request for the given CIC on the specified linkset\n";
17367 if (
a->argc == 6) {
17368 linkset = atoi(
a->argv[3]);
17373 if (!strcasecmp(
a->argv[1],
"block")) {
17375 }
else if (strcasecmp(
a->argv[1],
"unblock")) {
17379 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17380 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17384 if (!linksets[linkset-1].ss7.ss7) {
17385 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17389 cic = atoi(
a->argv[5]);
17391 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17395 dpc = atoi(
a->argv[4]);
17397 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17401 for (i = 0; i < linksets[linkset-1].ss7.numchans; i++) {
17402 if (linksets[linkset-1].ss7.pvts[i] && linksets[linkset-1].ss7.pvts[i]->cic == cic && linksets[linkset-1].ss7.pvts[i]->dpc == dpc) {
17403 blocked = linksets[linkset-1].ss7.pvts[i]->locallyblocked;
17406 ast_cli(
a->fd,
"Unable to allocate new ss7call\n");
17408 ast_cli(
a->fd,
"Sent %sblocking request for linkset %d on CIC %d DPC %d\n", (do_block) ?
"" :
"un", linkset, cic, dpc);
17410 }
else if (!do_block && blocked) {
17411 ast_cli(
a->fd,
"CIC %d is hardware locally blocked!\n", cic);
17413 ast_cli(
a->fd,
"CIC %d %s locally blocked\n", cic, do_block ?
"already" :
"is not");
17419 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17424#if defined(HAVE_SS7)
17436 e->
command =
"ss7 {reset|block|unblock} linkset";
17438 "Usage: ss7 {reset|block|unblock} linkset <linkset number>\n"
17439 " Sends a remote {reset|blocking|unblocking} request for all CICs on the given linkset\n";
17445 if (
a->argc == 4) {
17446 linkset = atoi(
a->argv[3]);
17451 if (!strcasecmp(
a->argv[1],
"block")) {
17452 do_what = DO_BLOCK;
17453 }
else if (!strcasecmp(
a->argv[1],
"unblock")) {
17454 do_what = DO_UNBLOCK;
17455 }
else if (!strcasecmp(
a->argv[1],
"reset")) {
17456 do_what = DO_RESET;
17461 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17462 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17466 if (!linksets[linkset - 1].ss7.ss7) {
17467 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17471 for (i = 0; i < linksets[linkset - 1].ss7.numchans; i++) {
17473 if (linksets[linkset - 1].ss7.pvts[i]) {
17478 ast_cli(
a->fd,
"Sent remote %s request on CIC %d\n",
17479 (do_what == DO_BLOCK) ?
"blocking" :
"unblocking",
17480 linksets[linkset - 1].ss7.pvts[i]->cic);
17485 linksets[linkset - 1].ss7.pvts[i]->cic,
17486 linksets[linkset - 1].ss7.pvts[i]->dpc)) {
17487 ast_cli(
a->fd,
"Sent reset request on CIC %d\n",
17488 linksets[linkset - 1].ss7.pvts[i]->cic);
17499#if defined(HAVE_SS7)
17502 int linkset, cic, range, chanpos;
17503 int i, dpc, orient = 0;
17505 unsigned char state[255];
17509 e->
command =
"ss7 {block|unblock} group";
17511 "Usage: ss7 {block|unblock} group <linkset> <dpc> <1st. CIC> <range> [H]\n"
17512 " Sends a remote {blocking|unblocking} request for CIC range on the specified linkset\n";
17518 if (
a->argc == 7 ||
a->argc == 8) {
17519 linkset = atoi(
a->argv[3]);
17524 if (!strcasecmp(
a->argv[1],
"block")) {
17526 }
else if (strcasecmp(
a->argv[1],
"unblock")) {
17530 if (
a->argc == 8) {
17531 if (!strcasecmp(
a->argv[7],
"H")) {
17538 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17539 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[4], 1,
NUM_SPANS);
17543 if (!linksets[linkset-1].ss7.ss7) {
17544 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17548 cic = atoi(
a->argv[5]);
17550 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17554 range = atoi(
a->argv[6]);
17556 if (range < 1 || range > (linksets[linkset - 1].ss7.type == SS7_ANSI ? 24 : 31)) {
17557 ast_cli(
a->fd,
"Invalid range specified!\n");
17561 dpc = atoi(
a->argv[4]);
17563 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17570 ast_cli(
a->fd,
"Invalid CIC/RANGE\n");
17575 for (i = 0; i <= range; ++i) {
17582 ast_cli(
a->fd,
"Unable allocate new ss7call\n");
17584 ast_cli(
a->fd,
"Sending remote%s %sblocking request linkset %d on CIC %d range %d\n",
17585 orient ?
" hardware" :
"", do_block ?
"" :
"un", linkset, cic, range);
17592 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
17598#if defined(HAVE_SS7)
17601 int linkset, cic, range;
17606 e->
command =
"ss7 reset group";
17608 "Usage: ss7 reset group <linkset> <dpc> <1st CIC> <range>\n"
17609 " Send a GRS for the given CIC range on the specified linkset\n";
17615 if (
a->argc == 7) {
17616 linkset = atoi(
a->argv[3]);
17621 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17622 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[4], 1,
NUM_SPANS);
17626 if (!linksets[linkset-1].ss7.ss7) {
17627 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17631 cic = atoi(
a->argv[5]);
17634 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17638 range = atoi(
a->argv[6]);
17639 if (range < 1 || range > (linksets[linkset - 1].ss7.type == SS7_ANSI ? 24 : 31)) {
17640 ast_cli(
a->fd,
"Invalid range specified!\n");
17644 dpc = atoi(
a->argv[4]);
17646 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17653 ast_cli(
a->fd,
"Invalid CIC/RANGE\n");
17658 ast_cli(
a->fd,
"Unable to allocate new ss7call\n");
17660 ast_cli(
a->fd,
"GRS sent ... \n");
17667 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
17673#if defined(HAVE_SS7)
17680 e->
command =
"ss7 show calls";
17682 "Usage: ss7 show calls <linkset>\n"
17683 " Show SS7 calls on the specified linkset\n";
17689 if (
a->argc == 4) {
17690 linkset = atoi(
a->argv[3]);
17695 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17696 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17700 if (!linksets[linkset-1].ss7.ss7) {
17701 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17706 isup_show_calls(linksets[linkset-1].ss7.ss7, &
ast_cli,
a->fd);
17713#if defined(HAVE_SS7)
17716 int linkset, cic, res;
17721 e->
command =
"ss7 reset cic";
17723 "Usage: ss7 reset cic <linkset> <dpc> <CIC>\n"
17724 " Send a RSC for the given CIC on the specified linkset\n";
17730 if (
a->argc == 6) {
17731 linkset = atoi(
a->argv[3]);
17736 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17737 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17741 if (!linksets[linkset-1].ss7.ss7) {
17742 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17746 cic = atoi(
a->argv[5]);
17749 ast_cli(
a->fd,
"Invalid CIC specified!\n");
17753 dpc = atoi(
a->argv[4]);
17755 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17761 ast_cli(
a->fd,
"%s RSC for linkset %d on CIC %d DPC %d\n", res ?
"Sent" :
"Failed", linkset, cic, dpc);
17767#if defined(HAVE_SS7)
17772 unsigned int arg = 0;
17779 "Usage: ss7 mtp3 <linkset> <slc> coo|coa|cbd|cba|eco|eca|tfp|tfa|lin|lun|lia|lua|lid|lfu <arg>\n"
17780 " Send a NET MNG message\n"
17781 " WARNING!!! WARNING!!! We are not a STP, just for testing/development purposes\n";
17791 linkset = atoi(
a->argv[2]);
17792 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17793 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[2], 1,
NUM_SPANS);
17796 if (!linksets[linkset-1].ss7.ss7) {
17797 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17801 slc = atoi(
a->argv[3]);
17803 if (
a->argc == 6) {
17804 arg = atoi(
a->argv[5]);
17808 res = mtp3_net_mng(linksets[linkset-1].ss7.ss7, slc,
a->argv[4], arg);
17813 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
17822#if defined(HAVE_SS7)
17826 unsigned int slc = 0;
17830 e->
command =
"ss7 restart mtp3";
17832 "Usage: ss7 restart mtp3 <linkset> <slc>\n"
17843 linkset = atoi(
a->argv[3]);
17844 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17845 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[2], 1,
NUM_SPANS);
17848 if (!linksets[linkset-1].ss7.ss7) {
17849 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17853 slc = atoi(
a->argv[4]);
17856 mtp3_init_restart(linksets[linkset-1].ss7.ss7, slc);
17861 pthread_kill(linksets[linkset-1].ss7.master, SIGURG);
17868#if defined(HAVE_SS7)
17875 e->
command =
"ss7 show linkset";
17877 "Usage: ss7 show linkset <span>\n"
17878 " Shows the status of an SS7 linkset.\n";
17888 linkset = atoi(
a->argv[3]);
17889 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17890 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17893 ss7 = &linksets[linkset - 1].ss7;
17895 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17901 ast_cli(
a->fd,
"SS7 calling nai: %i\n",
ss7->calling_nai);
17902 ast_cli(
a->fd,
"SS7 called nai: %i\n",
ss7->called_nai);
17903 ast_cli(
a->fd,
"SS7 nationalprefix: %s\n",
ss7->nationalprefix);
17904 ast_cli(
a->fd,
"SS7 internationalprefix: %s\n",
ss7->internationalprefix);
17905 ast_cli(
a->fd,
"SS7 unknownprefix: %s\n",
ss7->unknownprefix);
17906 ast_cli(
a->fd,
"SS7 networkroutedprefix: %s\n",
ss7->networkroutedprefix);
17907 ast_cli(
a->fd,
"SS7 subscriberprefix: %s\n",
ss7->subscriberprefix);
17914#if defined(HAVE_SS7)
17921 e->
command =
"ss7 show channels";
17923 "Usage: ss7 show channels\n"
17924 " Displays SS7 channel information at a glance.\n";
17930 if (
a->argc != 3) {
17935 for (linkset = 0; linkset <
NUM_SPANS; ++linkset) {
17936 if (linksets[linkset].
ss7.ss7) {
17944#if defined(HAVE_SS7)
17947#define FORMAT "%5s %5s %6s %12s %-12s\n"
17948#define FORMAT2 "%5i %5i %6i %12s %-12s\n"
17949 int i, linkset, dpc = 0;
17956 e->
command =
"ss7 show cics";
17958 "Usage: ss7 show cics <linkset> [dpc]\n"
17959 " Shows the cics of an SS7 linkset.\n";
17965 if (
a->argc < 4 ||
a->argc > 5) {
17969 linkset = atoi(
a->argv[3]);
17971 if ((linkset < 1) || (linkset >
NUM_SPANS)) {
17972 ast_cli(
a->fd,
"Invalid linkset %s. Should be a number %d to %d\n",
a->argv[3], 1,
NUM_SPANS);
17976 if (!linksets[linkset-1].
ss7.ss7) {
17977 ast_cli(
a->fd,
"No SS7 running on linkset %d\n", linkset);
17980 ss7 = &linksets[linkset-1].ss7;
17982 if (
a->argc == 5) {
17983 dpc = atoi(
a->argv[4]);
17985 ast_cli(
a->fd,
"Invalid DPC specified!\n");
17990 ast_cli(
a->fd,
FORMAT,
"CIC",
"DPC",
"DAHDI",
"STATE",
"BLOCKING");
17992 for (i = 0; i <
ss7->numchans; i++) {
17993 if (!dpc || (
ss7->pvts[i] &&
ss7->pvts[i]->dpc == dpc)) {
18001 state =
"NotInServ";
18007 strcpy(blocking,
"L:");
18009 strcat(blocking,
"M");
18011 strcat(blocking,
" ");
18015 strcat(blocking,
"H");
18017 strcat(blocking,
" ");
18020 strcpy(blocking,
" ");
18024 strcat(blocking,
" R:");
18026 strcat(blocking,
"M");
18028 strcat(blocking,
" ");
18032 strcat(blocking,
"H");
18034 strcat(blocking,
" ");
18048#if defined(HAVE_SS7)
18053 e->
command =
"ss7 show version";
18055 "Usage: ss7 show version\n"
18056 " Show the libss7 version\n";
18062 ast_cli(
a->fd,
"libss7 version: %s\n", ss7_get_version());
18068#if defined(HAVE_SS7)
18070 AST_CLI_DEFINE(handle_ss7_debug,
"Enables SS7 debugging on a linkset"),
18071 AST_CLI_DEFINE(handle_ss7_cic_blocking,
"Blocks/Unblocks the given CIC"),
18072 AST_CLI_DEFINE(handle_ss7_linkset_mng,
"Resets/Blocks/Unblocks all CICs on a linkset"),
18073 AST_CLI_DEFINE(handle_ss7_group_blocking,
"Blocks/Unblocks the given CIC range"),
18075 AST_CLI_DEFINE(handle_ss7_group_reset,
"Resets the given CIC range"),
18078 AST_CLI_DEFINE(handle_ss7_show_linkset,
"Shows the status of a linkset"),
18079 AST_CLI_DEFINE(handle_ss7_show_channels,
"Displays SS7 channel information"),
18086#if defined(HAVE_PRI)
18087#if defined(HAVE_PRI_CCSS)
18134#if defined(HAVE_PRI)
18135#if defined(HAVE_PRI_CCSS)
18147static void dahdi_pri_cc_agent_destructor(
struct ast_cc_agent *agent)
18156#if defined(HAVE_PRI)
18157#if defined(HAVE_PRI_CCSS)
18159 .
type = dahdi_pri_cc_type,
18160 .init = dahdi_pri_cc_agent_init,
18169 .destructor = dahdi_pri_cc_agent_destructor,
18174#if defined(HAVE_PRI)
18175#if defined(HAVE_PRI_CCSS)
18177 .
type = dahdi_pri_cc_type,
18191#if defined(HAVE_PRI) || defined(HAVE_SS7)
18198 pthread_cancel(pris[i].pri.
master);
18199 pthread_kill(pris[i].pri.
master, SIGURG);
18204#ifdef HAVE_PRI_PROG_W_CAUSE
18208#if defined(HAVE_SS7)
18211 pthread_cancel(linksets[i].ss7.
master);
18212 pthread_kill(linksets[i].ss7.
master, SIGURG);
18217#if defined(HAVE_OPENR2)
18218 dahdi_r2_destroy_links();
18234#if defined(HAVE_PRI)
18261#if defined(HAVE_PRI)
18267 dahdi_close_pri_fd(&(pris[i]), j);
18271#if defined(HAVE_PRI_CCSS)
18278#if defined(HAVE_SS7)
18284 dahdi_close_ss7_fd(&(linksets[i]), j);
18286 if (linksets[i].ss7.
ss7) {
18287 ss7_destroy(linksets[i].ss7.
ss7);
18288 linksets[i].ss7.ss7 =
NULL;
18304#if defined(HAVE_PRI) || defined(HAVE_SS7)
18311#if defined(HAVE_SS7)
18321 int x, start, finish;
18324 if ((
reload == 0) && (
conf->chan.sig < 0) && !
conf->is_sig_auto) {
18325 ast_log(
LOG_ERROR,
"Signalling must be specified before any channels are.\n");
18331 while ((chan =
strsep(&
c,
","))) {
18332 if (sscanf(chan,
"%30d-%30d", &start, &finish) == 2) {
18334 }
else if (sscanf(chan,
"%30d", &start)) {
18337 }
else if (!strcasecmp(chan,
"pseudo")) {
18343 if (finish < start) {
18350 for (x = start; x <= finish; x++) {
18351 if (
conf->wanted_channels_start &&
18352 (x < conf->wanted_channels_start ||
18353 x >
conf->wanted_channels_end)
18363 (
reload == 1) ?
"reconfigure" :
"register",
value);
18377#define MAX_CHANLIST_LEN 80
18382 char *
params[DAHDI_MAX_ECHOCANPARAMS + 1];
18383 unsigned int param_count;
18395 if ((x == 32) || (x == 64) || (x == 128) || (x == 256) || (x == 512) || (x == 1024))
18402 for (x = 1; x < param_count; x++) {
18409 ast_log(
LOG_WARNING,
"Invalid echocancel parameter supplied at line %u: '%s'\n", line, params[x]);
18414 ast_log(
LOG_WARNING,
"Invalid echocancel parameter supplied at line %u: '%s'\n", line, param.name);
18422 ast_log(
LOG_WARNING,
"Invalid echocancel parameter value supplied at line %u: '%s'\n", line, param.value);
18430#if defined(HAVE_PRI)
18431#if defined(HAVE_PRI_DISPLAY_TEXT)
18441static unsigned long dahdi_display_text_option(
const char *
value)
18451 opt_str =
strsep(&val_str,
",");
18460 if (!strcasecmp(opt_str,
"block")) {
18461 options |= PRI_DISPLAY_OPTION_BLOCK;
18462 }
else if (!strcasecmp(opt_str,
"name_initial")) {
18463 options |= PRI_DISPLAY_OPTION_NAME_INITIAL;
18464 }
else if (!strcasecmp(opt_str,
"name_update")) {
18465 options |= PRI_DISPLAY_OPTION_NAME_UPDATE;
18466 }
else if (!strcasecmp(opt_str,
"name")) {
18467 options |= (PRI_DISPLAY_OPTION_NAME_INITIAL | PRI_DISPLAY_OPTION_NAME_UPDATE);
18468 }
else if (!strcasecmp(opt_str,
"text")) {
18469 options |= PRI_DISPLAY_OPTION_TEXT;
18477#if defined(HAVE_PRI)
18478#if defined(HAVE_PRI_DATETIME_SEND)
18488static int dahdi_datetime_send_option(
const char *
value)
18492 option = PRI_DATE_TIME_SEND_DEFAULT;
18495 option = PRI_DATE_TIME_SEND_NO;
18496 }
else if (!strcasecmp(
value,
"date")) {
18497 option = PRI_DATE_TIME_SEND_DATE;
18498 }
else if (!strcasecmp(
value,
"date_hh")) {
18499 option = PRI_DATE_TIME_SEND_DATE_HH;
18500 }
else if (!strcasecmp(
value,
"date_hhmm")) {
18501 option = PRI_DATE_TIME_SEND_DATE_HHMM;
18502 }
else if (!strcasecmp(
value,
"date_hhmmss")) {
18503 option = PRI_DATE_TIME_SEND_DATE_HHMMSS;
18512#define PROC_DAHDI_OPT_NOCHAN (1 << 0)
18514#define PROC_DAHDI_OPT_NOWARN (1 << 1)
18518 int count_pattern = 0;
18524 if (!sscanf(v->
value,
"%30d", &norval) && count_pattern == 0) {
18525 ast_log(
LOG_ERROR,
"busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->
lineno);
18529 busy_cadence->
pattern[count_pattern] = norval;
18532 if (count_pattern == 4) {
18536 temp = strchr(v->
value,
',');
18537 if (temp ==
NULL) {
18540 v->
value = temp + 1;
18542 busy_cadence->
length = count_pattern;
18544 if (count_pattern % 2 != 0) {
18546 ast_log(
LOG_ERROR,
"busypattern= expects either busypattern=tonelength,quietlength or busypattern=t1length, q1length, t2length, q2length at line %d.\n", v->
lineno);
18560 for (; v; v = v->
next) {
18565 if (!strcasecmp(v->
name,
"channel") || !strcasecmp(v->
name,
"channels")) {
18579 }
else if (!strcasecmp(v->
name,
"ignore_failed_channels")) {
18581 }
else if (!strcasecmp(v->
name,
"buffers")) {
18587 }
else if (!strcasecmp(v->
name,
"faxbuffers")) {
18591 }
else if (!strcasecmp(v->
name,
"dahdichan")) {
18594 }
else if (!strcasecmp(v->
name,
"usedistinctiveringdetection")) {
18596 }
else if (!strcasecmp(v->
name,
"distinctiveringaftercid")) {
18598 }
else if (!strcasecmp(v->
name,
"dring1context")) {
18600 }
else if (!strcasecmp(v->
name,
"dring2context")) {
18602 }
else if (!strcasecmp(v->
name,
"dring3context")) {
18604 }
else if (!strcasecmp(v->
name,
"dring1range")) {
18606 }
else if (!strcasecmp(v->
name,
"dring2range")) {
18608 }
else if (!strcasecmp(v->
name,
"dring3range")) {
18610 }
else if (!strcasecmp(v->
name,
"dring1")) {
18612 }
else if (!strcasecmp(v->
name,
"dring2")) {
18614 }
else if (!strcasecmp(v->
name,
"dring3")) {
18616 }
else if (!strcasecmp(v->
name,
"usecallerid")) {
18618 }
else if (!strcasecmp(v->
name,
"cidsignalling")) {
18619 if (!strcasecmp(v->
value,
"bell"))
18621 else if (!strcasecmp(v->
value,
"v23"))
18623 else if (!strcasecmp(v->
value,
"dtmf"))
18625 else if (!strcasecmp(v->
value,
"smdi"))
18627 else if (!strcasecmp(v->
value,
"v23_jp"))
18631 }
else if (!strcasecmp(v->
name,
"cidstart")) {
18632 if (!strcasecmp(v->
value,
"ring"))
18634 else if (!strcasecmp(v->
value,
"polarity_in"))
18636 else if (!strcasecmp(v->
value,
"polarity"))
18638 else if (!strcasecmp(v->
value,
"dtmf"))
18642 }
else if (!strcasecmp(v->
name,
"threewaycalling")) {
18644 }
else if (!strcasecmp(v->
name,
"threewaysilenthold")) {
18646 }
else if (!strcasecmp(v->
name,
"cancallforward")) {
18648 }
else if (!strcasecmp(v->
name,
"relaxdtmf")) {
18653 }
else if (!strcasecmp(v->
name,
"mailbox")) {
18655 }
else if (!strcasecmp(v->
name,
"description")) {
18657 }
else if (!strcasecmp(v->
name,
"hasvoicemail")) {
18663 if (strchr(cat,
'@')) {
18667 "%s@default", cat);
18670 }
else if (!strcasecmp(v->
name,
"adsi")) {
18672 }
else if (!strcasecmp(v->
name,
"usesmdi")) {
18674 }
else if (!strcasecmp(v->
name,
"smdiport")) {
18676 }
else if (!strcasecmp(v->
name,
"transfer")) {
18678 }
else if (!strcasecmp(v->
name,
"canpark")) {
18680 }
else if (!strcasecmp(v->
name,
"echocancelwhenbridged")) {
18682 }
else if (!strcasecmp(v->
name,
"busydetect")) {
18684 }
else if (!strcasecmp(v->
name,
"busycount")) {
18686 }
else if (!strcasecmp(v->
name,
"busypattern")) {
18688 }
else if (!strcasecmp(v->
name,
"calledsubscriberheld")) {
18690 }
else if (!strcasecmp(v->
name,
"lastnumredial")) {
18692 }
else if (!strcasecmp(v->
name,
"callprogress")) {
18696 }
else if (!strcasecmp(v->
name,
"waitfordialtone")) {
18698 }
else if (!strcasecmp(v->
name,
"dialtone_detect")) {
18699 if (!strcasecmp(v->
value,
"always")) {
18708 }
else if (!strcasecmp(v->
name,
"faxdetect")) {
18710 if (!strcasecmp(v->
value,
"incoming")) {
18712 }
else if (!strcasecmp(v->
value,
"outgoing")) {
18716 }
else if (!strcasecmp(v->
name,
"faxdetect_timeout")) {
18720 }
else if (!strcasecmp(v->
name,
"firstdigit_timeout")) {
18725 }
else if (!strcasecmp(v->
name,
"interdigit_timeout")) {
18730 }
else if (!strcasecmp(v->
name,
"matchdigit_timeout")) {
18735 }
else if (!strcasecmp(v->
name,
"echocancel")) {
18737 }
else if (!strcasecmp(v->
name,
"echotraining")) {
18738 if (sscanf(v->
value,
"%30d", &y) == 1) {
18739 if ((y < 10) || (y > 4000)) {
18748 }
else if (!strcasecmp(v->
name,
"hidecallerid")) {
18750 }
else if (!strcasecmp(v->
name,
"hidecalleridname")) {
18752 }
else if (!strcasecmp(v->
name,
"pulsedial")) {
18754 }
else if (!strcasecmp(v->
name,
"callreturn")) {
18756 }
else if (!strcasecmp(v->
name,
"callwaiting")) {
18758 }
else if (!strcasecmp(v->
name,
"callwaitingcallerid")) {
18760 }
else if (!strcasecmp(v->
name,
"context")) {
18762 }
else if (!strcasecmp(v->
name,
"language")) {
18764 }
else if (!strcasecmp(v->
name,
"progzone")) {
18766 }
else if (!strcasecmp(v->
name,
"mohinterpret")
18767 ||!strcasecmp(v->
name,
"musiconhold") || !strcasecmp(v->
name,
"musicclass")) {
18769 }
else if (!strcasecmp(v->
name,
"mohsuggest")) {
18771 }
else if (!strcasecmp(v->
name,
"parkinglot")) {
18773 }
else if (!strcasecmp(v->
name,
"stripmsd")) {
18774 ast_log(
LOG_NOTICE,
"Configuration option \"%s\" has been deprecated. Please use dialplan instead\n", v->
name);
18776 }
else if (!strcasecmp(v->
name,
"jitterbuffers")) {
18778 }
else if (!strcasecmp(v->
name,
"group")) {
18780 }
else if (!strcasecmp(v->
name,
"callgroup")) {
18784 if (!strcasecmp(v->
value,
"none"))
18788 }
else if (!strcasecmp(v->
name,
"pickupgroup")) {
18792 if (!strcasecmp(v->
value,
"none"))
18796 }
else if (!strcasecmp(v->
name,
"namedcallgroup")) {
18798 ast_log(
LOG_WARNING,
"Only FXO signalled channels may belong to a named call group\n");
18801 }
else if (!strcasecmp(v->
name,
"namedpickupgroup")) {
18803 ast_log(
LOG_WARNING,
"Only FXO signalled channels may belong to a named pickup group\n");
18806 }
else if (!strcasecmp(v->
name,
"setvar")) {
18808 char *varval =
NULL;
18810 char varname[strlen(v->
value) + 1];
18811 strcpy(varname, v->
value);
18812 if ((varval = strchr(varname,
'='))) {
18822 }
else if (!strcasecmp(v->
name,
"immediate")) {
18824 }
else if (!strcasecmp(v->
name,
"immediatering")) {
18826 }
else if (!strcasecmp(v->
name,
"transfertobusy")) {
18828 }
else if (!strcasecmp(v->
name,
"dialmode")) {
18829 if (!strcasecmp(v->
value,
"pulse")) {
18831 }
else if (!strcasecmp(v->
value,
"dtmf") || !strcasecmp(v->
value,
"tone")) {
18833 }
else if (!strcasecmp(v->
value,
"none")) {
18838 }
else if (!strcasecmp(v->
name,
"mwimonitor")) {
18855 }
else if (!strcasecmp(v->
name,
"hwrxgain")) {
18857 if (strcasecmp(v->
value,
"disabled")) {
18864 }
else if (!strcasecmp(v->
name,
"hwtxgain")) {
18866 if (strcasecmp(v->
value,
"disabled")) {
18873 }
else if (!strcasecmp(v->
name,
"cid_rxgain")) {
18877 }
else if (!strcasecmp(v->
name,
"rxgain")) {
18881 }
else if (!strcasecmp(v->
name,
"txgain")) {
18885 }
else if (!strcasecmp(v->
name,
"txdrc")) {
18889 }
else if (!strcasecmp(v->
name,
"rxdrc")) {
18893 }
else if (!strcasecmp(v->
name,
"tonezone")) {
18897 }
else if (!strcasecmp(v->
name,
"callerid")) {
18898 if (!strcasecmp(v->
value,
"asreceived")) {
18904 }
else if (!strcasecmp(v->
name,
"fullname")) {
18906 }
else if (!strcasecmp(v->
name,
"cid_number")) {
18908 }
else if (!strcasecmp(v->
name,
"cid_tag")) {
18910 }
else if (!strcasecmp(v->
name,
"useincomingcalleridondahditransfer")) {
18912 }
else if (!strcasecmp(v->
name,
"restrictcid")) {
18914 }
else if (!strcasecmp(v->
name,
"usecallingpres")) {
18916 }
else if (!strcasecmp(v->
name,
"accountcode")) {
18918 }
else if (!strcasecmp(v->
name,
"amaflags")) {
18924 }
else if (!strcasecmp(v->
name,
"polarityonanswerdelay")) {
18926 }
else if (!strcasecmp(v->
name,
"answeronpolarityswitch")) {
18928 }
else if (!strcasecmp(v->
name,
"ani_info_digits")) {
18930 }
else if (!strcasecmp(v->
name,
"ani_wink_time")) {
18932 }
else if (!strcasecmp(v->
name,
"ani_timeout")) {
18934 }
else if (!strcasecmp(v->
name,
"hanguponpolarityswitch")) {
18936 }
else if (!strcasecmp(v->
name,
"autoreoriginate")) {
18938 }
else if (!strcasecmp(v->
name,
"sendcalleridafter")) {
18940 }
else if (!strcasecmp(v->
name,
"mwimonitornotify")) {
18944 }
else if (!strcasecmp(v->
name,
"mwisendtype")) {
18945#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
18946 if (!strcasecmp(v->
value,
"rpas")) {
18953 memset(&confp->
chan.mwisend_setting, 0,
sizeof(confp->
chan.mwisend_setting));
18955 confp->
chan.mwisend_fsk = 0;
18957 confp->
chan.mwisend_fsk = 1;
18960 confp->
chan.mwisend_rpas = 1;
18962 confp->
chan.mwisend_rpas = 0;
18965 confp->
chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_LREV;
18968 confp->
chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVDC;
18971 confp->
chan.mwisend_setting.vmwi_type |= DAHDI_VMWI_HVAC;
18974 }
else if (
reload != 1) {
18975 if (!strcasecmp(v->
name,
"signalling") || !strcasecmp(v->
name,
"signaling")) {
18983 if (!strcasecmp(v->
value,
"em")) {
18985 }
else if (!strcasecmp(v->
value,
"em_e1")) {
18987 }
else if (!strcasecmp(v->
value,
"em_w")) {
18989 }
else if (!strcasecmp(v->
value,
"fxs_ls")) {
18991 }
else if (!strcasecmp(v->
value,
"fxs_gs")) {
18993 }
else if (!strcasecmp(v->
value,
"fxs_ks")) {
18995 }
else if (!strcasecmp(v->
value,
"fxo_ls")) {
18997 }
else if (!strcasecmp(v->
value,
"fxo_gs")) {
18999 }
else if (!strcasecmp(v->
value,
"fxo_ks")) {
19001 }
else if (!strcasecmp(v->
value,
"fxs_rx")) {
19004 }
else if (!strcasecmp(v->
value,
"fxo_rx")) {
19007 }
else if (!strcasecmp(v->
value,
"fxs_tx")) {
19010 }
else if (!strcasecmp(v->
value,
"fxo_tx")) {
19013 }
else if (!strcasecmp(v->
value,
"em_rx")) {
19016 }
else if (!strcasecmp(v->
value,
"em_tx")) {
19019 }
else if (!strcasecmp(v->
value,
"em_rxtx")) {
19022 }
else if (!strcasecmp(v->
value,
"em_txrx")) {
19025 }
else if (!strcasecmp(v->
value,
"sf")) {
19027 }
else if (!strcasecmp(v->
value,
"sf_w")) {
19029 }
else if (!strcasecmp(v->
value,
"sf_featd")) {
19031 }
else if (!strcasecmp(v->
value,
"sf_featdmf")) {
19033 }
else if (!strcasecmp(v->
value,
"sf_featb")) {
19035 }
else if (!strcasecmp(v->
value,
"sf")) {
19037 }
else if (!strcasecmp(v->
value,
"sf_rx")) {
19040 }
else if (!strcasecmp(v->
value,
"sf_tx")) {
19043 }
else if (!strcasecmp(v->
value,
"sf_rxtx")) {
19046 }
else if (!strcasecmp(v->
value,
"sf_txrx")) {
19049 }
else if (!strcasecmp(v->
value,
"featd")) {
19051 }
else if (!strcasecmp(v->
value,
"featdmf")) {
19053 }
else if (!strcasecmp(v->
value,
"featdmf_ta")) {
19055 }
else if (!strcasecmp(v->
value,
"e911")) {
19057 }
else if (!strcasecmp(v->
value,
"fgccama")) {
19059 }
else if (!strcasecmp(v->
value,
"fgccamamf")) {
19061 }
else if (!strcasecmp(v->
value,
"featb")) {
19064 }
else if (!strcasecmp(v->
value,
"pri_net")) {
19066 confp->pri.pri.nodetype = PRI_NETWORK;
19067 }
else if (!strcasecmp(v->
value,
"pri_cpe")) {
19069 confp->pri.pri.nodetype = PRI_CPE;
19070 }
else if (!strcasecmp(v->
value,
"bri_cpe")) {
19072 confp->pri.pri.nodetype = PRI_CPE;
19073 }
else if (!strcasecmp(v->
value,
"bri_net")) {
19075 confp->pri.pri.nodetype = PRI_NETWORK;
19076 }
else if (!strcasecmp(v->
value,
"bri_cpe_ptmp")) {
19078 confp->pri.pri.nodetype = PRI_CPE;
19079 }
else if (!strcasecmp(v->
value,
"bri_net_ptmp")) {
19080#if defined(HAVE_PRI_CALL_HOLD)
19082 confp->pri.pri.nodetype = PRI_NETWORK;
19084 ast_log(
LOG_WARNING,
"How cool would it be if someone implemented this mode! For now, sucks for you. (line %d)\n", v->
lineno);
19087#if defined(HAVE_SS7)
19088 }
else if (!strcasecmp(v->
value,
"ss7")) {
19092 }
else if (!strcasecmp(v->
value,
"mfcr2")) {
19095 }
else if (!strcasecmp(v->
value,
"auto")) {
19103 }
else if (!strcasecmp(v->
name,
"outsignalling") || !strcasecmp(v->
name,
"outsignaling")) {
19104 if (!strcasecmp(v->
value,
"em")) {
19106 }
else if (!strcasecmp(v->
value,
"em_e1")) {
19108 }
else if (!strcasecmp(v->
value,
"em_w")) {
19110 }
else if (!strcasecmp(v->
value,
"sf")) {
19112 }
else if (!strcasecmp(v->
value,
"sf_w")) {
19114 }
else if (!strcasecmp(v->
value,
"sf_featd")) {
19116 }
else if (!strcasecmp(v->
value,
"sf_featdmf")) {
19118 }
else if (!strcasecmp(v->
value,
"sf_featb")) {
19120 }
else if (!strcasecmp(v->
value,
"sf")) {
19122 }
else if (!strcasecmp(v->
value,
"featd")) {
19124 }
else if (!strcasecmp(v->
value,
"featdmf")) {
19126 }
else if (!strcasecmp(v->
value,
"featdmf_ta")) {
19128 }
else if (!strcasecmp(v->
value,
"e911")) {
19130 }
else if (!strcasecmp(v->
value,
"fgccama")) {
19132 }
else if (!strcasecmp(v->
value,
"fgccamamf")) {
19134 }
else if (!strcasecmp(v->
value,
"featb")) {
19140 }
else if (!strcasecmp(v->
name,
"pridialplan")) {
19141 if (!strcasecmp(v->
value,
"national")) {
19142 confp->pri.pri.dialplan = PRI_NATIONAL_ISDN + 1;
19143 }
else if (!strcasecmp(v->
value,
"unknown")) {
19144 confp->pri.pri.dialplan = PRI_UNKNOWN + 1;
19145 }
else if (!strcasecmp(v->
value,
"private")) {
19146 confp->pri.pri.dialplan = PRI_PRIVATE + 1;
19147 }
else if (!strcasecmp(v->
value,
"international")) {
19148 confp->pri.pri.dialplan = PRI_INTERNATIONAL_ISDN + 1;
19149 }
else if (!strcasecmp(v->
value,
"local")) {
19150 confp->pri.pri.dialplan = PRI_LOCAL_ISDN + 1;
19151 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19152 confp->pri.pri.dialplan = -1;
19153 }
else if (!strcasecmp(v->
value,
"redundant")) {
19154 confp->pri.pri.dialplan = -2;
19158 }
else if (!strcasecmp(v->
name,
"prilocaldialplan")) {
19159 if (!strcasecmp(v->
value,
"national")) {
19160 confp->pri.pri.localdialplan = PRI_NATIONAL_ISDN + 1;
19161 }
else if (!strcasecmp(v->
value,
"unknown")) {
19162 confp->pri.pri.localdialplan = PRI_UNKNOWN + 1;
19163 }
else if (!strcasecmp(v->
value,
"private")) {
19164 confp->pri.pri.localdialplan = PRI_PRIVATE + 1;
19165 }
else if (!strcasecmp(v->
value,
"international")) {
19166 confp->pri.pri.localdialplan = PRI_INTERNATIONAL_ISDN + 1;
19167 }
else if (!strcasecmp(v->
value,
"local")) {
19168 confp->pri.pri.localdialplan = PRI_LOCAL_ISDN + 1;
19169 }
else if (!strcasecmp(v->
value,
"from_channel")) {
19170 confp->pri.pri.localdialplan = 0;
19171 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19172 confp->pri.pri.localdialplan = -1;
19173 }
else if (!strcasecmp(v->
value,
"redundant")) {
19174 confp->pri.pri.localdialplan = -2;
19178 }
else if (!strcasecmp(v->
name,
"pricpndialplan")) {
19179 if (!strcasecmp(v->
value,
"national")) {
19180 confp->pri.pri.cpndialplan = PRI_NATIONAL_ISDN + 1;
19181 }
else if (!strcasecmp(v->
value,
"unknown")) {
19182 confp->pri.pri.cpndialplan = PRI_UNKNOWN + 1;
19183 }
else if (!strcasecmp(v->
value,
"private")) {
19184 confp->pri.pri.cpndialplan = PRI_PRIVATE + 1;
19185 }
else if (!strcasecmp(v->
value,
"international")) {
19186 confp->pri.pri.cpndialplan = PRI_INTERNATIONAL_ISDN + 1;
19187 }
else if (!strcasecmp(v->
value,
"local")) {
19188 confp->pri.pri.cpndialplan = PRI_LOCAL_ISDN + 1;
19189 }
else if (!strcasecmp(v->
value,
"from_channel")) {
19190 confp->pri.pri.cpndialplan = 0;
19191 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19192 confp->pri.pri.cpndialplan = -1;
19193 }
else if (!strcasecmp(v->
value,
"redundant")) {
19194 confp->pri.pri.cpndialplan = -2;
19198 }
else if (!strcasecmp(v->
name,
"switchtype")) {
19199 if (!strcasecmp(v->
value,
"national"))
19200 confp->pri.pri.switchtype = PRI_SWITCH_NI2;
19201 else if (!strcasecmp(v->
value,
"ni1"))
19202 confp->pri.pri.switchtype = PRI_SWITCH_NI1;
19203 else if (!strcasecmp(v->
value,
"dms100"))
19204 confp->pri.pri.switchtype = PRI_SWITCH_DMS100;
19205 else if (!strcasecmp(v->
value,
"4ess"))
19206 confp->pri.pri.switchtype = PRI_SWITCH_ATT4ESS;
19207 else if (!strcasecmp(v->
value,
"5ess"))
19208 confp->pri.pri.switchtype = PRI_SWITCH_LUCENT5E;
19209 else if (!strcasecmp(v->
value,
"euroisdn"))
19210 confp->pri.pri.switchtype = PRI_SWITCH_EUROISDN_E1;
19211 else if (!strcasecmp(v->
value,
"qsig"))
19212 confp->pri.pri.switchtype = PRI_SWITCH_QSIG;
19217 }
else if (!strcasecmp(v->
name,
"msn")) {
19219 sizeof(confp->pri.pri.msn_list));
19220 }
else if (!strcasecmp(v->
name,
"nsf")) {
19221 if (!strcasecmp(v->
value,
"sdn"))
19222 confp->pri.pri.nsf = PRI_NSF_SDN;
19223 else if (!strcasecmp(v->
value,
"megacom"))
19224 confp->pri.pri.nsf = PRI_NSF_MEGACOM;
19225 else if (!strcasecmp(v->
value,
"tollfreemegacom"))
19226 confp->pri.pri.nsf = PRI_NSF_TOLL_FREE_MEGACOM;
19227 else if (!strcasecmp(v->
value,
"accunet"))
19228 confp->pri.pri.nsf = PRI_NSF_ACCUNET;
19229 else if (!strcasecmp(v->
value,
"none"))
19230 confp->pri.pri.nsf = PRI_NSF_NONE;
19233 confp->pri.pri.nsf = PRI_NSF_NONE;
19235 }
else if (!strcasecmp(v->
name,
"priindication")) {
19236 if (!strcasecmp(v->
value,
"outofband"))
19238 else if (!strcasecmp(v->
value,
"inband"))
19241 ast_log(
LOG_WARNING,
"'%s' is not a valid pri indication value, should be 'inband' or 'outofband' at line %d.\n",
19243 }
else if (!strcasecmp(v->
name,
"priexclusive")) {
19245 }
else if (!strcasecmp(v->
name,
"internationalprefix")) {
19246 ast_copy_string(confp->pri.pri.internationalprefix, v->
value,
sizeof(confp->pri.pri.internationalprefix));
19247 }
else if (!strcasecmp(v->
name,
"nationalprefix")) {
19248 ast_copy_string(confp->pri.pri.nationalprefix, v->
value,
sizeof(confp->pri.pri.nationalprefix));
19249 }
else if (!strcasecmp(v->
name,
"localprefix")) {
19251 }
else if (!strcasecmp(v->
name,
"privateprefix")) {
19252 ast_copy_string(confp->pri.pri.privateprefix, v->
value,
sizeof(confp->pri.pri.privateprefix));
19253 }
else if (!strcasecmp(v->
name,
"unknownprefix")) {
19254 ast_copy_string(confp->pri.pri.unknownprefix, v->
value,
sizeof(confp->pri.pri.unknownprefix));
19255 }
else if (!strcasecmp(v->
name,
"resetinterval")) {
19256 if (!strcasecmp(v->
value,
"never"))
19257 confp->pri.pri.resetinterval = -1;
19258 else if (atoi(v->
value) >= 60)
19259 confp->pri.pri.resetinterval = atoi(v->
value);
19261 ast_log(
LOG_WARNING,
"'%s' is not a valid reset interval, should be >= 60 seconds or 'never' at line %d.\n",
19263 }
else if (!strcasecmp(v->
name,
"force_restart_unavailable_chans")) {
19264 confp->pri.pri.force_restart_unavailable_chans =
ast_true(v->
value);
19265 }
else if (!strcasecmp(v->
name,
"minunused")) {
19266 confp->pri.pri.minunused = atoi(v->
value);
19267 }
else if (!strcasecmp(v->
name,
"minidle")) {
19268 confp->pri.pri.minidle = atoi(v->
value);
19269 }
else if (!strcasecmp(v->
name,
"idleext")) {
19271 }
else if (!strcasecmp(v->
name,
"idledial")) {
19273 }
else if (!strcasecmp(v->
name,
"overlapdial")) {
19276 }
else if (!strcasecmp(v->
value,
"incoming")) {
19278 }
else if (!strcasecmp(v->
value,
"outgoing")) {
19285#ifdef HAVE_PRI_PROG_W_CAUSE
19286 }
else if (!strcasecmp(v->
name,
"qsigchannelmapping")) {
19287 if (!strcasecmp(v->
value,
"logical")) {
19289 }
else if (!strcasecmp(v->
value,
"physical")) {
19295 }
else if (!strcasecmp(v->
name,
"discardremoteholdretrieval")) {
19296 confp->pri.pri.discardremoteholdretrieval =
ast_true(v->
value);
19297#if defined(HAVE_PRI_SERVICE_MESSAGES)
19298 }
else if (!strcasecmp(v->
name,
"service_message_support")) {
19300 if ((confp->pri.pri.switchtype == PRI_SWITCH_ATT4ESS
19301 || confp->pri.pri.switchtype == PRI_SWITCH_LUCENT5E
19302 || confp->pri.pri.switchtype == PRI_SWITCH_NI2) &&
ast_true(v->
value)) {
19303 confp->pri.pri.enable_service_message_support = 1;
19305 confp->pri.pri.enable_service_message_support = 0;
19308#ifdef HAVE_PRI_INBANDDISCONNECT
19309 }
else if (!strcasecmp(v->
name,
"inbanddisconnect")) {
19312 }
else if (!strcasecmp(v->
name,
"pritimer")) {
19313#ifdef PRI_GETSET_TIMERS
19324 timeridx = pri_timer2idx(timerc);
19326 if (timeridx < 0 || PRI_MAX_TIMERS <= timeridx) {
19328 "'%s' is not a valid ISDN timer at line %d.\n", timerc,
19330 }
else if (!
timer) {
19332 "'%s' is not a valid value for ISDN timer '%s' at line %d.\n",
19335 confp->pri.pri.pritimers[timeridx] =
timer;
19339 "'%s' is not a valid ISDN timer configuration string at line %d.\n",
19343 }
else if (!strcasecmp(v->
name,
"facilityenable")) {
19345#if defined(HAVE_PRI_AOC_EVENTS)
19346 }
else if (!strcasecmp(v->
name,
"aoc_enable")) {
19347 confp->pri.pri.aoc_passthrough_flag = 0;
19348 if (strchr(v->
value,
's') || strchr(v->
value,
'S')) {
19351 if (strchr(v->
value,
'd') || strchr(v->
value,
'D')) {
19354 if (strchr(v->
value,
'e') || strchr(v->
value,
'E')) {
19357 }
else if (!strcasecmp(v->
name,
"aoce_delayhangup")) {
19360#if defined(HAVE_PRI_CALL_HOLD)
19361 }
else if (!strcasecmp(v->
name,
"hold_disconnect_transfer")) {
19362 confp->pri.pri.hold_disconnect_transfer =
ast_true(v->
value);
19364 }
else if (!strcasecmp(v->
name,
"moh_signaling")
19365 || !strcasecmp(v->
name,
"moh_signalling")) {
19366 if (!strcasecmp(v->
value,
"moh")) {
19368 }
else if (!strcasecmp(v->
value,
"notify")) {
19370#if defined(HAVE_PRI_CALL_HOLD)
19371 }
else if (!strcasecmp(v->
value,
"hold")) {
19372 confp->pri.pri.moh_signaling = SIG_PRI_MOH_SIGNALING_HOLD;
19377#if defined(HAVE_PRI_CCSS)
19378 }
else if (!strcasecmp(v->
name,
"cc_ptmp_recall_mode")) {
19379 if (!strcasecmp(v->
value,
"global")) {
19380 confp->pri.pri.cc_ptmp_recall_mode = 0;
19381 }
else if (!strcasecmp(v->
value,
"specific")) {
19382 confp->pri.pri.cc_ptmp_recall_mode = 1;
19384 confp->pri.pri.cc_ptmp_recall_mode = 1;
19386 }
else if (!strcasecmp(v->
name,
"cc_qsig_signaling_link_req")) {
19387 if (!strcasecmp(v->
value,
"release")) {
19388 confp->pri.pri.cc_qsig_signaling_link_req = 0;
19389 }
else if (!strcasecmp(v->
value,
"retain")) {
19390 confp->pri.pri.cc_qsig_signaling_link_req = 1;
19391 }
else if (!strcasecmp(v->
value,
"do_not_care")) {
19392 confp->pri.pri.cc_qsig_signaling_link_req = 2;
19394 confp->pri.pri.cc_qsig_signaling_link_req = 1;
19396 }
else if (!strcasecmp(v->
name,
"cc_qsig_signaling_link_rsp")) {
19397 if (!strcasecmp(v->
value,
"release")) {
19398 confp->pri.pri.cc_qsig_signaling_link_rsp = 0;
19399 }
else if (!strcasecmp(v->
value,
"retain")) {
19400 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;
19402 confp->pri.pri.cc_qsig_signaling_link_rsp = 1;
19405#if defined(HAVE_PRI_CALL_WAITING)
19406 }
else if (!strcasecmp(v->
name,
"max_call_waiting_calls")) {
19407 confp->pri.pri.max_call_waiting_calls = atoi(v->
value);
19408 if (confp->pri.pri.max_call_waiting_calls < 0) {
19410 confp->pri.pri.max_call_waiting_calls = 0;
19412 }
else if (!strcasecmp(v->
name,
"allow_call_waiting_calls")) {
19413 confp->pri.pri.allow_call_waiting_calls =
ast_true(v->
value);
19415#if defined(HAVE_PRI_MWI)
19416 }
else if (!strcasecmp(v->
name,
"mwi_mailboxes")) {
19418 sizeof(confp->pri.pri.mwi_mailboxes));
19419 }
else if (!strcasecmp(v->
name,
"mwi_vm_boxes")) {
19421 sizeof(confp->pri.pri.mwi_vm_boxes));
19422 }
else if (!strcasecmp(v->
name,
"mwi_vm_numbers")) {
19424 sizeof(confp->pri.pri.mwi_vm_numbers));
19426 }
else if (!strcasecmp(v->
name,
"append_msn_to_cid_tag")) {
19427 confp->pri.pri.append_msn_to_user_tag =
ast_true(v->
value);
19428 }
else if (!strcasecmp(v->
name,
"inband_on_setup_ack")) {
19430 }
else if (!strcasecmp(v->
name,
"inband_on_proceeding")) {
19432#if defined(HAVE_PRI_DISPLAY_TEXT)
19433 }
else if (!strcasecmp(v->
name,
"display_send")) {
19434 confp->pri.pri.display_flags_send = dahdi_display_text_option(v->
value);
19435 }
else if (!strcasecmp(v->
name,
"display_receive")) {
19436 confp->pri.pri.display_flags_receive = dahdi_display_text_option(v->
value);
19438#if defined(HAVE_PRI_MCID)
19439 }
else if (!strcasecmp(v->
name,
"mcid_send")) {
19442#if defined(HAVE_PRI_DATETIME_SEND)
19443 }
else if (!strcasecmp(v->
name,
"datetime_send")) {
19444 confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->
value);
19446 }
else if (!strcasecmp(v->
name,
"layer1_presence")) {
19447 if (!strcasecmp(v->
value,
"required")) {
19448 confp->pri.pri.layer1_ignored = 0;
19449 }
else if (!strcasecmp(v->
value,
"ignore")) {
19450 confp->pri.pri.layer1_ignored = 1;
19453 confp->pri.pri.layer1_ignored = 0;
19455#if defined(HAVE_PRI_L2_PERSISTENCE)
19456 }
else if (!strcasecmp(v->
name,
"layer2_persistence")) {
19457 if (!strcasecmp(v->
value,
"keep_up")) {
19458 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_KEEP_UP;
19459 }
else if (!strcasecmp(v->
value,
"leave_down")) {
19460 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_LEAVE_DOWN;
19462 confp->pri.pri.l2_persistence = PRI_L2_PERSISTENCE_DEFAULT;
19465 }
else if (!strcasecmp(v->
name,
"colp_send")) {
19466 if (!strcasecmp(v->
value,
"block")) {
19468 }
else if (!strcasecmp(v->
value,
"connect")) {
19470 }
else if (!strcasecmp(v->
value,
"update")) {
19476#if defined(HAVE_SS7)
19477 }
else if (!strcasecmp(v->
name,
"ss7type")) {
19478 if (!strcasecmp(v->
value,
"itu")) {
19479 cur_ss7type = SS7_ITU;
19480 }
else if (!strcasecmp(v->
value,
"ansi")) {
19481 cur_ss7type = SS7_ANSI;
19485 }
else if (!strcasecmp(v->
name,
"slc")) {
19486 cur_slc = atoi(v->
value);
19487 }
else if (!strcasecmp(v->
name,
"linkset")) {
19488 cur_linkset = atoi(v->
value);
19489 }
else if (!strcasecmp(v->
name,
"pointcode")) {
19490 cur_pointcode = parse_pointcode(v->
value);
19491 }
else if (!strcasecmp(v->
name,
"adjpointcode")) {
19492 cur_adjpointcode = parse_pointcode(v->
value);
19493 }
else if (!strcasecmp(v->
name,
"defaultdpc")) {
19494 cur_defaultdpc = parse_pointcode(v->
value);
19495 }
else if (!strcasecmp(v->
name,
"cicbeginswith")) {
19496 cur_cicbeginswith = atoi(v->
value);
19497 }
else if (!strcasecmp(v->
name,
"networkindicator")) {
19498 if (!strcasecmp(v->
value,
"national")) {
19499 cur_networkindicator = SS7_NI_NAT;
19500 }
else if (!strcasecmp(v->
value,
"national_spare")) {
19501 cur_networkindicator = SS7_NI_NAT_SPARE;
19502 }
else if (!strcasecmp(v->
value,
"international")) {
19503 cur_networkindicator = SS7_NI_INT;
19504 }
else if (!strcasecmp(v->
value,
"international_spare")) {
19505 cur_networkindicator = SS7_NI_INT_SPARE;
19507 cur_networkindicator = -1;
19509 }
else if (!strcasecmp(v->
name,
"ss7_internationalprefix")) {
19510 ast_copy_string(confp->ss7.ss7.internationalprefix, v->
value,
sizeof(confp->ss7.ss7.internationalprefix));
19511 }
else if (!strcasecmp(v->
name,
"ss7_nationalprefix")) {
19512 ast_copy_string(confp->ss7.ss7.nationalprefix, v->
value,
sizeof(confp->ss7.ss7.nationalprefix));
19513 }
else if (!strcasecmp(v->
name,
"ss7_subscriberprefix")) {
19514 ast_copy_string(confp->ss7.ss7.subscriberprefix, v->
value,
sizeof(confp->ss7.ss7.subscriberprefix));
19515 }
else if (!strcasecmp(v->
name,
"ss7_unknownprefix")) {
19516 ast_copy_string(confp->ss7.ss7.unknownprefix, v->
value,
sizeof(confp->ss7.ss7.unknownprefix));
19517 }
else if (!strcasecmp(v->
name,
"ss7_networkroutedprefix")) {
19518 ast_copy_string(confp->ss7.ss7.networkroutedprefix, v->
value,
sizeof(confp->ss7.ss7.networkroutedprefix));
19519 }
else if (!strcasecmp(v->
name,
"ss7_called_nai")) {
19520 if (!strcasecmp(v->
value,
"national")) {
19521 confp->ss7.ss7.called_nai = SS7_NAI_NATIONAL;
19522 }
else if (!strcasecmp(v->
value,
"international")) {
19523 confp->ss7.ss7.called_nai = SS7_NAI_INTERNATIONAL;
19524 }
else if (!strcasecmp(v->
value,
"subscriber")) {
19525 confp->ss7.ss7.called_nai = SS7_NAI_SUBSCRIBER;
19526 }
else if (!strcasecmp(v->
value,
"unknown")) {
19527 confp->ss7.ss7.called_nai = SS7_NAI_UNKNOWN;
19528 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19533 }
else if (!strcasecmp(v->
name,
"ss7_calling_nai")) {
19534 if (!strcasecmp(v->
value,
"national")) {
19535 confp->ss7.ss7.calling_nai = SS7_NAI_NATIONAL;
19536 }
else if (!strcasecmp(v->
value,
"international")) {
19537 confp->ss7.ss7.calling_nai = SS7_NAI_INTERNATIONAL;
19538 }
else if (!strcasecmp(v->
value,
"subscriber")) {
19539 confp->ss7.ss7.calling_nai = SS7_NAI_SUBSCRIBER;
19540 }
else if (!strcasecmp(v->
value,
"unknown")) {
19541 confp->ss7.ss7.calling_nai = SS7_NAI_UNKNOWN;
19542 }
else if (!strcasecmp(v->
value,
"dynamic")) {
19547 }
else if (!strcasecmp(v->
name,
"sigchan")) {
19549 sigchan = atoi(v->
value);
19550 res = linkset_addsigchan(sigchan);
19554 }
else if (!strcasecmp(v->
name,
"ss7_explicitacm")) {
19555 struct dahdi_ss7 *link;
19556 link = ss7_resolve_linkset(cur_linkset);
19564 link->ss7.flags &= ~LINKSET_FLAG_EXPLICITACM;
19566 }
else if (!strcasecmp(v->
name,
"ss7_autoacm")) {
19567 struct dahdi_ss7 *link;
19568 link = ss7_resolve_linkset(cur_linkset);
19576 link->ss7.flags &= ~LINKSET_FLAG_AUTOACM;
19578 }
else if (!strcasecmp(v->
name,
"ss7_initialhwblo")) {
19579 struct dahdi_ss7 *link;
19580 link = ss7_resolve_linkset(cur_linkset);
19588 link->ss7.flags &= ~LINKSET_FLAG_INITIALHWBLO;
19590 }
else if (!strcasecmp(v->
name,
"ss7_use_echocontrol")) {
19591 struct dahdi_ss7 *link;
19592 link = ss7_resolve_linkset(cur_linkset);
19600 link->ss7.flags &= ~LINKSET_FLAG_USEECHOCONTROL;
19602 }
else if (!strcasecmp(v->
name,
"ss7_default_echocontrol")) {
19603 struct dahdi_ss7 *link;
19604 link = ss7_resolve_linkset(cur_linkset);
19612 link->ss7.flags &= ~LINKSET_FLAG_DEFAULTECHOCONTROL;
19614 }
else if (!strncasecmp(v->
name,
"isup_timer.", 11)) {
19615 struct dahdi_ss7 *link;
19616 link = ss7_resolve_linkset(cur_linkset);
19621 if (!link->ss7.ss7) {
19623 }
else if (!ss7_set_isup_timer(link->ss7.ss7, strstr(v->
name,
".") + 1, atoi(v->
value))) {
19626 }
else if (!strncasecmp(v->
name,
"mtp3_timer.", 11)) {
19627 struct dahdi_ss7 *link;
19628 link = ss7_resolve_linkset(cur_linkset);
19633 if (!link->ss7.ss7) {
19635 }
else if (!ss7_set_mtp3_timer(link->ss7.ss7, strstr(v->
name,
".") + 1, atoi(v->
value))) {
19638 }
else if (!strcasecmp(v->
name,
"inr_if_no_calling")) {
19639 struct dahdi_ss7 *link;
19640 link = ss7_resolve_linkset(cur_linkset);
19645 if (!link->ss7.ss7) {
19648 ss7_set_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
19650 ss7_clear_flags(link->ss7.ss7, SS7_INR_IF_NO_CALLING);
19652 }
else if (!strcasecmp(v->
name,
"non_isdn_access")) {
19653 struct dahdi_ss7 *link;
19654 link = ss7_resolve_linkset(cur_linkset);
19659 if (!link->ss7.ss7) {
19662 ss7_clear_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
19664 ss7_set_flags(link->ss7.ss7, SS7_ISDN_ACCESS_INDICATOR);
19666 }
else if (!strcasecmp(v->
name,
"sls_shift")) {
19667 struct dahdi_ss7 *link;
19668 int sls_shift = atoi(v->
value);
19670 if (sls_shift < 0 || sls_shift > 7) {
19675 link = ss7_resolve_linkset(cur_linkset);
19680 if (!link->ss7.ss7) {
19683 ss7_set_sls_shift(link->ss7.ss7, sls_shift);
19685 }
else if (!strcasecmp(v->
name,
"cause_location")) {
19686 struct dahdi_ss7 *link;
19687 int cause_location = atoi(v->
value);
19689 if (cause_location < 0 || cause_location > 15) {
19690 ast_log(
LOG_ERROR,
"Invalid cause_location value. Must be between 0 and 15\n");
19693 link = ss7_resolve_linkset(cur_linkset);
19698 if (!link->ss7.ss7) {
19701 ss7_set_cause_location(link->ss7.ss7, cause_location);
19705 }
else if (!strcasecmp(v->
name,
"mfcr2_advanced_protocol_file")) {
19707 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);
19708 }
else if (!strcasecmp(v->
name,
"mfcr2_logdir")) {
19710 }
else if (!strcasecmp(v->
name,
"mfcr2_variant")) {
19711 confp->mfcr2.variant = openr2_proto_get_variant(v->
value);
19712 if (OR2_VAR_UNKNOWN == confp->mfcr2.variant) {
19714 confp->mfcr2.variant = OR2_VAR_ITU;
19716 }
else if (!strcasecmp(v->
name,
"mfcr2_mfback_timeout")) {
19717 confp->mfcr2.mfback_timeout = atoi(v->
value);
19718 if (!confp->mfcr2.mfback_timeout) {
19719 ast_log(
LOG_WARNING,
"MF timeout of 0? hum, I will protect you from your ignorance. Setting default.\n");
19720 confp->mfcr2.mfback_timeout = -1;
19721 }
else if (confp->mfcr2.mfback_timeout > 0 && confp->mfcr2.mfback_timeout < 500) {
19722 ast_log(
LOG_WARNING,
"MF timeout less than 500ms is not recommended, you have been warned!\n");
19724 }
else if (!strcasecmp(v->
name,
"mfcr2_metering_pulse_timeout")) {
19725 confp->mfcr2.metering_pulse_timeout = atoi(v->
value);
19726 if (confp->mfcr2.metering_pulse_timeout > 500) {
19727 ast_log(
LOG_WARNING,
"Metering pulse timeout greater than 500ms is not recommended, you have been warned!\n");
19729#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
19730 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_detection")) {
19732 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_dialing")) {
19734 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_time_on")) {
19735 confp->mfcr2.dtmf_time_on = atoi(v->
value);
19736 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_time_off")) {
19737 confp->mfcr2.dtmf_time_off = atoi(v->
value);
19739#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
19740 }
else if (!strcasecmp(v->
name,
"mfcr2_dtmf_end_timeout")) {
19741 confp->mfcr2.dtmf_end_timeout = atoi(v->
value);
19743 }
else if (!strcasecmp(v->
name,
"mfcr2_get_ani_first")) {
19745 }
else if (!strcasecmp(v->
name,
"mfcr2_double_answer")) {
19747 }
else if (!strcasecmp(v->
name,
"mfcr2_charge_calls")) {
19749 }
else if (!strcasecmp(v->
name,
"mfcr2_accept_on_offer")) {
19751 }
else if (!strcasecmp(v->
name,
"mfcr2_allow_collect_calls")) {
19752 confp->mfcr2.allow_collect_calls =
ast_true(v->
value) ? 1 : 0;
19753 }
else if (!strcasecmp(v->
name,
"mfcr2_forced_release")) {
19755 }
else if (!strcasecmp(v->
name,
"mfcr2_immediate_accept")) {
19756 confp->mfcr2.immediate_accept =
ast_true(v->
value) ? 1 : 0;
19757#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
19758 }
else if (!strcasecmp(v->
name,
"mfcr2_skip_category")) {
19759 confp->mfcr2.skip_category_request =
ast_true(v->
value) ? 1 : 0;
19761 }
else if (!strcasecmp(v->
name,
"mfcr2_call_files")) {
19763 }
else if (!strcasecmp(v->
name,
"mfcr2_max_ani")) {
19764 confp->mfcr2.max_ani = atoi(v->
value);
19768 }
else if (!strcasecmp(v->
name,
"mfcr2_max_dnis")) {
19769 confp->mfcr2.max_dnis = atoi(v->
value);
19773 }
else if (!strcasecmp(v->
name,
"mfcr2_category")) {
19774 confp->mfcr2.category = openr2_proto_get_category(v->
value);
19775 if (OR2_CALLING_PARTY_CATEGORY_UNKNOWN == confp->mfcr2.category) {
19776 confp->mfcr2.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER;
19777 ast_log(
LOG_WARNING,
"Invalid MFC/R2 caller category '%s' at line %d. Using national subscriber as default.\n",
19780 }
else if (!strcasecmp(v->
name,
"mfcr2_logging")) {
19781 openr2_log_level_t tmplevel;
19788 clevel =
strsep(&logval,
",");
19789 if (-1 == (tmplevel = openr2_log_get_level(clevel))) {
19793 confp->mfcr2.loglevel |= tmplevel;
19796 }
else if (!strcasecmp(v->
name,
"cadence")) {
19798 int element_count,
c[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
19800 struct dahdi_ring_cadence new_cadence;
19801 int cid_location = -1;
19802 int firstcadencepos = 0;
19803 char original_args[80];
19804 int cadence_is_ok = 1;
19808 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]);
19811 if (element_count % 2 == 1) {
19812 ast_log(
LOG_ERROR,
"Must be a silence duration for each ring duration: %s at line %d.\n", original_args, v->
lineno);
19822 for (i = 0; i < element_count; i++) {
19824 ast_log(
LOG_ERROR,
"Ring or silence duration cannot be zero: %s at line %d.\n", original_args, v->
lineno);
19827 }
else if (
c[i] < 0) {
19830 if (cid_location == -1) {
19839 if (firstcadencepos == 0) {
19840 firstcadencepos = i;
19843 ast_log(
LOG_ERROR,
"First cadence position specified twice: %s at line %d.\n", original_args, v->
lineno);
19852 for (i = 0; i < 16; i++) {
19853 new_cadence.ringcadence[i] =
c[i];
19856 if (cadence_is_ok) {
19858 if (element_count < 2) {
19861 if (cid_location == -1) {
19866 cid_location = (cid_location + 1) / 2;
19881 }
else if (!strcasecmp(v->
name,
"ringtimeout")) {
19883 }
else if (!strcasecmp(v->
name,
"prewink")) {
19885 }
else if (!strcasecmp(v->
name,
"preflash")) {
19887 }
else if (!strcasecmp(v->
name,
"wink")) {
19889 }
else if (!strcasecmp(v->
name,
"flash")) {
19891 }
else if (!strcasecmp(v->
name,
"start")) {
19893 }
else if (!strcasecmp(v->
name,
"rxwink")) {
19895 }
else if (!strcasecmp(v->
name,
"rxflash")) {
19897 }
else if (!strcasecmp(v->
name,
"debounce")) {
19899 }
else if (!strcasecmp(v->
name,
"toneduration")) {
19903 struct dahdi_dialparams dps;
19905 ctlfd = open(
"/dev/dahdi/ctl", O_RDWR);
19911 toneduration = atoi(v->
value);
19912 if (toneduration > -1) {
19913 memset(&dps, 0,
sizeof(dps));
19915 dps.dtmf_tonelen = dps.mfv1_tonelen = toneduration;
19916 res = ioctl(ctlfd, DAHDI_SET_DIALPARAMS, &dps);
19924 }
else if (!strcasecmp(v->
name,
"defaultcic")) {
19926 }
else if (!strcasecmp(v->
name,
"defaultozz")) {
19928 }
else if (!strcasecmp(v->
name,
"mwilevel")) {
19930 }
else if (!strcasecmp(v->
name,
"dtmfcidlevel")) {
19932 }
else if (!strcasecmp(v->
name,
"reportalarms")) {
19933 if (!strcasecmp(v->
value,
"all"))
19935 if (!strcasecmp(v->
value,
"none"))
19937 else if (!strcasecmp(v->
value,
"channels"))
19939 else if (!strcasecmp(v->
value,
"spans"))
19951 "Dahdichan '%s' failure ignored: ignore_failed_channels.\n",
19969 for (tmp =
iflist, y=-1; tmp; tmp = tmp->
next) {
19987 if (
conf.chan.cc_params) {
19993 ast_verb(3,
"Automatically generated pseudo channel\n");
20057 static int had_cfg_before = 1;
20060 have_cfg_now = !!cfg;
20063 if (had_cfg_before) {
20092 have_cfg_now = !!cfg;
20094 if (had_cfg_before) {
20122 had_cfg_before = have_cfg_now;
20131 if (!strcasecmp(v->
name,
"trunkgroup")) {
20132 trunkgroup = atoi(v->
value);
20133 if (trunkgroup > 0) {
20134 if ((
c = strchr(v->
value,
','))) {
20136 memset(dchannels, 0,
sizeof(dchannels));
20138 dchannels[i] = atoi(
c + 1);
20139 if (dchannels[i] < 0) {
20140 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);
20143 c = strchr(
c + 1,
',');
20146 if (pri_create_trunkgroup(trunkgroup, dchannels)) {
20147 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);
20149 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");
20151 ast_log(
LOG_WARNING,
"Trunk group %d lacks any valid D-channels at line %d of chan_dahdi.conf\n", trunkgroup, v->
lineno);
20153 ast_log(
LOG_WARNING,
"Trunk group %d lacks a primary D-channel at line %d of chan_dahdi.conf\n", trunkgroup, v->
lineno);
20155 ast_log(
LOG_WARNING,
"Trunk group identifier must be a positive integer at line %d of chan_dahdi.conf\n", v->
lineno);
20156 }
else if (!strcasecmp(v->
name,
"spanmap")) {
20157 spanno = atoi(v->
value);
20159 if ((
c = strchr(v->
value,
','))) {
20160 trunkgroup = atoi(
c + 1);
20161 if (trunkgroup > 0) {
20162 if ((
c = strchr(
c + 1,
',')))
20163 logicalspan = atoi(
c + 1);
20166 if (logicalspan >= 0) {
20167 if (pri_create_spanmap(spanno - 1, trunkgroup, logicalspan)) {
20168 ast_log(
LOG_WARNING,
"Failed to map span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
20170 ast_verb(2,
"Mapped span %d to trunk group %d (logical span %d)\n", spanno, trunkgroup, logicalspan);
20172 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);
20209 if (!strcasecmp(cat,
"general") ||
20210 !strcasecmp(cat,
"trunkgroups") ||
20211 !strcasecmp(cat,
"globals") ||
20212 !strcasecmp(cat,
"channels")) {
20245 if (!strcasecmp(cat,
"general")) {
20272 if (pris[x].pri.
pvts[0] &&
20274 prepare_pri(pris + x);
20279 ast_verb(2,
"Starting D-Channel on span %d\n", x + 1);
20284#if defined(HAVE_SS7)
20288 if (linksets[x].ss7.
ss7) {
20293 ast_verb(2,
"Starting SS7 linkset on span %d\n", x + 1);
20300 struct r2link_entry *cur;
20304 struct dahdi_mfcr2 *r2 = &cur->mfcr2;
20307 ast_log(
LOG_ERROR,
"Unable to start R2 monitor on channel group %d\n", x + 1);
20310 ast_verb(2,
"Starting R2 monitor on channel group %d\n", x + 1);
20364#if defined(HAVE_PRI) || defined(HAVE_SS7)
20385 memset(pris, 0,
sizeof(pris));
20389 pri_set_error(dahdi_pri_error);
20390 pri_set_message(dahdi_pri_message);
20392#ifdef HAVE_PRI_PROG_W_CAUSE
20395#if defined(HAVE_PRI_CCSS)
20403#
if defined(HAVE_PRI_CCSS)
20413#if defined(HAVE_SS7)
20414 memset(linksets, 0,
sizeof(linksets));
20418 ss7_set_error(dahdi_ss7_error);
20419 ss7_set_message(dahdi_ss7_message);
20438#if defined(HAVE_SS7)
20458#if defined(HAVE_PRI)
20472#define END_SILENCE_LEN 400
20473#define HEADER_MS 50
20474#define TRAILER_MS 5
20475#define HEADER_LEN ((HEADER_MS + TRAILER_MS) * 8)
20476#define ASCII_BYTES_PER_CHAR 80
20478 unsigned char *
buf,*mybuf;
20480 struct pollfd fds[1];
20481 int size,res,fd,
len,x;
20503 if ((!p->
tdd) && (!p->
mate)) {
20504#if defined(HAVE_PRI)
20505#if defined(HAVE_PRI_DISPLAY_TEXT)
20530 for (x = 0;
text[x]; x++) {
20558 fds[0].events = POLLOUT | POLLPRI;
20559 fds[0].revents = 0;
20560 res = poll(fds, 1, -1);
20566 if (fds[0].revents & POLLPRI) {
20570 if (!(fds[0].revents & POLLOUT)) {
20574 res = write(fd,
buf, size);
20613 .
requires =
"ccss",
20614 .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)
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.
static struct chans chans
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
@ AST_BRIDGE_TRANSFER_SUCCESS
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
void dahdi_native_unload(void)
int dahdi_native_load(const struct ast_channel_tech *tech)
Native DAHDI bridging support.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
int ast_callerid_callwaiting_full_generate(unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, struct ast_format *codec)
Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
#define CID_UNKNOWN_NUMBER
int ast_gen_cas(unsigned char *outbuf, int sas, int len, struct ast_format *codec)
Generate a CAS (CPE Alert Signal) tone for 'n' samples.
int ast_callerid_full_generate(unsigned char *buf, const char *name, const char *number, const char *ddn, int redirecting, int pres, int qualifier, int format, struct ast_format *codec)
Generate Caller-ID spill from the "callerid" field of asterisk (in e-mail address like format)
int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec)
Read samples into the state machine.
#define AST_PRES_USER_NUMBER_UNSCREENED
#define AST_PRES_UNAVAILABLE
int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct ast_format *codec, const char *name, const char *number, int flags)
Generate message waiting indicator.
#define AST_PRES_RESTRICTED
void callerid_free(struct callerid_state *cid)
This function frees callerid_state cid.
void callerid_get_with_redirecting(struct callerid_state *cid, char **name, char **number, int *flags, int *redirecting)
Extract info out of callerID state machine. Flags are listed above.
#define MAX_CALLERID_SIZE
const char * ast_redirecting_reason_name(const struct ast_party_redirecting_reason *data)
Convert redirecting reason value to text code.
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
#define CID_PRIVATE_NUMBER
struct callerid_state * callerid_new(int cid_signalling)
Create a callerID state machine.
int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec)
Read samples into the state machine.
#define CID_MWI_TYPE_MDMF_FULL
void callerid_get_dtmf(char *cidstring, char *number, int *flags)
Get and parse DTMF-based callerid.
#define CID_START_POLARITY
void callerid_get(struct callerid_state *cid, char **number, char **name, int *flags)
Extract info out of callerID state machine. Flags are listed above.
#define CID_START_POLARITY_IN
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
#define CID_START_DTMF_NOALERT
Internal Asterisk hangup causes.
#define AST_CAUSE_SWITCH_CONGESTION
#define AST_CAUSE_CONGESTION
#define AST_CAUSE_UNALLOCATED
#define AST_CAUSE_INTERWORKING
#define AST_CAUSE_PROTOCOL_ERROR
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
#define AST_CAUSE_NO_USER_RESPONSE
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
#define AST_CAUSE_NOTDEFINED
#define AST_CAUSE_CALL_REJECTED
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
#define AST_CAUSE_UNREGISTERED
#define AST_CAUSE_NO_ANSWER
#define AST_CAUSE_NORMAL_CLEARING
#define AST_CAUSE_USER_BUSY
Call Completion Supplementary Services API.
#define ast_cc_config_params_init()
Allocate and initialize an ast_cc_config_params structure.
#define AST_CC_GENERIC_MONITOR_TYPE
int ast_cc_monitor_register(const struct ast_cc_monitor_callbacks *callbacks)
Register a set of monitor callbacks with the core.
void ast_cc_config_params_destroy(struct ast_cc_config_params *params)
Free memory from CCSS configuration params.
void(* ast_cc_callback_fn)(struct ast_channel *chan, struct ast_cc_config_params *cc_params, const char *monitor_type, const char *const device_name, const char *const dialstring, void *private_data)
Callback made from ast_cc_callback for certain channel types.
int ast_cc_agent_register(const struct ast_cc_agent_callbacks *callbacks)
Register a set of agent callbacks with the core.
void ast_cc_copy_config_params(struct ast_cc_config_params *dest, const struct ast_cc_config_params *src)
copy CCSS configuration parameters from one structure to another
void ast_cc_monitor_unregister(const struct ast_cc_monitor_callbacks *callbacks)
Unregister a set of monitor callbacks with the core.
enum ast_cc_monitor_policies ast_get_cc_monitor_policy(struct ast_cc_config_params *config)
Get the cc_monitor_policy.
void ast_cc_agent_unregister(const struct ast_cc_agent_callbacks *callbacks)
Unregister a set of agent callbacks with the core.
int ast_cc_is_config_param(const char *const name)
Is this a CCSS configuration parameter?
int ast_cc_set_param(struct ast_cc_config_params *params, const char *const name, const char *value)
set a CCSS configuration parameter, given its name
static struct ao2_container * pvts
#define CALLPROGRESS_FAX_INCOMING
static int dahdi_create_channel_range(int start, int end)
static int dahdi_confmute(struct dahdi_pvt *p, int muted)
static ast_mutex_t ss_thread_lock
static int calc_energy(const unsigned char *buf, int len, struct ast_format *law)
#define CALLWAITING_SUPPRESS_SAMPLES
static int isourconf(struct dahdi_pvt *p, struct dahdi_subchannel *c)
static void release_doomed_pris(void)
static struct dahdi_pvt * round_robin[64]
static void my_set_new_owner(void *pvt, struct ast_channel *new_owner)
static int restore_gains(struct dahdi_pvt *p)
static void publish_channel_alarm_clear(int channel)
static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index)
static char * dahdi_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void my_set_confirmanswer(void *pvt, int flag)
#define CIDCW_EXPIRE_SAMPLES
static int my_dahdi_write(struct dahdi_pvt *p, unsigned char *buf, int len, int idx, int linear)
static int my_callwait(void *pvt)
static int restore_conference(struct dahdi_pvt *p)
static void publish_span_alarm_clear(int span)
static ast_mutex_t iflock
Protect the interface list (of dahdi_pvt's)
static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)
static void notify_message(char *mailbox, int thereornot)
Send MWI state change.
static struct dahdi_pvt * mkintf(int channel, const struct dahdi_chan_conf *conf, int reloading)
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel)
static int unalloc_sub(struct dahdi_pvt *p, int x)
static int my_check_confirmanswer(void *pvt)
static const char *const events[]
static int reset_conf(struct dahdi_pvt *p)
static int my_is_dialing(void *pvt, enum analog_sub sub)
static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop)
static struct ast_manager_event_blob * dahdichannel_to_ami(struct stasis_message *msg)
static void my_cancel_cidspill(void *pvt)
static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out)
static int my_set_echocanceller(void *pvt, int enable)
static int dahdi_wink(struct dahdi_pvt *p, int index)
static char mwimonitornotify[PATH_MAX]
static char * alarm2str(int alm)
static void my_hangup_polarityswitch(void *pvt)
static int is_group_or_channel_match(struct dahdi_pvt *p, int span, ast_group_t groupmatch, int *groupmatched, int channelmatch, int *channelmatched)
static int dahdi_ring_phone(struct dahdi_pvt *p)
static char * dahdi_show_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define CALLWAITING_REPEAT_SAMPLES
static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
#define CALLPROGRESS_FAX_OUTGOING
static int dahdi_call(struct ast_channel *ast, const char *rdest, int timeout)
static int my_stop_cid_detect(void *pvt)
static int my_get_sub_fd(void *pvt, enum analog_sub sub)
static void my_set_needringing(void *pvt, int value)
static char * dahdi_destroy_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_jb_conf default_jbconf
static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback)
Callback made when dial failed to get a channel out of dahdi_request().
static struct dahdi_pvt * find_channel_from_str(const char *channel)
static int __unload_module(void)
static void dahdi_softhangup_all(void)
static void dahdi_train_ec(struct dahdi_pvt *p)
static int build_channels(struct dahdi_chan_conf *conf, const char *value, int reload, int lineno)
static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
static enum analog_event dahdievent_to_analogevent(int event)
static int dahdi_digit_begin(struct ast_channel *ast, char digit)
static void my_unlock_private(void *pvt)
static int 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 struct dahdi_pvt * fxo_pvt(struct ast_channel *chan)
Return DAHDI pivot if channel is FXO signalled.
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 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 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 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)
STASIS_MESSAGE_TYPE_DEFN_LOCAL(dahdichannel_type,.to_ami=dahdichannel_to_ami,)
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)
static struct @114 alarms[]
#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
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_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 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 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)
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel.
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
void ast_channel_softhangup_internal_flag_add(struct ast_channel *chan, int value)
#define ast_channel_unref(c)
Decrease channel reference count.
@ AST_FLAG_DISABLE_DEVSTATE_CACHE
void ast_party_number_free(struct ast_party_number *doomed)
Destroy the party number contents.
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
const char * ast_channel_language(const struct ast_channel *chan)
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
struct ast_namedgroups * ast_unref_namedgroups(struct ast_namedgroups *groups)
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
ast_group_t ast_get_group(const char *s)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
const char * ast_channel_exten(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
#define AST_MAX_EXTENSION
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
@ AST_SOFTHANGUP_EXPLICIT
@ AST_SOFTHANGUP_APPUNLOAD
ast_channel_state
ast_channel states
@ AST_STATE_DIALING_OFFHOOK
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static struct channel_usage channels
#define container_of(ptr, type, member)
@ AST_DEVSTATE_NOT_CACHABLE
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
int ast_devstate_changed_literal(enum ast_device_state state, enum ast_devstate_cache cachable, const char *device)
Tells Asterisk the State for Device is changed.
ast_device_state
Device States.
Convenient Signal Processing routines.
void ast_dsp_free(struct ast_dsp *dsp)
int ast_dsp_get_tcount(struct ast_dsp *dsp)
Get tcount (Threshold counter)
#define DSP_FEATURE_WAITDIALTONE
#define DSP_FEATURE_BUSY_DETECT
#define DSP_TONE_STATE_DIALTONE
void ast_dsp_digitreset(struct ast_dsp *dsp)
Reset DTMF detector.
#define DSP_DIGITMODE_MUTEMAX
void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, const struct ast_dsp_busy_pattern *cadence)
Set expected lengths of the busy tone.
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress,...
#define DSP_FEATURE_DIGIT_DETECT
#define DSP_FEATURE_FAX_DETECT
#define DSP_FEATURE_CALL_PROGRESS
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
#define DSP_DIGITMODE_MUTECONF
int ast_dsp_get_tstate(struct ast_dsp *dsp)
Get tstate (Tone State)
int ast_dsp_was_muted(struct ast_dsp *dsp)
Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) hap...
#define DSP_TONE_STATE_RINGING
void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
Set number of required cadences for busy.
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
#define DSP_DIGITMODE_DTMF
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
#define DSP_DIGITMODE_RELAXDTMF
int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
Set zone for doing progress detection.
void ast_verbose(const char *fmt,...)
Call Parking and Pickup API Includes code and algorithms from the Zapata library.
Generic File Format Support. Should be included by clients of the file handling routines....
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
void ast_manager_publish_event(const char *type, int class_type, struct ast_json *obj)
Publish an event to AMI.
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
void astman_append(struct mansession *s, const char *fmt,...)
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
#define AST_APP_ARG(name)
Define an application argument.
#define ast_app_separate_args(a, b, c, d)
int ast_app_has_voicemail(const char *mailboxes, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX"....
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.