dahdi-tools-2.10.2/0000755000000000000000000000000012537624573012517 5ustar rootrootdahdi-tools-2.10.2/dahdi_tool.c0000644000000000000000000003125612537624573015000 0ustar rootroot/* * Configuration program for Zapata Telephony Interface * * Written by Mark Spencer * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2010 Digium, Inc. * * All rights reserved. * */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ /*** MODULEINFO newt ***/ #include #include #include #include #include #include #include #include #include #include #include #include "dahdi_tools_version.h" static int ctl = -1; static int span_max_chan_pos; static struct dahdi_spaninfo s[DAHDI_MAX_SPANS]; static char *dahdi_txlevelnames[] = { "0 db (CSU)/0-133 feet (DSX-1)", "133-266 feet (DSX-1)", "266-399 feet (DSX-1)", "399-533 feet (DSX-1)", "533-655 feet (DSX-1)", "-7.5db (CSU)", "-15db (CSU)", "-22.5db (CSU)" } ; static char *alarmstr(int span) { static char alarms[80]; strcpy(alarms, ""); if (s[span].alarms > 0) { if (s[span].alarms & DAHDI_ALARM_BLUE) strcat(alarms,"Blue Alarm/"); if (s[span].alarms & DAHDI_ALARM_YELLOW) strcat(alarms, "Yellow Alarm/"); if (s[span].alarms & DAHDI_ALARM_RED) strcat(alarms, "Red Alarm/"); if (s[span].alarms & DAHDI_ALARM_LOOPBACK) strcat(alarms,"Loopback/"); if (s[span].alarms & DAHDI_ALARM_RECOVER) strcat(alarms,"Recovering/"); if (s[span].alarms & DAHDI_ALARM_NOTOPEN) strcat(alarms, "Not Open/"); if (!strlen(alarms)) strcat(alarms, "/"); if (strlen(alarms)) { /* Strip trailing / */ alarms[strlen(alarms)-1]='\0'; } } else strcpy(alarms, "No alarms."); return alarms; } static char *getalarms(int span, int err) { int res; static char tmp[256]; char alarms[50]; s[span].spanno = span; res = ioctl(ctl, DAHDI_SPANSTAT, &s[span]); if (res) { if (err) fprintf(stderr, "Unable to get span info on span %d: %s\n", span, strerror(errno)); return NULL; } strcpy(alarms, ""); if (s[span].alarms > 0) { if (s[span].alarms & DAHDI_ALARM_BLUE) strcat(alarms,"BLU/"); if (s[span].alarms & DAHDI_ALARM_YELLOW) strcat(alarms, "YEL/"); if (s[span].alarms & DAHDI_ALARM_RED) strcat(alarms, "RED/"); if (s[span].alarms & DAHDI_ALARM_LOOPBACK) strcat(alarms,"LB/"); if (s[span].alarms & DAHDI_ALARM_RECOVER) strcat(alarms,"REC/"); if (s[span].alarms & DAHDI_ALARM_NOTOPEN) strcat(alarms, "NOP/"); if (!strlen(alarms)) strcat(alarms, "UUU/"); if (strlen(alarms)) { /* Strip trailing / */ alarms[strlen(alarms)-1]='\0'; } } else { if (s[span].numchans) strcpy(alarms, "OK"); else strcpy(alarms, "UNCONFIGURED"); } snprintf(tmp, sizeof(tmp), "%-15s %s", alarms, s[span].desc); return tmp; } static void add_cards(newtComponent spans) { int x; char *s; void *prev=NULL; if (spans) prev = newtListboxGetCurrent(spans); newtListboxClear(spans); for (x=0;x -1)) { if (zp.rxbits & DAHDI_ABIT) rabits[zp.chanpos - 1] = '1'; else rabits[zp.chanpos - 1] = '0'; if (zp.rxbits & DAHDI_BBIT) rbbits[zp.chanpos - 1] = '1'; else rbbits[zp.chanpos - 1] = '0'; if (zp.rxbits & DAHDI_CBIT) rcbits[zp.chanpos - 1] = '1'; else rcbits[zp.chanpos - 1] = '0'; if (zp.rxbits & DAHDI_DBIT) rdbits[zp.chanpos - 1] = '1'; else rdbits[zp.chanpos - 1] = '0'; if (zp.txbits & DAHDI_ABIT) tabits[zp.chanpos - 1] = '1'; else tabits[zp.chanpos - 1] = '0'; if (zp.txbits & DAHDI_BBIT) tbbits[zp.chanpos - 1] = '1'; else tbbits[zp.chanpos - 1] = '0'; if (zp.txbits & DAHDI_CBIT) tcbits[zp.chanpos - 1] = '1'; else tcbits[zp.chanpos - 1] = '0'; if (zp.txbits & DAHDI_DBIT) tdbits[zp.chanpos - 1] = '1'; else tdbits[zp.chanpos - 1] = '0'; } else { c = '-'; if (!zp.sigtype) c = ' '; tabits[zp.chanpos - 1] = c; tbbits[zp.chanpos - 1] = c; tcbits[zp.chanpos - 1] = c; tdbits[zp.chanpos - 1] = c; rabits[zp.chanpos - 1] = c; rbbits[zp.chanpos - 1] = c; rcbits[zp.chanpos - 1] = c; rdbits[zp.chanpos - 1] = c; } if (zp.rxisoffhook) use++; } } } snprintf(tmp, sizeof(tmp), "%s\n%s\n%s\n%s\n\n%s\n%s\n%s\n%s", tabits, tbbits,tcbits,tdbits,rabits,rbbits,rcbits,rdbits); newtTextboxSetText(bitbox, tmp); sprintf(tmp, "%3d/%3d/%3d", s[span].totalchans, s[span].numchans, use); newtTextboxSetText(inuse, tmp); sprintf(tmp, "%s/", dahdi_txlevelnames[s[span].txlevel]); strcat(tmp, dahdi_txlevelnames[s[span].rxlevel]); sprintf(tmp, "%3d/%3d", s[span].txlevel, s[span].rxlevel); newtTextboxSetText(levels, tmp); sprintf(tmp, "%7d", s[span].bpvcount); newtTextboxSetText(bpvcount, tmp); sprintf(tmp, "%7d", s[span].irqmisses); newtTextboxSetText(irqmisses, tmp); newtTextboxSetText(alarms, alarmstr(span)); if (s[span].syncsrc > 0) strcpy(tmp, s[s[span].syncsrc].desc); else strcpy(tmp, "Internally clocked"); newtTextboxSetText(syncsrc, tmp); } static newtComponent spans; static void show_span(int span) { newtComponent form; newtComponent back; newtComponent label; newtComponent bitbox; newtComponent inuse; newtComponent levels; newtComponent bpvcount; newtComponent alarms; newtComponent syncsrc; newtComponent irqmisses; char s1[] = " 1111111111222222222233"; char s2[] = "1234567890123456789012345678901"; int x; struct newtExitStruct es; void *ss; char info2[256]; if (span < 0) { /* Display info on a span */ ss = newtListboxGetCurrent(spans); if (ss) { span = (long)(ss); } } snprintf(info2, sizeof(info2), "%-59s F10=Back", s[span].desc); newtCenteredWindow(60,20, s[span].desc); newtPushHelpLine(info2); back = newtButton(48,8,"Back"); form = newtForm(NULL, NULL, 0); newtFormAddComponents(form, back, NULL); span_max_chan_pos = s[span].totalchans; for (x=0;x span_max_chan_pos ) span_max_chan_pos = zp.chanpos; } if (span_max_chan_pos > 32) span_max_chan_pos = 32; s1[span_max_chan_pos] = '\0'; s2[span_max_chan_pos] = '\0'; bitbox = newtTextbox(8,10,span_max_chan_pos,9,0); newtFormAddComponent(form, bitbox); label = newtLabel(8,8,s1); newtFormAddComponent(form, label); label = newtLabel(8,9,s2); newtFormAddComponent(form, label); newtFormAddHotKey(form, NEWT_KEY_F10); newtFormSetTimer(form, 200); label = newtLabel(4,10,"TxA"); newtFormAddComponent(form, label); label = newtLabel(4,11,"TxB"); newtFormAddComponent(form, label); label = newtLabel(4,12,"TxC"); newtFormAddComponent(form, label); label = newtLabel(4,13,"TxD"); newtFormAddComponent(form, label); label = newtLabel(4,15,"RxA"); newtFormAddComponent(form, label); label = newtLabel(4,16,"RxB"); newtFormAddComponent(form, label); label = newtLabel(4,17,"RxC"); newtFormAddComponent(form, label); label = newtLabel(4,18,"RxD"); newtFormAddComponent(form, label); label = newtLabel(4,7,"Total/Conf/Act: "); newtFormAddComponent(form, label); inuse = newtTextbox(24,7,12,1,0); newtFormAddComponent(form, inuse); label = newtLabel(4,6,"Tx/Rx Levels: "); newtFormAddComponent(form, label); levels = newtTextbox(24,6,30,1,0); newtFormAddComponent(form, levels); label = newtLabel(4,5,"Bipolar Viol: "); newtFormAddComponent(form, label); bpvcount = newtTextbox(24,5,30,1,0); newtFormAddComponent(form, bpvcount); label = newtLabel(4,4,"IRQ Misses: "); newtFormAddComponent(form, label); irqmisses = newtTextbox(24,4,30,1,0); newtFormAddComponent(form, irqmisses); label = newtLabel(4,3,"Sync Source: "); newtFormAddComponent(form, label); syncsrc = newtTextbox(24,3,30,1,0); newtFormAddComponent(form, syncsrc); label = newtLabel(4,2,"Current Alarms: "); newtFormAddComponent(form, label); alarms = newtTextbox(24,2,30,1,0); newtFormAddComponent(form, alarms); for(;;) { /* Wait for user to select something */ do { add_cards(NULL); show_bits(span, bitbox, inuse, levels, bpvcount, alarms, syncsrc, irqmisses); newtFormRun(form, &es); } while(es.reason == NEWT_EXIT_TIMER); switch(es.reason) { case NEWT_EXIT_COMPONENT: if (es.u.co == back) { goto out; } break; case NEWT_EXIT_HOTKEY: switch(es.u.key) { #if 0 case NEWT_KEY_F1: show_span(-1); break; #endif case NEWT_KEY_F10: goto out; } break; default: break; } } out: newtFormDestroy(form); newtPopWindow(); newtPopHelpLine(); span_max_chan_pos = 0; } static void show_spans(void) { newtComponent form; newtComponent quit; newtComponent label; newtComponent sel; struct newtExitStruct es; quit = newtButton(50,14,"Quit"); sel = newtButton(10,14,"Select"); spans = newtListbox(5, 2, 10, NEWT_FLAG_SCROLL); newtListboxSetWidth(spans, 65); label = newtLabel(5,1,"Alarms Span"); newtCenteredWindow(72,18, "DAHDI Telephony Interfaces"); form = newtForm(NULL, NULL, 0); newtFormSetTimer(form, 200); newtFormAddComponents(form, spans, sel, quit, label, NULL); newtComponentAddCallback(spans, sel_callback, NULL); newtFormAddHotKey(form, NEWT_KEY_F1); newtFormAddHotKey(form, NEWT_KEY_F10); for(;;) { /* Wait for user to select something */ do { add_cards(spans); newtFormRun(form, &es); } while(es.reason == NEWT_EXIT_TIMER); switch(es.reason) { case NEWT_EXIT_COMPONENT: if (es.u.co == quit) { /* Quit if appropriate */ newtFormDestroy(form); return; } else if (es.u.co == sel) { show_span(-1); } break; case NEWT_EXIT_HOTKEY: switch(es.u.key) { case NEWT_KEY_F1: show_span(-1); break; case NEWT_KEY_F10: newtFormDestroy(form); return; } break; default: break; } } } static void cleanup(void) { newtPopWindow(); } int main(int argc, char *argv[]) { ctl = open("/dev/dahdi/ctl", O_RDWR); if (ctl < 0) { fprintf(stderr, "Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); exit(1); } newtInit(); newtCls(); newtDrawRootText(0,0,"DAHDI Tool (C)2002-2008 Digium, Inc."); newtPushHelpLine("Welcome to the DAHDI Tool!"); show_spans(); cleanup(); newtFinished(); return 0; } dahdi-tools-2.10.2/sethdlc.c0000644000000000000000000003570712537624573014325 0ustar rootroot/* * sethdlc.c * * Copyright (C) 1999 - 2002 Krzysztof Halasa * */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dahdi_tools_version.h" #if GENERIC_HDLC_VERSION != 4 #error Generic HDLC layer version mismatch, please get correct sethdlc.c #endif #if !defined(IF_PROTO_HDLC_ETH) || !defined(IF_PROTO_FR_ETH_PVC) #warning "No kernel support for Ethernet over Frame Relay / HDLC, skipping it" #endif static struct ifreq req; /* for ioctl */ static int argc; static char **argv; int sock; static void error(const char *format, ...) __attribute__ ((noreturn, format(printf, 1, 2))); static void error(const char *format, ...) { va_list args; va_start(args, format); fprintf(stderr, "%s: ", req.ifr_name); vfprintf(stderr, format, args); va_end(args); exit(1); } typedef struct { const char *name; const unsigned int value; } parsertab; static int checkkey(const char* name) { if (argc < 1) return -1; /* no enough parameters */ if (strcmp(name, argv[0])) return -1; argc--; argv++; return 0; } static int checktab(parsertab *tab, unsigned int *value) { int i; if (argc < 1) return -1; /* no enough parameters */ for (i = 0; tab[i].name; i++) if (!strcmp(tab[i].name, argv[0])) { argc--; argv++; *value = tab[i].value; return 0; } return -1; /* Not found */ } static const char* tabstr(unsigned int value, parsertab *tab, const char* unknown) { int i; for (i = 0; tab[i].name; i++) if (tab[i].value == value) return tab[i].name; return unknown; /* Not found */ } static unsigned int match(const char* name, unsigned int *value, unsigned int minimum, unsigned int maximum) { char test; if (argc < 1) return -1; /* no enough parameters */ if (name) { if (strcmp(name, argv[0])) return -1; argc--; argv++; } if (argc < 1) error("Missing parameter\n"); if (sscanf(argv[0], "%u%c", value, &test) != 1) error("Invalid parameter: %s\n", argv[0]); if ((*value > maximum) || (*value < minimum)) error("Parameter out of range [%u - %u]: %u\n", minimum, maximum, *value); argc--; argv++; return 0; } static parsertab ifaces[] = {{ "v35", IF_IFACE_V35 }, { "v24", IF_IFACE_V24 }, { "x21", IF_IFACE_X21 }, { "e1", IF_IFACE_E1 }, { "t1", IF_IFACE_T1 }, { NULL, 0 }}; static parsertab clocks[] = {{ "int", CLOCK_INT }, { "ext", CLOCK_EXT }, { "txint", CLOCK_TXINT }, { "txfromrx", CLOCK_TXFROMRX }, { NULL, 0 }}; static parsertab protos[] = {{ "hdlc", IF_PROTO_HDLC}, { "cisco", IF_PROTO_CISCO}, { "fr", IF_PROTO_FR}, { "ppp", IF_PROTO_PPP}, { "x25", IF_PROTO_X25}, #ifdef IF_PROTO_HDLC_ETH { "hdlc-eth", IF_PROTO_HDLC_ETH}, #endif { NULL, 0 }}; static parsertab hdlc_enc[] = {{ "nrz", ENCODING_NRZ }, { "nrzi", ENCODING_NRZI }, { "fm-mark", ENCODING_FM_MARK }, { "fm-space", ENCODING_FM_SPACE }, { "manchester", ENCODING_MANCHESTER }, { NULL, 0 }}; static parsertab hdlc_par[] = {{ "no-parity", PARITY_NONE }, { "crc16", PARITY_CRC16_PR1 }, { "crc16-pr0", PARITY_CRC16_PR0 }, { "crc16-itu", PARITY_CRC16_PR1_CCITT }, { "crc16-itu-pr0", PARITY_CRC16_PR0_CCITT }, { "crc32-itu", PARITY_CRC32_PR1_CCITT }, { NULL, 0 }}; static parsertab lmi[] = {{ "none", LMI_NONE }, { "ansi", LMI_ANSI }, { "ccitt", LMI_CCITT }, { NULL, 0 }}; static void set_iface(void) { int orig_argc = argc; te1_settings te1; memset(&te1, 0, sizeof(te1)); req.ifr_settings.type = IF_IFACE_SYNC_SERIAL; while (argc > 0) { if (req.ifr_settings.type == IF_IFACE_SYNC_SERIAL) if (!checktab(ifaces, &req.ifr_settings.type)) continue; if (!te1.clock_type) if (!checkkey("clock")) { if (!checktab(clocks, &te1.clock_type)) continue; error("Invalid clock type\n"); } if (!te1.clock_rate && (te1.clock_type == CLOCK_INT || te1.clock_type == CLOCK_TXINT)) if (!match("rate", &te1.clock_rate, 1, 0xFFFFFFFF)) continue; if (!te1.loopback) { if (!checkkey("loopback") || !checkkey("lb")) { te1.loopback = 1; continue; } } /* slotmap goes here */ if (orig_argc == argc) return; /* not an iface definition */ error("Invalid parameter: %s\n", argv[0]); } if (!te1.clock_rate && (te1.clock_type == CLOCK_INT || te1.clock_type == CLOCK_TXINT)) te1.clock_rate = 64000; /* FIXME stupid hack, will remove it later */ req.ifr_settings.ifs_ifsu.te1 = &te1; if (req.ifr_settings.type == IF_IFACE_E1 || req.ifr_settings.type == IF_IFACE_T1) req.ifr_settings.size = sizeof(te1_settings); else req.ifr_settings.size = sizeof(sync_serial_settings); if (ioctl(sock, SIOCWANDEV, &req)) error("Unable to set interface information: %s\n", strerror(errno)); exit(0); } static void set_proto_fr(void) { unsigned int lmi_type = 0; fr_proto fr; memset(&fr, 0, sizeof(fr)); while (argc > 0) { if (!lmi_type) if (!checkkey("lmi")) { if (!checktab(lmi, &lmi_type)) continue; error("Invalid LMI type: %s\n", argv[0]); } if (lmi_type && lmi_type != LMI_NONE) { if (!fr.dce) if (!checkkey("dce")) { fr.dce = 1; continue; } if (!fr.t391) if (!match("t391", &fr.t391, 1, 1000)) continue; if (!fr.t392) if (!match("t392", &fr.t392, 1, 1000)) continue; if (!fr.n391) if (!match("n391", &fr.n391, 1, 1000)) continue; if (!fr.n392) if (!match("n392", &fr.n392, 1, 1000)) continue; if (!fr.n393) if (!match("n393", &fr.n393, 1, 1000)) continue; } error("Invalid parameter: %s\n", argv[0]); } /* polling verification timer*/ if (!fr.t391) fr.t391 = 10; /* link integrity verification polling timer */ if (!fr.t392) fr.t392 = 15; /* full status polling counter*/ if (!fr.n391) fr.n391 = 6; /* error threshold */ if (!fr.n392) fr.n392 = 3; /* monitored events count */ if (!fr.n393) fr.n393 = 4; if (!lmi_type) fr.lmi = LMI_DEFAULT; else fr.lmi = lmi_type; req.ifr_settings.ifs_ifsu.fr = &fr; req.ifr_settings.size = sizeof(fr); if (ioctl(sock, SIOCWANDEV, &req)) error("Unable to set FR protocol information: %s\n", strerror(errno)); } static void set_proto_hdlc(int eth) { unsigned int enc = 0, par = 0; raw_hdlc_proto raw; memset(&raw, 0, sizeof(raw)); while (argc > 0) { if (!enc) if (!checktab(hdlc_enc, &enc)) continue; if (!par) if (!checktab(hdlc_par, &par)) continue; error("Invalid parameter: %s\n", argv[0]); } if (!enc) raw.encoding = ENCODING_DEFAULT; else raw.encoding = enc; if (!par) raw.parity = ENCODING_DEFAULT; else raw.parity = par; req.ifr_settings.ifs_ifsu.raw_hdlc = &raw; req.ifr_settings.size = sizeof(raw); if (ioctl(sock, SIOCWANDEV, &req)) error("Unable to set HDLC%s protocol information: %s\n", eth ? "-ETH" : "", strerror(errno)); } static void set_proto_cisco(void) { cisco_proto cisco; memset(&cisco, 0, sizeof(cisco)); while (argc > 0) { if (!cisco.interval) if (!match("interval", &cisco.interval, 1, 100)) continue; if (!cisco.timeout) if (!match("timeout", &cisco.timeout, 1, 100)) continue; error("Invalid parameter: %s\n", argv[0]); } if (!cisco.interval) cisco.interval = 10; if (!cisco.timeout) cisco.timeout = 25; req.ifr_settings.ifs_ifsu.cisco = &cisco; req.ifr_settings.size = sizeof(cisco); if (ioctl(sock, SIOCWANDEV, &req)) error("Unable to set Cisco HDLC protocol information: %s\n", strerror(errno)); } static void set_proto(void) { if (checktab(protos, &req.ifr_settings.type)) return; switch(req.ifr_settings.type) { case IF_PROTO_HDLC: set_proto_hdlc(0); break; #ifdef IF_PROTO_HDLC_ETH case IF_PROTO_HDLC_ETH: set_proto_hdlc(1); break; #endif case IF_PROTO_CISCO: set_proto_cisco(); break; case IF_PROTO_FR: set_proto_fr(); break; case IF_PROTO_PPP: case IF_PROTO_X25: req.ifr_settings.ifs_ifsu.sync = NULL; /* FIXME */ req.ifr_settings.size = 0; if (!ioctl(sock, SIOCWANDEV, &req)) break; error("Unable to set %s protocol information: %s\n", req.ifr_settings.type == IF_PROTO_PPP ? "PPP" : "X.25", strerror(errno)); default: error("Unknown protocol %u\n", req.ifr_settings.type); } if (argc > 0) error("Unexpected parameter: %s\n", argv[0]); close(sock); exit(0); } static void set_pvc(void) { char *op = argv[0]; parsertab ops[] = {{ "create", IF_PROTO_FR_ADD_PVC }, { "delete", IF_PROTO_FR_DEL_PVC }, { NULL, 0 }}; fr_proto_pvc pvc; memset(&pvc, 0, sizeof(pvc)); if (checktab(ops, &req.ifr_settings.type)) return; #ifdef IF_PROTO_FR_ETH_PVC if (!match("ether", &pvc.dlci, 0, 1023)) { if (req.ifr_settings.type == IF_PROTO_FR_ADD_PVC) req.ifr_settings.type = IF_PROTO_FR_ADD_ETH_PVC; else req.ifr_settings.type = IF_PROTO_FR_DEL_ETH_PVC; } else #endif if (match(NULL, &pvc.dlci, 0, 1023)) return; if (argc != 0) return; req.ifr_settings.ifs_ifsu.fr_pvc = &pvc; req.ifr_settings.size = sizeof(pvc); if (ioctl(sock, SIOCWANDEV, &req)) error("Unable to %s PVC: %s\n", op, strerror(errno)); exit(0); } static void private(void) { if (argc < 1) return; if (!strcmp(argv[0], "private")) { if (argc != 1) return; if (ioctl(sock, SIOCDEVPRIVATE, &req)) error("SIOCDEVPRIVATE: %s\n", strerror(errno)); exit(0); } } static void show_port(void) { const char *s; char buffer[128]; const te1_settings *te1 = (void*)buffer; const raw_hdlc_proto *raw = (void*)buffer; const cisco_proto *cisco = (void*)buffer; const fr_proto *fr = (void*)buffer; #ifdef IF_PROTO_FR_PVC const fr_proto_pvc_info *pvc = (void*)buffer; #endif req.ifr_settings.ifs_ifsu.sync = (void*)buffer; /* FIXME */ printf("%s: ", req.ifr_name); req.ifr_settings.size = sizeof(buffer); req.ifr_settings.type = IF_GET_IFACE; if (ioctl(sock, SIOCWANDEV, &req)) if (errno != EINVAL) { printf("unable to get interface information: %s\n", strerror(errno)); close(sock); exit(1); } /* Get and print physical interface settings */ if (req.ifr_settings.type == IF_IFACE_SYNC_SERIAL) s = ""; /* Unspecified serial interface */ else s = tabstr(req.ifr_settings.type, ifaces, NULL); if (!s) printf("unknown interface 0x%x\n", req.ifr_settings.type); else { if (*s) printf("interface %s ", s); printf("clock %s", tabstr(te1->clock_type, clocks, "type unknown")); if (te1->clock_type == CLOCK_INT || te1->clock_type == CLOCK_TXINT) printf(" rate %u", te1->clock_rate); if (te1->loopback) printf(" loopback"); if (req.ifr_settings.type == IF_IFACE_E1 || req.ifr_settings.type == IF_IFACE_T1) { unsigned int u; printf(" slotmap "); for (u = te1->slot_map; u != 0; u /= 2) printf("%u", u % 2); } printf("\n"); } /* Get and print protocol settings */ do { printf("\t"); req.ifr_settings.size = sizeof(buffer); req.ifr_settings.type = IF_GET_PROTO; if (ioctl(sock, SIOCWANDEV, &req)) { if (errno == EINVAL) printf("no protocol set\n"); else printf("unable to get protocol information: " "%s\n", strerror(errno)); break; } switch(req.ifr_settings.type) { case IF_PROTO_FR: printf("protocol fr lmi %s", tabstr(fr->lmi, lmi, "unknown")); if (fr->lmi == LMI_ANSI || fr->lmi == LMI_CCITT) printf("%s t391 %u t392 %u n391 %u n392 %u " "n393 %u\n", fr->dce ? " dce" : "", fr->t391, fr->t392, fr->n391, fr->n392, fr->n393); else putchar('\n'); break; #ifdef IF_PROTO_FR_PVC case IF_PROTO_FR_PVC: printf("Frame-Relay PVC: DLCI %u, master device %s\n", pvc->dlci, pvc->master); break; #endif #ifdef IF_PROTO_FR_ETH_PVC case IF_PROTO_FR_ETH_PVC: printf("Frame-Relay PVC (Ethernet emulation): DLCI %u," " master device %s\n", pvc->dlci, pvc->master); break; #endif case IF_PROTO_HDLC: printf("protocol hdlc %s %s\n", tabstr(raw->encoding, hdlc_enc, "unknown"), tabstr(raw->parity, hdlc_par, "unknown")); break; #ifdef IF_PROTO_HDLC_ETH case IF_PROTO_HDLC_ETH: printf("protocol hdlc-eth %s %s\n", tabstr(raw->encoding, hdlc_enc, "unknown"), tabstr(raw->parity, hdlc_par, "unknown")); break; #endif case IF_PROTO_CISCO: printf("protocol cisco interval %u timeout %u\n", cisco->interval, cisco->timeout); break; case IF_PROTO_PPP: printf("protocol ppp\n"); break; case IF_PROTO_X25: printf("protocol x25\n"); break; default: printf("unknown protocol %u\n", req.ifr_settings.type); } }while(0); close(sock); exit(0); } static void usage(void) { fprintf(stderr, "sethdlc version 1.15\n" "Copyright (C) 2000 - 2003 Krzysztof Halasa \n" "\n" "Usage: sethdlc INTERFACE [PHYSICAL] [clock CLOCK] [LOOPBACK] " "[slotmap SLOTMAP]\n" " sethdlc INTERFACE [PROTOCOL]\n" " sethdlc INTERFACE create | delete" #ifdef IF_PROTO_FR_ETH_PVC " [ether]" #endif " DLCI\n" " sethdlc INTERFACE private...\n" "\n" "PHYSICAL := v24 | v35 | x21 | e1 | t1\n" "CLOCK := int [rate RATE] | ext | txint [rate RATE] | txfromrx\n" "LOOPBACK := loopback | lb\n" "\n" "PROTOCOL := hdlc [ENCODING] [PARITY] |\n" #ifdef IF_PROTO_HDLC_ETH " hdlc-eth [ENCODING] [PARITY] |\n" #endif " cisco [interval val] [timeout val] |\n" " fr [lmi LMI] |\n" " ppp |\n" " x25\n" "\n" "ENCODING := nrz | nrzi | fm-mark | fm-space | manchester\n" "PARITY := no-parity | crc16 | crc16-pr0 | crc16-itu | crc16-itu-pr0 | crc32-itu\n" "LMI := none | ansi [LMI_SPEC] | ccitt [LMI_SPEC]\n" "LMI_SPEC := [dce] [t391 val] [t392 val] [n391 val] [n392 val] [n393 val]\n"); exit(0); } int main(int arg_c, char *arg_v[]) { argc = arg_c; argv = arg_v; if (argc <= 1) usage(); sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock < 0) error("Unable to create socket: %s\n", strerror(errno)); dahdi_copy_string(req.ifr_name, argv[1], sizeof(req.ifr_name)); /* Device name */ if (argc == 2) show_port(); argc -= 2; argv += 2; set_iface(); set_proto(); set_pvc(); private(); close(sock); usage(); exit(0); } dahdi-tools-2.10.2/tonezone.h0000644000000000000000000000570212537624573014535 0ustar rootroot/* * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01 * * Working with the "Tormenta ISA" Card * * Copyright (C) 2001-2008, Digium, Inc. * * Primary Author: Mark Spencer * */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU Lesser General Public License Version 2.1 as published * by the Free Software Foundation. See the LICENSE.LGPL file * included with this program for more details. * * In addition, when this program is distributed with Asterisk in * any form that would qualify as a 'combined work' or as a * 'derivative work' (but not mere aggregation), you can redistribute * and/or modify the combination under the terms of the license * provided with that copy of Asterisk, instead of the license * terms granted here. */ #ifndef _TONEZONE_H #define _TONEZONE_H #include struct tone_zone_sound { int toneid; char data[256]; /* Actual zone description */ /* Description is a series of tones of the format: [!]freq1[+freq2][/time] separated by commas. There are no spaces. The sequence is repeated back to the first tone description not preceeded by !. time is specified in milliseconds */ }; struct tone_zone { int zone; /* Zone number */ char country[10]; /* Country code */ char description[40]; /* Description */ int ringcadence[DAHDI_MAX_CADENCE]; /* Ring cadence */ struct tone_zone_sound tones[DAHDI_TONE_MAX]; int dtmf_high_level; /* Power level of high frequency component of DTMF, expressed in dBm0. */ int dtmf_low_level; /* Power level of low frequency component of DTMF, expressed in dBm0. */ int mfr1_level; /* Power level of MFR1, expressed in dBm0. */ int mfr2_level; /* Power level of MFR2, expressed in dBm0. */ }; extern struct tone_zone builtin_zones[]; /* Register a given two-letter tone zone if we can */ int tone_zone_register(int fd, char *country); /* Register a given two-letter tone zone if we can */ int tone_zone_register_zone(int fd, struct tone_zone *z); /* Retrieve a raw tone zone structure */ struct tone_zone *tone_zone_find(char *country); /* Retrieve a raw tone zone structure by id instead of country*/ struct tone_zone *tone_zone_find_by_num(int id); /* Retrieve a string name for a given tone id */ char *tone_zone_tone_name(int id); /* Set a given file descriptor into a given country -- USE THIS INTERFACE INSTEAD OF THE IOCTL ITSELF. Auto-loads tone zone if necessary */ int tone_zone_set_zone(int fd, char *country); /* Get the current tone zone */ int tone_zone_get_zone(int fd); /* Play a given tone, loading tone zone automatically if necessary */ int tone_zone_play_tone(int fd, int toneid); #endif dahdi-tools-2.10.2/timertest.c0000644000000000000000000000413112537624573014702 0ustar rootroot/* * Written by Mark Spencer * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include "dahdi_tools_version.h" int main(int argc, char *argv[]) { int fd; int x = 8000; int res; fd_set fds; struct timeval orig, now; fd = open("/dev/dahdi/timer", O_RDWR); if (fd < 0) { fprintf(stderr, "Unable to open timer: %s\n", strerror(errno)); exit(1); } printf("Opened timer...\n"); if (ioctl(fd, DAHDI_TIMERCONFIG, &x)) { fprintf(stderr, "Unable to set timer: %s\n", strerror(errno)); exit(1); } printf("Set timer duration to %d samples (%d ms)\n", x, x/8); printf("Waiting...\n"); gettimeofday(&orig, NULL); for(;;) { FD_ZERO(&fds); FD_SET(fd, &fds); res = select(fd + 1, NULL, NULL, &fds, NULL); if (res != 1) { fprintf(stderr, "Unexpected result %d: %s\n", res, strerror(errno)); exit(1); } x = -1; if (ioctl(fd, DAHDI_TIMERACK, &x)) { fprintf(stderr, "Unable to ack timer: %s\n", strerror(errno)); exit(1); } gettimeofday(&now, NULL); printf("Timer Expired (%ld ms)!\n", (now.tv_sec - orig.tv_sec) * 1000 + (now.tv_usec - orig.tv_usec) / 1000); } exit(0); } dahdi-tools-2.10.2/UPGRADE.txt0000644000000000000000000000762312537624573014357 0ustar rootrootUpgrade Notes ------------- Information for upgrading from Zaptel 1.2 or 1.4 to DAHDI 2.0 Upgrading from Zaptel to DAHDI is fairly straightforward; install this package using the installation instructions, and then reconfigure and rebuild Asterisk; Asterisk 1.4 releases later than 1.4.21, and all releases of Asterisk 1.6, will automatically use DAHDI in preference to Zaptel, even if Zaptel is still installed on the system. Important notes about upgrading: The Zaptel package, which included both kernel modules and userspace tools for configuring and managing the modules, has been split into two packages: * dahdi-linux: kernel modules * dahdi-tools: userspace tools In addition, there is a dahdi-linux-complete package that contains both dahdi-linux and dahdi-tools for simplified installation. NOTE: The dahdi-linux and dahdi-tools packages have *separate* version numbers; they will not be released 'in sync', and it is perfectly acceptable to use (for example) dahdi-tools 2.0.6 with dahdi-linux 2.0.11. The dahdi-linux-complete package version number will always include *both* of these version numbers so that you will know what is included in it. DAHDI-Linux ~~~~~~~~~~~ Module Names ^^^^^^^^^^^^ The primary kernel modules have changed names; the new names are: zaptel.ko -> dahdi.ko ztd-eth.ko -> dahdi_dynamic_eth.ko ztd-loc.ko -> dahdi_dynamic_loc.ko ztdummy.ko -> dahdi_dummy.ko ztdynamic.ko -> dahdi_dynamic.ko zttranscode.ko -> dahdi_transcode.ko * The kernel modules for card drivers have *not* changed names, although the wcusb and torisa drivers are no longer included. * This package no longer includes the 'menuselect' utility for choosing which modules to build; all modules that can be built are built automatically. Echo Canceller Modules ^^^^^^^^^^^^^^^^^^^^^^ It is no longer possible and needed to select a software echo canceler at compile time to build into dahdi.ko; all four included echo cancelers (MG2, KB1, SEC and SEC2) are built as loadable modules. If the Digium HPEC binary object file has been placed into the proper directory the HPEC module will be built as well. Any or all of these modules can be loaded at the same time, and the echo canceler to be used on the system's channels can be configured using the dahdi_cfg tool from the dahdi-tools package. IMPORTANT: It is *mandatory* to configure an echo canceler for the system's channels using dahdi_cfg. There is *no* default echo canceler with DAHDI, not even hardware echo cancellation modules. See <<_echo_cancellers,section on echo cancellers>> in sample system.conf. DAHDI-Tools ~~~~~~~~~~~ Many tool names have changed: ztcfg -> dahdi_cfg ztmonitor -> dahdi_monitor ztscan -> dahdi_scan ztspeed -> dahdi_speed zttest -> dahdi_test zttool -> dahdi_tool zapconf -> dahdi_genconf (deprecates genzaptelconf) * The system configuration file has moved from /etc/zaptel.conf to <<_sample_system_conf,/etc/dahdi/system.conf>>. * The dahdi_cfg tool can now be used to select an echo canceler on a channel-by-channel basis in the system configuration file; see system.conf.sample for examples of how to do this. * The configuration for XPP init_card_* scripts is done now in /etc/dahdi/xpp.conf and uses a simple syntax (example included). For PRI modules, the 'pri_protocol' setting, determines how to configure it (E1/T1). * In Astribank PRI modules, the LED behaviour represents which ports are *CLOCK MASTER* (red color) and which are *CLOCK SLAVE* (green color). Usually (but not always), this corresponds to the NT/TE settings in Asterisk. * The /etc/sysconfig/zaptel (or /etc/default/zaptel file, depending on your distribution) is now split into two separate files: /etc/dahdi/modules control which modules are loaded and module options are set via /etc/modprobe.d/dahdi. dahdi-tools-2.10.2/dahdi_pcap.c0000644000000000000000000001577112537624573014752 0ustar rootroot/* * Capturing a pcap from the DAHDI interface * * Copyright (C) 2011 Torrey Searle * * ISDN support added by Horacio Peña * Command line cleanups by Sverker Abrahamsson * * Requirements: * - pcap development library * - DAHDI_MIRROR ioctl which isn't enabled by default in dahdi-linux * To enable this unsupported feature, #define CONFIG_DAHDI_MIRROR * in dahdi-linux * - To build this program call the 'make dahdi_pcap' target */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BLOCK_SIZE 512 #define MAX_CHAN 16 //char ETH_P_LAPD[2] = {0x00, 0x30}; struct mtp2_phdr { u_int8_t sent; u_int8_t annex_a_used; u_int16_t link_number; }; struct lapd_sll_hdr { u_int16_t sll_pkttype; /* packet type */ u_int16_t sll_hatype; u_int16_t sll_halen; u_int8_t sll_addr[8]; u_int8_t sll_protocol[2]; /* protocol, should be ETH_P_LAPD */ }; struct chan_fds { int rfd; int tfd; int chan_id; int proto; char tx_buf[BLOCK_SIZE * 4]; int tx_len; char rx_buf[BLOCK_SIZE * 4]; int rx_len; }; int make_mirror(long type, int chan) { int res = 0; int fd = 0; struct dahdi_bufferinfo bi; fd = open("/dev/dahdi/pseudo", O_RDONLY); memset(&bi, 0, sizeof(bi)); bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; bi.numbufs = 32; bi.bufsize = BLOCK_SIZE; ioctl(fd, DAHDI_SET_BUFINFO, &bi); res = ioctl(fd, type, &chan); if(res) { printf("error setting channel err=%d!\n", res); return -1; } return fd; } int log_packet(struct chan_fds * fd, char is_read, pcap_dumper_t * dump) { unsigned char buf[BLOCK_SIZE * 4]; int res = 0; struct pcap_pkthdr hdr; struct mtp2_phdr * mtp2 = (struct mtp2_phdr *)buf; struct lapd_sll_hdr * lapd = (struct lapd_sll_hdr *)buf; unsigned char *dataptr = buf; int datasize = sizeof(buf); if(fd->proto == DLT_LINUX_LAPD) { dataptr += sizeof(struct lapd_sll_hdr); datasize -= sizeof(struct lapd_sll_hdr); } else { dataptr += sizeof(struct mtp2_phdr); datasize -= sizeof(struct mtp2_phdr); } memset(buf, 0, sizeof(buf)); if(is_read) { res = read(fd->rfd, dataptr, datasize); if(fd->rx_len > 0 && res == fd->rx_len && !memcmp(fd->rx_buf, dataptr, res) ) { //skipping dup return 0; } memcpy(fd->rx_buf, dataptr, res); fd->rx_len = res; } else { res = read(fd->tfd, dataptr, datasize); if(fd->tx_len > 0 && res == fd->tx_len && !memcmp(fd->tx_buf, dataptr, res) ) { //skipping dup return 0; } memcpy(fd->tx_buf, dataptr, res); fd->tx_len = res; } gettimeofday(&hdr.ts, NULL); if(res > 0) { if(fd->proto == DLT_LINUX_LAPD) { hdr.caplen = res+sizeof(struct lapd_sll_hdr)-2; hdr.len = res+sizeof(struct lapd_sll_hdr)-2; lapd->sll_pkttype = 3; lapd->sll_hatype = 0; lapd->sll_halen = res; // lapd->sll_addr = ??? lapd->sll_protocol[0] = 0x00; lapd->sll_protocol[1] = 0x30; } else { hdr.caplen = res+sizeof(struct mtp2_phdr); hdr.len = res+sizeof(struct mtp2_phdr); if(is_read) { mtp2->sent = 0; mtp2->annex_a_used = 0; } else { mtp2->sent = 1; mtp2->annex_a_used = 0; } mtp2->link_number = htons(fd->chan_id); } pcap_dump((u_char*)dump, &hdr, buf); pcap_dump_flush(dump); } return 1; } void usage() { printf("Usage: dahdi_pcap [OPTIONS]\n"); printf("Capture packets from DAHDI channels to pcap file\n\n"); printf("Options:\n"); printf(" -p, --proto=[mtp2|lapd] The protocol to capture, default mtp2\n"); printf(" -c, --chan= Comma separated list of channels to capture from, max %d. Mandatory\n", MAX_CHAN); printf(" -f, --file= The pcap file to capture to. Mandatory\n"); printf(" -h, --help Display this text\n"); } int main(int argc, char **argv) { struct chan_fds chans[MAX_CHAN]; char *filename = NULL; int num_chans = 0; int max_fd = 0; int proto = DLT_MTP2_WITH_PHDR; int i; int packetcount; int c; while (1) { int option_index = 0; static struct option long_options[] = { {"proto", required_argument, 0, 'p'}, {"chan", required_argument, 0, 'c'}, {"file", required_argument, 0, 'f'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "p:c:f:?", long_options, &option_index); if (c == -1) break; switch (c) { case 'p': // Protocol if(strcasecmp("LAPD", optarg)==0) { proto = DLT_LINUX_LAPD; } else if(argc > 0 && strcasecmp("MTP2", argv[1])==0) { proto = DLT_MTP2_WITH_PHDR; } break; case 'c': // TODO Should it be possible to override protocol per channel? // Channels, comma separated list while(optarg != NULL && num_chans < MAX_CHAN) { int chan = atoi(strsep(&optarg, ",")); chans[num_chans].tfd = make_mirror(DAHDI_TXMIRROR, chan); chans[num_chans].rfd = make_mirror(DAHDI_RXMIRROR, chan); chans[num_chans].chan_id = chan; chans[num_chans].proto = proto; if(chans[num_chans].tfd > max_fd) { max_fd = chans[num_chans].tfd; } if(chans[num_chans].rfd > max_fd) { max_fd = chans[num_chans].rfd; } num_chans++; } max_fd++; break; case 'f': // File to capture to filename=optarg; break; case 'h': default: // Usage usage(); exit(0); } } if((num_chans == 0) || (filename == NULL)) { usage(); exit(0); } else { printf("Capturing protocol %s on channels ", (proto == DLT_MTP2_WITH_PHDR ? "mtp2":"lapd")); for(i = 0; i < num_chans; i++) { printf("%d", chans[i].chan_id); if(i header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_SOUNDCARD_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define this to indicate the ${NEWT_DESCRIP} library */ #undef HAVE_NEWT /* Define to indicate the ${NEWT_DESCRIP} library version */ #undef HAVE_NEWT_VERSION /* Define to 1 if you have the `semtimedop' function. */ #undef HAVE_SEMTIMEDOP /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOUNDCARD_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define this to indicate the ${USB_DESCRIP} library */ #undef HAVE_USB /* Define to indicate the ${USB_DESCRIP} library version */ #undef HAVE_USB_VERSION /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif /* Enable threading extensions on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # undef __EXTENSIONS__ #endif /* Define to 1 if on MINIX. */ #undef _MINIX /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE /* Define to 1 if you need to in order for `stat' and other things to work. */ #undef _POSIX_SOURCE dahdi-tools-2.10.2/configure.ac0000644000000000000000000001267612537624573015021 0ustar rootroot# Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) m4_define([TOOLSVERSION], m4_bpatsubst(m4_esyscmd([build_tools/make_version . dahdi/tools]), [\([0-9.]*\)\(\w\|\W\)*], [\1])) AC_INIT(dahdi, TOOLSVERSION, www.asterisk.org) # check existence of the package AC_CONFIG_SRCDIR([dahdi_cfg.c]) AC_COPYRIGHT("dahdi-tools") AC_REVISION($Revision$) ac_default_prefix=/usr if test ${sysconfdir} = '${prefix}/etc'; then sysconfdir=/etc fi if test ${mandir} = '${prefix}/man'; then mandir=/usr/share/man fi if test ${localstatedir} = '${prefix}/var'; then localstatedir=/var fi # specify output header file AC_CONFIG_HEADER(autoconfig.h) # This needs to be before any macros that use the C compiler AC_GNU_SOURCE AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h]) AC_CHECK_TOOL([LD], [ld]) # Checks for programs. AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AST_CHECK_GNU_MAKE test_obj=conftest.o AC_COMPILE_IFELSE(AC_LANG_SOURCE(),[ BDFNAME=`LANG=C objdump -f $test_obj | grep -e "$test_obj:" | sed "s/.*file format \(.*\)/\1/"` BDFARCH=`LANG=C objdump -f $test_obj | grep -e "architecture:" | sed "s/.*ture: \(.*\),.*/\1/"` ],[]) AC_SUBST(BDFNAME) AC_SUBST(BDFARCH) # Set the default value of HOSTCC from CC if --host was not provided: HOSTCC=${HOSTCC:=${CC}} AC_SUBST(HOSTCC) AC_PATH_PROG([GREP], [grep], :) AC_PATH_PROG([SHELL], [sh], :) AC_PATH_PROG([LN], [ln], :) AC_PATH_PROG([WGET], [wget], :) if test "${WGET}" != ":" ; then DOWNLOAD=${WGET} else AC_PATH_PROG([FETCH], [fetch], [:]) DOWNLOAD=${FETCH} fi AC_SUBST(DOWNLOAD) AC_LANG(C) AC_ARG_ENABLE(dev-mode, [ --enable-dev-mode Turn on developer mode], [case "${enableval}" in y|ye|yes) DAHDI_DEVMODE=yes ;; n|no) DAHDI_DEVMODE=no ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-dev-mode) ;; esac]) AC_SUBST(DAHDI_DEVMODE) AC_MSG_CHECKING(for -Wdeclaration-after-statement support) if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then AC_MSG_RESULT(yes) DAHDI_DECLARATION_AFTER_STATEMENT=-Wdeclaration-after-statement else AC_MSG_RESULT(no) DAHDI_DECLARATION_AFTER_STATEMENT= fi AC_SUBST(DAHDI_DECLARATION_AFTER_STATEMENT) AST_EXT_LIB_SETUP([DAHDI], [DAHDI], [dahdi]) AST_EXT_LIB_SETUP([NEWT], [newt], [newt]) AST_EXT_LIB_SETUP([USB], [usb], [usb]) AST_C_DEFINE_CHECK([DAHDI], [DAHDI_CODE], [dahdi/user.h]) DAHDI23_DIR="${DAHDI_DIR}" AST_C_DEFINE_CHECK([DAHDI23], [DAHDI_CONFIG_NTTE], [dahdi/user.h]) AST_EXT_LIB_CHECK([NEWT], [newt], [newtBell], [newt.h]) AST_EXT_LIB_CHECK([USB], [usb], [usb_init], [usb.h]) AC_CHECK_FUNCS([semtimedop]) PBX_HDLC=0 AC_MSG_CHECKING([for GENERIC_HDLC_VERSION version 4 in linux/hdlc.h]) AC_COMPILE_IFELSE( [ AC_LANG_PROGRAM( [#include ], [#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 int foo = 0; #else int foo = bar; #endif 0])], [AC_MSG_RESULT(yes) PBX_HDLC=1], [AC_MSG_RESULT(no)] ) if test $PBX_HDLC = 0; then AC_MSG_CHECKING([for GENERIC_HDLC_VERSION version 4 in linux/hdlc/ioctl.h]) AC_COMPILE_IFELSE( [ AC_LANG_PROGRAM( [ #include #include ], [#if defined(GENERIC_HDLC_VERSION) && GENERIC_HDLC_VERSION >= 4 int foo = 0; #else int foo = bar; #endif 0])], [AC_MSG_RESULT(yes) PBX_HDLC=1], [AC_MSG_RESULT(no)] ) fi if test "x${PBX_HDLC}" != "x1"; then AC_MSG_NOTICE([GENERIC_HDLC_VERSION (version 4) not found, disabling sethdlc.]) fi AC_SUBST(PBX_HDLC) AC_ARG_WITH(selinux, [AS_HELP_STRING([--with-selinux], [enable (with) / disable (without) SELinux])], [USE_SELINUX=$withval], [ if test ! -x /usr/sbin/sestatus; then USE_SELINUX=no; elif /usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled"; then USE_SELINUX=yes fi ] ) AC_SUBST(USE_SELINUX) # for asciidoc before ver. 7, the backend must be stated explicitly: ASCIIDOC='asciidoc' asciidoc_ver=`asciidoc --version 2>&1 | awk '/^asciidoc /{print $2}' | cut -d. -f 1 | head -n 1` if test "$asciidoc_ver" != '' && test $asciidoc_ver -lt 7; then ASCIIDOC="asciidoc -b xhtml" fi AC_SUBST(ASCIIDOC) AC_ARG_WITH(ppp, [AS_HELP_STRING([--with-ppp=PATH],[Use PPP support from PATH])], [], [with_ppp=check] ) # somebody will fix that default_ppp_path=/usr case "$with_ppp" in yes|check) ppp_path="$default_ppp_path";; no) ppp_path='' ;; *) ppp_path="$with_ppp" ;; esac level_file="$ppp_path/include/pppd/patchlevel.h" PPP_VERSION= if test "$ppp_path" != '' && test -r "$level_file"; then PPPD_VERSION=`awk -F '"' '/VERSION/ { print $$2; }' $level_file` fi case "$with_ppp" in check|no) :;; *) # If we asked explicitly for ppp support if test "$PPPD_VERSION" = ''; then # but have not detected it AC_MSG_ERROR(failed to find pppd/patchlevel.h: no ppp support.) fi ;; esac if test "x${PBX_DAHDI}" != "x1"; then AC_MSG_NOTICE([***]) AC_MSG_NOTICE([*** Building this package requires DAHDI support. *** ]) AC_MSG_NOTICE([*** Please install the dahdi-linux package. ***]) AC_MSG_NOTICE([***]) exit 1 fi if test "x${PBX_DAHDI23}" != "x1"; then AC_MSG_NOTICE([***]) AC_MSG_NOTICE([*** Building this package requires DAHDI support (>= 2.3) *** ]) AC_MSG_NOTICE([*** Please install a recent dahdi-linux package. ***]) AC_MSG_NOTICE([***]) exit 1 fi AC_SUBST(PPPD_VERSION) AC_CONFIG_FILES([makeopts]) AC_OUTPUT AC_MSG_NOTICE(*** dahdi-tools build successfully configured ***) dahdi-tools-2.10.2/dahdi_speed.c0000644000000000000000000000271612537624573015122 0ustar rootroot/* * Written by Mark Spencer * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * * Generic speed test -- Run an infinite loop and * see how high we can count (in 5 seconds). You * can use this to measure how much CPU DAHDI REALLY * is taking. * * MUST BE COMPILED WITHOUT OPTIMIZATION * */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include "dahdi_tools_version.h" static long count=0; static void alm(int sig) { printf("Count: %ld\n", count); exit(0); } int main(int argc, char *argv[]) { int a=0,b=0,c; signal(SIGALRM, alm); alarm(5); for (;;) { for (c=0;c<1000;c++) a = a * b; count++; } } dahdi-tools-2.10.2/hdlctest.c0000644000000000000000000002060112537624573014474 0ustar rootroot/* * Written by Mark Spencer * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include #define FAST_HDLC_NEED_TABLES #include #include "bittest.h" #include "dahdi_tools_version.h" #define BLOCK_SIZE 2039 static unsigned short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; #define PPP_INITFCS 0xffff /* Initial FCS value */ #define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) void print_packet(unsigned char *buf, int len) { int x; printf("{ "); for (x = 0; x < len; x++) { printf("%02x ", buf[x]); } printf("}\n"); } static int bytes; static int errors; static int c; void dump_bits(unsigned char *outbuf, int len) { int x, i; for (x = 0; x < len; x++) { for (i = 0; i < 8; i++) { if (outbuf[x] & (1 << (7 - i))) { printf("1"); } else { printf("0"); } } } printf("\n"); } void dump_bitslong(unsigned int outbuf, int bits) { int i; printf("Dumping %d bits from %04x\n", bits, outbuf); for (i = 0; i < bits; i++) { if (outbuf & (1 << (31 - i))) { printf("1"); } else { printf("0"); } } printf("\n"); } int check_frame(unsigned char *outbuf, int res) { static int setup = 0; int x; unsigned short fcs = PPP_INITFCS; if (c < 1) { c = 1; } if (!setup) { c = outbuf[0]; setup++; } for (x = 0; x < res; x++) { if (outbuf[x] != c && (x < res - 2)) { printf("(Error %d): Unexpected result, %d != %d, position %d %d bytes since last error.\n", ++errors, outbuf[x], c, x, bytes); if (!x) { c = outbuf[0]; } bytes = 0; } else { bytes++; } fcs = PPP_FCS(fcs, outbuf[x]); } if (fcs != PPP_GOODFCS) { printf("FCS Check failed :( (%04x != %04x)\n", fcs, PPP_GOODFCS); } #if 0 if (res != c) { printf("Res is %d, expected %d\n", res, c+2); } #endif c = bit_next(c); return 0; } int main(int argc, char *argv[]) { int fd; int res, x; struct dahdi_params tp; struct dahdi_bufferinfo bi; int bs = BLOCK_SIZE; int pos = 0; unsigned char inbuf[BLOCK_SIZE]; unsigned char outbuf[BLOCK_SIZE]; int bytes = 0; int out; unsigned int olddata1; int oldones1; int oldbits1; unsigned int olddata = 0; int oldones = 0; int oldbits = 0; int hdlcmode = 0; struct fasthdlc_state fs; if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } fd = open(argv[1], O_RDWR, 0600); if (fd < 0) { fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno)); exit(1); } if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs)) { fprintf(stderr, "Unable to set block size to %d: %s\n", bs, strerror(errno)); exit(1); } if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { fprintf(stderr, "Unable to get channel parameters\n"); exit(1); } if ((tp.sigtype & DAHDI_SIG_HDLCRAW) == DAHDI_SIG_HDLCRAW) { printf("In HDLC mode\n"); hdlcmode = 1; } else if ((tp.sigtype & DAHDI_SIG_CLEAR) == DAHDI_SIG_CLEAR) { printf("In CLEAR mode\n"); hdlcmode = 0; } else { fprintf(stderr, "Not in a reasonable mode\n"); exit(1); } res = ioctl(fd, DAHDI_GET_BUFINFO, &bi); if (!res) { bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; bi.numbufs = 4; res = ioctl(fd, DAHDI_SET_BUFINFO, &bi); if (res < 0) { fprintf(stderr, "Unable to set buf info: %s\n", strerror(errno)); exit(1); } } else { fprintf(stderr, "Unable to get buf info: %s\n", strerror(errno)); exit(1); } ioctl(fd, DAHDI_GETEVENT); fasthdlc_precalc(); fasthdlc_init(&fs, FASTHDLC_MODE_64); for (;;) { res = read(fd, outbuf, sizeof(outbuf)); if (hdlcmode) { if (res < 0) { if (errno == ELAST) { if (ioctl(fd, DAHDI_GETEVENT, &x) < 0) { fprintf(stderr, "Unaable to get event: %s\n", strerror(errno)); exit(1); } fprintf(stderr, "Event: %d (%d bytes since last error)\n", x, bytes); bytes = 0; continue; } else { fprintf(stderr, "Error: %s\n", strerror(errno)); exit(1); } } #if 0 printf("Res is %d, buf0 is %d, buf1 is %d\n", res, outbuf[0], outbuf[1]); #endif if (res < 2) { fprintf(stderr, "Too small? Only got %d bytes\n", res); } check_frame(outbuf, res); } else { for (x = 0; x < res; x++) { oldones1 = oldones; oldbits1 = oldbits; olddata1 = olddata; oldones = fs.ones; oldbits = fs.bits; olddata = fs.data; fasthdlc_rx_load(&fs, outbuf[x]); out = fasthdlc_rx_run(&fs); if (out & RETURN_EMPTY_FLAG) { /* Empty */ } else if (out & RETURN_COMPLETE_FLAG) { if (pos && (pos < 2)) { printf("Too short? (%d)\n", pos); } else if (pos) { check_frame(inbuf, pos); } pos = 0; } else if (out & RETURN_DISCARD_FLAG) { printf("Discard (search = %d, len = %d, buf = %d, x=%d, res=%d, oldones: %d, oldbits: %d)\n", c, pos, inbuf[0], x, res, oldones, oldbits); dump_bitslong(olddata, oldbits); printf("Discard oldones: %d, oldbits: %d)\n", oldones1, oldbits1); dump_bitslong(olddata1, oldbits1); if (x > 64) { dump_bits(outbuf + x - 64, 64); dump_bits(outbuf + x, 64); } pos = 0; } else { if ((out != c) && (pos < c) && !pos) { printf("Warning: Expecting %d at pos %d, got %d (x =%d)\n", c, pos, out, x); if (x > 64) { dump_bits(outbuf + x - 64, 64); dump_bits(outbuf + x, 64); } } inbuf[pos++] = out; } } } } } dahdi-tools-2.10.2/config.sub0000755000000000000000000010115312537624573014503 0ustar rootroot#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2008-01-16' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray) os= basic_machine=$1 ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64vr | mips64vrel \ | mips64orion | mips64orionel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | score \ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64vr-* | mips64vrel-* \ | mips64orion-* | mips64orionel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; c90) basic_machine=c90-cray os=-unicos ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: dahdi-tools-2.10.2/bittest.h0000644000000000000000000000105212537624573014344 0ustar rootroot/* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ static int bit_next(int prev) { return (prev + 1) % 256; } dahdi-tools-2.10.2/Makefile0000644000000000000000000002525512537624573014170 0ustar rootroot# # Makefile for DAHDI tools # # Copyright (C) 2001-2010 Digium, Inc. # # ifeq ($(strip $(foreach var,clean distclean dist-clean update,$(findstring $(var),$(MAKECMDGOALS)))),) endif ifeq ($(strip $(foreach var,clean distclean dist-clean update,$(findstring $(var),$(MAKECMDGOALS)))),) ifneq ($(wildcard makeopts),) include makeopts endif endif SUBDIRS_UTILS_ALL:= ppp SUBDIRS_UTILS := xpp OPTFLAGS=-O2 CFLAGS+=-I. $(OPTFLAGS) -g -fPIC -Wall -DBUILDING_TONEZONE #-DTONEZONE_DRIVER ifneq (,$(findstring ppc,$(UNAME_M))) CFLAGS+=-fsigned-char endif ifneq (,$(findstring x86_64,$(UNAME_M))) CFLAGS+=-m64 endif ifeq ($(DAHDI_DEVMODE),yes) CFLAGS+=-Werror -Wunused -Wundef $(DAHDI_DECLARATION_AFTER_STATEMENT) -Wmissing-format-attribute -Wformat-security #-Wformat=2 endif ROOT_PREFIX= # extra cflags to build dependencies. Recursively expanded. MAKE_DEPS= -MD -MT $@ -MF .$(subst /,_,$@).d -MP CFLAGS+=$(DAHDI_INCLUDE) CHKCONFIG := $(wildcard /sbin/chkconfig) UPDATE_RCD := $(wildcard /usr/sbin/update-rc.d) ifeq (,$(DESTDIR)) ifneq (,$(CHKCONFIG)) ADD_INITD := $(CHKCONFIG) --add dahdi else ifneq (,$(UPDATE_RCD)) ADD_INITD := $(UPDATE_RCD) dahdi defaults 15 30 endif endif endif INITRD_DIR := $(firstword $(wildcard $(DESTDIR)/etc/rc.d/init.d $(DESTDIR)/etc/init.d)) ifneq (,$(INITRD_DIR)) INIT_TARGET := $(INITRD_DIR)/dahdi COPY_INITD := install -D dahdi.init $(INIT_TARGET) endif RCCONF_FILE = /etc/dahdi/init.conf MODULES_FILE = /etc/dahdi/modules GENCONF_FILE = /etc/dahdi/genconf_parameters MODPROBE_FILE = /etc/modprobe.d/dahdi.conf BLACKLIST_FILE = /etc/modprobe.d/dahdi.blacklist.conf BASH_COMP_DIR = /etc/bash_completion.d BASH_COMP_FILE = $(BASH_COMP_DIR)/dahdi NETSCR_DIR := $(firstword $(wildcard $(DESTDIR)/etc/sysconfig/network-scripts )) ifneq (,$(NETSCR_DIR)) NETSCR_TARGET := $(NETSCR_DIR)/ifup-hdlc COPY_NETSCR := install -D ifup-hdlc $(NETSCR_TARGET) endif TOOLSVERSION=$(shell build_tools/make_version . dahdi/tools) LTZ_A:=libtonezone.a LTZ_A_OBJS:=zonedata.o tonezone.o version.o LTZ_SO:=libtonezone.so LTZ_SO_OBJS:=zonedata.lo tonezone.lo version.o LTZ_SO_MAJOR_VER:=2 LTZ_SO_MINOR_VER:=0 # sbindir, libdir, includedir and mandir are defined in makeopts # (from configure). BIN_DIR:=$(sbindir) LIB_DIR:=$(libdir) INC_DIR:=$(includedir)/dahdi MAN_DIR:=$(mandir)/man8 DATA_DIR:=${datadir}/dahdi CONFIG_DIR:=$(sysconfdir)/dahdi CONFIG_FILE:=$(CONFIG_DIR)/system.conf UDEVRULES_DIR:=$(sysconfdir)/udev/rules.d # Utilities we build with a standard build procedure: UTILS = dahdi_tool dahdi_test dahdi_monitor dahdi_speed sethdlc dahdi_cfg \ fxstest fxotune dahdi_diag dahdi_scan # some tests: UTILS += patgen pattest patlooptest hdlcstress hdlctest hdlcgen \ hdlcverify timertest dahdi_maint BINS:=fxotune dahdi_cfg dahdi_monitor dahdi_speed dahdi_test dahdi_scan dahdi_maint ifeq (1,$(PBX_NEWT)) BINS += dahdi_tool endif ifeq (1,$(PBX_HDLC)) BINS += sethdlc endif ASSIGNED_DATA_SCRIPTS:=\ dahdi_handle_device \ dahdi_span_config \ dahdi_auto_assign_compat \ span_config.d/10-dahdi-cfg \ span_config.d/20-fxotune \ span_config.d/50-asterisk \ handle_device.d/10-span-types \ handle_device.d/20-span-assignments ASSIGNED_UTILS:=dahdi_span_assignments dahdi_span_types \ dahdi_waitfor_span_assignments ASSIGNED_CONF:=assigned-spans.conf.sample span-types.conf.sample MAN_PAGES:= \ $(wildcard $(BINS:%=doc/%.8)) \ $(wildcard $(ASSIGNED_UTILS:%=doc/%.8)) TEST_BINS:=patgen pattest patlooptest hdlcstress hdlctest hdlcgen hdlcverify timertest dahdi_maint # All the man pages. Not just installed ones: GROFF_PAGES := $(wildcard doc/*.8 xpp/*.8) GROFF_HTML := $(GROFF_PAGES:%=%.html) GENERATED_DOCS := $(GROFF_HTML) README.html README.Astribank.html all: prereq programs libs: $(LTZ_SO) $(LTZ_A) utils-subdirs: @for dir in $(SUBDIRS_UTILS); do \ $(MAKE) -C $$dir; \ done programs: libs utils utils: $(BINS) utils-subdirs version.c: FORCE @TOOLSVERSION="${TOOLSVERSION}" build_tools/make_version_c > $@.tmp @if cmp -s $@.tmp $@ ; then :; else \ mv $@.tmp $@ ; \ fi @rm -f $@.tmp tests: $(TEST_BINS) $(UTILS): %: %.o $(UTILS): version.o %.o: %.c $(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $< %.lo: %.c $(CC) $(CFLAGS) $(MAKE_DEPS) -c -o $@ $< %: %.o $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ prereq: config.status dahdi_tool: CFLAGS+=$(NEWT_INCLUDE) dahdi_tool: LIBS+=$(NEWT_LIB) dahdi_speed: CFLAGS+=-O0 $(LTZ_A): $(LTZ_A_OBJS) ar rcs $@ $^ ranlib $@ $(LTZ_SO): $(LTZ_SO_OBJS) $(CC) $(CFLAGS) -shared -Wl,-soname,$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) -o $@ $^ -lm dahdi_cfg: $(LTZ_A) dahdi_cfg: LIBS+=-lm -lpthread dahdi_pcap: $(CC) $(CFLAGS) dahdi_pcap.c -lpcap -o $@ $< fxstest: $(LTZ_SO) fxstest: LIBS+=-lm fxotune: LIBS+=-lm tonezones.txt: zonedata.c perl -ne 'next unless (/\.(country|description) = *"([^"]*)/); \ print (($$1 eq "country")? "* $$2\t":"$$2\n");' $< \ >$@ %.asciidoc: %.sample perl -n -e \ 'if (/^#($$|\s)(.*)/){ if (!$$in_doc){print "\n"}; $$in_doc=1; print "$$2\n" } else { if ($$in_doc){print "\n"}; $$in_doc=0; print " $$_" }' \ $< \ | perl -p -e 'if (/^ #?(\w+)=/ && ! exists $$cfgs{$$1}){my $$cfg = $$1; $$cfgs{$$cfg} = 1; s/^/\n[[cfg_$$cfg]]\n/}' >$@ docs: $(GENERATED_DOCS) genconf_parameters.sample: xpp/genconf_parameters cp $< $@ README.html: README system.conf.asciidoc init.conf.asciidoc tonezones.txt \ UPGRADE.txt genconf_parameters.asciidoc assigned-spans.conf.asciidoc \ span-types.conf.asciidoc $(ASCIIDOC) -n -a toc -a toclevels=4 $< README.Astribank.html: xpp/README.Astribank $(ASCIIDOC) -o $@ -n -a toc -a toclevels=4 $< # on Debian: this requires the full groff, not just groff-base. %.8.html: %.8 man -Thtml $^ >$@ htmlman: $(GROFF_HTML) install: all install-programs @echo "###################################################" @echo "###" @echo "### DAHDI tools installed successfully." @echo "### If you have not done so before, install init scripts with:" @echo "###" @echo "### make config" @echo "###" @echo "###################################################" install-programs: install-utils install-libs install-utils: utils install-utils-subdirs ifneq (,$(BINS)) install -d $(DESTDIR)$(BIN_DIR) install $(BINS) $(DESTDIR)$(BIN_DIR)/ install -d $(DESTDIR)$(MAN_DIR) install -m 644 $(MAN_PAGES) $(DESTDIR)$(MAN_DIR)/ endif ifeq (,$(wildcard $(DESTDIR)$(CONFIG_FILE))) $(INSTALL) -d $(DESTDIR)$(CONFIG_DIR) $(INSTALL) -m 644 system.conf.sample $(DESTDIR)$(CONFIG_FILE) endif install -d $(DESTDIR)$(DATA_DIR) tar cf - -C hotplug $(ASSIGNED_DATA_SCRIPTS) | tar xf - -C $(DESTDIR)$(DATA_DIR)/ install $(ASSIGNED_UTILS) $(DESTDIR)/$(BIN_DIR)/ install -m 644 $(ASSIGNED_CONF) $(DESTDIR)/$(CONFIG_DIR)/ install -d $(DESTDIR)$(BASH_COMP_DIR) install -m 644 dahdi-bash-completion $(DESTDIR)$(BASH_COMP_FILE) install-libs: libs $(INSTALL) -d -m 755 $(DESTDIR)/$(LIB_DIR) $(INSTALL) -m 755 $(LTZ_A) $(DESTDIR)$(LIB_DIR)/ $(INSTALL) -m 755 $(LTZ_SO) $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) ifeq (,$(DESTDIR)) if [ `id -u` = 0 ]; then \ /sbin/ldconfig || : ;\ fi endif rm -f $(DESTDIR)$(LIB_DIR)/$(LTZ_SO) $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).$(LTZ_SO_MAJOR_VER) $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ $(DESTDIR)$(LIB_DIR)/$(LTZ_SO) # Overwrite the 1.0 links out there. dahdi-tools 2.0.0 installed # 1.0 links but dahdi-tools changed them to 2.0 in order to explicitly # break applications linked with zaptel. But, this also meant that # applications linked with libtonezone.so.1.0 broke when dahdi-tools # 2.1.0 was installed. $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).1.0 $(LN) -sf $(LTZ_SO).$(LTZ_SO_MAJOR_VER).$(LTZ_SO_MINOR_VER) \ $(DESTDIR)$(LIB_DIR)/$(LTZ_SO).1 ifneq (no,$(USE_SELINUX)) ifeq (,$(DESTDIR)) /sbin/restorecon -v $(DESTDIR)$(LIB_DIR)/$(LTZ_SO) endif endif $(INSTALL) -d -m 755 $(DESTDIR)/$(INC_DIR) $(INSTALL) -m 644 tonezone.h $(DESTDIR)$(INC_DIR)/ install-utils-subdirs: @for dir in $(SUBDIRS_UTILS); do \ $(MAKE) -C $$dir install; \ done install-tests: tests ifneq (,$(TEST_BINS)) install -d $(DESTDIR)$(BIN_DIR) install $(TEST_BINS) $(DESTDIR)$(BIN_DIR)/ endif config: ifneq (,$(COPY_INITD)) $(COPY_INITD) endif ifeq (,$(wildcard $(DESTDIR)$(RCCONF_FILE))) $(INSTALL) -D -m 644 init.conf.sample $(DESTDIR)$(RCCONF_FILE) endif ifeq (,$(wildcard $(DESTDIR)$(MODULES_FILE))) $(INSTALL) -D -m 644 modules.sample $(DESTDIR)$(MODULES_FILE) endif ifeq (,$(wildcard $(DESTDIR)$(GENCONF_FILE))) $(INSTALL) -D -m 644 xpp/genconf_parameters $(DESTDIR)$(GENCONF_FILE) endif ifeq (,$(wildcard $(DESTDIR)$(MODPROBE_FILE))) $(INSTALL) -D -m 644 modprobe.conf.sample $(DESTDIR)$(MODPROBE_FILE) endif ifeq (,$(wildcard $(DESTDIR)$(BLACKLIST_FILE))) $(INSTALL) -D -m 644 blacklist.sample $(DESTDIR)$(BLACKLIST_FILE) endif $(INSTALL) -d $(DESTDIR)$(UDEVRULES_DIR) $(INSTALL) -D -m 644 dahdi.rules $(DESTDIR)$(UDEVRULES_DIR)/ ifneq (,$(COPY_NETSCR)) $(COPY_NETSCR) endif ifneq (,$(ADD_INITD)) $(ADD_INITD) endif @echo "DAHDI has been configured." @echo "" @echo "List of detected DAHDI devices:" @echo "" @if [ `xpp/dahdi_hardware | tee /dev/stderr | wc -l` -eq 0 ]; then \ echo "No hardware found"; \ else \ echo ""; \ echo "run 'dahdi_genconf modules' to load support for only " ;\ echo "the DAHDI hardware installed in this system. By "; \ echo "default support for all DAHDI hardware is loaded at "; \ echo "DAHDI start. "; \ fi update: @if [ -d .svn ]; then \ echo "Updating from Subversion..." ; \ svn update | tee update.out; \ rm -f .version; \ if [ `grep -c ^C update.out` -gt 0 ]; then \ echo ; echo "The following files have conflicts:" ; \ grep ^C update.out | cut -b4- ; \ fi ; \ rm -f update.out; \ else \ echo "Not under version control"; \ fi dist: @./build_tools/make_dist "dahdi-tools" "$(TOOLSVERSION)" clean: rm -f $(BINS) $(TEST_BINS) rm -f *.o dahdi_cfg tzdriver sethdlc rm -f $(LTZ_SO) $(LTZ_A) *.lo @for dir in $(SUBDIRS_UTILS_ALL); do \ $(MAKE) -C $$dir clean; \ done @for dir in $(SUBDIRS_UTILS); do \ $(MAKE) -C $$dir clean; \ done rm -f libtonezone* rm -f fxotune rm -f core rm -f dahdi_cfg-shared fxstest rm -rf $(GENERATED_DOCS) *.asciidoc tonezones.txt rm -f dahdi_pcap distclean: dist-clean dist-clean: clean rm -f makeopts rm -f config.log config.status rm -f .*.d config.status: configure @CFLAGS="" ./configure @echo "****" @echo "**** The configure script was just executed, so 'make' needs to be" @echo "**** restarted." @echo "****" @exit 1 .PHONY: distclean dist-clean clean all install programs tests devel data config update install-programs install-libs install-utils-subdirs utils-subdirs prereq dist FORCE: ifneq ($(wildcard .*.d),) include .*.d endif dahdi-tools-2.10.2/hotplug/0000755000000000000000000000000012537624573014201 5ustar rootrootdahdi-tools-2.10.2/hotplug/dahdi_span_config0000755000000000000000000000460412537624573017552 0ustar rootroot#! /bin/sh # # /usr/share/dahdi/dahdi_span_config # # Called by UDEV when a dahdi span is added/removed # me=`basename $0` dir=`dirname $0` LOGGER="logger -i -t '$me'" NAME=`basename "$DEVPATH" | tr -c 'A-Za-z0-9-' '_'` exec 2> /dev/null # Always redirect stderr somewhere, otherwise the shell script will die # when it tries to do I/O related stuff on closed file descriptor. # Our default is to throw it down the bit-bucket. #exec 2> /dev/console ## If you wish to trace this script: #exec 2> "/tmp/${me}.$NAME" 1>&2 # Our directory in the beginning, so we can use local lab setup PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" export PATH set -e #echo >&2 "$0($ACTION): DEBUG($# args): '$*'" # Do we have a configuration? if [ -f /etc/dahdi/init.conf ]; then . /etc/dahdi/init.conf fi if [ "$DAHDI_UDEV_DISABLE_SPANS" = 'yes' ]; then echo "DAHDI_UDEV_DISABLE_SPANS=yes. Skip $DEVPATH" | $LOGGER exit 0 fi # Can we pass a different value so we can use # alternate (testing) configuration? # Meanwhile, make it hard-coded. DAHDICONFDIR='/etc/dahdi' export DAHDICONFDIR run_parts() { # Have our internal "run-parts" (adapted from Fedora), # as implementations differ for i in `LC_ALL=C; ls -d $dir/span_config.d/*[!~,] 2>/dev/null` ; do [ -d "$i" ] && continue [ ! -x "$i" ] && continue # Don't run *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} files case "$i" in *.cfsaved|*.rpmsave|*.rpmorig|*.rpmnew|*.swp|*,v) continue ;; esac #echo "D: Running '$i'" "$i" done } case "$ACTION" in add) echo "$ACTION: $DEVPATH" | $LOGGER # Old driver. These scripts probably won't work anyway. if [ ! -f /sys/module/dahdi/parameters/auto_assign_spans ]; then if [ -f /sys/module/dahdi ]; then $LOGGER "Old driver (no auto_assign_spans parameter). Skip $DEVPATH" exit 0 fi fi if [ $(cat /sys/module/dahdi/parameters/auto_assign_spans) -ne 0 ]; then $LOGGER "auto_assign_spans=1. Skip $DEVPATH" exit 0 fi # Set variables span_devpath="/sys$DEVPATH" SPANNO=`echo "$span_devpath" | sed 's,.*/span-,,'` BASECHAN=`cat "$span_devpath/basechan"` CHANNELS=`cat "$span_devpath/channels"` ENDCHAN=`expr "$BASECHAN" + "$CHANNELS" - 1` export SPANNO BASECHAN CHANNELS ENDCHAN # Background run -- don't block udev run_parts 2>&1 < /dev/null | $LOGGER & ;; remove|online|offline) # Nothing to do yet... echo "$ACTION: $DEVPATH" | $LOGGER ;; *) echo "UNHANDLED: $ACTION: $DEVPATH" | $LOGGER ;; esac dahdi-tools-2.10.2/hotplug/handle_device.d/0000755000000000000000000000000012537624573017175 5ustar rootrootdahdi-tools-2.10.2/hotplug/handle_device.d/10-span-types0000755000000000000000000000022012537624573021436 0ustar rootroot#! /bin/sh case "$ACTION" in add) ;; *) exit 0 esac if [ -r "$DAHDICONFDIR/span-types.conf" ]; then dahdi_span_types set "/sys$DEVPATH" fi dahdi-tools-2.10.2/hotplug/handle_device.d/20-span-assignments0000755000000000000000000000044212537624573022634 0ustar rootroot#! /bin/sh case "$ACTION" in add) ;; *) exit 0 esac # For now, handle only spans in assigned-spans.conf # We leave other cases to /etc/init.d/dahdi, so # legacy ordering can be preserved. if [ -r "$DAHDICONFDIR/assigned-spans.conf" ]; then dahdi_span_assignments add "/sys$DEVPATH" fi dahdi-tools-2.10.2/hotplug/dahdi_auto_assign_compat0000755000000000000000000000101212537624573021131 0ustar rootroot#! /bin/sh devdir='/sys/bus/dahdi_devices/devices' # DAHDI is loaded? if [ ! -d "$devdir" ]; then exit 0 fi devices_by_registration_time() { grep -H '' $devdir/*/registration_time 2>/dev/null | \ sed 's,/registration_time:,\t,' | \ sort -k 2,2 } # First assign non-Astribank devices devices_by_registration_time | \ grep -v '/astribanks:' | \ while read devpath time; do echo >&2 "D: auto '$devpath'" dahdi_span_assignments auto "$devpath" done # Now handle Astribanks LC_ALL=C dahdi_registration -Rv on dahdi-tools-2.10.2/hotplug/span_config.d/0000755000000000000000000000000012537624573016711 5ustar rootrootdahdi-tools-2.10.2/hotplug/span_config.d/50-asterisk0000755000000000000000000000064712537624573020715 0ustar rootroot#! /bin/sh # This file, if installed under /usr/share/dahdi/span_config.d/ , will # attempt to add a newly-generated span to a running copy of Asterisk. # Asterisk has to be running (if not: it will pick the span on its # startup), and has to have the channels already configured. if [ "$ACTION" != 'add' ]; then # Nothing to do here exit 0 fi # Add to asterisk asterisk -rx "dahdi create channels $BASECHAN $ENDCHAN" dahdi-tools-2.10.2/hotplug/span_config.d/10-dahdi-cfg0000755000000000000000000000115712537624573020667 0ustar rootroot#! /bin/sh if [ "$ACTION" != 'add' ]; then # Nothing to do here exit 0 fi # Sanity check checkit=`"dahdi_cfg" --help 2>&1 | grep -- '-S' | wc -l` if [ "$checkit" != 1 ]; then echo "Bad dahdi_cfg (no -S support). Skipping" exit 0 fi run_dahdi_cfg() { echo "dahdi_cfg: span $SPANNO <$BASECHAN-$ENDCHAN> ($DEVPATH)" dahdi_cfg -c "$cfg_file" -S "$SPANNO" -C "$BASECHAN-$ENDCHAN" } # Configure DAHDI cfg_file="$DAHDICONFDIR/system.conf" if [ -r "$cfg_file" ]; then run_dahdi_cfg else echo "Using auto-generated config for dahdi_cfg" cfg_file='-' DAHDI_CONF_FILE="$cfg_file" dahdi_genconf system | run_dahdi_cfg fi dahdi-tools-2.10.2/hotplug/span_config.d/20-fxotune0000755000000000000000000000036712537624573020554 0ustar rootroot#! /bin/sh if [ "$ACTION" != 'add' ]; then # Nothing to do here exit 0 fi fxotune_cfg='/etc/fxotune.conf' if [ -r "$fxotune_cfg" ]; then echo "fxotune: span $SPANNO <$BASECHAN-$ENDCHAN> ($DEVPATH)" fxotune -s -b "$BASECHAN" -e "$ENDCHAN" fi dahdi-tools-2.10.2/hotplug/dahdi_handle_device0000755000000000000000000000416412537624573020037 0ustar rootroot#! /bin/sh # # /usr/share/dahdi/dahdi_handle_device # # Called by UDEV when a dahdi device is added/removed # me=`basename $0` dir=`dirname $0` LOGGER="logger -i -t '$me'" NAME=`basename "$DEVPATH" | tr -c 'A-Za-z0-9-' '_'` # Always redirect stderr somewhere, otherwise the shell script will die # when it tries to do I/O related stuff on closed file descriptor. # Our default is to throw it down the bit-bucket. exec 2> /dev/null # If you wish to trace this script: #exec 2> "/tmp/${me}.$NAME" 1>&2 #exec 2> /dev/console # Our directory in the beginning, so we can use local lab setup PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" export PATH set -e #echo >&2 "$0($ACTION): DEBUG($# args): '$*'" # Do we have a configuration? if [ -f /etc/dahdi/init.conf ]; then . /etc/dahdi/init.conf fi if [ "$DAHDI_UDEV_DISABLE_DEVICES" = 'yes' ]; then echo "DAHDI_UDEV_DISABLE_DEVICES=yes. Skip $DEVPATH" | $LOGGER exit 0 fi # Can we pass a different value so we can use # alternate (testing) configuration? # Meanwhile, make it hard-coded. DAHDICONFDIR='/etc/dahdi' export DAHDICONFDIR run_parts() { # Have our internal "run-parts" (adapted from Fedora), # as implementations differ for i in `LC_ALL=C; ls -d $dir/handle_device.d/*[!~,] 2>/dev/null` ; do [ -d "$i" ] && continue [ ! -x "$i" ] && continue # Don't run *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} files case "$i" in *.cfsaved|*.rpmsave|*.rpmorig|*.rpmnew|*.swp|*,v) continue ;; esac echo "D: Running '$i'" "$i" done } case "$ACTION" in add) echo "$ACTION: $DEVPATH" | $LOGGER # Check if we can safely do our job if [ ! -f /sys/module/dahdi/parameters/auto_assign_spans ]; then echo "Old driver (no auto_assign_spans parameter). Skip $DEVPATH" | $LOGGER exit 0 fi if [ `cat /sys/module/dahdi/parameters/auto_assign_spans` -ne 0 ]; then echo "auto_assign_spans=1. Skip $DEVPATH" | $LOGGER exit 0 fi # Background run -- don't block udev run_parts 2>&1 < /dev/null | $LOGGER & ;; remove) echo "$ACTION: $DEVPATH" | $LOGGER # Background run -- don't block udev run_parts 2>&1 < /dev/null | $LOGGER & ;; *) echo "UNHANDLED: $ACTION: $DEVPATH" | $LOGGER ;; esac dahdi-tools-2.10.2/assigned-spans.conf.sample0000644000000000000000000000312112537624573017562 0ustar rootroot# # /etc/dahdi/assigned-spans.conf: # # This file assigns span and channel numbers to dahdi devices # # Built as a table keyed by : # .... # # Where: # * The field may be either: # hardware_id # @location # devpath (in sysfs) # * Shell-style globbing is allowed for the field # * There may one or more of # * Each is composed as: # :: # # Examples: # Astribank with two spans: # FXS * 8 channels + 4 digital inputs 2 digital outputs # FXO * 8 channels #usb:QA-1 1:1:1 #usb:QA-1 2:2:15 # Same Astribank in one-liner #usb:QA-1 1:1:1 2:2:15 # Astribank with 4*PRI spans and 3*FXS*8 spans # Note that channels are NOT globally contigous # each span get its own 50 numbers. Also, skip # Channel number 250... #usb:INT03165 1:1:1 # E1 #usb:INT03165 2:2:51 # E1 #usb:INT03165 3:3:151 # E1 #usb:INT03165 4:4:201 # E1 #usb:INT03165 5:5:301 # FXS * 8 channels #usb:INT03165 6:6:351 # FXS * 8 channels #usb:INT03165 7:7:401 # FXS * 8 channels # Alternatively -- all in one-line #usb:INT03165 1:1:1 2:2:51 3:3:151 4:4:201 5:5:301 6:6:351 7:7:401 # Astribank with 4*BRI without hardware_id :-( # We use the location on the bus (ie: where it is physically # located). Note the '@' prefix that indicate the location key. #@usb-0000:00:1d.7-3 1:1:50 #@usb-0000:00:1d.7-3 2:2:100 #@usb-0000:00:1d.7-3 3:3:150 #@usb-0000:00:1d.7-3 4:4:200 # Same configuration with globbing: #/sys/*/usb1/1-6/* 1:1:50 #/sys/*/usb1/1-6/* 2:2:100 #/sys/*/usb1/1-6/* 3:3:150 #/sys/*/usb1/1-6/* 4:4:200 dahdi-tools-2.10.2/dahdi_cfg.c0000644000000000000000000013621512537624573014563 0ustar rootroot/* * Configuration program for DAHDI Telephony Interface * * Written by Mark Spencer * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tonezone.h" #include "dahdi_tools_version.h" #define CONFIG_FILENAME "/etc/dahdi/system.conf" #define MASTER_DEVICE "/dev/dahdi/ctl" #define NUM_SPANS DAHDI_MAX_SPANS #define NUM_TONES 15 /*! A sanity check for the timing parameter of the span. * * Note that each driver using it is still responsible for validating * that value. */ #define MAX_TIMING 255 /* Assume no more than 1024 dynamics */ #define NUM_DYNAMIC 1024 static int lineno=0; static FILE *cf; static char *filename=CONFIG_FILENAME; int rxtones[NUM_TONES + 1],rxtags[NUM_TONES + 1],txtones[NUM_TONES + 1]; int bursttime = 0, debouncetime = 0, invertcor = 0, exttone = 0, corthresh = 0; int txgain = 0, rxgain = 0, deemp = 0, preemp = 0; int corthreshes[] = {3125,6250,9375,12500,15625,18750,21875,25000,0} ; static int toneindex = 1; #define DEBUG_READER (1 << 0) #define DEBUG_PARSER (1 << 1) #define DEBUG_APPLY (1 << 2) static int debug = 0; static int errcnt = 0; static int deftonezone = -1; static struct dahdi_lineconfig lc[DAHDI_MAX_SPANS]; static struct dahdi_chanconfig cc[DAHDI_MAX_CHANNELS]; static int current_span = 0; static int only_span = 0; static int restrict_channels = 0; static int selected_channels[DAHDI_MAX_CHANNELS]; static int chan2span[DAHDI_MAX_CHANNELS]; static int declared_spans[DAHDI_MAX_SPANS]; static struct dahdi_attach_echocan ae[DAHDI_MAX_CHANNELS]; static struct dahdi_dynamic_span zds[NUM_DYNAMIC]; static const char *sig[DAHDI_MAX_CHANNELS]; /* Signalling */ static int slineno[DAHDI_MAX_CHANNELS]; /* Line number where signalling specified */ static int fiftysixkhdlc[DAHDI_MAX_CHANNELS]; static int spans=0; static int dry_run = 0; static int verbose = 0; static int force = 0; static int stopmode = 0; static int numdynamic = 0; static char zonestoload[DAHDI_TONE_ZONE_MAX][10]; static int numzones = 0; static int fd = -1; static const char *lbostr[] = { "0 db (CSU)/0-133 feet (DSX-1)", "133-266 feet (DSX-1)", "266-399 feet (DSX-1)", "399-533 feet (DSX-1)", "533-655 feet (DSX-1)", "-7.5db (CSU)", "-15db (CSU)", "-22.5db (CSU)" }; static const char *laws[] = { "Default", "Mu-law", "A-law" }; static bool _are_all_spans_assigned(const char *device_path) { char attribute[1024]; int res; FILE *fp; int span_count; DIR *dirp; struct dirent *dirent; snprintf(attribute, sizeof(attribute) - 1, "%s/span_count", device_path); fp = fopen(attribute, "r"); if (NULL == fp) { fprintf(stderr, "Failed to open '%s'.\n", attribute); return false; } res = fscanf(fp, "%d", &span_count); fclose(fp); if (EOF == res) { fprintf(stderr, "Failed to read '%s'.\n", attribute); return false; } dirp = opendir(device_path); while (span_count) { dirent = readdir(dirp); if (NULL == dirent) break; if (!strncmp("span-", dirent->d_name, 5)) { --span_count; } } closedir(dirp); return (span_count > 0) ? false : true; } /** * are_all_spans_assigned - Look in sysfs to see if all spans for a device are assigned. * * Returns true if there are $span_count child spans of all devices, or false * otherwise. */ static bool are_all_spans_assigned(void) { DIR *dirp; struct dirent *dirent; bool res = true; char device_path[1024]; dirp = opendir("/sys/bus/dahdi_devices/devices"); if (!dirp) { /* If we cannot open dahdi_devices, either dahdi isn't loaded, * or we're using an older version of DAHDI that doesn't use * sysfs. */ return true; } while (true && res) { dirent = readdir(dirp); if (NULL == dirent) break; if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..")) continue; snprintf(device_path, sizeof(device_path)-1, "/sys/bus/dahdi_devices/devices/%s", dirent->d_name); res = _are_all_spans_assigned(device_path); } closedir(dirp); errno = 0; return res; } static bool wait_for_all_spans_assigned(unsigned long timeout_sec) { bool all_assigned = are_all_spans_assigned(); unsigned int timeout = 10*timeout_sec; while (!all_assigned && --timeout) { usleep(100000); all_assigned = are_all_spans_assigned(); } return all_assigned; } static const char *sigtype_to_str(const int sig) { switch (sig) { case 0: return "Unused"; case DAHDI_SIG_EM: return "E & M"; case DAHDI_SIG_EM_E1: return "E & M E1"; case DAHDI_SIG_FXSLS: return "FXS Loopstart"; case DAHDI_SIG_FXSGS: return "FXS Groundstart"; case DAHDI_SIG_FXSKS: return "FXS Kewlstart"; case DAHDI_SIG_FXOLS: return "FXO Loopstart"; case DAHDI_SIG_FXOGS: return "FXO Groundstart"; case DAHDI_SIG_FXOKS: return "FXO Kewlstart"; case DAHDI_SIG_CAS: return "CAS / User"; case DAHDI_SIG_DACS: return "DACS"; case DAHDI_SIG_DACS_RBS: return "DACS w/RBS"; case DAHDI_SIG_CLEAR: return "Clear channel"; case DAHDI_SIG_SLAVE: return "Slave channel"; case DAHDI_SIG_HDLCRAW: return "Raw HDLC"; case DAHDI_SIG_HDLCNET: return "Network HDLC"; case DAHDI_SIG_HDLCFCS: return "HDLC with FCS check"; case DAHDI_SIG_HARDHDLC: return "Hardware assisted D-channel"; case DAHDI_SIG_MTP2: return "MTP2"; default: return "Unknown"; } } static void clear_fields() { memset(rxtones,0,sizeof(rxtones)); memset(rxtags,0,sizeof(rxtags)); memset(txtones,0,sizeof(txtones)); bursttime = 0; debouncetime = 0; invertcor = 0; exttone = 0; txgain = 0; rxgain = 0; deemp = 0; preemp = 0; } static int error(char *fmt, ...) __attribute__ ((format(printf, 1, 2))); static int error(char *fmt, ...) { int res; static int shown=0; va_list ap; if (!shown) { fprintf(stderr, "Notice: Configuration file is %s\n", filename); shown++; } res = fprintf(stderr, "line %d: ", lineno); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); errcnt++; return res; } static char *trim(char *buf) { size_t len; while (*buf && (*buf < 33)) { buf++; } len = strlen(buf); while (len && buf[len-1] < 33) { buf[--len] = '\0'; } return buf; } static int skip_channel(int x) { int spanno = chan2span[x]; if (restrict_channels) { if (!selected_channels[x]) return 1; /* sanity check */ if (only_span) { if (spanno != 0 && only_span != spanno) { fprintf(stderr, "Only span %d. Skip selected channel %d from span %d\n", only_span, x, spanno); return 1; } } } else { if (only_span && !declared_spans[only_span]) { fprintf(stderr, "Error: analog span %d given to '-S', without '-C' restriction.\n", only_span); exit(1); } if (only_span && only_span != spanno) return 1; } return 0; } static int parseargs(char *input, char *output[], int maxargs, char sep) { char *c; int pos=0; c = input; output[pos++] = c; while(*c) { while(*c && (*c != sep)) c++; if (*c) { *c = '\0'; c++; while(*c && (*c < 33)) c++; if (*c) { if (pos >= maxargs) return -1; output[pos] = c; trim(output[pos]); pos++; output[pos] = NULL; /* Return error if we have too many */ } else return pos; } } return pos; } int dspanconfig(char *keyword, char *args) { static char *realargs[10]; int res; int chans; int timing; res = parseargs(args, realargs, 4, ','); if (res != 4) { error("Incorrect number of arguments to 'dynamic' (should be ,
,, )\n"); return -1; } res = sscanf(realargs[2], "%d", &chans); if ((res == 1) && (chans < 1)) res = -1; if (res != 1) { error("Invalid number of channels '%s', should be a number > 0.\n", realargs[2]); return -1; } res = sscanf(realargs[3], "%d", &timing); if ((res == 1) && (timing < 0)) res = -1; if (res != 1) { error("Invalid timing '%s', should be a number > 0.\n", realargs[3]); return -1; } dahdi_copy_string(zds[numdynamic].driver, realargs[0], sizeof(zds[numdynamic].driver)); dahdi_copy_string(zds[numdynamic].addr, realargs[1], sizeof(zds[numdynamic].addr)); zds[numdynamic].numchans = chans; zds[numdynamic].timing = timing; numdynamic++; return 0; } int spanconfig(char *keyword, char *args) { static char *realargs[10]; int res; int argc; int span; int timing; int i; argc = res = parseargs(args, realargs, 9, ','); if ((res < 5) || (res > 9)) { error("Incorrect number of arguments to 'span' (should be ,,,,[, crc4 | yellow [, yellow]])\n"); return -1; } res = sscanf(realargs[0], "%d", &span); if (res != 1) { error("Span number should be a valid span number, not '%s'\n", realargs[0]); return -1; } current_span = span; declared_spans[span] = 1; res = sscanf(realargs[1], "%d", &timing); if ((res != 1) || (timing < 0) || (timing > MAX_TIMING)) { error("Timing should be a number from 0 to %d, not '%s'\n", MAX_TIMING, realargs[1]); return -1; } res = sscanf(realargs[2], "%d", &lc[spans].lbo); if (res != 1) { error("Line build-out (LBO) should be a number from 0 to 7 (usually 0) not '%s'\n", realargs[2]); return -1; } if ((lc[spans].lbo < 0) || (lc[spans].lbo > 7)) { error("Line build-out should be in the range 0 to 7, not %d\n", lc[spans].lbo); return -1; } if (!strcasecmp(realargs[3], "d4")) { lc[spans].lineconfig |= DAHDI_CONFIG_D4; lc[spans].lineconfig &= ~DAHDI_CONFIG_ESF; lc[spans].lineconfig &= ~DAHDI_CONFIG_CCS; } else if (!strcasecmp(realargs[3], "esf")) { lc[spans].lineconfig |= DAHDI_CONFIG_ESF; lc[spans].lineconfig &= ~DAHDI_CONFIG_D4; lc[spans].lineconfig &= ~DAHDI_CONFIG_CCS; } else if (!strcasecmp(realargs[3], "ccs")) { lc[spans].lineconfig |= DAHDI_CONFIG_CCS; lc[spans].lineconfig &= ~(DAHDI_CONFIG_ESF | DAHDI_CONFIG_D4); } else if (!strcasecmp(realargs[3], "cas")) { lc[spans].lineconfig &= ~DAHDI_CONFIG_CCS; lc[spans].lineconfig &= ~(DAHDI_CONFIG_ESF | DAHDI_CONFIG_D4); } else { error("Framing(T1)/Signalling(E1) must be one of 'd4', 'esf', 'cas' or 'ccs', not '%s'\n", realargs[3]); return -1; } if (!strcasecmp(realargs[4], "ami")) { lc[spans].lineconfig &= ~(DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_HDB3); lc[spans].lineconfig |= DAHDI_CONFIG_AMI; } else if (!strcasecmp(realargs[4], "b8zs")) { lc[spans].lineconfig |= DAHDI_CONFIG_B8ZS; lc[spans].lineconfig &= ~(DAHDI_CONFIG_AMI | DAHDI_CONFIG_HDB3); } else if (!strcasecmp(realargs[4], "hdb3")) { lc[spans].lineconfig |= DAHDI_CONFIG_HDB3; lc[spans].lineconfig &= ~(DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS); } else { error("Coding must be one of 'ami', 'b8zs' or 'hdb3', not '%s'\n", realargs[4]); return -1; } for (i = 5; i < argc; i++) { if (!strcasecmp(realargs[i], "yellow")) lc[spans].lineconfig |= DAHDI_CONFIG_NOTOPEN; else if (!strcasecmp(realargs[i], "crc4")) lc[spans].lineconfig |= DAHDI_CONFIG_CRC4; else if (!strcasecmp(realargs[i], "nt")) lc[spans].lineconfig |= DAHDI_CONFIG_NTTE; else if (!strcasecmp(realargs[i], "te")) lc[spans].lineconfig &= ~DAHDI_CONFIG_NTTE; else if (!strcasecmp(realargs[i], "term")) lc[spans].lineconfig |= DAHDI_CONFIG_TERM; else { error("Remaining arguments may be any of: 'yellow', 'crc4', 'nt', 'te', 'term', not '%s'\n", realargs[i]); return -1; } } lc[spans].span = span; lc[spans].sync = timing; /* Valid span */ spans++; return 0; } int apply_channels(int chans[], char *argstr) { char *args[DAHDI_MAX_CHANNELS+1]; char *range[3]; int res,x, res2,y; int chan; int start, finish; char argcopy[256]; res = parseargs(argstr, args, DAHDI_MAX_CHANNELS, ','); if (res < 0) { error("Too many arguments... Max is %d\n", DAHDI_MAX_CHANNELS); return -1; } for (x=0;x-.\n", args[x]); return -1; } res2 =sscanf(range[0], "%d", &start); if (res2 != 1) { error("Syntax error. Start of range '%s' should be a number from 1 to %d\n", args[x], DAHDI_MAX_CHANNELS - 1); return -1; } else if ((start < 1) || (start >= DAHDI_MAX_CHANNELS)) { error("Start of range '%s' must be between 1 and %d (not '%d')\n", args[x], DAHDI_MAX_CHANNELS - 1, start); return -1; } res2 =sscanf(range[1], "%d", &finish); if (res2 != 1) { error("Syntax error. End of range '%s' should be a number from 1 to %d\n", args[x], DAHDI_MAX_CHANNELS - 1); return -1; } else if ((finish < 1) || (finish >= DAHDI_MAX_CHANNELS)) { error("end of range '%s' must be between 1 and %d (not '%d')\n", args[x], DAHDI_MAX_CHANNELS - 1, finish); return -1; } if (start > finish) { error("Range '%s' should start before it ends\n", args[x]); return -1; } for (y=start;y<=finish;y++) chans[y]=1; } else { /* It's a single channel */ res2 =sscanf(args[x], "%d", &chan); if (res2 != 1) { error("Syntax error. Channel should be a number from 1 to %d, not '%s'\n", DAHDI_MAX_CHANNELS - 1, args[x]); return -1; } else if ((chan < 1) || (chan >= DAHDI_MAX_CHANNELS)) { error("Channel must be between 1 and %d (not '%d')\n", DAHDI_MAX_CHANNELS - 1, chan); return -1; } chans[chan]=1; } } return res; } int parse_idle(int *i, char *s) { char a,b,c,d; if (s) { if (sscanf(s, "%c%c%c%c", &a,&b,&c,&d) == 4) { if (((a == '0') || (a == '1')) && ((b == '0') || (b == '1')) && ((c == '0') || (c == '1')) && ((d == '0') || (d == '1'))) { *i = 0; if (a == '1') *i |= DAHDI_ABIT; if (b == '1') *i |= DAHDI_BBIT; if (c == '1') *i |= DAHDI_CBIT; if (d == '1') *i |= DAHDI_DBIT; return 0; } } } error("CAS Signalling requires idle definition in the form ':xxxx' at the end of the channel definition, where xxxx represent the a, b, c, and d bits\n"); return -1; } static int parse_channel(char *channel, int *startchan) { if (!channel || (sscanf(channel, "%d", startchan) != 1) || (*startchan < 1)) { error("DACS requires a starting channel in the form ':x' where x is the channel\n"); return -1; } return 0; } static int chanconfig(char *keyword, char *args) { int chans[DAHDI_MAX_CHANNELS]; int res = 0; int x; int master=0; int dacschan = 0; char *idle; int is_digital; bzero(chans, sizeof(chans)); strtok(args, ":"); idle = strtok(NULL, ":"); if (!strcasecmp(keyword, "dacs") || !strcasecmp(keyword, "dacsrbs")) { res = parse_channel(idle, &dacschan); } if (!res) res = apply_channels(chans, args); if (res <= 0) return -1; for (x=1;x= DAHDI_TONE_ZONE_MAX) { error("Too many tone zones specified\n"); return 0; } dahdi_copy_string(zonestoload[numzones++], args, sizeof(zonestoload[0])); return 0; } static int defaultzone(char *keyword, char *args) { struct tone_zone *z; if (!(z = tone_zone_find(args))) { error("No such tone zone known: %s\n", args); return 0; } deftonezone = z->zone; return 0; } #if 0 static int unimplemented(char *keyword, char *args) { fprintf(stderr, "Warning: '%s' is not yet implemented\n", keyword); return 0; } #endif /* Radio functions */ int ctcss(char *keyword, char *args) { static char *realargs[10]; int res; int rxtone; int rxtag; int txtone; int isdcs = 0; res = parseargs(args, realargs, 3, ','); if (res != 3) { error("Incorrect number of arguments to 'ctcss' (should be ,,)\n"); return -1; } res = sscanf(realargs[0], "%d", &rxtone); if ((res == 1) && (rxtone < 1)) res = -1; if (res != 1) { error("Invalid rxtone '%s', should be a number > 0.\n", realargs[0]); return -1; } res = sscanf(realargs[1], "%d", &rxtag); if ((res == 1) && (rxtag < 0)) res = -1; if (res != 1) { error("Invalid rxtag '%s', should be a number > 0.\n", realargs[1]); return -1; } if ((*realargs[2] == 'D') || (*realargs[2] == 'd')) { realargs[2]++; isdcs = 0x8000; } res = sscanf(realargs[2], "%d", &txtone); if ((res == 1) && (rxtag < 0)) res = -1; if (res != 1) { error("Invalid txtone '%s', should be a number > 0.\n", realargs[2]); return -1; } if (toneindex >= NUM_TONES) { error("Cannot specify more then %d CTCSS tones\n",NUM_TONES); return -1; } rxtones[toneindex] = rxtone; rxtags[toneindex] = rxtag; txtones[toneindex] = txtone | isdcs; toneindex++; return 0; } int dcsrx(char *keyword, char *args) { static char *realargs[10]; int res; int rxtone; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'dcsrx' (should be )\n"); return -1; } res = sscanf(realargs[0], "%d", &rxtone); if ((res == 1) && (rxtone < 1)) res = -1; if (res != 1) { error("Invalid rxtone '%s', should be a number > 0.\n", realargs[0]); return -1; } rxtones[0] = rxtone; return 0; } int tx(char *keyword, char *args) { static char *realargs[10]; int res; int txtone; int isdcs = 0; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'tx' (should be )\n"); return -1; } if ((*realargs[0] == 'D') || (*realargs[0] == 'd')) { realargs[0]++; isdcs = 0x8000; } res = sscanf(realargs[0], "%d", &txtone); if ((res == 1) && (txtone < 1)) res = -1; if (res != 1) { error("Invalid tx (tone) '%s', should be a number > 0.\n", realargs[0]); return -1; } txtones[0] = txtone | isdcs; return 0; } int debounce_time(char *keyword, char *args) { static char *realargs[10]; int res; int val; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'debouncetime' (should be )\n"); return -1; } res = sscanf(realargs[0], "%d", &val); if ((res == 1) && (val < 1)) res = -1; if (res != 1) { error("Invalid value '%s', should be a number > 0.\n", realargs[0]); return -1; } debouncetime = val; return 0; } int burst_time(char *keyword, char *args) { static char *realargs[10]; int res; int val; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'bursttime' (should be )\n"); return -1; } res = sscanf(realargs[0], "%d", &val); if ((res == 1) && (val < 1)) res = -1; if (res != 1) { error("Invalid value '%s', should be a number > 0.\n", realargs[0]); return -1; } bursttime = val; return 0; } int tx_gain(char *keyword, char *args) { static char *realargs[10]; int res; int val; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'txgain' (should be )\n"); return -1; } res = sscanf(realargs[0], "%d", &val); if (res != 1) { error("Invalid value '%s', should be a number > 0.\n", realargs[0]); return -1; } txgain = val; return 0; } int rx_gain(char *keyword, char *args) { static char *realargs[10]; int res; int val; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'rxgain' (should be )\n"); return -1; } res = sscanf(realargs[0], "%d", &val); if (res != 1) { error("Invalid value '%s', should be a number > 0.\n", realargs[0]); return -1; } rxgain = val; return 0; } int de_emp(char *keyword, char *args) { static char *realargs[10]; int res; int val; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'de-emp' (should be )\n"); return -1; } res = sscanf(realargs[0], "%d", &val); if ((res == 1) && (val < 1)) res = -1; if (res != 1) { error("Invalid value '%s', should be a number > 0.\n", realargs[0]); return -1; } deemp = val; return 0; } int pre_emp(char *keyword, char *args) { static char *realargs[10]; int res; int val; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'pre_emp' (should be )\n"); return -1; } res = sscanf(realargs[0], "%d", &val); if ((res == 1) && (val < 1)) res = -1; if (res != 1) { error("Invalid value '%s', should be a number > 0.\n", realargs[0]); return -1; } preemp = val; return 0; } int invert_cor(char *keyword, char *args) { static char *realargs[10]; int res; int val; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'invertcor' (should be )\n"); return -1; } if ((*realargs[0] == 'y') || (*realargs[0] == 'Y')) val = 1; else if ((*realargs[0] == 'n') || (*realargs[0] == 'N')) val = 0; else { res = sscanf(realargs[0], "%d", &val); if ((res == 1) && (val < 0)) res = -1; if (res != 1) { error("Invalid value '%s', should be a number > 0.\n", realargs[0]); return -1; } } invertcor = (val > 0); return 0; } int ext_tone(char *keyword, char *args) { static char *realargs[10]; int res; int val; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'exttone' (should be )\n"); return -1; } if ((*realargs[0] == 'y') || (*realargs[0] == 'Y')) val = 1; else if ((*realargs[0] == 'n') || (*realargs[0] == 'N')) val = 0; else if ((*realargs[0] == 'i') || (*realargs[0] == 'I')) val = 2; else { res = sscanf(realargs[0], "%d", &val); if ((res == 1) && (val < 0)) res = -1; if (val > 2) res = -1; if (res != 1) { error("Invalid value '%s', should be a number > 0.\n", realargs[0]); return -1; } } exttone = val; return 0; } int cor_thresh(char *keyword, char *args) { static char *realargs[10]; int res; int val; int x = 0; res = parseargs(args, realargs, 1, ','); if (res != 1) { error("Incorrect number of arguments to 'corthresh' (should be )\n"); return -1; } res = sscanf(realargs[0], "%d", &val); if ((res == 1) && (val < 1)) res = -1; for(x = 0; corthreshes[x]; x++) { if (corthreshes[x] == val) break; } if (!corthreshes[x]) res = -1; if (res != 1) { error("Invalid value '%s', should be a number > 0.\n", realargs[0]); return -1; } corthresh = x + 1; return 0; } static int rad_chanconfig(char *keyword, char *args) { int chans[DAHDI_MAX_CHANNELS]; int res = 0; int x,i,n; struct dahdi_radio_param p; int chanfd; toneindex = 1; bzero(chans, sizeof(chans)); res = apply_channels(chans, args); if (res <= 0) return -1; for (x=1;x 1) { printf("\nChannel map:\n\n"); for (x=1;x -- Use instead of " CONFIG_FILENAME "\n" " -d [level] -- Generate debugging output. (Default level is 1.)\n" " -f -- Always reconfigure every channel\n" " -h -- Generate this help statement\n" " -s -- Shutdown spans only\n" " -t -- Test mode only, do not apply\n" " -C -- Only configure specified channels\n" " -S -- Only configure specified span\n" " -v -- Verbose (more -v's means more verbose)\n" ,c); exit(exitcode); } static int chan_restrict(char *str) { if (apply_channels(selected_channels, str) < 0) return 0; restrict_channels = 1; return 1; } static int span_restrict(char *str) { long spanno; char *endptr; spanno = strtol(str, &endptr, 10); if (endptr == str) { fprintf(stderr, "Missing valid span number after '-S'\n"); return 0; } if (*endptr != '\0') { fprintf(stderr, "Extra garbage after span number in '-S'\n"); return 0; } only_span = spanno; return 1; } static const char *SEM_NAME = "dahdi_cfg"; static sem_t *lock = SEM_FAILED; static void signal_handler(int signal) { if (SEM_FAILED != lock) { sem_unlink(SEM_NAME); } /* The default handler should have been restored before this handler was * called, so we can let the "normal" processing finish the cleanup. */ raise(signal); } int main(int argc, char *argv[]) { int c; char *buf; char *key, *value; int x,found; int exit_code = 0; struct sigaction act; while((c = getopt(argc, argv, "fthc:vsd::C:S:")) != -1) { switch(c) { case 'c': filename=optarg; break; case 'h': usage(argv[0], 0); break; case '?': usage(argv[0], 1); break; case 'v': verbose++; break; case 'f': force++; break; case 't': dry_run = 1; break; case 's': stopmode = 1; break; case 'C': if (!chan_restrict(optarg)) usage(argv[0], 1); break; case 'S': if (!span_restrict(optarg)) usage(argv[0], 1); break; case 'd': if (optarg) debug = atoi(optarg); else debug = 1; break; } } if (verbose) { fprintf(stderr, "%s\n", dahdi_tools_version); } if (!restrict_channels && !only_span) { bool all_assigned = wait_for_all_spans_assigned(5); if (!all_assigned) { fprintf(stderr, "Timeout waiting for all spans to be assigned.\n"); } } if (fd == -1) fd = open(MASTER_DEVICE, O_RDWR); if (fd < 0) { error("Unable to open master device '%s'\n", MASTER_DEVICE); goto finish; } if (strcmp(filename, "-") == 0) cf = fdopen(STDIN_FILENO, "r"); else cf = fopen(filename, "r"); if (cf) { while((buf = readline())) { if (*buf == 10) /* skip new line */ continue; if (debug & DEBUG_READER) fprintf(stderr, "Line %d: %s\n", lineno, buf); if ((value = strchr(buf, '='))) { *value++ = '\0'; value = trim(value); key = trim(buf); } if (!value || !*value || !*key) { error("Syntax error. Should be =\n"); continue; } if (debug & DEBUG_PARSER) fprintf(stderr, "Keyword: [%s], Value: [%s]\n", key, value); found = 0; for (x = 0; x < sizeof(handlers) / sizeof(handlers[0]); x++) { if (!strcasecmp(key, handlers[x].keyword)) { found++; handlers[x].func(key, value); break; } } if (!found) error("Unknown keyword '%s'\n", key); } if (debug & DEBUG_READER) fprintf(stderr, "\n"); /* fclose(cf); // causes seg fault (double free) */ } else { error("Unable to open configuration file '%s'\n", filename); } finish: if (errcnt) { fprintf(stderr, "\n%d error(s) detected\n\n", errcnt); exit(1); } if (verbose) { printconfig(fd); } if (dry_run) exit(0); if (debug & DEBUG_APPLY) { printf("About to open Master device\n"); fflush(stdout); } sigemptyset(&act.sa_mask); act.sa_handler = signal_handler; act.sa_flags = SA_RESETHAND; if (sigaction(SIGTERM, &act, NULL) == -1) { perror("Failed to install SIGTERM handler."); exit(1); } if (sigaction(SIGINT, &act, NULL) == -1) { perror("Failed to install SIGINT handler."); exit(1); } lock = sem_open(SEM_NAME, O_CREAT, O_RDWR, 1); if (SEM_FAILED == lock) { perror("Unable to create 'dahdi_cfg' mutex"); exit_code = 1; goto release_sem; } if (-1 == sem_wait(lock)) { perror("Failed to wait for 'dahdi_cfg' mutex"); exit_code = 1; goto unlink_sem; } if (!restrict_channels && !only_span) { for (x=0;x> 16; if (cc[x].sigtype != current_state.sigtype) { needupdate++; if (verbose > 1) printf("Changing signalling on channel %d from %s to %s\n", cc[x].chan, sigtype_to_str(current_state.sigtype), sigtype_to_str(cc[x].sigtype)); } if ((cc[x].deflaw != DAHDI_LAW_DEFAULT) && (cc[x].deflaw != current_state.curlaw)) { needupdate++; if (verbose > 1) printf("Changing law on channel %d from %s to %s\n", cc[x].chan, laws[current_state.curlaw], laws[cc[x].deflaw]); } if (cc[x].master != master) { needupdate++; if (verbose > 1) printf("Changing master of channel %d from %d to %d\n", cc[x].chan, master, cc[x].master); } if (cc[x].idlebits != current_state.idlebits) { needupdate++; if (verbose > 1) printf("Changing idle bits of channel %d from %d to %d\n", cc[x].chan, current_state.idlebits, cc[x].idlebits); } } if (needupdate && ioctl(fd, DAHDI_CHANCONFIG, &cc[x])) { fprintf(stderr, "DAHDI_CHANCONFIG failed on channel %d: %s (%d)\n", x, strerror(errno), errno); if (errno == EINVAL) { /* give helpful suggestions on signaling errors */ fprintf(stderr, "Selected signaling not " "supported\n"); fprintf(stderr, "Possible causes:\n"); switch(cc[x].sigtype) { case DAHDI_SIG_FXOKS: case DAHDI_SIG_FXOLS: case DAHDI_SIG_FXOGS: fprintf(stderr, "\tFXO signaling is " "being used on a FXO interface" " (use a FXS signaling variant" ")\n"); fprintf(stderr, "\tRBS signaling is " "being used on a E1 CCS span" "\n"); break; case DAHDI_SIG_FXSKS: case DAHDI_SIG_FXSLS: case DAHDI_SIG_FXSGS: fprintf(stderr, "\tFXS signaling is " "being used on a FXS interface" " (use a FXO signaling variant" ")\n"); fprintf(stderr, "\tRBS signaling is " "being used on a E1 CCS span" "\n"); break; case DAHDI_SIG_EM: fprintf(stderr, "\te&m signaling is " "being used on a E1 line (use" " e&me1)\n"); break; case DAHDI_SIG_EM_E1: fprintf(stderr, "\te&me1 signaling is " "being used on a T1 line (use " "e&m)\n"); fprintf(stderr, "\tRBS signaling is " "being used on a E1 CCS span" "\n"); break; case DAHDI_SIG_HARDHDLC: fprintf(stderr, "\thardhdlc is being " "used on a TE12x (use dchan)\n" ); break; case DAHDI_SIG_HDLCFCS: fprintf(stderr, "\tdchan is being used" " on a BRI span (use hardhdlc)" "\n"); break; default: break; } fprintf(stderr, "\tSignaling is being assigned" " to channel 16 of an E1 CAS span\n"); } close(fd); exit_code = 1; goto release_sem; } ae[x].chan = x; if (verbose) { printf("Setting echocan for channel %d to %s\n", ae[x].chan, ae[x].echocan[0] ? ae[x].echocan : "none"); } if (ioctl(fd, DAHDI_ATTACH_ECHOCAN, &ae[x])) { fprintf(stderr, "DAHDI_ATTACH_ECHOCAN failed on channel %d: %s (%d)\n", x, strerror(errno), errno); close(fd); exit_code = 1; goto release_sem; } } if (0 == numzones) { /* Default to the us zone if one wasn't specified. */ dahdi_copy_string(zonestoload[numzones++], "us", sizeof(zonestoload[0])); deftonezone = 0; } for (x=0;x -1) { if (ioctl(fd, DAHDI_DEFAULTZONE, &deftonezone)) { fprintf(stderr, "DAHDI_DEFAULTZONE failed: %s (%d)\n", strerror(errno), errno); close(fd); exit_code = 1; goto release_sem; } } for (x=0;x * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include "bittest.h" #include #include "dahdi_tools_version.h" #define BLOCK_SIZE 2039 #define DEVICE "/dev/dahdi/channel" static const char rcsid[] = "$Id$"; char *prog_name; static void usage(void) { fprintf(stderr, "Usage: %s \n", prog_name); fprintf(stderr, " e.g.: %s /dev/dahdi/55\n", prog_name); fprintf(stderr, " %s 455\n", prog_name); fprintf(stderr, "%s version %s\n", prog_name, rcsid); exit(1); } void print_packet(unsigned char *buf, int len) { int x; printf("{ "); for (x=0;x 0) { fd = open(DEVICE, O_RDWR, 0600); if (fd < 0) { perror(DEVICE); return -1; } if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { perror("DAHDI_SPECIFY ioctl failed"); return -1; } /* die */ } else { fprintf(stderr, "Specified channel is not a valid character " "device or channel number"); return -1; } if (ioctl(fd, DAHDI_SET_BLOCKSIZE, bs) < 0) { perror("SET_BLOCKSIZE"); return -1; } if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { fprintf(stderr, "Unable to get channel parameters\n"); return -1; } return fd; } int main(int argc, char *argv[]) { int fd; int res, x; int bs = BLOCK_SIZE; unsigned char c=0; unsigned char outbuf[BLOCK_SIZE]; int setup=0; int errors=0; int bytes=0; prog_name = argv[0]; if (argc < 2) { usage(); } fd = channel_open(argv[1], &bs); if (fd < 0) exit(1); ioctl(fd, DAHDI_GETEVENT); for(;;) { res = bs; res = read(fd, outbuf, res); if (res < bs) { int e; struct dahdi_spaninfo zi; res = ioctl(fd,DAHDI_GETEVENT,&e); if (res == -1) { perror("DAHDI_GETEVENT"); exit(1); } if (e == DAHDI_EVENT_NOALARM) printf("ALARMS CLEARED\n"); if (e == DAHDI_EVENT_ALARM) { zi.spanno = 0; res = ioctl(fd,DAHDI_SPANSTAT,&zi); if (res == -1) { perror("DAHDI_SPANSTAT"); exit(1); } printf("Alarm mask %x hex\n",zi.alarms); } continue; } if (!setup) { c = outbuf[0]; setup++; } for (x=0;x * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dahdi_tools_version.h" #include "wavformat.h" #include "autoconfig.h" #ifdef HAVE_SYS_SOUNDCARD_H # include #else # ifdef HAVE_LINUX_SOUNDCARD_H # include # else # error "Your installation appears to be missing soundcard.h which is needed to continue." # endif #endif /* * defines for file handle numbers */ #define MON_BRX 0 /*!< both channels if multichannel==1 or receive otherwise */ #define MON_TX 1 /*!< transmit channel */ #define MON_PRE_BRX 2 /*!< same as MON_BRX but before echo cancellation */ #define MON_PRE_TX 3 /*!< same as MON_TX but before echo cancellation */ #define MON_STEREO 4 /*!< stereo mix of rx/tx streams */ #define MON_PRE_STEREO 5 /*!< stereo mix of rx/tx before echo can. This is exactly what is fed into the echo can */ #define BLOCK_SIZE 240 #define BUFFERS 4 #define FRAG_SIZE 8 #define MAX_OFH 6 /* Put the ofh (output file handles) outside the main loop in case we ever add a * signal handler. */ static FILE *ofh[MAX_OFH]; static int run = 1; static int stereo; static int verbose; /* handler to catch ctrl-c */ void cleanup_and_exit(int signal) { fprintf(stderr, "cntrl-c pressed\n"); run = 0; /* stop reading */ } int filename_is_wav(char *filename) { if (NULL != strstr(filename, ".wav")) return 1; return 0; } /* * Fill the wav header with default info * num_chans - 0 = mono; 1 = stereo */ void wavheader_init(struct wavheader *wavheader, int num_chans) { memset(wavheader, 0, sizeof(struct wavheader)); memcpy(&wavheader->riff_chunk_id, "RIFF", 4); memcpy(&wavheader->riff_type, "WAVE", 4); memcpy(&wavheader->fmt_chunk_id, "fmt ", 4); wavheader->fmt_data_size = 16; wavheader->fmt_compression_code = 1; wavheader->fmt_num_channels = num_chans; wavheader->fmt_sample_rate = 8000; wavheader->fmt_avg_bytes_per_sec = 16000; wavheader->fmt_block_align = 2; wavheader->fmt_significant_bps = 16; memcpy(&wavheader->data_chunk_id, "data", 4); } int audio_open(void) { int fd; int speed = 8000; int fmt = AFMT_S16_LE; int fragsize = (BUFFERS << 16) | (FRAG_SIZE); struct audio_buf_info ispace, ospace; fd = open("/dev/dsp", O_WRONLY); if (fd < 0) { fprintf(stderr, "Unable to open /dev/dsp: %s\n", strerror(errno)); return -1; } /* Step 1: Signed linear */ if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) < 0) { fprintf(stderr, "ioctl(SETFMT) failed: %s\n", strerror(errno)); close(fd); return -1; } /* Step 2: Make non-stereo */ if (ioctl(fd, SNDCTL_DSP_STEREO, &stereo) < 0) { fprintf(stderr, "ioctl(STEREO) failed: %s\n", strerror(errno)); close(fd); return -1; } if (stereo != 0) { fprintf(stderr, "Can't turn stereo off :(\n"); } /* Step 3: Make 8000 Hz */ if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) < 0) { fprintf(stderr, "ioctl(SPEED) failed: %s\n", strerror(errno)); close(fd); return -1; } if (speed != 8000) { fprintf(stderr, "Warning: Requested 8000 Hz, got %d\n", speed); } if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragsize)) { fprintf(stderr, "Sound card won't let me set fragment size to %u %u-byte buffers (%x)\n" "so sound may be choppy: %s.\n", BUFFERS, (1 << FRAG_SIZE), fragsize, strerror(errno)); } bzero(&ispace, sizeof(ispace)); bzero(&ospace, sizeof(ospace)); if (ioctl(fd, SNDCTL_DSP_GETISPACE, &ispace)) { /* They don't support block size stuff, so just return but notify the user */ fprintf(stderr, "Sound card won't let me know the input buffering...\n"); } if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &ospace)) { /* They don't support block size stuff, so just return but notify the user */ fprintf(stderr, "Sound card won't let me know the output buffering...\n"); } fprintf(stderr, "New input space: %d of %d %d byte fragments (%d bytes left)\n", ispace.fragments, ispace.fragstotal, ispace.fragsize, ispace.bytes); fprintf(stderr, "New output space: %d of %d %d byte fragments (%d bytes left)\n", ospace.fragments, ospace.fragstotal, ospace.fragsize, ospace.bytes); return fd; } int pseudo_open(void) { int fd; int x = 1; fd = open("/dev/dahdi/pseudo", O_RDWR); if (fd < 0) { fprintf(stderr, "Unable to open pseudo channel: %s\n", strerror(errno)); return -1; } if (ioctl(fd, DAHDI_SETLINEAR, &x)) { fprintf(stderr, "Unable to set linear mode: %s\n", strerror(errno)); close(fd); return -1; } x = BLOCK_SIZE; if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &x)) { fprintf(stderr, "unable to set sane block size: %s\n", strerror(errno)); close(fd); return -1; } return fd; } #define barlen 35 #define baroptimal 3250 //define barlevel 200 #define barlevel ((baroptimal/barlen)*2) #define maxlevel (barlen*barlevel) void draw_barheader() { char bar[barlen + 4]; memset(bar, '-', sizeof(bar)); memset(bar, '<', 1); memset(bar + barlen + 2, '>', 1); memset(bar + barlen + 3, '\0', 1); memcpy(bar + (barlen / 2), "(RX)", 4); printf("%s", bar); memcpy(bar + (barlen / 2), "(TX)", 4); printf(" %s\n", bar); } void draw_bar(int avg, int max) { char bar[barlen+5]; memset(bar, ' ', sizeof(bar)); max /= barlevel; avg /= barlevel; if (avg > barlen) avg = barlen; if (max > barlen) max = barlen; if (avg > 0) memset(bar, '#', avg); if (max > 0) memset(bar + max, '*', 1); bar[barlen+1] = '\0'; printf("%s", bar); fflush(stdout); } void visualize(short *tx, short *rx, int cnt) { int x; float txavg = 0; float rxavg = 0; static int txmax = 0; static int rxmax = 0; static int sametxmax = 0; static int samerxmax = 0; static int txbest = 0; static int rxbest = 0; float ms; static struct timeval last; struct timeval tv; gettimeofday(&tv, NULL); ms = (tv.tv_sec - last.tv_sec) * 1000.0 + (tv.tv_usec - last.tv_usec) / 1000.0; for (x = 0; x < cnt; x++) { txavg += abs(tx[x]); rxavg += abs(rx[x]); } txavg = abs(txavg / cnt); rxavg = abs(rxavg / cnt); if (txavg > txbest) txbest = txavg; if (rxavg > rxbest) rxbest = rxavg; /* Update no more than 10 times a second */ if (ms < 100) return; /* Save as max levels, if greater */ if (txbest > txmax) { txmax = txbest; sametxmax = 0; } if (rxbest > rxmax) { rxmax = rxbest; samerxmax = 0; } memcpy(&last, &tv, sizeof(last)); /* Clear screen */ printf("\r "); draw_bar(rxbest, rxmax); printf(" "); draw_bar(txbest, txmax); if (verbose) printf(" Rx: %5d (%5d) Tx: %5d (%5d)", rxbest, rxmax, txbest, txmax); txbest = 0; rxbest = 0; /* If we have had the same max hits for x times, clear the values */ sametxmax++; samerxmax++; if (sametxmax > 6) { txmax = 0; sametxmax = 0; } if (samerxmax > 6) { rxmax = 0; samerxmax = 0; } } int main(int argc, char *argv[]) { int afd = -1; int pfd[4] = {-1, -1, -1, -1}; short buf_brx[BLOCK_SIZE * 2]; short buf_tx[BLOCK_SIZE * 4]; short stereobuf[BLOCK_SIZE * 4]; int res_brx, res_tx; int visual = 0; int multichannel = 0; int ossoutput = 0; int preecho = 0; int savefile = 0; int stereo_output = 0; int limit = 0; int readcount = 0; int x, chan; struct dahdi_confinfo zc; int opt; extern char *optarg; struct wavheader wavheaders[MAX_OFH]; /* we have one for each potential filehandle */ unsigned int bytes_written[MAX_OFH] = {0}; int file_is_wav[MAX_OFH] = {0}; int i; if ((argc < 2) || (atoi(argv[1]) < 1)) { fprintf(stderr, "Usage: dahdi_monitor [-v[v]] [-m] [-o] [-l limit] [-f FILE | -s FILE | -r FILE1 -t FILE2] [-F FILE | -S FILE | -R FILE1 -T FILE2]\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -v: Visual mode. Implies -m.\n"); fprintf(stderr, " -vv: Visual/Verbose mode. Implies -m.\n"); fprintf(stderr, " -l LIMIT: Stop after reading LIMIT bytes\n"); fprintf(stderr, " -m: Separate rx/tx streams.\n"); fprintf(stderr, " -o: Output audio via OSS. Note: Only 'normal' combined rx/tx streams are output via OSS.\n"); fprintf(stderr, " -f FILE: Save combined rx/tx stream to mono FILE. Cannot be used with -m.\n"); fprintf(stderr, " -r FILE: Save rx stream to FILE. Implies -m.\n"); fprintf(stderr, " -t FILE: Save tx stream to FILE. Implies -m.\n"); fprintf(stderr, " -s FILE: Save stereo rx/tx stream to FILE. Implies -m.\n"); fprintf(stderr, " -F FILE: Save combined pre-echocanceled rx/tx stream to FILE. Cannot be used with -m.\n"); fprintf(stderr, " -R FILE: Save pre-echocanceled rx stream to FILE. Implies -m.\n"); fprintf(stderr, " -T FILE: Save pre-echocanceled tx stream to FILE. Implies -m.\n"); fprintf(stderr, " -S FILE: Save pre-echocanceled stereo rx/tx stream to FILE. Implies -m.\n"); fprintf(stderr, "Examples:\n"); fprintf(stderr, "Save a stream to a file\n"); fprintf(stderr, " dahdi_monitor 1 -f stream.raw\n"); fprintf(stderr, "Visualize an rx/tx stream and save them to separate files.\n"); fprintf(stderr, " dahdi_monitor 1 -v -r streamrx.raw -t streamtx.raw\n"); fprintf(stderr, "Play a combined rx/tx stream via OSS and save it to a file\n"); fprintf(stderr, " dahdi_monitor 1 -o -f stream.raw\n"); fprintf(stderr, "Save a combined normal rx/tx stream and a combined 'preecho' rx/tx stream to files\n"); fprintf(stderr, " dahdi_monitor 1 -f stream.raw -F streampreecho.raw\n"); fprintf(stderr, "Save a normal rx/tx stream and a 'preecho' rx/tx stream to separate files\n"); fprintf(stderr, " dahdi_monitor 1 -m -r streamrx.raw -t streamtx.raw -R streampreechorx.raw -T streampreechotx.raw\n"); exit(1); } chan = atoi(argv[1]); while ((opt = getopt(argc, argv, "vmol:f:r:t:s:F:R:T:S:")) != -1) { switch (opt) { case '?': exit(EXIT_FAILURE); case 'v': if (visual) verbose = 1; visual = 1; multichannel = 1; break; case 'm': multichannel = 1; break; case 'o': ossoutput = 1; break; case 'l': if (sscanf(optarg, "%d", &limit) != 1 || limit < 0) limit = 0; fprintf(stderr, "Will stop reading after %d bytes\n", limit); break; case 'f': if (multichannel) { fprintf(stderr, "'%c' mode cannot be used when multichannel mode is enabled.\n", opt); exit(EXIT_FAILURE); } if (ofh[MON_BRX]) { fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); exit(EXIT_FAILURE); } if ((ofh[MON_BRX] = fopen(optarg, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } fprintf(stderr, "Writing combined stream to %s\n", optarg); file_is_wav[MON_BRX] = filename_is_wav(optarg); if (file_is_wav[MON_BRX]) { wavheader_init(&wavheaders[MON_BRX], 1); if (fwrite(&wavheaders[MON_BRX], 1, sizeof(struct wavheader), ofh[MON_BRX]) != sizeof(struct wavheader)) { fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } } savefile = 1; break; case 'F': if (multichannel) { fprintf(stderr, "'%c' mode cannot be used when multichannel mode is enabled.\n", opt); exit(EXIT_FAILURE); } if (ofh[MON_PRE_BRX]) { fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); exit(EXIT_FAILURE); } if ((ofh[MON_PRE_BRX] = fopen(optarg, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } fprintf(stderr, "Writing pre-echo combined stream to %s\n", optarg); file_is_wav[MON_PRE_BRX] = filename_is_wav(optarg); if (file_is_wav[MON_PRE_BRX]) { wavheader_init(&wavheaders[MON_PRE_BRX], 1); if (fwrite(&wavheaders[MON_PRE_BRX], 1, sizeof(struct wavheader), ofh[MON_PRE_BRX]) != sizeof(struct wavheader)) { fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } } preecho = 1; savefile = 1; break; case 'r': if (!multichannel && ofh[MON_BRX]) { fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); exit(EXIT_FAILURE); } if (ofh[MON_BRX]) { fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); exit(EXIT_FAILURE); } if ((ofh[MON_BRX] = fopen(optarg, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } fprintf(stderr, "Writing receive stream to %s\n", optarg); file_is_wav[MON_BRX] = filename_is_wav(optarg); if (file_is_wav[MON_BRX]) { wavheader_init(&wavheaders[MON_BRX], 1); if (fwrite(&wavheaders[MON_BRX], 1, sizeof(struct wavheader), ofh[MON_BRX]) != sizeof(struct wavheader)) { fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } } multichannel = 1; savefile = 1; break; case 'R': if (!multichannel && ofh[MON_PRE_BRX]) { fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); exit(EXIT_FAILURE); } if (ofh[MON_PRE_BRX]) { fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); exit(EXIT_FAILURE); } if ((ofh[MON_PRE_BRX] = fopen(optarg, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } fprintf(stderr, "Writing pre-echo receive stream to %s\n", optarg); file_is_wav[MON_PRE_BRX] = filename_is_wav(optarg); if (file_is_wav[MON_PRE_BRX]) { wavheader_init(&wavheaders[MON_PRE_BRX], 1); if (fwrite(&wavheaders[MON_PRE_BRX], 1, sizeof(struct wavheader), ofh[MON_PRE_BRX]) != sizeof(struct wavheader)) { fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } } preecho = 1; multichannel = 1; savefile = 1; break; case 't': if (!multichannel && ofh[MON_BRX]) { fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); exit(EXIT_FAILURE); } if (ofh[MON_TX]) { fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); exit(EXIT_FAILURE); } if ((ofh[MON_TX] = fopen(optarg, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } fprintf(stderr, "Writing transmit stream to %s\n", optarg); file_is_wav[MON_TX] = filename_is_wav(optarg); if (file_is_wav[MON_TX]) { wavheader_init(&wavheaders[MON_TX], 1); if (fwrite(&wavheaders[MON_TX], 1, sizeof(struct wavheader), ofh[MON_TX]) != sizeof(struct wavheader)) { fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } } multichannel = 1; savefile = 1; break; case 'T': if (!multichannel && ofh[MON_PRE_BRX]) { fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); exit(EXIT_FAILURE); } if (ofh[MON_PRE_TX]) { fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); exit(EXIT_FAILURE); } if ((ofh[MON_PRE_TX] = fopen(optarg, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } fprintf(stderr, "Writing pre-echo transmit stream to %s\n", optarg); file_is_wav[MON_PRE_TX] = filename_is_wav(optarg); if (file_is_wav[MON_PRE_TX]) { wavheader_init(&wavheaders[MON_PRE_TX], 1); if (fwrite(&wavheaders[MON_PRE_TX], 1, sizeof(struct wavheader), ofh[MON_PRE_TX]) != sizeof(struct wavheader)) { fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } } preecho = 1; multichannel = 1; savefile = 1; break; case 's': if (!multichannel && ofh[MON_BRX]) { fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); exit(EXIT_FAILURE); } if (ofh[MON_STEREO]) { fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); exit(EXIT_FAILURE); } if ((ofh[MON_STEREO] = fopen(optarg, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } fprintf(stderr, "Writing stereo stream to %s\n", optarg); file_is_wav[MON_STEREO] = filename_is_wav(optarg); if (file_is_wav[MON_STEREO]) { wavheader_init(&wavheaders[MON_STEREO], 2); if (fwrite(&wavheaders[MON_STEREO], 1, sizeof(struct wavheader), ofh[MON_STEREO]) != sizeof(struct wavheader)) { fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } } multichannel = 1; savefile = 1; stereo_output = 1; break; case 'S': if (!multichannel && ofh[MON_PRE_BRX]) { fprintf(stderr, "'%c' mode cannot be used when combined mode is enabled.\n", opt); exit(EXIT_FAILURE); } if (ofh[MON_PRE_STEREO]) { fprintf(stderr, "Cannot specify option '%c' more than once.\n", opt); exit(EXIT_FAILURE); } if ((ofh[MON_PRE_STEREO] = fopen(optarg, "w")) == NULL) { fprintf(stderr, "Could not open %s for writing: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } fprintf(stderr, "Writing pre-echo stereo stream to %s\n", optarg); file_is_wav[MON_PRE_STEREO] = filename_is_wav(optarg); if (file_is_wav[MON_PRE_STEREO]) { wavheader_init(&wavheaders[MON_PRE_STEREO], 2); if (fwrite(&wavheaders[MON_PRE_STEREO], 1, sizeof(struct wavheader), ofh[MON_PRE_STEREO]) != sizeof(struct wavheader)) { fprintf(stderr, "Could not write wav header to %s: %s\n", optarg, strerror(errno)); exit(EXIT_FAILURE); } } preecho = 1; multichannel = 1; savefile = 1; stereo_output = 1; break; } } if (ossoutput) { if (multichannel) { printf("Multi-channel audio is enabled. OSS output will be disabled.\n"); ossoutput = 0; } else { /* Open audio */ if ((afd = audio_open()) < 0) { printf("Cannot open audio ...\n"); ossoutput = 0; } } } if (!ossoutput && !multichannel && !savefile) { fprintf(stderr, "Nothing to do with the stream(s) ...\n"); exit(1); } /* Open Pseudo device */ if ((pfd[MON_BRX] = pseudo_open()) < 0) exit(1); if (multichannel && ((pfd[MON_TX] = pseudo_open()) < 0)) exit(1); if (preecho) { if ((pfd[MON_PRE_BRX] = pseudo_open()) < 0) exit(1); if (multichannel && ((pfd[MON_PRE_TX] = pseudo_open()) < 0)) exit(1); } /* Conference them */ if (multichannel) { memset(&zc, 0, sizeof(zc)); zc.chan = 0; zc.confno = chan; /* Two pseudo's, one for tx, one for rx */ zc.confmode = DAHDI_CONF_MONITOR; if (ioctl(pfd[MON_BRX], DAHDI_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); exit(1); } memset(&zc, 0, sizeof(zc)); zc.chan = 0; zc.confno = chan; zc.confmode = DAHDI_CONF_MONITORTX; if (ioctl(pfd[MON_TX], DAHDI_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); exit(1); } if (preecho) { memset(&zc, 0, sizeof(zc)); zc.chan = 0; zc.confno = chan; /* Two pseudo's, one for tx, one for rx */ zc.confmode = DAHDI_CONF_MONITOR_RX_PREECHO; if (ioctl(pfd[MON_PRE_BRX], DAHDI_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); exit(1); } memset(&zc, 0, sizeof(zc)); zc.chan = 0; zc.confno = chan; zc.confmode = DAHDI_CONF_MONITOR_TX_PREECHO; if (ioctl(pfd[MON_PRE_TX], DAHDI_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); exit(1); } } } else { memset(&zc, 0, sizeof(zc)); zc.chan = 0; zc.confno = chan; zc.confmode = DAHDI_CONF_MONITORBOTH; if (ioctl(pfd[MON_BRX], DAHDI_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); exit(1); } if (preecho) { memset(&zc, 0, sizeof(zc)); zc.chan = 0; zc.confno = chan; zc.confmode = DAHDI_CONF_MONITORBOTH_PREECHO; if (ioctl(pfd[MON_PRE_BRX], DAHDI_SETCONF, &zc) < 0) { fprintf(stderr, "Unable to monitor: %s\n", strerror(errno)); exit(1); } } } if (signal(SIGINT, cleanup_and_exit) == SIG_ERR) { fprintf(stderr, "Error registering signal handler: %s\n", strerror(errno)); } if (visual) { printf("\nVisual Audio Levels.\n"); printf("--------------------\n"); printf(" Use chan_dahdi.conf file to adjust the gains if needed.\n\n"); printf("( # = Audio Level * = Max Audio Hit )\n"); draw_barheader(); } /* Now, copy from pseudo to audio */ while (run) { res_brx = read(pfd[MON_BRX], buf_brx, sizeof(buf_brx)); if (res_brx < 1) break; readcount += res_brx; if (ofh[MON_BRX]) bytes_written[MON_BRX] += fwrite(buf_brx, 1, res_brx, ofh[MON_BRX]); if (multichannel) { res_tx = read(pfd[MON_TX], buf_tx, res_brx); if (res_tx < 1) break; if (ofh[MON_TX]) bytes_written[MON_TX] += fwrite(buf_tx, 1, res_tx, ofh[MON_TX]); if (stereo_output && ofh[MON_STEREO]) { for (x = 0; x < res_tx; x++) { stereobuf[x*2] = buf_brx[x]; stereobuf[x*2+1] = buf_tx[x]; } bytes_written[MON_STEREO] += fwrite(stereobuf, 1, res_tx*2, ofh[MON_STEREO]); } if (visual) { if (res_brx == res_tx) visualize((short *)buf_tx, (short *)buf_brx, res_brx/2); else printf("Huh? res_tx = %d, res_brx = %d?\n", res_tx, res_brx); } } if (preecho) { res_brx = read(pfd[MON_PRE_BRX], buf_brx, sizeof(buf_brx)); if (res_brx < 1) break; if (ofh[MON_PRE_BRX]) bytes_written[MON_PRE_BRX] += fwrite(buf_brx, 1, res_brx, ofh[MON_PRE_BRX]); if (multichannel) { res_tx = read(pfd[MON_PRE_TX], buf_tx, res_brx); if (res_tx < 1) break; if (ofh[MON_PRE_TX]) bytes_written[MON_PRE_TX] += fwrite(buf_tx, 1, res_tx, ofh[MON_PRE_TX]); if (stereo_output && ofh[MON_PRE_STEREO]) { for (x = 0; x < res_brx; x++) { stereobuf[x*2] = buf_brx[x]; stereobuf[x*2+1] = buf_tx[x]; } bytes_written[MON_PRE_STEREO] += fwrite(stereobuf, 1, res_brx * 2, ofh[MON_PRE_STEREO]); } } } if (ossoutput && afd) { if (stereo) { for (x = 0; x < res_brx; x++) { buf_tx[x << 1] = buf_tx[(x << 1) + 1] = buf_brx[x]; } x = write(afd, buf_tx, res_brx << 1); } else { x = write(afd, buf_brx, res_brx); } } if (limit && readcount >= limit) { /* bail if we've read too much */ break; } } /* write filesize info */ for (i = 0; i < MAX_OFH; i++) { if (NULL == ofh[i]) continue; if (!(file_is_wav[i])) continue; wavheaders[i].riff_chunk_size = (bytes_written[i]) + sizeof(struct wavheader) - 8; /* filesize - 8 */ wavheaders[i].data_data_size = bytes_written[i]; rewind(ofh[i]); if (fwrite(&wavheaders[i], 1, sizeof(struct wavheader), ofh[i]) != sizeof(struct wavheader)) { fprintf(stderr, "Failed to write out a full wav header.\n"); } fclose(ofh[i]); } printf("done cleaning up ... exiting.\n"); return 0; } dahdi-tools-2.10.2/dahdi_span_assignments0000755000000000000000000002157612537624573017165 0ustar rootroot#! /bin/sh # # /usr/sbin/dahdi_span_assignments: # # this script can be used both from udev and # from the command line to assign/unassign and list # current span assignments. # # It uses a configuration file: $DAHDICONFDIR/assigned-spans.conf # (default DAHDICONFDIR=/etc/dahdi) # # The first argument is an action: # "auto" - trigger driver auto_assign attribute for given devices # (no configuration file is used) # "add" - assign (spans which are not already assigned), according # to /etc/dahdi/assigned-spans.conf configuration file # "remove" - unassign spans which are not already unassigned # "list" - human-readable list of all spans (with/without assignments) # "dumpconfig" - dump current assignments in a /etc/dahdi/assigned-spans.conf # compatible format # # Without further arguments, it operates on all existing spans # With one or more sysfs dahdi_devices it is limited to those. # # We may use alternative "keys" for device matching: # * Available keys: # - "hwid" - Hardware id attribute from sysfs # - "@location" - Location attribute from sysfs (embeded inside '<>') # - "/devpath" - The sysfs absolute devpath # # * During "dumpconfig", for each device we take the first available key: # - The preference is: "hwid" or else "@location" or else "/devpath" # - This can be overriden via the SPAN_ASSIGNMENTS_KEY environment variable # or the '{-k|--key} key' command line option. # # * During "add": # - Any key match is valid (hwid/location/devpath) # - Shell globs (wildcards: '*', '?', '[...]') may be optionally used. # # Command line options: # - The '-h|--help' show a usage message. # - The '-n|--dry-run' affects the "add" and "remove" operations. # - The '-v|--verbose' currently shows device matches during "add" operation. # - The '-k |--key ' overrides the SPAN_ASSIGNMENTS_KEY environment # variable. # # Examples: # dahdi_span_assignments list # dahdi_span_assignments add # all unassigned devices # dahdi_span_assignments add /sys/bus/dahdi_devices/devices/astribanks:xbus-00 # dahdi_span_assignments remove # all assigned devices # dahdi_span_assignments -k location dumpconfig # devbase='/sys/bus/dahdi_devices/devices' DAHDICONFDIR="${DAHDICONFDIR:-/etc/dahdi}" DAHDISASSIGNEDSPANSCONF="${DAHDIASSIGNEDSPANSCONF:-"${DAHDICONFDIR}/assigned-spans.conf"}" SPAN_ASSIGNMENTS_KEY=${SPAN_ASSIGNMENTS_KEY:-hwid} dry_run= verbose= usage() { echo >&2 "Usage: $0 [options] action [devpath ...]" echo >&2 " action:" echo >&2 " auto - trigger driver auto_assign attribute for given devices" echo >&2 " add - assign spans, according to /etc/dahdi/assigned-spans.conf" echo >&2 " remove - unassign spans" echo >&2 " list - human-readable list of all spans" echo >&2 " dumpconfig - dump current state as new configuration" echo >&2 "" echo >&2 " options:" echo >&2 " -h|--help - Show this help" echo >&2 " -n|--dry-run - For 'add/remove' actions" echo >&2 " -v|--versbose - Show matches during 'add' action" echo >&2 " -k|--key - Override prefered key during dumpconfig action" exit 1 } # Parse command line options TEMP=`getopt -o hnvk: --long help,dry-run,verbose,key: -n "$0" -- "$@"` if [ $? != 0 ]; then echo >&2 "Bad options" usage fi # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" while true ; do case "$1" in -h|--help) usage ;; -n|--dry-run) dry_run='true' shift ;; -v|--verbose) verbose='true' shift ;; -k|--key) SPAN_ASSIGNMENTS_KEY="$2" shift shift ;; --) shift break ;; *) echo "Internal error!" exit 1 ;; esac done if [ "$#" -eq 0 ]; then echo >&2 "Missing action argument" usage fi action="$1" shift # Validate SPAN_ASSIGNMENTS_KEY case "$SPAN_ASSIGNMENTS_KEY" in hwid|location|devpath) ;; *) echo >&2 "Bad SPAN_ASSIGNMENTS_KEY='$SPAN_ASSIGNMENTS_KEY' (should be: hwid|location|devpath)" usage ;; esac if [ ! -d "$devbase" ]; then echo >&2 "$0: Missing '$devbase' (DAHDI driver unloaded?)" exit 1 fi # Use given devices or otherwise, all existing devices if [ "$#" -gt 0 ]; then DEVICES="$@" else DEVICES=`ls -d $devbase/* 2>/dev/null` fi # Beware of special characters in attributes attr_clean() { cat "$1" 2>/dev/null | tr -d '\n' | tr '!' '/' | tr -c 'a-zA-Z0-9/:.-' '_' } show_devices() { for device in $DEVICES do devpath=`cd "$device" && pwd -P` location='@'`attr_clean "$device/location"` hardware_id=`attr_clean "$device/hardware_id"` for local_spanno in `cut -d: -f1 "$device/spantype"` do span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` if [ "$span" != '' ]; then spanno=`echo $span | sed 's/^.*-//'` name=`cat 2>/dev/null "$device/$span/name"` basechan=`cat 2>/dev/null "$device/$span/basechan"` else spanno='-' basechan='-' fi printf "%-8s %-14s %s %s\n" "$local_spanno:$spanno:$basechan" "[$hardware_id]" "$location" "$devpath" done | sort -n done } dump_config() { echo '#' echo "# Autogenerated by $0 on `date`" echo "# Map devices + local spans to span + base channel number" echo '' for device in $DEVICES do devpath=`cd "$device" && pwd -P` location=`attr_clean "$device/location"` hardware_id=`attr_clean "$device/hardware_id"` if [ "$SPAN_ASSIGNMENTS_KEY" = 'hwid' -a "$hardware_id" != '' ]; then id="$hardware_id" elif [ "$SPAN_ASSIGNMENTS_KEY" = 'location' -a "$location" != '' ]; then id="@$location" else id="$devpath" fi echo "# Device: [$hardware_id] @$location $devpath" for local_spanno in `cut -d: -f1 "$device/spantype"` do span=`grep 2>/dev/null -Hw "$local_spanno" "$device/span-"*"/local_spanno" | \ sed -e 's,/local_spanno:.*,,' -e 's,.*/,,'` if [ "$span" != '' ]; then spanno=`echo $span | sed 's/^.*-//'` name=`cat 2>/dev/null "$device/$span/name"` basechan=`cat 2>/dev/null "$device/$span/basechan"` printf "%-30s %s\n" "$id" "$local_spanno:$spanno:$basechan" else echo "# Skipped unassigned local span $local_spanno" fi done | sort echo '' done } unassign_all_spans() { for device in $DEVICES do find "$device" -follow -maxdepth 1 -name 'span-*' -type d | \ sort | while read spandir; do local_spanno=`cat "$spandir/local_spanno"` if [ "$dry_run" = true ]; then echo "(dry-run) unassign $device $local_spanno" continue fi echo "unassign $device $local_spanno" if ! echo "$local_spanno" > "$device/unassign_span"; then echo >&2 "$0: failed unassigning '$local_spanno' in '$device'" fi done done } # Allow comments and empty lines in config file filter_conf() { sed -e 's/#.*//' -e '/^[ \t]*$/d' "$DAHDISASSIGNEDSPANSCONF" } assign_device_spans() { device="$1" for s in $spanspecs do local_spanno=`echo "$s" | cut -d: -f1` spanno=`echo "$s" | cut -d: -f2` span="$device/span-$spanno" if [ "$dry_run" = true ]; then echo "(dry-run) assign $device: $s" continue fi if [ -d "$span" ]; then span_local_spanno=`cat "$span/local_spanno"` if [ "$span_local_spanno" != "$local_spanno" ]; then echo "WARNING: $span_local_spanno != $local_spanno" fi echo "$device [$local_spanno] already assigned to span $spanno. Skipping..." continue fi echo "assign $device: $s" if ! echo "$s" > "$device/assign_span"; then echo >&2 "$0: failed assigning '$s' to '$device'" fi done } match_device() { device="$1" devpath=`cd "$device" && pwd -P` location='@'`attr_clean "$device/location"` hardware_id=`attr_clean "$device/hardware_id"` filter_conf | while read id spanspecs do # We use case to enable shell-style globbing in configuration case "$hardware_id" in $id) [ "$verbose" = true ] && echo "match by hwid ($id ~ $hardware_id): $spanspecs" assign_device_spans "$device" ;; esac # We use case to enable shell-style globbing in configuration case "$location" in $id) [ "$verbose" = true ] && echo "match by location ($id ~ $location): $spanspecs" assign_device_spans "$device" ;; esac # We use case to enable shell-style globbing in configuration case "$devpath" in $id) [ "$verbose" = true ] && echo "match by devpath ($id ~ $devpath): $spanspecs" assign_device_spans "$device" ;; esac done } assign_devices() { if [ ! -f "$DAHDISASSIGNEDSPANSCONF" ]; then echo >&2 "$0: Missing '$DAHDISASSIGNEDSPANSCONF'" exit 1 fi echo "using '$DAHDISASSIGNEDSPANSCONF'" for device in $DEVICES do match_device "$device" done } auto_assign_devices() { for device in $DEVICES do echo "auto-assign $device" if [ "$dry_run" != true ]; then echo 1 > "$device/auto_assign" fi done } case "$action" in auto) auto_assign_devices ;; add) assign_devices ;; remove) unassign_all_spans ;; list) show_devices ;; dumpconfig) dump_config ;; *) echo >&2 "Bad action='$action'" usage ;; esac dahdi-tools-2.10.2/acinclude.m40000644000000000000000000010457712537624573014726 0ustar rootroot# Various support functions for configure.ac in asterisk # # Helper function to check for gcc attributes. # AST_GCC_ATTRIBUTE([attribute name]) AC_DEFUN([AST_GCC_ATTRIBUTE], [ AC_MSG_CHECKING(for compiler 'attribute $1' support) saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror" AC_COMPILE_IFELSE( AC_LANG_PROGRAM([static void __attribute__(($1)) *test(void *muffin, ...) {}], []), AC_MSG_RESULT(yes) AC_DEFINE_UNQUOTED([HAVE_ATTRIBUTE_$1], 1, [Define to 1 if your GCC C compiler supports the '$1' attribute.]), AC_MSG_RESULT(no)) ] CFLAGS="$saved_CFLAGS" ) # Helper function to setup variables for a package. # $1 -> the package name. Used in configure.ac and also as a prefix # for the variables ($1_DIR, $1_INCLUDE, $1_LIB) in makeopts # $3 -> option name, used in --with-$3 or --without-$3 when calling configure. # $2 and $4 are just text describing the package (short and long form) # AST_EXT_LIB_SETUP([package], [short description], [configure option name], [long description]) AC_DEFUN([AST_EXT_LIB_SETUP], [ $1_DESCRIP="$2" $1_OPTION="$3" AC_ARG_WITH([$3], AC_HELP_STRING([--with-$3=PATH],[use $2 files in PATH $4]), [ case ${withval} in n|no) USE_$1=no ;; y|ye|yes) ac_mandatory_list="${ac_mandatory_list} $1" ;; *) $1_DIR="${withval}" ac_mandatory_list="${ac_mandatory_list} $1" ;; esac ]) PBX_$1=0 AC_SUBST([$1_LIB]) AC_SUBST([$1_INCLUDE]) AC_SUBST([$1_DIR]) AC_SUBST([PBX_$1]) ]) # Check whether any of the mandatory modules are not present, and # print error messages in case. The mandatory list is built using # --with-* arguments when invoking configure. AC_DEFUN([AST_CHECK_MANDATORY], [ AC_MSG_CHECKING([for mandatory modules: ${ac_mandatory_list}]) err=0; for i in ${ac_mandatory_list}; do eval "a=\${PBX_$i}" if test "x${a}" = "x1" ; then continue; fi if test ${err} = "0" ; then AC_MSG_RESULT(fail) ; fi AC_MSG_RESULT() eval "a=\${${i}_OPTION}" AC_MSG_NOTICE([***]) AC_MSG_NOTICE([*** The $i installation appears to be missing or broken.]) AC_MSG_NOTICE([*** Either correct the installation, or run configure]) AC_MSG_NOTICE([*** including --without-${a}.]) err=1 done if test $err = 1 ; then exit 1; fi AC_MSG_RESULT(ok) ]) # The next three functions check for the availability of a given package. # AST_C_DEFINE_CHECK looks for the presence of a #define in a header file, # AST_C_COMPILE_CHECK can be used for testing for various items in header files, # AST_EXT_LIB_CHECK looks for a symbol in a given library, or at least # for the presence of a header file. # AST_EXT_TOOL_CHECK looks for a symbol in using $1-config to determine CFLAGS and LIBS # # They are only run if PBX_$1 != 1 (where $1 is the package), # so you can call them multiple times and stop at the first matching one. # On success, they both set PBX_$1 = 1, set $1_INCLUDE and $1_LIB as applicable, # and also #define HAVE_$1 1 and #define HAVE_$1_VERSION ${last_argument} # in autoconfig.h so you can tell which test succeeded. # They should be called after AST_EXT_LIB_SETUP($1, ...) # Check if a given macro is defined in a certain header. # AST_C_DEFINE_CHECK([package], [macro name], [header file], [version]) AC_DEFUN([AST_C_DEFINE_CHECK], [ if test "x${PBX_$1}" != "x1"; then AC_MSG_CHECKING([for $2 in $3]) saved_cppflags="${CPPFLAGS}" if test "x${$1_DIR}" != "x"; then $1_INCLUDE="-I${$1_DIR}/include" fi CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" AC_COMPILE_IFELSE( [ AC_LANG_PROGRAM( [#include <$3>], [#if defined($2) int foo = 0; #else int foo = bar; #endif 0 ])], [ AC_MSG_RESULT(yes) PBX_$1=1 AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.]) AC_DEFINE([HAVE_$1_VERSION], $4, [Define $1 headers version]) ], [ AC_MSG_RESULT(no) ] ) CPPFLAGS="${saved_cppflags}" fi AC_SUBST(PBX_$1) ]) # Check if a given expression will compile using a certain header. # AST_C_COMPILE_CHECK([package], [expression], [header file], [version]) AC_DEFUN([AST_C_COMPILE_CHECK], [ if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then AC_MSG_CHECKING([if "$2" compiles using $3]) saved_cppflags="${CPPFLAGS}" if test "x${$1_DIR}" != "x"; then $1_INCLUDE="-I${$1_DIR}/include" fi CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" AC_COMPILE_IFELSE( [ AC_LANG_PROGRAM( [#include <$3>], [ $2; ] )], [ AC_MSG_RESULT(yes) PBX_$1=1 AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.]) AC_DEFINE([HAVE_$1_VERSION], $4, [Define $1 headers version]) ], [ AC_MSG_RESULT(no) ] ) CPPFLAGS="${saved_cppflags}" fi ]) # Check for existence of a given package ($1), either looking up a function # in a library, or, if no function is supplied, only check for the # existence of the header files. # AST_EXT_LIB_CHECK([package], [library], [function], [header], # [extra libs], [extra cflags], [version]) AC_DEFUN([AST_EXT_LIB_CHECK], [ if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then pbxlibdir="" # if --with-$1=DIR has been specified, use it. if test "x${$1_DIR}" != "x"; then if test -d ${$1_DIR}/lib; then pbxlibdir="-L${$1_DIR}/lib" else pbxlibdir="-L${$1_DIR}" fi fi pbxfuncname="$3" if test "x${pbxfuncname}" = "x" ; then # empty lib, assume only headers AST_$1_FOUND=yes else AC_CHECK_LIB([$2], [${pbxfuncname}], [AST_$1_FOUND=yes], [AST_$1_FOUND=no], ${pbxlibdir} $5) fi # now check for the header. if test "${AST_$1_FOUND}" = "yes"; then $1_LIB="${pbxlibdir} -l$2 $5" # if --with-$1=DIR has been specified, use it. if test "x${$1_DIR}" != "x"; then $1_INCLUDE="-I${$1_DIR}/include" fi $1_INCLUDE="${$1_INCLUDE} $6" if test "x$4" = "x" ; then # no header, assume found $1_HEADER_FOUND="1" else # check for the header saved_cppflags="${CPPFLAGS}" CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE} $6" AC_CHECK_HEADER([$4], [$1_HEADER_FOUND=1], [$1_HEADER_FOUND=0]) CPPFLAGS="${saved_cppflags}" fi if test "x${$1_HEADER_FOUND}" = "x0" ; then $1_LIB="" $1_INCLUDE="" else if test "x${pbxfuncname}" = "x" ; then # only checking headers -> no library $1_LIB="" fi PBX_$1=1 # XXX don't know how to evaluate the description (third argument) in AC_DEFINE_UNQUOTED AC_DEFINE_UNQUOTED([HAVE_$1], 1, [Define this to indicate the ${$1_DESCRIP} library]) AC_DEFINE_UNQUOTED([HAVE_$1_VERSION], [$7], [Define to indicate the ${$1_DESCRIP} library version]) fi fi fi ]) # Check for a package using $2-config. Similar to AST_EXT_LIB_CHECK, # but use $2-config to determine cflags and libraries to use. # $3 and $4 can be used to replace --cflags and --libs in the request # AST_EXT_TOOL_CHECK([package], [tool name], [--cflags], [--libs], [includes], [expression]) AC_DEFUN([AST_EXT_TOOL_CHECK], [ if test "x${PBX_$1}" != "x1" -a "${USE_$1}" != "no"; then PBX_$1=0 AC_CHECK_TOOL(CONFIG_$1, $2-config, No) if test ! "x${CONFIG_$1}" = xNo; then if test x"$3" = x ; then A=--cflags ; else A="$3" ; fi $1_INCLUDE=$(${CONFIG_$1} $A) if test x"$4" = x ; then A=--libs ; else A="$4" ; fi $1_LIB=$(${CONFIG_$1} $A) if test x"$5" != x ; then saved_cppflags="${CPPFLAGS}" if test "x${$1_DIR}" != "x"; then $1_INCLUDE="-I${$1_DIR}/include" fi CPPFLAGS="${CPPFLAGS} ${$1_INCLUDE}" saved_ldflags="${LDFLAGS}" LDFLAGS="${$1_LIB}" AC_LINK_IFELSE( [ AC_LANG_PROGRAM( [ $5 ], [ $6; ] )], [ PBX_$1=1 AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 headers.]) ], [] ) CPPFLAGS="${saved_cppflags}" LDFLAGS="${saved_ldflags}" else PBX_$1=1 AC_DEFINE([HAVE_$1], 1, [Define if your system has the $1 libraries.]) fi fi fi ]) AC_DEFUN([AST_CHECK_GNU_MAKE], [AC_CACHE_CHECK([for GNU make], [ac_cv_GNU_MAKE], ac_cv_GNU_MAKE='Not Found' ; ac_cv_GNU_MAKE_VERSION_MAJOR=0 ; ac_cv_GNU_MAKE_VERSION_MINOR=0 ; for a in make gmake gnumake ; do if test -z "$a" ; then continue ; fi ; if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then ac_cv_GNU_MAKE=$a ; ac_cv_GNU_MAKE_VERSION_MAJOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f3 -d' ' | cut -f1 -d'.'` ac_cv_GNU_MAKE_VERSION_MINOR=`$ac_cv_GNU_MAKE --version | grep "GNU Make" | cut -f2 -d'.' | cut -c1-2` break; fi done ; ) ; if test "x$ac_cv_GNU_MAKE" = "xNot Found" ; then AC_MSG_ERROR( *** Please install GNU make. It is required to build Asterisk!) exit 1 fi AC_SUBST([GNU_MAKE], [$ac_cv_GNU_MAKE]) ]) AC_DEFUN( [AST_CHECK_PWLIB], [ PWLIB_INCDIR= PWLIB_LIBDIR= AC_LANG_PUSH([C++]) if test "${PWLIBDIR:-unset}" != "unset" ; then AC_CHECK_HEADER(${PWLIBDIR}/version.h, HAS_PWLIB=1, ) fi if test "${HAS_PWLIB:-unset}" = "unset" ; then if test "${OPENH323DIR:-unset}" != "unset"; then AC_CHECK_HEADER(${OPENH323DIR}/../pwlib/version.h, HAS_PWLIB=1, ) fi if test "${HAS_PWLIB:-unset}" != "unset" ; then PWLIBDIR="${OPENH323DIR}/../pwlib" else AC_CHECK_HEADER(${HOME}/pwlib/include/ptlib.h, HAS_PWLIB=1, ) if test "${HAS_PWLIB:-unset}" != "unset" ; then PWLIBDIR="${HOME}/pwlib" else AC_CHECK_HEADER(/usr/local/include/ptlib.h, HAS_PWLIB=1, ) if test "${HAS_PWLIB:-unset}" != "unset" ; then AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/bin) if test "${PTLIB_CONFIG:-unset}" = "unset" ; then AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/local/share/pwlib/make) fi PWLIB_INCDIR="/usr/local/include" PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir` if test "${PWLIB_LIBDIR:-unset}" = "unset"; then if test "x$LIB64" != "x"; then PWLIB_LIBDIR="/usr/local/lib64" else PWLIB_LIBDIR="/usr/local/lib" fi fi PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs` PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`" else AC_CHECK_HEADER(/usr/include/ptlib.h, HAS_PWLIB=1, ) if test "${HAS_PWLIB:-unset}" != "unset" ; then AC_PATH_PROG(PTLIB_CONFIG, ptlib-config, , /usr/share/pwlib/make) PWLIB_INCDIR="/usr/include" PWLIB_LIBDIR=`${PTLIB_CONFIG} --pwlibdir` if test "${PWLIB_LIBDIR:-unset}" = "unset"; then if test "x$LIB64" != "x"; then PWLIB_LIBDIR="/usr/lib64" else PWLIB_LIBDIR="/usr/lib" fi fi PWLIB_LIB=`${PTLIB_CONFIG} --ldflags --libs` PWLIB_LIB="-L${PWLIB_LIBDIR} `echo ${PWLIB_LIB}`" fi fi fi fi fi #if test "${HAS_PWLIB:-unset}" = "unset" ; then # echo "Cannot find pwlib - please install or set PWLIBDIR and try again" # exit #fi if test "${HAS_PWLIB:-unset}" != "unset" ; then if test "${PWLIBDIR:-unset}" = "unset" ; then if test "${PTLIB_CONFIG:-unset}" != "unset" ; then PWLIBDIR=`$PTLIB_CONFIG --prefix` else echo "Cannot find ptlib-config - please install and try again" exit fi fi if test "x$PWLIBDIR" = "x/usr" -o "x$PWLIBDIR" = "x/usr/"; then PWLIBDIR="/usr/share/pwlib" PWLIB_INCDIR="/usr/include" if test "x$LIB64" != "x"; then PWLIB_LIBDIR="/usr/lib64" else PWLIB_LIBDIR="/usr/lib" fi fi if test "x$PWLIBDIR" = "x/usr/local" -o "x$PWLIBDIR" = "x/usr/"; then PWLIBDIR="/usr/local/share/pwlib" PWLIB_INCDIR="/usr/local/include" if test "x$LIB64" != "x"; then PWLIB_LIBDIR="/usr/local/lib64" else PWLIB_LIBDIR="/usr/local/lib" fi fi if test "${PWLIB_INCDIR:-unset}" = "unset"; then PWLIB_INCDIR="${PWLIBDIR}/include" fi if test "${PWLIB_LIBDIR:-unset}" = "unset"; then PWLIB_LIBDIR="${PWLIBDIR}/lib" fi AC_SUBST([PWLIBDIR]) AC_SUBST([PWLIB_INCDIR]) AC_SUBST([PWLIB_LIBDIR]) fi AC_LANG_POP([C++]) ]) AC_DEFUN( [AST_CHECK_OPENH323_PLATFORM], [ PWLIB_OSTYPE= case "$host_os" in linux*) PWLIB_OSTYPE=linux ; ;; freebsd* ) PWLIB_OSTYPE=FreeBSD ; ;; openbsd* ) PWLIB_OSTYPE=OpenBSD ; ENDLDLIBS="-lossaudio" ; ;; netbsd* ) PWLIB_OSTYPE=NetBSD ; ENDLDLIBS="-lossaudio" ; ;; solaris* | sunos* ) PWLIB_OSTYPE=solaris ; ;; darwin* ) PWLIB_OSTYPE=Darwin ; ;; beos*) PWLIB_OSTYPE=beos ; STDCCFLAGS="$STDCCFLAGS -D__BEOS__" ;; cygwin*) PWLIB_OSTYPE=cygwin ; ;; mingw*) PWLIB_OSTYPE=mingw ; STDCCFLAGS="$STDCCFLAGS -mms-bitfields" ; ENDLDLIBS="-lwinmm -lwsock32 -lsnmpapi -lmpr -lcomdlg32 -lgdi32 -lavicap32" ; ;; * ) PWLIB_OSTYPE="$host_os" ; AC_MSG_WARN("OS $PWLIB_OSTYPE not recognized - proceed with caution!") ; ;; esac PWLIB_MACHTYPE= case "$host_cpu" in x86 | i686 | i586 | i486 | i386 ) PWLIB_MACHTYPE=x86 ;; x86_64) PWLIB_MACHTYPE=x86_64 ; P_64BIT=1 ; LIB64=1 ; ;; alpha | alphaev56 | alphaev6 | alphaev67 | alphaev7) PWLIB_MACHTYPE=alpha ; P_64BIT=1 ; ;; sparc ) PWLIB_MACHTYPE=sparc ; ;; powerpc ) PWLIB_MACHTYPE=ppc ; ;; ppc ) PWLIB_MACHTYPE=ppc ; ;; powerpc64 ) PWLIB_MACHTYPE=ppc64 ; P_64BIT=1 ; LIB64=1 ; ;; ppc64 ) PWLIB_MACHTYPE=ppc64 ; P_64BIT=1 ; LIB64=1 ; ;; ia64) PWLIB_MACHTYPE=ia64 ; P_64BIT=1 ; ;; s390x) PWLIB_MACHTYPE=s390x ; P_64BIT=1 ; LIB64=1 ; ;; s390) PWLIB_MACHTYPE=s390 ; ;; * ) PWLIB_MACHTYPE="$host_cpu"; AC_MSG_WARN("CPU $PWLIB_MACHTYPE not recognized - proceed with caution!") ;; esac PWLIB_PLATFORM="${PWLIB_OSTYPE}_${PWLIB_MACHTYPE}" AC_SUBST([PWLIB_PLATFORM]) ]) AC_DEFUN( [AST_CHECK_OPENH323], [ OPENH323_INCDIR= OPENH323_LIBDIR= AC_LANG_PUSH([C++]) if test "${OPENH323DIR:-unset}" != "unset" ; then AC_CHECK_HEADER(${OPENH323DIR}/version.h, HAS_OPENH323=1, ) fi if test "${HAS_OPENH323:-unset}" = "unset" ; then AC_CHECK_HEADER(${PWLIBDIR}/../openh323/version.h, OPENH323DIR="${PWLIBDIR}/../openh323"; HAS_OPENH323=1, ) if test "${HAS_OPENH323:-unset}" != "unset" ; then OPENH323DIR="${PWLIBDIR}/../openh323" saved_cppflags="${CPPFLAGS}" CPPFLAGS="${CPPFLAGS} -I${PWLIB_INCDIR}/openh323 -I${PWLIB_INCDIR}" AC_CHECK_HEADER(${OPENH323DIR}/include/h323.h, , OPENH323_INCDIR="${PWLIB_INCDIR}/openh323"; OPENH323_LIBDIR="${PWLIB_LIBDIR}", [#include ]) CPPFLAGS="${saved_cppflags}" else saved_cppflags="${CPPFLAGS}" CPPFLAGS="${CPPFLAGS} -I${HOME}/openh323/include -I${PWLIB_INCDIR}" AC_CHECK_HEADER(${HOME}/openh323/include/h323.h, HAS_OPENH323=1, ) CPPFLAGS="${saved_cppflags}" if test "${HAS_OPENH323:-unset}" != "unset" ; then OPENH323DIR="${HOME}/openh323" else saved_cppflags="${CPPFLAGS}" CPPFLAGS="${CPPFLAGS} -I/usr/local/include/openh323 -I${PWLIB_INCDIR}" AC_CHECK_HEADER(/usr/local/include/openh323/h323.h, HAS_OPENH323=1, ) CPPFLAGS="${saved_cppflags}" if test "${HAS_OPENH323:-unset}" != "unset" ; then OPENH323DIR="/usr/local/share/openh323" OPENH323_INCDIR="/usr/local/include/openh323" if test "x$LIB64" != "x"; then OPENH323_LIBDIR="/usr/local/lib64" else OPENH323_LIBDIR="/usr/local/lib" fi else saved_cppflags="${CPPFLAGS}" CPPFLAGS="${CPPFLAGS} -I/usr/include/openh323 -I${PWLIB_INCDIR}" AC_CHECK_HEADER(/usr/include/openh323/h323.h, HAS_OPENH323=1, , [#include ]) CPPFLAGS="${saved_cppflags}" if test "${HAS_OPENH323:-unset}" != "unset" ; then OPENH323DIR="/usr/share/openh323" OPENH323_INCDIR="/usr/include/openh323" if test "x$LIB64" != "x"; then OPENH323_LIBDIR="/usr/lib64" else OPENH323_LIBDIR="/usr/lib" fi fi fi fi fi fi if test "${HAS_OPENH323:-unset}" != "unset" ; then if test "${OPENH323_INCDIR:-unset}" = "unset"; then OPENH323_INCDIR="${OPENH323DIR}/include" fi if test "${OPENH323_LIBDIR:-unset}" = "unset"; then OPENH323_LIBDIR="${OPENH323DIR}/lib" fi OPENH323_LIBDIR="`cd ${OPENH323_LIBDIR}; pwd`" OPENH323_INCDIR="`cd ${OPENH323_INCDIR}; pwd`" OPENH323DIR="`cd ${OPENH323DIR}; pwd`" AC_SUBST([OPENH323DIR]) AC_SUBST([OPENH323_INCDIR]) AC_SUBST([OPENH323_LIBDIR]) fi AC_LANG_POP([C++]) ]) AC_DEFUN( [AST_CHECK_PWLIB_VERSION], [ if test "${HAS_$2:-unset}" != "unset"; then $2_VERSION=`grep "$2_VERSION" ${$2_INCDIR}/$3 | cut -f2 -d ' ' | sed -e 's/"//g'` $2_MAJOR_VERSION=`echo ${$2_VERSION} | cut -f1 -d.` $2_MINOR_VERSION=`echo ${$2_VERSION} | cut -f2 -d.` $2_BUILD_NUMBER=`echo ${$2_VERSION} | cut -f3 -d.` let $2_VER=${$2_MAJOR_VERSION}*10000+${$2_MINOR_VERSION}*100+${$2_BUILD_NUMBER} let $2_REQ=$4*10000+$5*100+$6 AC_MSG_CHECKING(if $1 version ${$2_VERSION} is compatible with chan_h323) if test ${$2_VER} -lt ${$2_REQ}; then AC_MSG_RESULT(no) unset HAS_$2 else AC_MSG_RESULT(yes) fi fi ]) AC_DEFUN( [AST_CHECK_PWLIB_BUILD], [ if test "${HAS_$2:-unset}" != "unset"; then AC_MSG_CHECKING($1 installation validity) saved_cppflags="${CPPFLAGS}" saved_libs="${LIBS}" if test "${$2_LIB:-unset}" != "unset"; then LIBS="${LIBS} ${$2_LIB} $7" else LIBS="${LIBS} -L${$2_LIBDIR} -l${PLATFORM_$2} $7" fi CPPFLAGS="${CPPFLAGS} -I${$2_INCDIR} $6" AC_LANG_PUSH([C++]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([$4],[$5])], [ AC_MSG_RESULT(yes) ac_cv_lib_$2="yes" ], [ AC_MSG_RESULT(no) ac_cv_lib_$2="no" ] ) AC_LANG_POP([C++]) LIBS="${saved_libs}" CPPFLAGS="${saved_cppflags}" if test "${ac_cv_lib_$2}" = "yes"; then if test "${$2_LIB:-undef}" = "undef"; then if test "${$2_LIBDIR}" != "" -a "${$2_LIBDIR}" != "/usr/lib"; then $2_LIB="-L${$2_LIBDIR} -l${PLATFORM_$2}" else $2_LIB="-l${PLATFORM_$2}" fi fi if test "${$2_INCDIR}" != "" -a "${$2_INCDIR}" != "/usr/include"; then $2_INCLUDE="-I${$2_INCDIR}" fi PBX_$2=1 AC_DEFINE([HAVE_$2], 1, [$3]) fi fi ]) AC_DEFUN( [AST_CHECK_OPENH323_BUILD], [ if test "${HAS_OPENH323:-unset}" != "unset"; then AC_MSG_CHECKING(OpenH323 build option) OPENH323_SUFFIX= prefixes="h323_${PWLIB_PLATFORM}_ h323_ openh323" for pfx in $prefixes; do files=`ls -l ${OPENH323_LIBDIR}/lib${pfx}*.so* 2>/dev/null` libfile= if test -n "$files"; then for f in $files; do if test -f $f -a ! -L $f; then libfile=`basename $f` break; fi done fi if test -n "$libfile"; then OPENH323_PREFIX=$pfx break; fi done if test "${libfile:-unset}" != "unset"; then OPENH323_SUFFIX=`eval "echo ${libfile} | sed -e 's/lib${OPENH323_PREFIX}\(@<:@^.@:>@*\)\..*/\1/'"` fi case "${OPENH323_SUFFIX}" in n) OPENH323_BUILD="notrace";; r) OPENH323_BUILD="opt";; d) OPENH323_BUILD="debug";; *) if test "${OPENH323_PREFIX:-undef}" = "openh323"; then notrace=`eval "grep NOTRACE ${OPENH323DIR}/openh323u.mak | grep = | sed -e 's/@<:@A-Z0-9_@:>@*@<:@ @:>@*=@<:@ @:>@*//'"` if test "x$notrace" = "x"; then notrace="0" fi if test "$notrace" -ne 0; then OPENH323_BUILD="notrace" else OPENH323_BUILD="opt" fi OPENH323_LIB="-l${OPENH323_PREFIX}" else OPENH323_BUILD="notrace" fi ;; esac AC_MSG_RESULT(${OPENH323_BUILD}) AC_SUBST([OPENH323_SUFFIX]) AC_SUBST([OPENH323_BUILD]) fi ]) # AST_FUNC_FORK # ------------- AN_FUNCTION([fork], [AST_FUNC_FORK]) AN_FUNCTION([vfork], [AST_FUNC_FORK]) AC_DEFUN([AST_FUNC_FORK], [AC_REQUIRE([AC_TYPE_PID_T])dnl AC_CHECK_HEADERS(vfork.h) AC_CHECK_FUNCS(fork vfork) if test "x$ac_cv_func_fork" = xyes; then _AST_FUNC_FORK else ac_cv_func_fork_works=$ac_cv_func_fork fi if test "x$ac_cv_func_fork_works" = xcross; then case $host in *-*-amigaos* | *-*-msdosdjgpp* | *-*-uclinux* | *-*-linux-uclibc* ) # Override, as these systems have only a dummy fork() stub ac_cv_func_fork_works=no ;; *) ac_cv_func_fork_works=yes ;; esac AC_MSG_WARN([result $ac_cv_func_fork_works guessed because of cross compilation]) fi ac_cv_func_vfork_works=$ac_cv_func_vfork if test "x$ac_cv_func_vfork" = xyes; then _AC_FUNC_VFORK fi; if test "x$ac_cv_func_fork_works" = xcross; then ac_cv_func_vfork_works=$ac_cv_func_vfork AC_MSG_WARN([result $ac_cv_func_vfork_works guessed because of cross compilation]) fi if test "x$ac_cv_func_vfork_works" = xyes; then AC_DEFINE(HAVE_WORKING_VFORK, 1, [Define to 1 if `vfork' works.]) else AC_DEFINE(vfork, fork, [Define as `fork' if `vfork' does not work.]) fi if test "x$ac_cv_func_fork_works" = xyes; then AC_DEFINE(HAVE_WORKING_FORK, 1, [Define to 1 if `fork' works.]) fi ])# AST_FUNC_FORK # _AST_FUNC_FORK # ------------- AC_DEFUN([_AST_FUNC_FORK], [AC_CACHE_CHECK(for working fork, ac_cv_func_fork_works, [AC_RUN_IFELSE( [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], [ /* By Ruediger Kuhlmann. */ return fork () < 0; ])], [ac_cv_func_fork_works=yes], [ac_cv_func_fork_works=no], [ac_cv_func_fork_works=cross])])] )# _AST_FUNC_FORK # AST_PROG_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([AST_PROG_LD], [AC_ARG_WITH([gnu-ld], [AC_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no]) AC_REQUIRE([AST_PROG_SED])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1 then ac_cv_prog_egrep='grep -E' else ac_cv_prog_egrep='egrep' fi]) EGREP=$ac_cv_prog_egrep AC_SUBST([EGREP]) ])]) # AST_PROG_EGREP # AST_PROG_SED # ----------- # Check for a fully functional sed program that truncates # as few characters as possible. Prefer GNU sed if found. AC_DEFUN([AST_PROG_SED], [AC_CACHE_CHECK([for a sed that does not truncate output], ac_cv_path_SED, [dnl ac_script should not contain more than 99 commands (for HP-UX sed), dnl but more than about 7000 bytes, to catch a limit in Solaris 8 /usr/ucb/sed. ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" | sed 99q >conftest.sed $as_unset ac_script || ac_script= _AC_PATH_PROG_FEATURE_CHECK(SED, [sed gsed], [_AC_FEATURE_CHECK_LENGTH([ac_path_SED], [ac_cv_path_SED], ["$ac_path_SED" -f conftest.sed])])]) SED="$ac_cv_path_SED" AC_SUBST([SED])dnl rm -f conftest.sed ])# AST_PROG_SED dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) dnl dnl @summary figure out how to build C programs using POSIX threads dnl dnl This macro figures out how to build C programs using POSIX threads. dnl It sets the PTHREAD_LIBS output variable to the threads library and dnl linker flags, and the PTHREAD_CFLAGS output variable to any special dnl C compiler flags that are needed. (The user can also force certain dnl compiler flags/libs to be tested by setting these environment dnl variables.) dnl dnl Also sets PTHREAD_CC to any special C compiler that is needed for dnl multi-threaded programs (defaults to the value of CC otherwise). dnl (This is necessary on AIX to use the special cc_r compiler alias.) dnl dnl NOTE: You are assumed to not only compile your program with these dnl flags, but also link it with them as well. e.g. you should link dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS dnl $LIBS dnl dnl If you are only building threads programs, you may wish to use dnl these variables in your default LIBS, CFLAGS, and CC: dnl dnl LIBS="$PTHREAD_LIBS $LIBS" dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" dnl CC="$PTHREAD_CC" dnl dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). dnl dnl ACTION-IF-FOUND is a list of shell commands to run if a threads dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the dnl default action will define HAVE_PTHREAD. dnl dnl Please let the authors know if this macro fails on any platform, or dnl if you have any other suggestions or comments. This macro was based dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. dnl We are also grateful for the helpful feedback of numerous users. dnl dnl @category InstalledPackages dnl @author Steven G. Johnson dnl @version 2006-05-29 dnl @license GPLWithACException AC_DEFUN([ACX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_SAVE AC_LANG_C acx_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) AC_MSG_RESULT($acx_pthread_ok) if test x"$acx_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac if test x"$acx_pthread_ok" = xno; then for flag in $acx_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) if test x"$acx_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_TRY_LINK([#include ], [pthread_t th; pthread_join(th, 0); pthread_attr_init(0); pthread_cleanup_push(0, 0); pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], [acx_pthread_ok=yes]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT($acx_pthread_ok) if test "x$acx_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$acx_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_TRY_LINK([#include ], [int attr=$attr; return attr;], [attr_name=$attr; break]) done AC_MSG_RESULT($attr_name) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case "${host_cpu}-${host_os}" in *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: must compile with xlc_r or cc_r if test x"$GCC" != xyes; then AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) else PTHREAD_CC=$CC fi else PTHREAD_CC="$CC" fi AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) AC_SUBST(PTHREAD_CC) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$acx_pthread_ok" = xyes; then ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) : else acx_pthread_ok=no $2 fi AC_LANG_RESTORE ])dnl ACX_PTHREAD dahdi-tools-2.10.2/dahdi.init0000755000000000000000000002045312537624573014464 0ustar rootroot#!/bin/sh # # dahdi This shell script takes care of loading and unloading \ # DAHDI Telephony interfaces # chkconfig: 2345 9 92 # description: The DAHDI drivers allow you to use your linux \ # computer to accept incoming data and voice interfaces # # config: /etc/dahdi/init.conf ### BEGIN INIT INFO # Provides: dahdi # Required-Start: $local_fs $remote_fs # Required-Stop: $local_fs $remote_fs # Should-Start: $network $syslog # Should-Stop: $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: DAHDI kernel modules # Description: dahdi - load and configure DAHDI modules ### END INIT INFO initdir=/etc/init.d # Don't edit the following values. Edit /etc/dahdi/init.conf instead. DAHDI_CFG=/usr/sbin/dahdi_cfg DAHDI_CFG_CMD=${DAHDI_CFG_CMD:-"$DAHDI_CFG"} # e.g: for a custom system.conf location FXOTUNE=/usr/sbin/fxotune # The default syncer Astribank. Usually set automatically to a sane # value by xpp_sync(1) if you have an Astribank. You can set this to an # explicit Astribank (e.g: 01). XPP_SYNC=auto # The maximal timeout (seconds) to wait for udevd to finish generating # device nodes after the modules have loaded and before running dahdi_cfg. DAHDI_DEV_TIMEOUT=20 # A list of modules to unload when stopping. # All of their dependencies will be unloaded as well. DAHDI_UNLOAD_MODULES="dahdi" # # Determine which kind of configuration we're using # system=redhat # assume redhat if [ -f /etc/debian_version ]; then system=debian fi if [ -f /etc/gentoo-release ]; then system=debian fi if [ -f /etc/SuSE-release -o -f /etc/novell-release ] then system=debian fi # Source function library. if [ $system = redhat ]; then . $initdir/functions || exit 0 fi DAHDI_MODULES_FILE="/etc/dahdi/modules" [ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf if [ $system = redhat ]; then LOCKFILE=/var/lock/subsys/dahdi fi # recursively unload a module and its dependencies, if possible. # where's modprobe -r when you need it? # inputs: module to unload. # returns: the result from unload_module() { module="$1" line=`lsmod 2>/dev/null | grep "^$1 "` if [ "$line" = '' ]; then return; fi # module was not loaded set -- $line # $1: the original module, $2: size, $3: refcount, $4: deps list mods=`echo $4 | tr , ' '` ec_modules="" # xpp_usb keeps the xpds below busy if an xpp hardware is # connected. Hence must be removed before them: case "$module" in xpd_*) mods="xpp_usb $mods";; esac for mod in $mods; do case "$mod" in dahdi_echocan_*) ec_modules="$mod $ec_modules" ;; *) # run in a subshell, so it won't step over our vars: (unload_module $mod) ;; esac done # Now that all the other dependencies are unloaded, we can unload the # dahdi_echocan modules. The drivers that register spans may keep # references on the echocan modules before they are unloaded. for mod in $ec_modules; do (unload_module $mod) done rmmod $module } unload_modules() { for module in $DAHDI_UNLOAD_MODULES; do unload_module $module done } # In (xpp) hotplug mode, the init script is also executed from the # hotplug hook. In that case it should not attempt to loade modules. # # This function only retunrs false (1) if we're in hotplug mode and # coming from the hotplug hook script. hotplug_should_load_modules() { if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" != '' ] then return 1 fi return 0 } # In (xpp) hotplug mode: quit after we loaded modules. # # In hotplug mode, the main run should end here, whereas the rest of the # script should be finished by the instance running from the hook. # Note that we only get here if there are actually Astribanks on the # system (otherwise noone will trigger the run of the hotplug hook # script). hotplug_exit_after_load() { if [ "$XPP_HOTPLUG_DAHDI" = yes -a "$CALLED_FROM_ATRIBANK_HOOK" = '' ] then exit 0 fi } # Initialize the Xorcom Astribank (xpp/) using perl utiliites: xpp_startup() { if [ "$ASTERISK_SUPPORTS_DAHDI_HOTPLUG" = yes ]; then aas_param='/sys/module/dahdi/parameters/auto_assign_spans' aas=`cat "$aas_param" 2>/dev/null` if [ "$aas" = 0 ]; then echo 1>&2 "Don't wait for Astribanks (use Asterisk hotplug-support)" return 0 fi fi # do nothing if there are no astribank devices: if ! /usr/share/dahdi/waitfor_xpds; then return 0; fi hotplug_exit_after_load } hpec_start() { # HPEC license found if ! echo /var/lib/digium/licenses/HPEC-*.lic | grep -v '\*' | grep -q .; then return fi # dahdihpec_enable not installed in /usr/sbin if [ ! -f /usr/sbin/dahdihpec_enable ]; then echo -n "Running dahdihpec_enable: Failed" echo -n "." echo " The dahdihpec_enable binary is not installed in /usr/sbin." return fi # dahdihpec_enable not set executable if [ ! -x /usr/sbin/dahdihpec_enable ]; then echo -n "Running dahdihpec_enable: Failed" echo -n "." echo " /usr/sbin/dahdihpec_enable is not set as executable." return fi # dahdihpec_enable properly installed if [ $system = debian ]; then echo -n "Running dahdihpec_enable: " /usr/sbin/dahdihpec_enable 2> /dev/null elif [ $system = redhat ]; then action "Running dahdihpec_enable: " /usr/sbin/dahdihpec_enable fi if [ $? = 0 ]; then echo -n "done" echo "." else echo -n "Failed" echo -n "." echo " This can be caused if you had already run dahdihpec_enable, or if your HPEC license is no longer valid." fi } shutdown_dynamic() { if ! grep -q ' DYN/' /proc/dahdi/* 2>/dev/null; then return; fi # we should only get here if we have dynamic spans. Right? $DAHDI_CFG_CMD -s } load_modules() { # Some systems, e.g. Debian Lenny, add here -b, which will break # loading of modules blacklisted in modprobe.d/* unset MODPROBE_OPTIONS modules=`sed -e 's/#.*$//' $DAHDI_MODULES_FILE 2>/dev/null` #if [ "$modules" = '' ]; then # what? #fi echo "Loading DAHDI hardware modules:" modprobe dahdi for line in $modules; do if [ $system = debian ]; then echo -n " ${line}: " if modprobe $line 2> /dev/null; then echo -n "done" else echo -n "error" fi elif [ $system = redhat ]; then action " ${line}: " modprobe $line fi done echo "" } # Make sure that either dahdi is loaded or modprobe-able dahdi_modules_loadable() { modinfo dahdi >/dev/null 2>&1 || lsmod | grep -q -w ^dahdi } if [ ! -x "$DAHDI_CFG" ]; then echo "dahdi_cfg not executable" exit 0 fi RETVAL=0 # See how we were called. case "$1" in start) if ! dahdi_modules_loadable; then echo "No DAHDI modules on the system. Not starting" exit 0 fi if hotplug_should_load_modules; then load_modules fi TMOUT=$DAHDI_DEV_TIMEOUT # max secs to wait while [ ! -d /dev/dahdi ] ; do sleep 1 TMOUT=`expr $TMOUT - 1` if [ $TMOUT -eq 0 ] ; then echo "Error: missing /dev/dahdi!" exit 1 fi done xpp_startup # Assign all spans that weren't handled via udev + /etc/dahdi/assigned-spans.conf /usr/share/dahdi/dahdi_auto_assign_compat if [ $system = debian ]; then echo -n "Running dahdi_cfg: " $DAHDI_CFG_CMD 2> /dev/null && echo -n "done" echo "." elif [ $system = redhat ]; then action "Running dahdi_cfg: " $DAHDI_CFG_CMD fi RETVAL=$? if [ "$LOCKFILE" != '' ]; then [ $RETVAL -eq 0 ] && touch $LOCKFILE fi if [ -x "$FXOTUNE" ] && [ -r /etc/fxotune.conf ]; then # Allowed to fail if e.g. Asterisk already uses channels: $FXOTUNE -s || : fi # Do not try to call xpp_sync if there are no Astribank devices # installed. if test -e /sys/bus/astribanks; then # Set the right Astribanks ticker: LC_ALL=C xpp_sync "$XPP_SYNC" fi hpec_start ;; stop) # Unload drivers #shutdown_dynamic # FIXME: needs test from someone with dynamic spans echo -n "Unloading DAHDI hardware modules: " if unload_modules; then echo "done" else echo "error" fi if [ "$LOCKFILE" != '' ]; then [ $RETVAL -eq 0 ] && rm -f $LOCKFILE fi ;; unload) unload_modules ;; restart|force-reload) $0 stop $0 start ;; reload) if [ $system = debian ]; then echo -n "Rerunning dahdi_cfg: " $DAHDI_CFG_CMD 2> /dev/null && echo -n "done" echo "." elif [ $system = redhat ]; then action "Rerunning dahdi_cfg: " $DAHDI_CFG_CMD fi RETVAL=$? ;; status) if [ -d /proc/dahdi ]; then /usr/sbin/lsdahdi RETVAL=0 else RETVAL=3 fi ;; *) echo "Usage: dahdi {start|stop|restart|status|reload|unload}" exit 1 esac exit $RETVAL dahdi-tools-2.10.2/ifup-hdlc0000644000000000000000000000146212537624573014320 0ustar rootroot#!/bin/sh PATH=/sbin:/usr/sbin:/bin:/usr/bin cd /etc/sysconfig/network-scripts . network-functions CONFIG=$1 source_config if [ "foo$2" = "fooboot" -a "${ONBOOT}" = "no" ] then exit fi if [ -z "${MODE}" ]; then echo "No mode specified!" exit fi sethdlc ${DEVICE} mode ${MODE} ifconfig ${DEVICE} ${IPADDR} pointopoint ${REMIP} route add -net ${NETWORK} netmask ${NETMASK} ${DEVICE} # this is broken! it's only here to keep compatibility with old RH sytstems if [ "${GATEWAY}" != "" -a "${GATEWAY}" != "none" ] then route add default gw ${GATEWAY} metric 1 ${DEVICE} fi . /etc/sysconfig/network if [ "${GATEWAY}" != "" ]; then if [ "${GATEWAYDEV}" = "" -o "${GATEWAYDEV}" = "${DEVICE}" ]; then # set up default gateway route add default gw ${GATEWAY} fi fi /etc/sysconfig/network-scripts/ifup-post $1 dahdi-tools-2.10.2/fxotune.h0000644000000000000000000001002012537624573014351 0ustar rootroot/* * fxotune.h -- data structures and associated definitions for fxotune.c * * By Matthew Fredrickson * * Echo coefficients and acim register values taken from AN84 from Silicon * Laboratories app note AN84 for setting echo cancellation coefficients * * (C) 2005 Digium, Inc. */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ struct wctdm_echo_coefs echo_trys [] = { /* 600 ohm echo settings */ { 0, 0, 0, 0, 0, 0, 0, 0, 0}, { 10, 0, 6, 1, 254, 2, 255, 0, 0}, { 3, 255, 255, 0, 1, 0, 0, 0, 0}, { 3, 1, 253, 253, 2, 255, 0, 0, 0}, { 9, 254, 251, 255, 2, 0, 1, 0, 0}, { 5, 3, 251, 250, 2, 254, 0, 0, 255}, { 8, 253, 2, 244, 255, 10, 244, 3, 253}, { 10, 249, 244, 8, 12, 245, 252, 0, 1}, /* 900 ohm echo settings */ { 1, 0, 0, 0, 0, 0, 0, 0, 0}, { 10, 252, 255, 1, 255, 0, 0, 0, 0}, { 7, 255, 251, 251, 2, 255, 255, 1, 255}, { 3, 1, 251, 250, 1, 254, 255, 0, 255}, { 5, 252, 250, 0, 0, 255, 1, 0, 0}, { 5, 3, 251, 250, 1, 253, 0, 0, 255}, { 8, 253, 2, 244, 255, 10, 244, 3, 253}, { 10, 249, 244, 8, 12, 245, 252, 0, 1}, /* 270 ohm + (750 ohm || 150 nF) (CTR21) */ { 2, 0, 0, 0, 0, 0, 0, 0, 0}, { 7, 0, 0, 255, 254, 0, 0, 0, 0}, { 9, 0, 253, 254, 2, 255, 0, 0, 0}, { 5, 1, 249, 254, 4, 253, 1, 0, 0}, { 5, 252, 250, 1, 1, 254, 0, 255, 0}, { 5, 3, 251, 250, 2, 253, 255, 255, 255}, { 8, 253, 2, 244, 255, 10, 244, 3, 253}, { 10, 249, 244, 8, 12, 245, 252, 0, 1}, /* 220 ohm + (820 ohm || 120 nF) (Australia/NewZealand) and 220 ohm + (820 ohm * || 115nF) (Slovakia/SAfrica/Germany/Austria/Bulgaria) */ { 3, 0, 0, 0, 0, 0, 0, 0, 0}, { 7, 0, 255, 254, 255, 0, 255, 0, 0}, { 9, 0, 253, 253, 1, 255, 0, 0, 0}, { 5, 1, 249, 254, 3, 253, 1, 0, 0}, { 5, 252, 250, 1, 1, 254, 0, 255, 0}, { 5, 3, 251, 251, 2, 253, 255, 255, 255}, { 8, 253, 2, 244, 255, 10, 244, 3, 253}, { 10, 249, 244, 8, 12, 245, 252, 0, 1}, /* 370 ohm + (620ohm || 310nF) (New Zealand #2/India) CO Termination */ { 4, 0, 0, 0, 0, 0, 0, 0, 0}, { 9, 255, 1, 4, 0, 0, 1, 255, 0}, { 9, 0, 253, 0, 3, 254, 0, 0, 255}, { 9, 2, 250, 253, 5, 253, 1, 0 ,255}, { 5, 252, 250, 1, 2, 255, 0 ,255, 0}, { 5, 3, 251, 250, 3, 254, 255, 255, 255}, { 8, 253, 2, 244, 255, 10, 244, 3, 253}, { 10, 249, 244, 8, 12, 245, 252, 0, 1}, /* 320 ohm + (1050ohm || 230 nF) (England) CO Termination */ { 5, 0, 0, 0, 0, 0, 0, 0, 0}, { 9, 0 ,255, 1, 255, 255, 0, 255, 0}, { 5, 255, 252, 0, 2, 254, 0, 255, 255}, { 9, 2, 250, 253, 4, 252, 0, 255, 255}, { 5, 252, 250, 1, 1, 254, 0 ,255, 255}, { 5, 3, 251, 250, 2, 253, 255, 255, 254}, { 3, 1, 1, 242, 2, 9, 245, 3, 253}, { 10, 249, 244, 8, 12, 245, 252, 0, 1}, /* 370 ohm + (820 ohm || 110 nF) CO Termination */ { 6, 0, 0, 0, 0, 0, 0, 0, 0}, { 6, 1, 254, 253, 0, 255, 0, 0, 0}, { 9, 0, 251, 252, 2, 255, 0, 0, 0}, { 5, 1, 248, 252, 4, 253, 1, 0, 0}, { 5, 252, 250, 0, 0, 254, 0 , 255, 0}, { 5, 3, 251, 250, 2, 253, 255, 255, 254}, { 3, 1, 1, 242, 2, 9, 245, 3, 253}, { 10, 249, 244, 8, 12, 245, 252, 0, 1}, /* 275 ohm + (780 ohm || 115 nF) CO Termination */ { 7, 0, 0, 0, 0, 0, 0, 0, 0}, { 7, 255, 255, 255, 255, 0, 0, 0, 0}, { 9, 0, 253, 254, 2, 255, 0, 0, 0}, { 5, 1, 249, 254, 4, 253, 1, 0, 0}, { 5, 252, 250, 1, 1, 254, 0, 255, 0}, { 5, 3, 251, 250, 2, 253, 255, 255, 255}, { 8, 253, 2, 244, 255, 10, 244, 3, 253}, { 10, 249, 244, 8, 12, 245, 252, 0, 1}, /* Make sure we include the rest of the impedances */ { 8, 0, 0, 0, 0, 0, 0, 0, 0}, { 9, 0, 0, 0, 0, 0, 0, 0, 0}, { 10, 0, 0, 0, 0, 0, 0, 0, 0}, { 11, 0, 0, 0, 0, 0, 0, 0, 0}, { 12, 0, 0, 0, 0, 0, 0, 0, 0}, { 13, 0, 0, 0, 0, 0, 0, 0, 0}, { 14, 0, 0, 0, 0, 0, 0, 0, 0}, { 15, 0, 0, 0, 0, 0, 0, 0, 0}, }; dahdi-tools-2.10.2/README0000644000000000000000000002770212537624573013407 0ustar rootrootDAHDI Telephony Interface Driver ================================= Asterisk Development Team $Revision$, $Date$ DAHDI stands for Digium Asterisk Hardware Device Interface. This package contains the user-space tools to configure the kernel modules included in the package dahdi-linux. Build Requirements ------------------ This package needs the headers from dahdi-linux. Thus you should install dahdi-linux before building dahdi-tools. Build System ~~~~~~~~~~~~ GCC and friends. Generally you will need to install the package gcc. There may be cases where you will need a specific version of gcc to build kernel modules. Extra Libraries ~~~~~~~~~~~~~~~ Some libraries are needed for extra utilities that are provided with DAHDI. - libusb is needed for building fpga_load, needed for firmware loading of the Xorcom Astribank. - libnewt is needed to build the optional but useful utility dahdi_tool. Installation ~~~~~~~~~~~~ Note: If using `sudo` to build/install, you may need to add /sbin to your PATH. ---------------------------------- ./configure make make install # To install init scripts and config files: #make config ---------------------------------- Build Tweaks ~~~~~~~~~~~~ Partial Build/Install ^^^^^^^^^^^^^^^^^^^^^ There are some make targets that are provided to build or install just parts of DAHDI: . Build targets: - make: Build DAHDI user-space programs and libraries. partial targets of it: * make 'utilname': builds 'utilname' alone (e.g: `make dahdi_diag`) * make utils: Build just the programs. * make libs: Build libtonezone. * make tests: Build testing binaries. . Install targets: - make install: Install everything. Sub-targets of it: * make install-utils: Installs most things. * make install-libs: Installs libtonezone. - make config: install configuration files (overriding existing ones). - make install-test: Install testing binaries. Installation to a Subtree ^^^^^^^^^^^^^^^^^^^^^^^^^ The following may be useful when testing the package or when preparing a package for a binary distribution (such as an rpm package) installing onto a subtree rather than on the real system. make install DESTDIR=targetdir This can be useful for any partial install target from the list above. Options For ./configure ^^^^^^^^^^^^^^^^^^^^^^^ The configure script executes various tests and based on them generates makeopts. You can pass it --with options and variable settings, for instance: ./configure --without-ncurses CC="gcc-4.10" If you just want to recreate the same files without a full detection run, use: ./config.status To re-run ./configure with the same parameters it was run with last time, use: ./config.status --recheck Configuration ------------- Configuration for DAHDI resides under /etc/dahdi . /etc/dahdi/system.conf ~~~~~~~~~~~~~~~~~~~~~~ The main method to configure DAHDI devices is using the utility *dahdi_cfg*. dahdi_cfg reads data from the configuration file /etc/dahdi/system.conf , figures out what configuration to send to channels, and send it to the kernel. A sample annotated system.conf is included in this directory and installed by default. Edit it to suit your configuration. Alternatively use the script dahdi_genconf to generate one that should work with your system. Note that while dahdi_genconf will generate a working configuration, it will not automatically detect hardware echo cancellation modules. These will have to be enabled manually in system.conf. /etc/dahdi/init.conf ~~~~~~~~~~~~~~~~~~~~ The configuration file of the dahdi init.d script is /etc/dahdi/init.conf . That file is used to override defaults that are set at the beginning of the init.d script. Reference Configuration ~~~~~~~~~~~~~~~~~~~~~~~ Sample system.conf ^^^^^^^^^^^^^^^^^^ include::system.conf.asciidoc[] Sample init.conf ^^^^^^^^^^^^^^^^ include::init.conf.asciidoc[] Sample genconf_parameters ^^^^^^^^^^^^^^^^^^^^^^^^^ FIXME: still not properly formatted. include::genconf_parameters.asciidoc[] Sample assigned-spans.conf ^^^^^^^^^^^^^^^^^^^^^^^^^^ include::assigned-spans.conf.asciidoc[] Sample span-types.conf ^^^^^^^^^^^^^^^^^^^^^^ include::span-types.conf.asciidoc[] Tonezones ~~~~~~~~~ The file zonedata.c contains the information about the tone zones used in libtonezone (and hence also in dahdi_cfg). Here is a list of those zones: include::tonezones.txt[] DAHDI PERL modules ~~~~~~~~~~~~~~~~~~ The directory xpp has, in addition to helper utilities for the Xorcom Astribank, a collection of PERL modules to provide information related to DAHDI. The PERL modules themselves are under xpp/perl_modules/ . In xpp/ there are several utilities that use those modules: - xpp-specific: dahdi_registration, xpp_sync, xpp_blink . - General: lsdahdi, dahdi_genconf, dahdi_hardware, dahdi_drivers The DAHDI PERL modules will currently only be automatically installed if you happen to install the xpp directory. Those utilities require the PERL modules to be installed, however they will also look for them in the directory perl_modules, and thus can be run directly from the DAHDI source tree. For example: ./xpp/dahdi_hardware -v To get usage information on a program, you can also use perldoc (sometimes provided in a package separate from perl itself). For instance: perldoc ./xpp/lsdahdi Some of them are specific for the Xorcom Astribank and described in its documentation. the others are: lsdahdi:: A somewhat glorified `cat /proc/dahdi/*`. dahdi_genconf:: Generates configuration based on the existing DAHDI channels and on /etc/dahdi/genconf_parameters (replaces genzaptelconf as well). dahdi_drivers:: A two-liner script (not installed by default) that simply returns the modules that should be modprobe-d on this system. dahdi_hardware:: Uses the information from SysFS and its own knowledge to show what PCI/USB DAHDI hardware is connected and if it is currently used by a driver. Shows also some more information for Astribanks from /proc/xpp . PPP Support ~~~~~~~~~~~ DAHDI digital cards can provide data channels through PPP as point-to-point connections. This requires a plug-in to the PPP daemon that is included in the ppp/ subdirectory. To install it: 1. Make sure you have the PPP source / headers installed. On Debian: apt-get install ppp-dev 2. Run 'make' on the ppp subdirectory: make -C ppp make -C ppp install 3. Make sure your kernel has support for both PPP (which is common is distribution kernels and for HDLC (much less common) - CONFIG_PPP and CONFIG_HDLC . Initialization -------------- This section documents the start up sequence of the DAHDI modules. There are generally two options: explicit (using an init script) and implicit (run from UDEV hook scripts). Explicit ~~~~~~~~ The dahdi init scripts does the following tasks: * Loading the module dahdi and any other module listed in /etc/dahdi/modules. * For xpp (Astribanks) - some specific initializations. See README.Astribank. * Runs link:doc/dahdi_cfg.8.html[dahdi_cfg] after all modules were loaded. * A number of other tools may need to be run: ** link:doc/fxotune.8.html[fxotune] ** dahdihpec_enable Only at this point Asterisk (or any other user of DAHDI) can be run. Implicit ~~~~~~~~ (Also known as "hot-plug" or "pinned-spans". This requires: * dahdi >= 2.8.0 * Setting the module parameter auto_assign_spans of dahdi to 0 * (Recommended) Asterisk >= 12 - which supports "dahdi create channels". When a device driver of a DAHDI device finishes initialization, it creates a dahdi_device kernel object. A dahdi_device represents a single DAHDI device (such as a PCI card) and may have several spans. If the value of auto_assign_spans is 1 when dahdi_device is created, spans are assigned automatically - each new span gets the first available span number and range of channels. However if it is set to 0, spans will not get assigned, and user space programs need to assign them. The low-level interface for doing so is explained in the section "Span Assignment" in the README of DAHDI-Linux. New Devices ^^^^^^^^^^^ When a kernel object is created or destroyed, the kernel sends an event to user space. Those events are normally handled by udevd. Configurations for udevd ("udev rules") may be placed in /etc/udev/rules.d or /lib/udev/rules.d. This package installs rules that instruct udevd to run the script `/usr/share/dahdi/dahdi_handle_device` on each new device, which runs all the scripts in `/usr/share/dahdi/handle_device.d`. Those scripts will: * If `/etc/dahdi/span-types.conf` exists, apply it to the device. It is used for E1/T1/J1 settings. See <<_sample_span_types_conf,sample span-types.conf>>. * If `/etc/dahdi/assigned-spans.conf` exists, assign the span according to it (if it is not specified there: don't assign it). used for E1/T1/J1 settings. See <<_sample_assigned_spans_conf,sample assigned-spans.conf>>. * But if that file does not exist, assign the span to the first available place. This script mainly uses the commands link:doc/dahdi_span_types.8.html[dahdi_span_types] and link:doc/dahdi_span_assignments.8.html[dahdi_span_assignments]. DAHDI devices are listed under `/sys/bus/dahdi_devices/devices`. If you want to disable running this script, add the following line to `/etc/dahdi/init.conf`: ............................. DAHDI_UDEV_DISABLE_DEVICES=yes ............................. New Spans ^^^^^^^^^ Once a span is assigned, a kernel object will appear for it. It will be listed under its device. As a new kernel object was created, an event is sent to udev. The standard DAHDI udev rules instruct udevd to run the script `/usr/share/dahdi/dahdi_span_config` which runs all the scripts in `/usr/share/dahdi/span_config.d`. Those script configures the new span: * If system.conf does not exist, generates a temporary configuration for the span using link:doc/dahdi_genconf.8.html[dahdi_genconf system]. * Runs link:doc/dahdi_cfg.8.html[dahdi_cfg] on the new span (using `-S` and -C`). * Runs `asterisk -rx 'dahdi create channels'` to add the new channels and spans to Asterisk (if they were configured in advance). If you want to disable running this script, add the following line to `/etc/dahdi/init.conf`: ............................. DAHDI_UDEV_DISABLE_SPANS=yes ............................. New Channels ^^^^^^^^^^^^ DAHDI channels have their own representation in the kernel. The standard udev rules that dahdi-tools includes for them, however, don't run a script for each device. Each DAHDI channel creates a block device file at /dev/dahdi/chan/'span'/'rel-chan', where 'span' and 'rel-chan' are each three-digit numbers (e.g: 035). 'span' is the span number and 'rel-chan' is the channel number relative to the span. The udev rules generate the following extra symlinks under /dev/dahdi: * /dev/dahdi/'num' - the channel number. As it was originally (but continues beyond 250). * /dev/dahdi/devices/'hardware_id'/'rel-span'/'rel-chan' - if the DAHDI device has a hardware ID field, provide listing of the device's span and channels. * /dev/dahdi/devices/@'hardware_id'/'rel-span'/'rel-chan' - likewise for the connector field. It has a "@" prefix. include::UPGRADE.txt[] License ------- This package is distributed under the terms of the GNU General Public License Version 2, except for some components which are distributed under the terms of the GNU Lesser General Public License Version 2.1. Both licenses are included in this directory, and each file is clearly marked as to which license applies. If you wish to use the DAHDI drivers in an application for which the license terms are not appropriate (e.g. a proprietary embedded system), licenses under more flexible terms can be readily obtained through Digium, Inc. at reasonable cost. Reporting Bugs -------------- Please report bug and patches to the Asterisk bug tracker at http://bugs.digium.com/[] in the "DAHDI" category. Links ----- - http://asterisk.org/[] - The Asterisk PBX - http://voip-info.org/[] - http://voip-info.org/wiki/view/DAHDI[] - http://docs.tzafrir.org.il/dahdi-tools/README.html[Up-to-date HTML version of this file] dahdi-tools-2.10.2/tonezone.c0000644000000000000000000003341412537624573014531 0ustar rootroot/* * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01 * * Working with the "Tormenta ISA" Card * * Primary Author: Mark Spencer * */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU Lesser General Public License Version 2.1 as published * by the Free Software Foundation. See the LICENSE.LGPL file * included with this program for more details. * * In addition, when this program is distributed with Asterisk in * any form that would qualify as a 'combined work' or as a * 'derivative work' (but not mere aggregation), you can redistribute * and/or modify the combination under the terms of the license * provided with that copy of Asterisk, instead of the license * terms granted here. */ #include #include #include #include #include #include #include #include #include "dahdi/user.h" #include "tonezone.h" #include "dahdi_tools_version.h" #define DEFAULT_DAHDI_DEV "/dev/dahdi/ctl" #define MAX_SIZE 16384 #define CLIP 32635 #define BIAS 0x84 #if 0 # define PRINT_DEBUG(x, ...) printf(x, __VA_ARGS__) #else # define PRINT_DEBUG(x, ...) #endif #ifndef ENODATA #define ENODATA EINVAL #endif struct tone_zone *tone_zone_find(char *country) { struct tone_zone *z; z = builtin_zones; while(z->zone > -1) { if (!strcasecmp(country, z->country)) return z; z++; } return NULL; } struct tone_zone *tone_zone_find_by_num(int id) { struct tone_zone *z; z = builtin_zones; while(z->zone > -1) { if (z->zone == id) return z; z++; } return NULL; } #define LEVEL -10 static int build_tone(void *data, size_t size, struct tone_zone_sound *t, int *count) { char *dup, *s; struct dahdi_tone_def *td=NULL; int firstnobang = -1; int freq1, freq2, time; int modulate = 0; float db = 1.0; float gain; int used = 0; dup = strdup(t->data); s = strtok(dup, ","); while(s && strlen(s)) { /* Handle optional ! which signifies don't start here*/ if (s[0] == '!') { s++; } else if (firstnobang < 0) { PRINT_DEBUG("First no bang: %s\n", s); firstnobang = *count; } if (sscanf(s, "%d+%d/%d", &freq1, &freq2, &time) == 3) { /* f1+f2/time format */ PRINT_DEBUG("f1+f2/time format: %d, %d, %d\n", freq1, freq2, time); } else if (sscanf(s, "%d*%d/%d", &freq1, &freq2, &time) == 3) { /* f1*f2/time format */ PRINT_DEBUG("f1+f2/time format: %d, %d, %d\n", freq1, freq2, time); modulate = 1; } else if (sscanf(s, "%d+%d", &freq1, &freq2) == 2) { PRINT_DEBUG("f1+f2 format: %d, %d\n", freq1, freq2); time = 0; } else if (sscanf(s, "%d*%d", &freq1, &freq2) == 2) { PRINT_DEBUG("f1+f2 format: %d, %d\n", freq1, freq2); modulate = 1; time = 0; } else if (sscanf(s, "%d/%d", &freq1, &time) == 2) { PRINT_DEBUG("f1/time format: %d, %d\n", freq1, time); freq2 = 0; } else if (sscanf(s, "%d@/%d", &freq1, &time) == 2) { /* The "@" character has been added to enable an * approximately -20db tone generation of any frequency This has been done * primarily to generate the Australian congestion tone. * Example: "425/375,0/375,425@/375,0/375" */ PRINT_DEBUG("f1 reduced amplitude/time format: %d, %d\n", freq1,time); db = 0.3; freq2 = 0; } else if (sscanf(s, "%d", &freq1) == 1) { PRINT_DEBUG("f1 format: %d\n", freq1); firstnobang = *count; freq2 = 0; time = 0; } else { fprintf(stderr, "tone component '%s' of '%s' is a syntax error\n", s,t->data); return -1; } PRINT_DEBUG("Using %d samples for %d and %d\n", time * 8, freq1, freq2); if (size < sizeof(*td)) { fprintf(stderr, "Not enough space for tones\n"); return -1; } td = data; /* Bring it down -8 dbm */ gain = db*(pow(10.0, (LEVEL - 3.14) / 20.0) * 65536.0 / 2.0); td->fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0; td->init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * gain; td->init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * gain; td->fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0; td->init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * gain; td->init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * gain; td->modulate = modulate; data += sizeof(*td); used += sizeof(*td); size -= sizeof(*td); td->tone = t->toneid; if (time) { /* We should move to the next tone */ td->next = *count + 1; td->samples = time * 8; } else { /* Stay with us */ td->next = *count; td->samples = 8000; } *count += 1; s = strtok(NULL, ","); } if (td && time) { /* If we don't end on a solid tone, return */ td->next = firstnobang; } if (firstnobang < 0) fprintf(stderr, "tone '%s' does not end with a solid tone or silence (all tone components have an exclamation mark)\n", t->data); return used; } char *tone_zone_tone_name(int id) { static char tmp[80]; switch(id) { case DAHDI_TONE_DIALTONE: return "Dialtone"; case DAHDI_TONE_BUSY: return "Busy"; case DAHDI_TONE_RINGTONE: return "Ringtone"; case DAHDI_TONE_CONGESTION: return "Congestion"; case DAHDI_TONE_CALLWAIT: return "Call Waiting"; case DAHDI_TONE_DIALRECALL: return "Dial Recall"; case DAHDI_TONE_RECORDTONE: return "Record Tone"; case DAHDI_TONE_CUST1: return "Custom 1"; case DAHDI_TONE_CUST2: return "Custom 2"; case DAHDI_TONE_INFO: return "Special Information"; case DAHDI_TONE_STUTTER: return "Stutter Dialtone"; default: snprintf(tmp, sizeof(tmp), "Unknown tone %d", id); return tmp; } } #ifdef TONEZONE_DRIVER static void dump_tone_zone(void *data, int size) { struct dahdi_tone_def_header *z; struct dahdi_tone_def *td; int x; int len = sizeof(*z); z = data; data += sizeof(*z); printf("Header: %d tones, %d bytes of data, zone %d (%s)\n", z->count, size, z->zone, z->name); for (x = 0; x < z->count; x++) { td = data; printf("Tone Fragment %d: tone is %d, next is %d, %d samples\n", x, td->tone, td->next, td->samples); data += sizeof(*td); len += sizeof(*td); } printf("Total measured bytes of data: %d\n", len); } #endif /* Tone frequency tables */ struct mf_tone { int tone; float f1; /* first freq */ float f2; /* second freq */ }; static struct mf_tone dtmf_tones[] = { { DAHDI_TONE_DTMF_0, 941.0, 1336.0 }, { DAHDI_TONE_DTMF_1, 697.0, 1209.0 }, { DAHDI_TONE_DTMF_2, 697.0, 1336.0 }, { DAHDI_TONE_DTMF_3, 697.0, 1477.0 }, { DAHDI_TONE_DTMF_4, 770.0, 1209.0 }, { DAHDI_TONE_DTMF_5, 770.0, 1336.0 }, { DAHDI_TONE_DTMF_6, 770.0, 1477.0 }, { DAHDI_TONE_DTMF_7, 852.0, 1209.0 }, { DAHDI_TONE_DTMF_8, 852.0, 1336.0 }, { DAHDI_TONE_DTMF_9, 852.0, 1477.0 }, { DAHDI_TONE_DTMF_s, 941.0, 1209.0 }, { DAHDI_TONE_DTMF_p, 941.0, 1477.0 }, { DAHDI_TONE_DTMF_A, 697.0, 1633.0 }, { DAHDI_TONE_DTMF_B, 770.0, 1633.0 }, { DAHDI_TONE_DTMF_C, 852.0, 1633.0 }, { DAHDI_TONE_DTMF_D, 941.0, 1633.0 }, { 0, 0, 0 } }; static struct mf_tone mfr1_tones[] = { { DAHDI_TONE_MFR1_0, 1300.0, 1500.0 }, { DAHDI_TONE_MFR1_1, 700.0, 900.0 }, { DAHDI_TONE_MFR1_2, 700.0, 1100.0 }, { DAHDI_TONE_MFR1_3, 900.0, 1100.0 }, { DAHDI_TONE_MFR1_4, 700.0, 1300.0 }, { DAHDI_TONE_MFR1_5, 900.0, 1300.0 }, { DAHDI_TONE_MFR1_6, 1100.0, 1300.0 }, { DAHDI_TONE_MFR1_7, 700.0, 1500.0 }, { DAHDI_TONE_MFR1_8, 900.0, 1500.0 }, { DAHDI_TONE_MFR1_9, 1100.0, 1500.0 }, { DAHDI_TONE_MFR1_KP, 1100.0, 1700.0 }, /* KP */ { DAHDI_TONE_MFR1_ST, 1500.0, 1700.0 }, /* ST */ { DAHDI_TONE_MFR1_STP, 900.0, 1700.0 }, /* KP' or ST' */ { DAHDI_TONE_MFR1_ST2P, 1300.0, 1700.0 }, /* KP'' or ST'' */ { DAHDI_TONE_MFR1_ST3P, 700.0, 1700.0 }, /* KP''' or ST''' */ { 0, 0, 0 } }; static struct mf_tone mfr2_fwd_tones[] = { { DAHDI_TONE_MFR2_FWD_1, 1380.0, 1500.0 }, { DAHDI_TONE_MFR2_FWD_2, 1380.0, 1620.0 }, { DAHDI_TONE_MFR2_FWD_3, 1500.0, 1620.0 }, { DAHDI_TONE_MFR2_FWD_4, 1380.0, 1740.0 }, { DAHDI_TONE_MFR2_FWD_5, 1500.0, 1740.0 }, { DAHDI_TONE_MFR2_FWD_6, 1620.0, 1740.0 }, { DAHDI_TONE_MFR2_FWD_7, 1380.0, 1860.0 }, { DAHDI_TONE_MFR2_FWD_8, 1500.0, 1860.0 }, { DAHDI_TONE_MFR2_FWD_9, 1620.0, 1860.0 }, { DAHDI_TONE_MFR2_FWD_10, 1740.0, 1860.0 }, { DAHDI_TONE_MFR2_FWD_11, 1380.0, 1980.0 }, { DAHDI_TONE_MFR2_FWD_12, 1500.0, 1980.0 }, { DAHDI_TONE_MFR2_FWD_13, 1620.0, 1980.0 }, { DAHDI_TONE_MFR2_FWD_14, 1740.0, 1980.0 }, { DAHDI_TONE_MFR2_FWD_15, 1860.0, 1980.0 }, { 0, 0, 0 } }; static struct mf_tone mfr2_rev_tones[] = { { DAHDI_TONE_MFR2_REV_1, 1020.0, 1140.0 }, { DAHDI_TONE_MFR2_REV_2, 900.0, 1140.0 }, { DAHDI_TONE_MFR2_REV_3, 900.0, 1020.0 }, { DAHDI_TONE_MFR2_REV_4, 780.0, 1140.0 }, { DAHDI_TONE_MFR2_REV_5, 780.0, 1020.0 }, { DAHDI_TONE_MFR2_REV_6, 780.0, 900.0 }, { DAHDI_TONE_MFR2_REV_7, 660.0, 1140.0 }, { DAHDI_TONE_MFR2_REV_8, 660.0, 1020.0 }, { DAHDI_TONE_MFR2_REV_9, 660.0, 900.0 }, { DAHDI_TONE_MFR2_REV_10, 660.0, 780.0 }, { DAHDI_TONE_MFR2_REV_11, 540.0, 1140.0 }, { DAHDI_TONE_MFR2_REV_12, 540.0, 1020.0 }, { DAHDI_TONE_MFR2_REV_13, 540.0, 900.0 }, { DAHDI_TONE_MFR2_REV_14, 540.0, 780.0 }, { DAHDI_TONE_MFR2_REV_15, 540.0, 660.0 }, { 0, 0, 0 } }; static int build_mf_tones(void *data, size_t size, int *count, struct mf_tone *tone, int low_tone_level, int high_tone_level) { struct dahdi_tone_def *td; float gain; int used = 0; while (tone->tone) { if (size < sizeof(*td)) { fprintf(stderr, "Not enough space for samples\n"); return -1; } td = data; data += sizeof(*td); used += sizeof(*td); size -= sizeof(*td); td->tone = tone->tone; *count += 1; /* Bring it down 6 dBm */ gain = pow(10.0, (low_tone_level - 3.14) / 20.0) * 65536.0 / 2.0; td->fac1 = 2.0 * cos(2.0 * M_PI * (tone->f1 / 8000.0)) * 32768.0; td->init_v2_1 = sin(-4.0 * M_PI * (tone->f1 / 8000.0)) * gain; td->init_v3_1 = sin(-2.0 * M_PI * (tone->f1 / 8000.0)) * gain; gain = pow(10.0, (high_tone_level - 3.14) / 20.0) * 65536.0 / 2.0; td->fac2 = 2.0 * cos(2.0 * M_PI * (tone->f2 / 8000.0)) * 32768.0; td->init_v2_2 = sin(-4.0 * M_PI * (tone->f2 / 8000.0)) * gain; td->init_v3_2 = sin(-2.0 * M_PI * (tone->f2 / 8000.0)) * gain; tone++; } return used; } int tone_zone_register_zone(int fd, struct tone_zone *z) { char buf[MAX_SIZE]; int res; int count = 0; int x; size_t space = MAX_SIZE; void *ptr = buf; int iopenedit = 1; struct dahdi_tone_def_header *h; memset(buf, 0, sizeof(buf)); h = ptr; ptr += sizeof(*h); space -= sizeof(*h); h->zone = z->zone; dahdi_copy_string(h->name, z->description, sizeof(h->name)); for (x = 0; x < DAHDI_MAX_CADENCE; x++) h->ringcadence[x] = z->ringcadence[x]; for (x = 0; x < DAHDI_TONE_MAX; x++) { if (!strlen(z->tones[x].data)) continue; PRINT_DEBUG("Tone: %d, string: %s\n", z->tones[x].toneid, z->tones[x].data); if ((res = build_tone(ptr, space, &z->tones[x], &count)) < 0) { fprintf(stderr, "Tone %d not built.\n", x); return -1; } ptr += res; space -= res; } if ((res = build_mf_tones(ptr, space, &count, dtmf_tones, z->dtmf_low_level, z->dtmf_high_level)) < 0) { fprintf(stderr, "Could not build DTMF tones.\n"); return -1; } ptr += res; space -= res; if ((res = build_mf_tones(ptr, space, &count, mfr1_tones, z->mfr1_level, z->mfr1_level)) < 0) { fprintf(stderr, "Could not build MFR1 tones.\n"); return -1; } ptr += res; space -= res; if ((res = build_mf_tones(ptr, space, &count, mfr2_fwd_tones, z->mfr2_level, z->mfr2_level)) < 0) { fprintf(stderr, "Could not build MFR2 FWD tones.\n"); return -1; } ptr += res; space -= res; if ((res = build_mf_tones(ptr, space, &count, mfr2_rev_tones, z->mfr2_level, z->mfr2_level)) < 0) { fprintf(stderr, "Could not build MFR2 REV tones.\n"); return -1; } ptr += res; space -= res; h->count = count; if (fd < 0) { if ((fd = open(DEFAULT_DAHDI_DEV, O_RDWR)) < 0) { fprintf(stderr, "Unable to open %s and fd not provided\n", DEFAULT_DAHDI_DEV); return -1; } iopenedit = 1; } x = z->zone; if ((res = ioctl(fd, DAHDI_FREEZONE, &x))) { if (errno != EBUSY) fprintf(stderr, "ioctl(DAHDI_FREEZONE) failed: %s\n", strerror(errno)); return res; } #if defined(TONEZONE_DRIVER) dump_tone_zone(h, MAX_SIZE - space); #endif #if defined(__FreeBSD__) if ((res = ioctl(fd, DAHDI_LOADZONE, &h))) { #else if ((res = ioctl(fd, DAHDI_LOADZONE, h))) { #endif fprintf(stderr, "ioctl(DAHDI_LOADZONE) failed: %s\n", strerror(errno)); return res; } if (iopenedit) close(fd); return res; } int tone_zone_register(int fd, char *country) { struct tone_zone *z; z = tone_zone_find(country); if (z) { return tone_zone_register_zone(-1, z); } else { return -1; } } int tone_zone_set_zone(int fd, char *country) { int res=-1; struct tone_zone *z; if (fd > -1) { z = tone_zone_find(country); if (z) res = ioctl(fd, DAHDI_SETTONEZONE, &z->zone); if ((res < 0) && (errno == ENODATA)) { tone_zone_register_zone(fd, z); res = ioctl(fd, DAHDI_SETTONEZONE, &z->zone); } } return res; } int tone_zone_get_zone(int fd) { int x=-1; if (fd > -1) { ioctl(fd, DAHDI_GETTONEZONE, &x); return x; } return -1; } int tone_zone_play_tone(int fd, int tone) { struct tone_zone *z; int res = -1; int zone; #if 0 fprintf(stderr, "Playing tone %d (%s) on %d\n", tone, tone_zone_tone_name(tone), fd); #endif if (fd > -1) { res = ioctl(fd, DAHDI_SENDTONE, &tone); if ((res < 0) && (errno == ENODATA)) { ioctl(fd, DAHDI_GETTONEZONE, &zone); z = tone_zone_find_by_num(zone); if (z) { res = tone_zone_register_zone(fd, z); /* Recall the zone */ ioctl(fd, DAHDI_SETTONEZONE, &zone); if (res < 0) { fprintf(stderr, "Failed to register zone '%s': %s\n", z->description, strerror(errno)); } else { res = ioctl(fd, DAHDI_SENDTONE, &tone); } } else fprintf(stderr, "Don't know anything about zone %d\n", zone); } } return res; } dahdi-tools-2.10.2/patgen.c0000644000000000000000000000727312537624573014152 0ustar rootroot/* * Written by Mark Spencer * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include "bittest.h" #include #include "dahdi_tools_version.h" /* #define BLOCK_SIZE 2048 */ #define BLOCK_SIZE 2041 #define DEVICE "/dev/dahdi/channel" static const char rcsid[] = "$Id$"; char *prog_name; static void usage(void) { fprintf(stderr, "Usage: %s \n", prog_name); fprintf(stderr, " e.g.: %s /dev/dahdi/55\n", prog_name); fprintf(stderr, " %s 455\n", prog_name); fprintf(stderr, "%s version %s\n", prog_name, rcsid); exit(1); } void print_packet(unsigned char *buf, int len) { int x; printf("{ "); for (x=0;x 0) { fd = open(DEVICE, O_RDWR, 0600); if (fd < 0) { perror(DEVICE); return -1; } if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { perror("DAHDI_SPECIFY ioctl failed"); return -1; } /* die */ } else { fprintf(stderr, "Specified channel is not a valid character " "device or channel number"); return -1; } if (ioctl(fd, DAHDI_SET_BLOCKSIZE, bs) < 0) { perror("SET_BLOCKSIZE"); return -1; } if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { fprintf(stderr, "Unable to get channel parameters\n"); return -1; } return fd; } int main(int argc, char *argv[]) { int fd; int res, res1, x; int bs = BLOCK_SIZE; unsigned char c=0; unsigned char outbuf[BLOCK_SIZE]; prog_name = argv[0]; if (argc < 2) { usage(); } fd = channel_open(argv[1], &bs); if (fd < 0) exit(1); ioctl(fd, DAHDI_GETEVENT); #if 0 print_packet(outbuf, res); printf("FCS is %x, PPP_GOODFCS is %x\n", fcs,PPP_GOODFCS); #endif for(;;) { res = bs; for (x=0;x * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include "tonezone.h" #include "dahdi_tools_version.h" static int tones[] = { DAHDI_TONE_DIALTONE, DAHDI_TONE_BUSY, DAHDI_TONE_RINGTONE, DAHDI_TONE_CONGESTION, DAHDI_TONE_DIALRECALL, }; struct dahdi_vmwi_info mwisend_setting; /*!< Which VMWI methods to use */ /* Use to translate a DTMF character to the value required by the dahdi call */ static int digit_to_dtmfindex(char digit) { if (isdigit(digit)) return DAHDI_TONE_DTMF_BASE + (digit - '0'); else if (digit >= 'A' && digit <= 'D') return DAHDI_TONE_DTMF_A + (digit - 'A'); else if (digit >= 'a' && digit <= 'd') return DAHDI_TONE_DTMF_A + (digit - 'a'); else if (digit == '*') return DAHDI_TONE_DTMF_s; else if (digit == '#') return DAHDI_TONE_DTMF_p; else return -1; } /* Place a channel into ringing mode */ static int dahdi_ring_phone(int fd) { int x; int res; /* Make sure our transmit state is on hook */ x = 0; x = DAHDI_ONHOOK; res = ioctl(fd, DAHDI_HOOK, &x); do { x = DAHDI_RING; res = ioctl(fd, DAHDI_HOOK, &x); if (res) { switch (errno) { case EBUSY: case EINTR: /* Wait just in case */ fprintf(stderr, "Ring phone is busy:%s\n", strerror(errno)); usleep(10000); continue; case EINPROGRESS: fprintf(stderr, "Ring In Progress:%s\n", strerror(errno)); res = 0; break; default: fprintf(stderr, "Couldn't ring the phone: %s\n", strerror(errno)); res = 0; } } else { fprintf(stderr, "Phone is ringing\n"); } } while (res); return res; } int channel_open(const char *name) { int channo, fd; struct stat filestat; const char *DEVICE = "/dev/dahdi/channel"; /* stat file, if character device, open it */ channo = strtoul(name, NULL, 10); fd = stat(name, &filestat); if (!fd && S_ISCHR(filestat.st_mode)) { fd = open(name, O_RDWR, 0600); if (fd < 0) { perror(name); return -1; } /* try out the dahdi_specify interface */ } else if (channo > 0) { fd = open(DEVICE, O_RDWR, 0600); if (fd < 0) { perror(DEVICE); return -1; } if (ioctl(fd, DAHDI_SPECIFY, &channo) < 0) { perror("DAHDI_SPECIFY ioctl failed"); return -1; } /* die */ } else { fprintf(stderr, "Specified channel is not a valid character " "device or channel number"); return -1; } return fd; } int main(int argc, char *argv[]) { int fd; int res; int x; if (argc < 3) { fprintf(stderr, "Usage: fxstest \n" " where cmd is one of:\n" " stats - reports voltages\n" " regdump - dumps ProSLIC registers\n" " tones - plays a series of tones\n" " polarity - tests polarity reversal\n" " ring - rings phone\n" " vmwi - toggles VMWI LED lamp\n" " hvdc - toggles VMWI HV lamp\n" " neon - toggles VMWI NEON lamp\n" " dtmf []- Send a sequence of dtmf tones (\"-\" denotes no tone)\n" " dtmfcid - create a dtmf cid spill without polarity reversal\n"); exit(1); } fd = channel_open(argv[1]); if (fd < 0) { fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno)); exit(1); } if ( !strcasecmp(argv[2], "neon") || !strcasecmp(argv[2], "vmwi") || !strcasecmp(argv[2], "hvdc")) { fprintf(stderr, "Twiddling %s ...\n", argv[2]); if ( !strcasecmp(argv[2], "vmwi") ) { mwisend_setting.vmwi_type = DAHDI_VMWI_LREV; } else if ( !strcasecmp(argv[2], "neon") ) { mwisend_setting.vmwi_type = DAHDI_VMWI_HVAC; } else if ( !strcasecmp(argv[2], "hvdc") ) { mwisend_setting.vmwi_type = DAHDI_VMWI_HVDC; } res = ioctl(fd, DAHDI_VMWI_CONFIG, &mwisend_setting); x = 1; res = ioctl(fd, DAHDI_VMWI, &x); if (res) { fprintf(stderr, "Unable to set %s ...\n", argv[2]); } else { fprintf(stderr, "Set 1 Voice Message...\n"); sleep(5); x = 2; ioctl(fd, DAHDI_VMWI, &x); fprintf(stderr, "Set 2 Voice Messages...\n"); sleep(5); x = 0; ioctl(fd, DAHDI_VMWI, &x); fprintf(stderr, "Set No Voice messages...\n"); sleep(2); mwisend_setting.vmwi_type = 0; } } else if (!strcasecmp(argv[2], "ring")) { fprintf(stderr, "Ringing phone...\n"); x = DAHDI_RING; res = ioctl(fd, DAHDI_HOOK, &x); if (res) { fprintf(stderr, "Unable to ring phone...\n"); } else { fprintf(stderr, "Phone is ringing...\n"); sleep(2); } } else if (!strcasecmp(argv[2], "polarity")) { fprintf(stderr, "Twiddling polarity...\n"); /* Insure that the channel is in active mode */ x = DAHDI_RING; res = ioctl(fd, DAHDI_HOOK, &x); usleep(100000); x = 0; res = ioctl(fd, DAHDI_HOOK, &x); x = 0; res = ioctl(fd, DAHDI_SETPOLARITY, &x); if (res) { fprintf(stderr, "Unable to polarity...\n"); } else { fprintf(stderr, "Polarity is forward...\n"); sleep(2); x = 1; ioctl(fd, DAHDI_SETPOLARITY, &x); fprintf(stderr, "Polarity is reversed...\n"); sleep(5); x = 0; ioctl(fd, DAHDI_SETPOLARITY, &x); fprintf(stderr, "Polarity is forward...\n"); sleep(2); } } else if (!strcasecmp(argv[2], "tones")) { int x = 0; for (;;) { res = tone_zone_play_tone(fd, tones[x]); if (res) fprintf(stderr, "Unable to play tone %d\n", tones[x]); sleep(3); x=(x+1) % (sizeof(tones) / sizeof(tones[0])); } } else if (!strcasecmp(argv[2], "stats")) { struct wctdm_stats stats; res = ioctl(fd, WCTDM_GET_STATS, &stats); if (res) { fprintf(stderr, "Unable to get stats on channel %s\n", argv[1]); } else { printf("TIP: %7.4f Volts\n", (float)stats.tipvolt / 1000.0); printf("RING: %7.4f Volts\n", (float)stats.ringvolt / 1000.0); printf("VBAT: %7.4f Volts\n", (float)stats.batvolt / 1000.0); } } else if (!strcasecmp(argv[2], "regdump")) { struct wctdm_regs regs; int numregs = NUM_REGS; memset(®s, 0, sizeof(regs)); res = ioctl(fd, WCTDM_GET_REGS, ®s); if (res) { fprintf(stderr, "Unable to get registers on channel %s\n", argv[1]); } else { for (x=60;x= 5) { sscanf(argv[4], "%30i", &duration); } printf("Going to send a set of DTMF tones >%s<\n", outstring); printf("Using a duration of %d mS per tone\n", duration); /* Flush any left remaining characs in the buffer and place the channel into on-hook transfer mode */ x = DAHDI_FLUSH_BOTH; res = ioctl(fd, DAHDI_FLUSH, &x); x = 500 + strlen(outstring) * duration; ioctl(fd, DAHDI_ONHOOKTRANSFER, &x); for (x = 0; '\0' != outstring[x]; x++) { dtmftone = digit_to_dtmfindex(outstring[x]); if (0 > dtmftone) { dtmftone = -1; } res = tone_zone_play_tone(fd, dtmftone); if (res) { fprintf(stderr, "Unable to play DTMF tone %d (0x%x)\n", dtmftone, dtmftone); } usleep(duration * 1000); } } } else if (!strcasecmp(argv[2], "dtmfcid")) { char * outstring = "A5551212C"; /* Default string using A and C tones to bracket the number */ int dtmftone; if(argc >= 4) { /* Use user supplied string */ outstring = argv[3]; } printf("Going to send a set of DTMF tones >%s<\n", outstring); /* Flush any left remaining characs in the buffer and place the channel into on-hook transfer mode */ x = DAHDI_FLUSH_BOTH; res = ioctl(fd, DAHDI_FLUSH, &x); x = 500 + strlen(outstring) * 100; ioctl(fd, DAHDI_ONHOOKTRANSFER, &x); /* Play the DTMF tones at a 50 mS on and 50 mS off rate which is standard for DTMF CID spills */ for (x = 0; '\0' != outstring[x]; x++) { dtmftone = digit_to_dtmfindex(outstring[x]); if (0 > dtmftone) { dtmftone = -1; } res = tone_zone_play_tone(fd, dtmftone); if (res) { fprintf(stderr, "Unable to play DTMF tone %d (0x%x)\n", dtmftone, dtmftone); } usleep(50000); tone_zone_play_tone(fd, -1); usleep(50000); } /* Wait for 150 mS from end of last tone to initiating the ring */ usleep(100000); dahdi_ring_phone(fd); sleep(10); printf("Ringing Done\n"); } else fprintf(stderr, "Invalid command\n"); close(fd); return 0; } dahdi-tools-2.10.2/LICENSE.LGPL0000644000000000000000000006346712537624573014301 0ustar rootroot GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! dahdi-tools-2.10.2/zonedata.c0000644000000000000000000012061712537624573014477 0ustar rootroot/* * BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01 * * Working with the "Tormenta ISA" Card * * Primary Author: Mark Spencer * * This information from ITU E.180 Supplement 2. * UK information from BT SIN 350 Issue 1.1 * Helpful reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU Lesser General Public License Version 2.1 as published * by the Free Software Foundation. See the LICENSE.LGPL file * included with this program for more details. * * In addition, when this program is distributed with Asterisk in * any form that would qualify as a 'combined work' or as a * 'derivative work' (but not mere aggregation), you can redistribute * and/or modify the combination under the terms of the license * provided with that copy of Asterisk, instead of the license * terms granted here. */ #include "tonezone.h" struct tone_zone builtin_zones[] = { { .zone = 0, .country = "us", .description = "United States / North America", .ringcadence = { 2000, 4000 }, .tones = { { DAHDI_TONE_DIALTONE, "350+440" }, { DAHDI_TONE_BUSY, "480+620/500,0/500" }, { DAHDI_TONE_RINGTONE, "440+480/2000,0/4000" }, { DAHDI_TONE_CONGESTION, "480+620/250,0/250" }, { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 1, .country = "au", .description = "Australia", .ringcadence = { 400, 200, 400, 2000 }, .tones = { { DAHDI_TONE_DIALTONE, "415+440" }, { DAHDI_TONE_BUSY, "425/375,0/375" }, { DAHDI_TONE_RINGTONE, "413+438/400,0/200,413+438/400,0/2000" }, /* The Australian congestion tone is 425Hz, 375ms On, 375ms Off, with the * second cadence being half the amplitude of the first; so the first cadence * is approximately -10dB with the second one being -20dB. Using the update * ToneZone.c file, this can be accomplished by adding the "@" symbol in front * of the frequency to reduce amplification, as in the following entry for * Congestion: */ { DAHDI_TONE_CONGESTION, "425/375,0/375,425@/375,0/375" }, { DAHDI_TONE_CALLWAIT, "425/100,0/200,425/200,0/4400" }, { DAHDI_TONE_DIALRECALL, "413+428" }, { DAHDI_TONE_RECORDTONE, "!425/1000,!0/15000,425/360,0/15000" }, { DAHDI_TONE_INFO, "425/2500,0/500" }, { DAHDI_TONE_STUTTER, "413+438/100,0/40" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 2, .country = "fr", .description = "France", .ringcadence = { 1500, 3500 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ /* Dialtone can also be 440+330 */ { DAHDI_TONE_DIALTONE, "440" }, { DAHDI_TONE_BUSY, "440/500,0/500" }, { DAHDI_TONE_RINGTONE, "440/1500,0/3500" }, /* CONGESTION - not specified */ { DAHDI_TONE_CONGESTION, "440/250,0/250" }, { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, { DAHDI_TONE_STUTTER, "!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,!440/100,!0/100,440" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 3, .country = "nl", .description = "Netherlands", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ /* Most of these 425's can also be 450's */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/250,0/250" }, { DAHDI_TONE_CALLWAIT, "425/500,0/9500" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "425/500,0/50" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 4, .country = "uk", .description = "United Kingdom", .ringcadence = { 400, 200, 400, 2000 }, .tones = { /* From British Telecom SIN350 v1.2 */ { DAHDI_TONE_DIALTONE, "350+440" }, { DAHDI_TONE_BUSY, "400/375,0/375" }, { DAHDI_TONE_RINGTONE, "400+450/400,0/200,400+450/400,0/2000" }, { DAHDI_TONE_CONGESTION, "400/400,0/350,400/225,0/525" }, { DAHDI_TONE_CALLWAIT, "400/100,0/4000" }, { DAHDI_TONE_DIALRECALL, "350+440" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/60000" }, { DAHDI_TONE_INFO, "950/330,0/15,1400/330,0/15,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "350+440/750,440/750" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 5, .country = "fi", .description = "Finland", .ringcadence = { 1000, 4000 }, .tones = { { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/300,0/300" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200" }, { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/8000" }, { DAHDI_TONE_DIALRECALL, "425/650,0/25" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "950/650,0/325,950/325,0/30,1400/1300,0/2600" }, { DAHDI_TONE_STUTTER, "425/650,0/25" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 6, .country = "es", .description = "Spain", .ringcadence = { 1500, 3000}, .tones = { { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/200,0/200" }, { DAHDI_TONE_RINGTONE, "425/1500,0/3000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200,425/200,0/200,425/200,0/600" }, { DAHDI_TONE_CALLWAIT, "425/175,0/175,425/175,0/3500" }, { DAHDI_TONE_DIALRECALL, "!425/200,!0/200,!425/200,!0/200,!425/200,!0/200,425" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "950/330,0/1000" }, { DAHDI_TONE_STUTTER, "425/500,0/50" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 7, .country = "jp", .description = "Japan", .ringcadence = { 1000, 2000 }, .tones = { { DAHDI_TONE_DIALTONE, "400" }, { DAHDI_TONE_BUSY, "400/500,0/500" }, { DAHDI_TONE_RINGTONE, "400+15/1000,0/2000" }, { DAHDI_TONE_CONGESTION, "400/500,0/500" }, { DAHDI_TONE_CALLWAIT, "400+16/500,0/8000" }, { DAHDI_TONE_DIALRECALL, "!400/200,!0/200,!400/200,!0/200,!400/200,!0/200,400" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, { DAHDI_TONE_STUTTER, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" }, }, .dtmf_high_level = -7, .dtmf_low_level = -7, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 8, .country = "no", .description = "Norway", .ringcadence = { 1000, 4000 }, .tones = { { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200" }, { DAHDI_TONE_CALLWAIT, "425/200,0/600,425/200,0/10000" }, { DAHDI_TONE_DIALRECALL, "470/400,425/400" }, { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, { DAHDI_TONE_STUTTER, "470/400,425/400" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 9, .country = "at", .description = "Austria", .ringcadence = { 1000, 5000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "420" }, { DAHDI_TONE_BUSY, "420/400,0/400" }, { DAHDI_TONE_RINGTONE, "420/1000,0/5000" }, { DAHDI_TONE_CONGESTION, "420/200,0/200" }, { DAHDI_TONE_CALLWAIT, "420/40,0/1960" }, { DAHDI_TONE_DIALRECALL, "420" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/80,0/14920" }, { DAHDI_TONE_INFO, "950/330,1450/330,1850/330,0/1000" }, { DAHDI_TONE_STUTTER, "380+420" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 10, .country = "nz", .description = "New Zealand", .ringcadence = { 400, 200, 400, 2000 }, .tones = { { DAHDI_TONE_DIALTONE, "400" }, { DAHDI_TONE_BUSY, "400/500,0/500" }, { DAHDI_TONE_RINGTONE, "400+450/400,0/200,400+450/400,0/2000" }, { DAHDI_TONE_CONGESTION, "400/250,0/250" }, { DAHDI_TONE_CALLWAIT, "400/250,0/250,400/250,0/3250" }, { DAHDI_TONE_DIALRECALL, "!400/100!0/100,!400/100,!0/100,!400/100,!0/100,400" }, { DAHDI_TONE_RECORDTONE, "1400/425,0/15000" }, { DAHDI_TONE_INFO, "400/750,0/100,400/750,0/100,400/750,0/100,400/750,0/400" }, { DAHDI_TONE_STUTTER, "!400/100!0/100,!400/100,!0/100,!400/100,!0/100,!400/100!0/100,!400/100,!0/100,!400/100,!0/100,400" }, }, .dtmf_high_level = -11, .dtmf_low_level = -9, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 11, .country = "it", .description = "Italy", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425/200,0/200,425/600,0/1000" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200" }, { DAHDI_TONE_CALLWAIT, "425/400,0/100,425/250,0/100,425/150,0/14000" }, { DAHDI_TONE_DIALRECALL, "470/400,425/400" }, { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, { DAHDI_TONE_STUTTER, "470/400,425/400" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 12, .country = "us-old", .description = "United States Circa 1950 / North America", .ringcadence = { 2000, 4000 }, .tones = { { DAHDI_TONE_DIALTONE, "600*120" }, { DAHDI_TONE_BUSY, "500*100/500,0/500" }, { DAHDI_TONE_RINGTONE, "420*40/2000,0/4000" }, { DAHDI_TONE_CONGESTION, "500*100/250,0/250" }, { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, { DAHDI_TONE_DIALRECALL, "!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, { DAHDI_TONE_STUTTER, "!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,!600*120/100,!0/100,600*120" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 13, .country = "gr", .description = "Greece", .ringcadence = { 1000, 4000 }, .tones = { { DAHDI_TONE_DIALTONE, "425/200,0/300,425/700,0/800" }, { DAHDI_TONE_BUSY, "425/300,0/300" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200" }, { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/8000" }, { DAHDI_TONE_DIALRECALL, "425/650,0/25" }, { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, { DAHDI_TONE_STUTTER, "425/650,0/25" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 14, .country = "tw", .description = "Taiwan", .ringcadence = { 1000, 4000 }, .tones = { { DAHDI_TONE_DIALTONE, "350+440" }, { DAHDI_TONE_BUSY, "480+620/500,0/500" }, { DAHDI_TONE_RINGTONE, "440+480/1000,0/2000" }, { DAHDI_TONE_CONGESTION, "480+620/250,0/250" }, { DAHDI_TONE_CALLWAIT, "350+440/250,0/250,350+440/250,0/3250" }, { DAHDI_TONE_DIALRECALL, "300/1500,0/500" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, }, .dtmf_high_level = -11, .dtmf_low_level = -9, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 15, .country = "cl", .description = "Chile", .ringcadence = { 1000, 3000 }, .tones = { { DAHDI_TONE_DIALTONE, "400" }, { DAHDI_TONE_BUSY, "400/500,0/500" }, { DAHDI_TONE_RINGTONE, "400/1000,0/3000" }, { DAHDI_TONE_CONGESTION, "400/200,0/200" }, { DAHDI_TONE_CALLWAIT, "400/250,0/8750" }, { DAHDI_TONE_DIALRECALL, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/333,!1400/333,!1800/333,0" }, { DAHDI_TONE_STUTTER, "!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,!400/100,!0/100,400" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 16, .country = "se", .description = "Sweden", .ringcadence = { 1000, 5000 }, .tones = { { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/250,0/250" }, { DAHDI_TONE_RINGTONE, "425/1000,0/5000" }, { DAHDI_TONE_CONGESTION, "425/250,0/750" }, { DAHDI_TONE_CALLWAIT, "425/200,0/500,425/200,0/9100" }, { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," "!950/332,!0/24,!1400/332,!0/24,!1800/332,!0/2024," "!950/332,!0/24,!1400/332,!0/24,!1800/332,0" }, /*{ DAHDI_TONE_STUTTER, "425/320,0/20" }, Real swedish standard, not used for now */ { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 17, .country = "be", .description = "Belgium", .ringcadence = { 1000, 3000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/3000" }, { DAHDI_TONE_CONGESTION, "425/167,0/167" }, { DAHDI_TONE_CALLWAIT, "1400/175,0/175,1400/175,0/3500" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "900/330,1400/330,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "425/1000,0/250" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 18, .country = "sg", .description = "Singapore", .ringcadence = { 400, 200, 400, 2000 }, .tones = { /* Reference: http://www.ida.gov.sg/idaweb/doc/download/I397/ida_ts_pstn1_i4r2.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/750,0/750" }, { DAHDI_TONE_RINGTONE, "425*24/400,0/200,425*24/400,0/2000" }, { DAHDI_TONE_CONGESTION, "425/250,0/250" }, { DAHDI_TONE_CALLWAIT, "425*24/300,0/200,425*24/300,0/3200" }, /* DIALRECALL - not specified - use repeating Holding Tone A,B*/ { DAHDI_TONE_DIALRECALL, "425*24/500,0/500,425/500,0/2500" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,!425/200,!0/200,!425/600,!0/200,425" }, }, .dtmf_high_level = -11, .dtmf_low_level = -9, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 19, .country = "il", .description = "Israel", .ringcadence = { 1000, 3000 }, .tones = { { DAHDI_TONE_DIALTONE, "414" }, { DAHDI_TONE_BUSY, "414/500,0/500" }, { DAHDI_TONE_RINGTONE, "414/1000,0/3000" }, { DAHDI_TONE_CONGESTION, "414/250,0/250" }, { DAHDI_TONE_CALLWAIT, "414/100,0/100,414/100,0/100,414/600,0/3000" }, { DAHDI_TONE_DIALRECALL, "!414/100,!0/100,!414/100,!0/100,!414/100,!0/100,414" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "1000/330,1400/330,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,!414/160,!0/160,414" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 20, .country = "br", .description = "Brazil", .ringcadence = { 1000, 4000 }, .tones = { { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/250,0/250" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/250,0/250,425/750,0/250" }, { DAHDI_TONE_CALLWAIT, "425/50,0/1000" }, { DAHDI_TONE_DIALRECALL, "350+440" }, { DAHDI_TONE_RECORDTONE, "425/250,0/250" }, { DAHDI_TONE_INFO, "950/330,1400/330,1800/330" }, { DAHDI_TONE_STUTTER, "350+440" } }, .dtmf_high_level = -10, .dtmf_low_level = -12, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 21, .country = "hu", .description = "Hungary", .ringcadence = { 1250, 3750 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/300,0/300" }, { DAHDI_TONE_RINGTONE, "425/1250,0/3750" }, { DAHDI_TONE_CONGESTION, "425/300,0/300" }, { DAHDI_TONE_CALLWAIT, "425/40,0/1960" }, { DAHDI_TONE_DIALRECALL, "425+450" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, { DAHDI_TONE_STUTTER, "350+375+400" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 22, .country = "lt", .description = "Lithuania", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/350,0/350" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200" }, { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/4000" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, /* STUTTER not specified */ { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 23, .country = "pl", .description = "Poland", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/500,0/500" }, { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/4000" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,0" }, /* STUTTER not specified */ { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 24, .country = "za", .description = "South Africa", .ringcadence = { 400, 200, 400, 2000 }, .tones = { { DAHDI_TONE_DIALTONE, "400*33" }, { DAHDI_TONE_BUSY, "400/500,0/500" }, { DAHDI_TONE_RINGTONE, "400*33/400,0/200,400*33/400,0/2000" }, { DAHDI_TONE_CONGESTION, "400/250,0/250" }, { DAHDI_TONE_CALLWAIT, "400*33/250,0/250,400*33/250,0/250,400*33/250,0/250,400*33/250,0/250" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "350+440" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,!950/330,!1400/330,!1800/330,!0/1000,0" }, /* STUTTER not specified */ { DAHDI_TONE_STUTTER, "!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,!400*33/100,!0/100,400*33" }, }, .dtmf_high_level = -11, .dtmf_low_level = -13, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 25, .country = "pt", .description = "Portugal", .ringcadence = { 1000, 5000 }, .tones = { { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/5000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200" }, { DAHDI_TONE_CALLWAIT, "425/200,425/200,425/200,0/5000" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "425/1000,0/200" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, /* STUTTER not specified */ { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 26, .country = "ee", .description = "Estonia", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/300,0/300" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200" }, { DAHDI_TONE_CALLWAIT, "950/650,0/325,950/325,0/30,1400/1300,0/2600" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "425/650,0/25" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "950/0,0/325,950/325,0/30,1400/1300,0/2600" }, /* STUTTER not specified */ { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 27, .country = "mx", .description = "Mexico", .ringcadence = { 2000, 4000 }, .tones = { { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/250,0/250" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/250,0/250" }, { DAHDI_TONE_CALLWAIT, "425/200,0/600,425/200,0/10000" }, { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "950/330,0/30,1400/330,0/30,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, }, .dtmf_high_level = -8, .dtmf_low_level = -6, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 28, .country = "in", .description = "India", .ringcadence = { 400, 200, 400, 2000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "400*25" }, { DAHDI_TONE_BUSY, "400/750,0/750" }, { DAHDI_TONE_RINGTONE, "400*25/400,0/200,400*25/400,0/2000" }, { DAHDI_TONE_CONGESTION, "400/250,0/250" }, { DAHDI_TONE_CALLWAIT, "400/200,0/100,400/200,0/7500" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, /* INFO - not specified */ { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0/1000" }, /* STUTTER - not specified */ { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 29, .country = "de", .description = "Germany", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/480,0/480" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/240,0/240" }, { DAHDI_TONE_CALLWAIT, "!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,!0/5000,!425/200,!0/200,!425/200,0" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/80,0/15000" }, { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "425+400" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 30, .country = "ch", .description = "Switzerland", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200" }, { DAHDI_TONE_CALLWAIT, "425/200,0/200,425/200,0/4000" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/80,0/15000" }, { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "425+340/1100,0/1100" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 31, .country = "dk", .description = "Denmark", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/200,0/200" }, { DAHDI_TONE_CALLWAIT, "!425/200,!0/600,!425/200,!0/3000,!425/200,!0/200,!425/200,0" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/80,0/15000" }, { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, /* STUTTER - not specified */ { DAHDI_TONE_STUTTER, "425/450,0/50" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 32, .country = "cz", .description = "Czech Republic", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425/330,0/330,425/660,0/660" }, { DAHDI_TONE_BUSY, "425/330,0/330" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/165,0/165" }, { DAHDI_TONE_CALLWAIT, "425/330,0/9000" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425/330,0/330,425/660,0/660" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/14000" }, { DAHDI_TONE_INFO, "950/330,0/30,1400/330,0/30,1800/330,0/1000" }, /* STUTTER - not specified */ { DAHDI_TONE_STUTTER, "425/450,0/50" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 33, .country = "cn", .description = "China", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "450" }, { DAHDI_TONE_BUSY, "450/350,0/350" }, { DAHDI_TONE_RINGTONE, "450/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "450/700,0/700" }, { DAHDI_TONE_CALLWAIT, "450/400,0/4000" }, { DAHDI_TONE_DIALRECALL, "450" }, { DAHDI_TONE_RECORDTONE, "950/400,0/10000" }, { DAHDI_TONE_INFO, "450/100,0/100,450/100,0/100,450/100,0/100,450/400,0/400" }, /* STUTTER - not specified */ { DAHDI_TONE_STUTTER, "450+425" }, }, .dtmf_high_level = -11, .dtmf_low_level = -9, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 34, .country = "ar", .description = "Argentina", .ringcadence = { 1000, 4500 }, .tones = { { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/300,0/300" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4500" }, { DAHDI_TONE_CONGESTION, "425/200,0/300" }, { DAHDI_TONE_CALLWAIT, "425/200,0/9000" }, { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425/330,0/330,425/660,0/660" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/14000" }, { DAHDI_TONE_INFO, "425/100,0/100" }, { DAHDI_TONE_STUTTER, "425/450,0/50" }, }, .dtmf_high_level = -11, .dtmf_low_level = -9, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 35, .country = "my", .description = "Malaysia", .ringcadence = { 400, 200, 400, 2000 }, .tones = { { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/400,0/200,425/400,0/2000" }, { DAHDI_TONE_CONGESTION, "425/500,0/500" }, { DAHDI_TONE_CALLWAIT, "425/100,0/4000" }, { DAHDI_TONE_DIALRECALL, "350+440" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/60000" }, { DAHDI_TONE_INFO, "950/330,0/15,1400/330,0/15,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "450+425" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 36, .country = "th", .description = "Thailand", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "400*50" }, { DAHDI_TONE_BUSY, "400/500,0/500" }, { DAHDI_TONE_RINGTONE, "400/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "400/300,0/300" }, { DAHDI_TONE_CALLWAIT, "1000/400,10000/400,1000/400" }, /* DIALRECALL - not specified - use special dial tone instead. */ { DAHDI_TONE_DIALRECALL, "400*50/400,0/100,400*50/400,0/100" }, /* RECORDTONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, /* INFO - specified as an announcement - use tones instead. */ { DAHDI_TONE_INFO, "950/330,1400/330,1800/330" }, /* STUTTER - not specified */ { DAHDI_TONE_STUTTER, "!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,!400/200,!0/200,!400/600,!0/200,400" }, }, .dtmf_high_level = -11, .dtmf_low_level = -9, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 37, .country = "bg", .description = "Bulgaria", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/250,0/250" }, { DAHDI_TONE_CALLWAIT, "425/150,0/150,425/150,0/4000" }, { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, { DAHDI_TONE_RECORDTONE, "1400/425,0/15000" }, { DAHDI_TONE_INFO, "950/330,1400/330,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "425/1500,0/100" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 38, .country = "ve", .description = "Venezuela", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/250,0/250" }, { DAHDI_TONE_CALLWAIT, "400+450/300,0/6000" }, { DAHDI_TONE_DIALRECALL, "425" }, { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1440/330,!1800/330,0/1000" }, /* STUTTER - not specified */ { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, }, .dtmf_high_level = -7, .dtmf_low_level = -9, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 39, .country = "ph", .description = "Philippines", .ringcadence = { 1000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "480+620/500,0/500" }, { DAHDI_TONE_RINGTONE, "425+480/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "480+620/250,0/250" }, { DAHDI_TONE_CALLWAIT, "440/300,0/10000" }, /* DIAL RECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, /* RECORD TONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, /* INFO TONE - not specified */ { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, /* STUTTER TONE - not specified */ { DAHDI_TONE_STUTTER, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 40, .country = "ru", .description = "Russian Federation", .ringcadence = { 1000, 4000 }, .tones = { /* References: http://www.minsvyaz.ru/site.shtml?id=1806 http://www.aboutphone.info/lib/gost/45-223-2001.html */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/350,0/350" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/175,0/175" }, { DAHDI_TONE_CALLWAIT, "425/200,0/5000" }, { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, { DAHDI_TONE_INFO, "950/330,1440/330,1800/330,0/1000" }, { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 41, .country = "tr", .description = "Turkey", .ringcadence = { 2000, 4000 }, .tones = { { DAHDI_TONE_DIALTONE, "450" }, { DAHDI_TONE_BUSY, "450/500,0/500" }, { DAHDI_TONE_RINGTONE, "450/2000,0/4000" }, { DAHDI_TONE_CONGESTION, "!450/200,!0/200,!450/200,!0/200,!450/200,!0/200,450/600,0/200" }, { DAHDI_TONE_CALLWAIT, "450/200,0/600,450/200,0/800" }, /* This should actually be 950+1400+1800, but we only support 2 tones at a time */ { DAHDI_TONE_INFO, "!950+1400/300,!0/1000,!950+1400/300,!0/1000,!950+1400/1000,0" }, { DAHDI_TONE_STUTTER, "!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,450" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 42, .country = "pa", .description = "Panama", .ringcadence = { 2000, 4000 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/320,0/320" }, { DAHDI_TONE_RINGTONE, "425/1200,0/4650" }, { DAHDI_TONE_CONGESTION, "425/320,0/320" }, { DAHDI_TONE_CALLWAIT, "425/180,0/180,425/180" }, /* RECALL DIAL TONE - not specified */ { DAHDI_TONE_DIALRECALL, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, /* RECORD TONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, /* STUTTER TONE - not specified */ { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 43, .country = "mo", .description = "Macao,China", .ringcadence = { 1000, 4000 }, .tones = { /* References: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "425" }, { DAHDI_TONE_BUSY, "425/500,0/500" }, { DAHDI_TONE_RINGTONE, "425/1000,0/4000" }, { DAHDI_TONE_CONGESTION, "425/250,0/250" }, { DAHDI_TONE_CALLWAIT, "425/200,0/600" }, /* RECORD TONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/400,0/15000" }, { DAHDI_TONE_INFO, "950/333,1400/333,1800/333,0/1000" }, /* STUTTER TONE - not specified */ { DAHDI_TONE_STUTTER, "!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,!425/100,!0/100,425" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = 44, .country = "cr", .description = "Costa Rica", .ringcadence = { 1203, 4797 }, .tones = { /* Reference: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf [^] */ { DAHDI_TONE_DIALTONE, "450" }, { DAHDI_TONE_BUSY, "450/330,0/330" }, { DAHDI_TONE_RINGTONE, "450/1203,0/4900" }, { DAHDI_TONE_CONGESTION, "450/330,0/330" }, { DAHDI_TONE_CALLWAIT, "450/150,0/150,450/150,450/8000" }, /* RECALL DIAL TONE - not specified */ { DAHDI_TONE_DIALRECALL, "!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,450" }, /* RECORD TONE - not specified */ { DAHDI_TONE_RECORDTONE, "1400/500,0/15000" }, { DAHDI_TONE_INFO, "!950/330,!1400/330,!1800/330,0" }, /* STUTTER TONE - not specified */ { DAHDI_TONE_STUTTER, "!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,!450/100,!0/100,450" }, }, .dtmf_high_level = -9, .dtmf_low_level = -11, .mfr1_level = -7, .mfr2_level = -8, }, { .zone = 45, .country = "ae", .description = "United Arab Emirates", .ringcadence = { 1500, 4000 }, .tones = { /* References: http://www.itu.int/ITU-T/inr/forms/files/tones-0203.pdf */ { DAHDI_TONE_DIALTONE, "350+440" }, { DAHDI_TONE_BUSY, "400/375,0/375" }, { DAHDI_TONE_RINGTONE, "400+425/400,0/200,400+425/400,0/2000" }, { DAHDI_TONE_CONGESTION, "425/400,0/350,425/225,0/525" }, { DAHDI_TONE_CALLWAIT, "420/40,0/1960" }, /* RECORD TONE */ { DAHDI_TONE_RECORDTONE, "1400/80,0/14920" }, { DAHDI_TONE_INFO, "950/330,1450/330,1850/330,0/1000" }, /* STUTTER TONE */ { DAHDI_TONE_STUTTER, "380+420" }, /* DIALRECALL - not specified */ { DAHDI_TONE_DIALRECALL, "!350+440/100,!0/100,!350+440/100,!0/100,!350+440/100,!0/100,350+440" }, }, .dtmf_high_level = -10, .dtmf_low_level = -10, .mfr1_level = -10, .mfr2_level = -8, }, { .zone = -1 } }; dahdi-tools-2.10.2/dahdi_scan.c0000644000000000000000000001575012537624573014750 0ustar rootroot/* * Scan and output information about DAHDI spans and ports. * * Written by Brandon Kruse * and Kevin P. Fleming * Copyright (C) 2007 Digium, Inc. * * Based on zttool written by Mark Spencer * * All rights reserved. * */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include "dahdi_tools_version.h" static inline int is_digital_span(struct dahdi_spaninfo *s) { return (s->linecompat > 0); } static int get_basechan(unsigned int spanno) { int res; int basechan; char filename[256]; FILE *fp; snprintf(filename, sizeof(filename), "/sys/bus/dahdi_spans/devices/span-%u/basechan", spanno); fp = fopen(filename, "r"); if (NULL == fp) { return -1; } res = fscanf(fp, "%d", &basechan); fclose(fp); if (EOF == res) { return -1; } return basechan; } int main(int argc, char *argv[]) { int ctl; int x, y, z; struct dahdi_params params; unsigned int basechan = 1; int direct_basechan; struct dahdi_spaninfo s; char buf[100]; char alarms[50]; int filter_count = 0; int span_filter[DAHDI_MAX_SPANS]; if ((ctl = open("/dev/dahdi/ctl", O_RDWR)) < 0) { fprintf(stderr, "Unable to open /dev/dahdi/ctl: %s\n", strerror(errno)); exit(1); } for (x = 1; x < argc && filter_count < DAHDI_MAX_SPANS; x++) { int s = atoi(argv[x]); if (s > 0) { span_filter[filter_count++] = s; } } for (x = 1; x < DAHDI_MAX_SPANS; x++) { memset(&s, 0, sizeof(s)); s.spanno = x; if (ioctl(ctl, DAHDI_SPANSTAT, &s)) continue; if (filter_count > 0) { int match = 0; for (z = 0; z < filter_count; z++) { if (x == span_filter[z]) { match = 1; break; } } if (!match) { basechan += s.totalchans; continue; } } /* DAHDI-Linux 2.5.x exposes the base channel in sysfs. Let's * try to look for it there in case there are holes in the span * numbering. */ direct_basechan = get_basechan(x); if (-1 != direct_basechan) { basechan = direct_basechan; } alarms[0] = '\0'; if (s.alarms) { if (s.alarms & DAHDI_ALARM_BLUE) strcat(alarms,"BLU/"); if (s.alarms & DAHDI_ALARM_YELLOW) strcat(alarms, "YEL/"); if (s.alarms & DAHDI_ALARM_RED) { strcat(alarms, "RED/"); /* Extended alarm feature test. Allows compilation with * versions of dahdi-linux prior to 2.4 */ #ifdef DAHDI_ALARM_LFA if (s.alarms & DAHDI_ALARM_LFA) strcat(alarms, "LFA/"); #endif /* ifdef DAHDI_ALARM_LFA */ } if (s.alarms & DAHDI_ALARM_LOOPBACK) strcat(alarms,"LB/"); if (s.alarms & DAHDI_ALARM_RECOVER) strcat(alarms,"REC/"); if (s.alarms & DAHDI_ALARM_NOTOPEN) strcat(alarms, "NOP/"); if (!strlen(alarms)) strcat(alarms, "UUU/"); if (strlen(alarms)) { /* Strip trailing / */ alarms[strlen(alarms)-1]='\0'; } } else { if (s.numchans) { #ifdef DAHDI_ALARM_LFA /* If we continuously receive framing errors * but our span is still in service, and we * are configured for E1 & crc4. We've lost * crc4-multiframe alignment */ if ((s.linecompat & DAHDI_CONFIG_CRC4) && (s.fecount > 0)) { struct dahdi_spaninfo t; memset(&t, 0, sizeof(t)); t.spanno = x; sleep(1); if (ioctl(ctl, DAHDI_SPANSTAT, &t)) continue; /* Test fecount at two separate time * intervals, if they differ, throw LMFA */ if ((t.fecount > s.fecount) && !t.alarms) { strcat(alarms, "LMFA/"); } } #endif /* ifdef DAHDI_ALARM_LFA */ strcat(alarms, "OK"); } else { strcpy(alarms, "UNCONFIGURED"); } } fprintf(stdout, "[%d]\n", x); fprintf(stdout, "active=yes\n"); fprintf(stdout, "alarms=%s\n", alarms); fprintf(stdout, "description=%s\n", s.desc); fprintf(stdout, "name=%s\n", s.name); fprintf(stdout, "manufacturer=%s\n", s.manufacturer); fprintf(stdout, "devicetype=%s\n", s.devicetype); fprintf(stdout, "location=%s\n", s.location); fprintf(stdout, "basechan=%d\n", basechan); fprintf(stdout, "totchans=%d\n", s.totalchans); fprintf(stdout, "irq=%d\n", s.irq); y = basechan; memset(¶ms, 0, sizeof(params)); params.channo = y; if (ioctl(ctl, DAHDI_GET_PARAMS, ¶ms)) { basechan += s.totalchans; continue; } if (is_digital_span(&s)) { /* this is a digital span */ fprintf(stdout, "type=digital-%s\n", s.spantype); fprintf(stdout, "syncsrc=%d\n", s.syncsrc); fprintf(stdout, "lbo=%s\n", s.lboname); fprintf(stdout, "coding_opts="); buf[0] = '\0'; if (s.linecompat & DAHDI_CONFIG_B8ZS) strcat(buf, "B8ZS,"); if (s.linecompat & DAHDI_CONFIG_AMI) strcat(buf, "AMI,"); if (s.linecompat & DAHDI_CONFIG_HDB3) strcat(buf, "HDB3,"); buf[strlen(buf) - 1] = '\0'; fprintf(stdout, "%s\n", buf); fprintf(stdout, "framing_opts="); buf[0] = '\0'; if (s.linecompat & DAHDI_CONFIG_ESF) strcat(buf, "ESF,"); if (s.linecompat & DAHDI_CONFIG_D4) strcat(buf, "D4,"); if (s.linecompat & DAHDI_CONFIG_CCS) strcat(buf, "CCS,"); if (s.linecompat & DAHDI_CONFIG_CRC4) strcat(buf, "CRC4,"); buf[strlen(buf) - 1] = '\0'; fprintf(stdout, "%s\n", buf); fprintf(stdout, "coding="); if (s.lineconfig & DAHDI_CONFIG_B8ZS) fprintf(stdout, "B8ZS"); else if (s.lineconfig & DAHDI_CONFIG_AMI) fprintf(stdout, "AMI"); else if (s.lineconfig & DAHDI_CONFIG_HDB3) fprintf(stdout, "HDB3"); fprintf(stdout, "\n"); fprintf(stdout, "framing="); if (s.lineconfig & DAHDI_CONFIG_ESF) fprintf(stdout, "ESF"); else if (s.lineconfig & DAHDI_CONFIG_D4) fprintf(stdout, "D4"); else if (s.lineconfig & DAHDI_CONFIG_CCS) fprintf(stdout, "CCS"); else fprintf(stdout, "CAS"); if (s.lineconfig & DAHDI_CONFIG_CRC4) fprintf(stdout, "/CRC4"); fprintf(stdout, "\n"); } else { /* this is an analog span */ fprintf(stdout, "type=analog\n"); for (y = basechan; y < (basechan + s.totalchans); y++) { memset(¶ms, 0, sizeof(params)); params.channo = y; if (ioctl(ctl, DAHDI_GET_PARAMS, ¶ms)) { fprintf(stdout, "port=%d,unknown\n", y); continue; }; fprintf(stdout, "port=%d,", y); switch (params.sigcap & (__DAHDI_SIG_FXO | __DAHDI_SIG_FXS)) { case __DAHDI_SIG_FXO: fprintf(stdout, "FXS"); break; case __DAHDI_SIG_FXS: fprintf(stdout, "FXO"); break; default: fprintf(stdout, "none"); } if (params.sigcap & DAHDI_SIG_BROKEN) fprintf(stdout, " FAILED"); fprintf(stdout, "\n"); } } basechan += s.totalchans; } exit(0); } dahdi-tools-2.10.2/dahdi_diag.c0000644000000000000000000000263312537624573014724 0ustar rootroot/* * Written by Mark Spencer * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include "dahdi_tools_version.h" int main(int argc, char *argv[]) { int fd; int chan; if ((argc < 2) || (sscanf(argv[1], "%d", &chan) != 1)) { fprintf(stderr, "Usage: dahdi_diag \n"); exit(1); } fd = open("/dev/dahdi/ctl", O_RDWR); if (fd < 0) { perror("open(/dev/dahdi/ctl"); exit(1); } if (ioctl(fd, DAHDI_CHANDIAG, &chan)) { perror("ioctl(DAHDI_CHANDIAG)"); exit(1); } exit(0); } dahdi-tools-2.10.2/dahdi_maint.c0000644000000000000000000001570412537624573015133 0ustar rootroot/* * Performance and Maintenance utility * * Written by Russ Meyerriecks * * Copyright (C) 2009-2010 Digium, Inc. * * All rights reserved. * */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include "dahdi_tools_version.h" #define DAHDI_CTL "/dev/dahdi/ctl" extern char *optarg; extern int optind; void display_help(char *argv0, int exitcode) { char *c; c = strrchr(argv0, '/'); if (!c) c = argv0; else c++; fprintf(stderr, "%s\n\n", dahdi_tools_version); fprintf(stderr, "Usage: %s -s \n", c); fprintf(stderr, "Options:\n"); fprintf(stderr, " -h, --help display help\n"); fprintf(stderr, " -s, --span specify the span\n"); fprintf(stderr, " -l, --loopback \n"\ "\t\tlocalhost - loop back towards host\n"\ "\t\tnetworkline - network line loopback\n"\ "\t\tnetworkpayload - network payload loopback\n"\ "\t\tloopup - transmit loopup signal\n"\ "\t\tloopdown - transmit loopdown signal\n"\ "\t\toff - end loopback mode\n"); fprintf(stderr, " -i, --insert "\ "\n\t\tinsert an error of a specific type\n"); fprintf(stderr, " -r, --reset "\ "reset the error counters\n\n"); fprintf(stderr, "Examples: \n"); fprintf(stderr, "Enable network line loopback\n"); fprintf(stderr, " dahdi_maint -s 1 --loopback networkline\n"); fprintf(stderr, "Disable network line loopback\n"); fprintf(stderr, " dahdi_maint -s 1 --loopback off\n\n"); exit(exitcode); } int main(int argc, char *argv[]) { static int ctl = -1; int res; int doloopback = 0; char *larg = NULL; int span = 1; int iflag = 0; char *iarg = NULL; int gflag = 0; int c; int rflag = 0; struct dahdi_maintinfo m; struct dahdi_spaninfo s; static struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"loopback", required_argument, 0, 'l'}, {"span", required_argument, 0, 's'}, {"insert", required_argument, 0, 'i'}, {"reset", no_argument, 0, 'r'}, {0, 0, 0, 0} }; int option_index = 0; if (argc < 2) { /* no options */ display_help(argv[0], 1); } while ((c = getopt_long(argc, argv, "hj:l:p:s:i:g:r", long_options, &option_index)) != -1) { switch (c) { case 'h': display_help(argv[0], 0); break; case 'l': /* loopback */ larg = optarg; doloopback = 1; break; case 's': /* specify a span */ span = atoi(optarg); break; case 'i': /* insert an error */ iarg = optarg; iflag = 1; break; case 'g': /* generate psuedo random sequence */ gflag = 1; break; case 'r': /* reset the error counters */ rflag = 1; break; } } ctl = open(DAHDI_CTL, O_RDWR); if (ctl < 0) { fprintf(stderr, "Unable to open %s\n", DAHDI_CTL); return -1; } if (!(doloopback || iflag || gflag || rflag)) { s.spanno = span; res = ioctl(ctl, DAHDI_SPANSTAT, &s); if (res || ((__u32)-1 == s.fecount)) printf("Error counters not supported by the driver"\ " for this span\n"); printf("Span %d:\n", span); printf(">Framing Errors : %d:\n", s.fecount); printf(">CRC Errors : %d:\n", s.crc4count); printf(">Code Violations : %d:\n", s.cvcount); printf(">E-bit Count : %d:\n", s.ebitcount); printf(">General Errored Seconds : %d:\n", s.errsec); return 0; } m.spanno = span; if (doloopback) { if (!strcasecmp(larg, "localhost")) { printf("Span %d: local host loopback ON\n", span); m.command = DAHDI_MAINT_LOCALLOOP; } else if (!strcasecmp(larg, "networkline")) { printf("Span %d: network line loopback ON\n", span); m.command = DAHDI_MAINT_NETWORKLINELOOP; } else if (!strcasecmp(larg, "networkpayload")) { printf("Span %d: network payload loopback ON\n", span); m.command = DAHDI_MAINT_NETWORKPAYLOADLOOP; } else if (!strcasecmp(larg, "loopup")) { printf("Span %d: transmitting loopup signal\n", span); m.command = DAHDI_MAINT_LOOPUP; } else if (!strcasecmp(larg, "loopdown")) { printf("Span %d: transmitting loopdown signal\n", span); m.command = DAHDI_MAINT_LOOPDOWN; } else if (!strcasecmp(larg, "off")) { printf("Span %d: loopback OFF\n", span); m.command = DAHDI_MAINT_NONE; } else { display_help(argv[0], 1); } res = ioctl(ctl, DAHDI_MAINT, &m); if (res) { printf("This type of looping not supported by the"\ " driver for this span\n"); return 1; } /* Leave the loopup/loopdown signal on the line for * five seconds according to AT&T TR 54016 */ if ((m.command == DAHDI_MAINT_LOOPUP) || (m.command == DAHDI_MAINT_LOOPDOWN)) { sleep(5); m.command = DAHDI_MAINT_NONE; ioctl(ctl, DAHDI_MAINT, &m); } } if (iflag) { if (!strcasecmp(iarg, "fas")) { m.command = DAHDI_MAINT_FAS_DEFECT; printf("Inserting a single FAS defect\n"); } else if (!strcasecmp(iarg, "multi")) { m.command = DAHDI_MAINT_MULTI_DEFECT; printf("Inserting a single multiframe defect\n"); } else if (!strcasecmp(iarg, "crc")) { m.command = DAHDI_MAINT_CRC_DEFECT; printf("Inserting a single CRC defect\n"); } else if (!strcasecmp(iarg, "cas")) { m.command = DAHDI_MAINT_CAS_DEFECT; printf("Inserting a single CAS defect\n"); } else if (!strcasecmp(iarg, "prbs")) { m.command = DAHDI_MAINT_PRBS_DEFECT; printf("Inserting a single PRBS defect\n"); } else if (!strcasecmp(iarg, "bipolar")) { m.command = DAHDI_MAINT_BIPOLAR_DEFECT; printf("Inserting a single bipolar defect\n"); #ifdef DAHDI_MAINT_ALARM_SIM } else if (!strcasecmp(iarg, "sim")) { m.command = DAHDI_MAINT_ALARM_SIM; printf("Incrementing alarm simulator\n"); #endif } else { display_help(argv[0], 1); } res = ioctl(ctl, DAHDI_MAINT, &m); if (res) printf("This type of error injection is not supported"\ " by the driver for this span\n"); } if (gflag) { printf("Enabled the Pseudo-Random Binary Sequence Generation"\ " and Monitor\n"); m.command = DAHDI_MAINT_PRBS; res = ioctl(ctl, DAHDI_MAINT, &m); if (res) { printf("Pseudo-random binary sequence generation is"\ " not supported by the driver for this span\n"); } } if (rflag) { printf("Resetting error counters for span %d\n", span); m.command = DAHDI_RESET_COUNTERS; res = ioctl(ctl, DAHDI_MAINT, &m); if (res) { printf("Resetting error counters is not supported by"\ " the driver for this span\n"); } } return 0; } dahdi-tools-2.10.2/doc/0000755000000000000000000000000012537624573013264 5ustar rootrootdahdi-tools-2.10.2/doc/dahdi_scan.80000644000000000000000000000510512537624573015433 0ustar rootroot.TH dahdi_scan 8 "2008-03-18" .SH NAME dahdi_scan \(em Print Configuration of DAHDI Spans .SH SYNOPSIS .B dahdi_scan .I [spans] .SH DESCRIPTION .B dahdi_scan prints information about DAHDI spans in the system. For analog spans it also provides a list of channels. By default it prints information about all the spans in the system. However if parameters are provided, they will be considered to be a list of span numbers and information will be printed for them. Output is printed to the standard output. The format is that of an Asterisk configuration file (similar to a "ini" configuration file), where the name of the section is the number of the span. Note that the specifically for analog spans some keys may appear more than once, and hence you can not use a parser for an "ini" format and assume you have a dictionary. .SH EXAMPLES Printing information for spans 1, 2 and 4: dahdi_scan 1 2 4 And to print all the spans: dahdi_scan Information about a certain analog span: [5] active=yes alarms=OK description=Xorcom XPD #00/10: FXS name=XBUS\-00/XPD\-10 manufacturer=Xorcom Inc. devicetype=Astribank: Unit 1 Subunit 0: FXS location=usb\-0000:00:03.3\-4 basechan=125 totchans=8 irq=0 type=analog port=125,FXS port=126,FXS port=127,FXS port=128,FXS port=129,FXS port=130,FXS port=131,FXS port=132,FXS And an example of a digital span: [1] active=yes alarms=RED description=T2XXP (PCI) Card 0 Span 1 name=TE2/0/1 manufacturer=Digium devicetype=Wildcard TE205P (4th Gen) location=Board ID Switch 0 basechan=1 totchans=24 irq=193 type=digital\-T1 syncsrc=0 lbo=0 db (CSU)/0\-133 feet (DSX\-1) coding_opts=B8ZS,AMI framing_opts=ESF,D4 coding=B8ZS framing=ESF The "type" field may contain: "analog", "digital\-T1", "digital\-E1", "digital\-J1" or "digital\-BRI". .SH FILES Requires read access to /dev/dahdi/ctl . .SH SEE ALSO dahdi_cfg(8), asterisk(8). .SH BUGS The program still does not do everything described in the man page. It also assumes that spans don't skip channel numbers, and that their channel numbers are "running". This is anyway almost always the case. And always the case in a normal boot process. .SH AUTHOR This manual page was written by Tzafrir Cohen Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common\-licenses/GPL. dahdi-tools-2.10.2/doc/dahdi_test.80000644000000000000000000000231012537624573015461 0ustar rootroot.TH dahdi_test 8 "2005-06-25" .SH "NAME" dahdi_test \(em Test if the DAHDI timer provides timely response .SH "SYNOPSIS" .B dahdi_test .I [ \-v ] .SH DESCRIPTION .B dahdi_test dahdi_test runs a timing test in a loop and prints the result of each loop. The test is as follows: It reads 8192 bytes from the DAHDI timer device (\fI/dev/dahdi/pseudo\fR). This should take exactly 8000 ms . It uses calls to .I gettimeofday(2) before and after that read to check that indeed exactly 8000ms have passed. Values of 100% and 99.99% Are normally considered a definite .I pass. Values of 99.98% and 99.97% are probably OK as well. .SH OPTIONS .B \-v .RS Be more verbose: print one line per test. .RE .B \-c .I count .RS Run for .I count times instead of running forever. .RE .SH FILES .B /dev/dahdi/pseudo .RS .RE The device file used to access the DAHDI timer. .SH SEE ALSO dahdi_tool(8), dahdi_cfg(8), asterisk(8). gettimeofday(2) .SH AUTHOR This manual page was written by Tzafrir Cohen Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. dahdi-tools-2.10.2/doc/dahdi_span_assignments.80000644000000000000000000001550512537624573020070 0ustar rootroot.TH "DAHDI_SPAN_ASSIGNMENTS" "8" "23 Jan 2014" "" "" .SH NAME dahdi_span_assignments \- handle DAHDI spans assignments .SH SYNOPSIS .B dahdi_span_assignments [\-v|\-\-verbose] [\-n|\-\-dry\-run] \fB[\fIdevpath\fB...] .B dahdi_span_assignments [\-v|\-\-verbose] list \fB[\fIdevpath\fB...] .B dahdi_span_assignments [\-v|\-\-verbose] [\-k|\-\-key \fIkey\fB] dumpconfig .B dahdi_span_assignments \-h|\-\-help .SH DESCRIPTION Channels in DAHDI devices (such as DAHDI PCI cards) are groups to logical units called "spans" (for example: a port in a digital card is a span). When the kernel module parameter \fBdahdi.auto_assign_span\fR is unset, DAHDI devices that register with DAHDI don't cause their spans to be automatically assigned. This allows user-space to order DAHDI to assign them to specific span and channel numbers. That way, specific spans on specific DAHDI devices may be assigned with specific span and channel numbers \fBregardless\fR of the registration order of the hardware (or if all hardware is present at all). .B dahdi_span_assignments is used to assign those spans or to help creating the configuration file used in their assignment: .B /etc/dahdi/assigned\-spans.conf . .SH SUB-COMMANDS There are several sub-commands. All sub-commands take an optional list of paths to SysFS nodes of devices. If given, the command will only operate on those DAHDI devices. The default is to operate on all devices (which would normally be the sane case when running from the command-line). .B add \fB[\fIdevpath \fB...] .RS Applies to all devices or to those listed on the command line. Parameters are paths (in SysFS) to DAHDI devices with unassigned spans. The command will assign spans with DAHDI according to configuration in \fBassigned\-spans.conf\fR. If no line matches the span, or if the assignment for it fails (it is not available) it will remain unassigned. If any of the span settings fails (the span number or range of channels is already in use), the program will print a message, but continue applying the others. In such a case you should fix assigned\-spans.conf and re-run \fBadd\fR (or run \fBauto\fR to give those channels the first available range and regenerate the file with 'dahdi_genconf assignedspans'). .RE .B remove \fB[\fIdevpath \fB...] .RS Applies to all devices or to those listed on the command line. Parameters are paths (in SysFS) to DAHDI devices with assigned spans. The command will un-assign them. .RE .B auto \fB[\fIdevpath \fB...] .RS Applies to all devices or to those listed on the command line. Parameters are paths (in SysFS) to DAHDI devices with unassigned spans. Each span is assigned to first available span number and channel numbers, as if \fBdahdi.auto_assign_span\fR was set. The configuration file doesn't affect these assignments. .RE .B list .RS List all spans in the system. .RE .B dumpconfig .RS List all assigned spans in the system in a format fit to be used in \fBassigned\-spans.conf\fR. Use this to generate a configuration file after you have (automatically or manually) assigned all existing spans. .B dahdi_genconf assignedspans uses this command internally. .RE .SH OPTIONS .B \-v \-\-verbose .RS Verbose output. .RE .B \-n \-\-dry\-run .RS Don't assign / un-assign spans. Only print commands used to do so. .RE .B \-k \fIkey .RS For \fBdumpconfig\fR \- The key by which to identify the hardware in the generated configuration. Legal values: .B hwid .RS Hardware identifier (e.g.: software-readable serial number). This is the default. If the device has no hwid, devpath is used. .RE .B location .RS The location field (file) in the SysFS device node (directory) for the DAHDI device. If not available (typically: DAHDI version <= 2.7.x), devpath is used. .RE .B devpath .RS Path in SysFS to the device node. .RE .RE .SH CONFIGURATION .B /etc/dahdi/assigned\-spans.conf is a file with lines specifying assignment of spans. Empty lines or lines beginning with '#' are ignored. Each line is in the format of: .I ID spanspec ... The \fIID\fR field specifies the DAHDI device and the \fIspanspecs\fR define how to assign its spans. A line may have multiple \fIspanspecs\fR in a single line (though dumpconfig generates a configuration with one per line). .SS Span Identifier A DAHDI device may be specified either by a hardware identifier (a software readable serial number or whatever) or the location in which it is installed on the system. The former makes it simpler to change connector / slot whereas the latter makes it simpler to replace a unit. The value in this field is matched (when the commands \fBadd\fR and \fBremove\fR) are used) to the following values: \fIhwid\fR \fB@\fIlocation\fR \fIdevpath\fR See above for their descriptions. The value may include shell wildcards: *, ? and [], which are used in the match. The values to be matched are first cleaned up: '!' is replaced with '/' and any character beyond "a\-zA\-Z0\-9/:.\-" is removed. .SS Span Specification Each line should have one or more span specifications: this is the value used to assign a span with DAHDI in the SysFS interface. A specification has three colon-separated numbers: .I rel_span_no:span_no:first_chan for instance, the following are four span specifications for a quad-E1 device: 1:6:53 2:7:84 3:8:115 4:9:146 occupying spans 6-9 and channels 53-176. .B rel_span_no .RS The relative number of the span in the device. E.g.: port number. .RE .B span_no .RS The desired DAHDI span number. Must be available. .RE .B first_chan .RS The desired DAHDI channel number for the first DAHDI channel in the span. All channels of the span will be assigned following it and hence that space must be available. .RE .SH ENVIRONMENT .B DAHDICONFDIR .RS The directory in which assigned\-spans.conf resides. /etc/dahdi if not overridden from the environment. .RE .B DAHDISASSIGNEDSPANSCONF .RS The path to assigned-spans.conf resides. /etc/dahdi/assigned\-spans.conf if not overridden from the environment. .RE .B SPAN_ASSIGNMENTS_KEY .RS The default value for \-k . Defaults to "hwid" if not overridden from the environment. .RE .SH FILES .B /etc/dahdi/assigned\-spans.conf .RS The default location for the configuration file. .RE .B /sys/bus/dahdi_devices/devices/\fIdevice\fR .RS SysFS node for the device. In this directory reside the following files, among others: .B location .RS The value of the device's location field. .RE .B assign_span, unassign_span, auto_assign .RS Write only files for the operations. Used by \fBadd\fR, \fBremove\fR and \fBauto\fR, respectively. .RE .RE .SH SEE ALSO dahdi_span_types(8), dahdi_genconf(8), dahdi_cfg(8) .SH AUTHOR dahdi_span_assignments was written by Oron Peled. This manual page was written by Tzafrir Cohen. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. dahdi-tools-2.10.2/doc/dahdi_maint.80000644000000000000000000000256512537624573015626 0ustar rootroot.TH "DAHDI_MAINT" "8" "9 Sep 2011" "" "" .SH NAME dahdi_maint \- Sets Dahdi spans into maintenance mode, e.g.: loopback .SH SYNOPSIS .B dahdi_maint \-s \fInum\fB [options] .B dahdi_maint <\-h|\-\-help> .SH DESCRIPTION dahdi_maint uses the DAHDI_MAINT interface to set a Dahdi span (port of a Dahdi adapter card) into loopback mode or similar maintenance mode. .SH OPTIONS .B \-s \-\-span \fInum\fR .RS The span number. Required. .RE .B \-l \-\-loopback .RS Loopback type. One of: .IP localhost 4 loop back towards host .IP networkline 4 network line loopback .IP networkpayload 4 network payload loopback .IP loopup 4 transmit loopup signal .IP loopdown 4 transmit loopdown signal .IP off 4 end loopback mode .RE .B \-i \-\-insert .RS Insert an error of a specific type .RE .SH EXAMPLES Enable network line loopback on span 1: dahdi_maint \-s 1 \-\-loopback networkline Disable network line loopback on span 1: dahdi_maint \-s 1 \-\-loopback off .SH SEE ALSO .PP dahdi_tool(8), dahdi_cfg(8), asterisk(8). .SH AUTHOR .PP This manual page was written by Tzafrir Cohen . Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. dahdi-tools-2.10.2/doc/fxstest.80000644000000000000000000000257412537624573015065 0ustar rootroot.TH "FXSTEST" "8" "9 June 2007" "asterisk" "System Manager's Manuals: Asterisk" .SH NAME fxstest \- Simple tests for DAHDI FXS adapters .SH SYNOPSIS .B fxstest /dev/dahdi/\fIN comand\fR .SH DESCRIPTION fxstest can be used to issue one of a number simple tests to FXS adapters (analog adapters intended to connect phones). .SH OPTIONS All of those tests operate on a single dahdi channel which has to be an FXS port, and must not be in use by Asterisk or any other program. The command has two mandatory parameters. The first parameter is the device file to operate on. It is typically /dev/dahdi/NN , a device file under /dev/dahdi . The second parameter is the name of the command to run on that channel: .I stats .RS Reports voltages .RE .I regdump .RS Dumps ProSLIC registers .RE .I tones .RS Plays a series of tones .RE .I polarity .RS Requests channel to reverse polarity. .RE .I ring .RS Rings phone .RE .SH "SEE ALSO" .PP dahdi_tool(8), dahdi_cfg(8), dahdi_monitor(8), asterisk(8). .SH BUGS Does not allow testing channels beyond 249. Should support opening channels through /dev/dahdi/channel . .SH AUTHOR .PP This manual page was written by Tzafrir Cohen . Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. .PP dahdi-tools-2.10.2/doc/pattest.80000644000000000000000000000255112537624573015044 0ustar rootroot.TH pattest 8 "2 Dec 2009" .SH NAME pattest \(em Tests a Pattern for a DAHDI Clear Channel Test .SH SYNOPSIS .B pattest .I dahdi-device .SH DESCRIPTION .B pattest Receives test data from a DAHDI channel and checks if it matches the test pattern. The channel should be of CLEAR signalling (e.g: B channel of a PRI line). patgen(8) is used to generate the data at the other side. .B pattest Must be able to read from the channel. Hence this cannot be used for a channel used by Asterisk. The pattern is a simple series of values from 0 to 255. Hence it takes at most one sample to get in sync with the other side. If there is no output, all is well. Output is an error message. .SH OPTIONS .I dahdi-device .RS A DAHDI device. Can be either a device number or an explicit device file name .RE .SH EXAMPLE pattest /dev/dahdi/5 pattest 305 .RE .SH BUGS Gives way too many errors when does not get any input. .SH SEE ALSO patgen(8), dahdi_cfg(8), asterisk(8). .SH AUTHOR This manual page was written by Tzafrir Cohen Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common\-licenses/GPL. dahdi-tools-2.10.2/doc/dahdi_cfg.80000644000000000000000000000354412537624573015253 0ustar rootroot.TH "DAHDI_CFG" "8" "16 Jun 2008" "" "" .SH NAME dahdi_cfg \- configures DAHDI kernel modules from /etc/dahdi/system.conf .SH SYNOPSIS .B dahdi_cfg [\-c \fICFG_FILE\fB] [\-S\fINUM\fB [\-S\fICHANS\fB]] [\-s] [\-f] [\-t] [\-v [\-v ... ] ] .B dahdi_cfg \-h .SH DESCRIPTION .B dahdi_cfg configures DAHDI interface cards from a config file. You generally need to run it with a valid configurations in order for DAHDI modules to work properly. It must be run to configure every DAHDI span. Normally it is run from the DAHDI init script. .SH OPTIONS .B \-c \fICFG_FILE .RS Use an alternative configuration file instead of .I /etc/dahdi/system.conf If \fICFG_FILE\fR is '\fB\-\fR', it is read from stdin. .RE .B \-C \fICHANNELS .RS Only apply changes to channels in the specified range. Only applicable when \-S is in use. .RE .B \-s .RS Only shutdown spans. .RE .B \-S \fISPAN .RS Only apply changes to span no. \fISPAN\fR. For a digital span (with a 'span=' line in the configuration file) this will do. For an analog span you'll have to explicitly tell dahdi_cfg the range of channels, using \-C . .RE .B \-f .RS Always configure every channel, even if it appears not to have changed. .RE .B \-t .RS Test mode. Don't do anything, just report what you wanted to do. .RE .B \-v .RS Be more verbose. Add extra v-s for extra verbosity. .RE .B \-h .RS Display a brief help message. .RE .SH FILES .I /etc/dahdi/system.conf .RS The default location for the configuration file. .RE .SH SEE ALSO dahdi_tool(8), dahdi_monitor(8), asterisk(8). .SH AUTHOR This manual page was written by Santiago Ruano Rinc\['o]n for the Debian system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. dahdi-tools-2.10.2/doc/dahdi_monitor.80000644000000000000000000000615512537624573016204 0ustar rootroot.TH "DAHDI_MONITOR" "8" "9 Sep 2011" "" "" .SH NAME dahdi_monitor \- checks the Rx/Tx levels of a DAHDI channels .SH SYNOPSIS .B dahdi_monitor \fInum\fB [\-v[v]] .B dahdi_monitor \fInum\fB [\-o] [<\-f|\-F> \fIFILE\fB] .B dahdi_monitor \fInum\fB [[<\-r|\-R> \fIFILE\fB]] [[<\-t|\-T> \fIFILE\fB]] .SH DESCRIPTION dahdi_monitor monitors a Dahdi channel. It can record the output to a file, play it to the speaker, or visualize the audio levels on the terminal. Recorded audio files are by default raw signed linear PCM. If the file name ends with ".wav", the recorded file will be a WAV file. The visual display shows the current audio level at both the Rx (audio Received by Asterisk) and Tx (audio Transmitted by Asterisk) To exit the program, press Ctrl-C. .SH OPTIONS The first (mandatory) parameter is the number of the channel to monitor. .B \-m .RS Multiple channels. Don't multiplex both Rx and Tx in a single channel. Normally there's a different option that you need that implies it. .RE .B \-o .RS Plays the output to OSS (/dev/dsp). Requires \-m not to be used. .RE .B \-v .RS Display Visual audio levels. With two v-s, Verbose mode is enabled, that shows the actual levels as numbers. Note that this requires a terminal wider than 80 columns to be properly displayed. Implies \-m. .RE .B \-f \fIFILE .RS Record the content of the channel (Tx + Rx) to a file. .RE .B \-F \fIFILE .RS Record the content of the channel (Tx + Rx) before the echo canceler to a file. .RE .B \-r \fIFILE .RS Record the content of the Rx channel to a file. Implies \-m. .RE .B \-R \fIFILE .RS Record the content of the R channel before the echo canceler to a file. Implies \-m. .RE .B \-s \fIFILE .RS Record the content of the Tx and Rx of the channel to a file. .RE .B \-S \fIFILE .RS Records a stereo of both Tx and Rx of the channel before the echo canceler to a file. .RE .B \-t \fIFILE .RS Record the content of the Tx channel to a file. Implies \-m. .RE .B \-T \fIFILE .RS Record the content of the Tx channel before the echo canceler to a file. Implies \-m. .RE .SH EXAMPLES Visualize audio levels on DAHDI channel 2: dahdi_monitor 2 \-v Record channel 3 to a file: dahdi_monitor 3 \-f output.raw This will create a raw PCM file (signed-linear, 8kHz, mono, 16 bits per sample). Both the Tx and Rx will be multiplexed in a single channel. It can be converted to a WAV file using e.g.: sox \-s \-c1 \-2 \-r8000 output.raw output.wav Record Tx and Rx of channel 5 to separate files. This time directly to WAV files: dahdi_monitor 5 \-r output_rx.wav \-t output_tx.wav Record channel 8 to a stereo file (Tx and Rx on its two channels): dahdi_monitor 8 \-s output.raw Converting it to a WAV file: sox \-s \-c2 \-2 \-r8000 output.raw output.wav .SH SEE ALSO .PP dahdi_tool(8), dahdi_cfg(8). .SH AUTHOR .PP This manual page was written by Santiago Ruano Rinc\['o]n for the Debian system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. dahdi-tools-2.10.2/doc/dahdi_waitfor_span_assignments.80000644000000000000000000000256712537624573021627 0ustar rootroot.TH "DAHDI_WAITFOR_SPAN_ASSIGNMENTS" "8" "22 Jan 2014" "" "" .SH NAME dahdi_waitfor_span_assignments \- wait for DAHDI spans to get (un)assigned .SH SYNOPSIS .B dahdi_span_assignments assigned .B dahdi_span_assignments unassigned .SH DESCRIPTION DAHDI spans get assigned / unassigned asynchronously. .B dahdi_span_assignments is a helper script that allows running commands after all the spans have been assigned or unassigned. It takes a single command: \fBassigned\fR or \fBunassigned\fR and waits (up until a timeout of 5 seconds) for all the DAHDI spans in the system to do so. Note that if the system has a span that will not get assigned automatically (e.g.: it's not in assigned\-spans.conf), this program does not know and will wait until a timeout. .SH EXAMPLES modprobe wctdm24xxp dahdi_waitfor_span_assignments assigned do_something dahdi_span_assignments add dahdi_waitfor_span_assignments assigned do_something_else dahdi_span_assignments remove dahdi_span_assignments unassigned do_something_completely_different .SH SEE ALSO dahdi_span_assignments(8) .SH AUTHOR dahdi_waitfor_span_assignments was written by Oron Peled. This manual page was written by Tzafrir Cohen. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. dahdi-tools-2.10.2/doc/patgen.80000644000000000000000000000223512537624573014635 0ustar rootroot.TH patgen 8 "2 Dec 2009" .SH NAME patgen \(em Generates a Pattern for a DAHDI Clear Channel Test .SH SYNOPSIS .B patgen .I dahdi-device .SH DESCRIPTION .B patgen Sends test data to a DAHDI channel. The channel should be of CLEAR signalling (e.g: B channel of a PRI line). pattest(8) is used to test the data at the other side. See its manual for more information. .B patgen Must be able to write to the channel. Hence this cannot be used for a channel used by Asterisk. .SH OPTIONS .I dahdi-device .RS A DAHDI device. Can be either a device number or an explicit device file name .RE .SH EXAMPLE patgen /dev/dahdi/5 patgen 305 .SH BUGS Waiting for you to report them at . .SH SEE ALSO pattest(8), dahdi_cfg(8), asterisk(8). .SH AUTHOR This manual page was written by Tzafrir Cohen Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common\-licenses/GPL. dahdi-tools-2.10.2/doc/fxotune.80000644000000000000000000001431612537624573015052 0ustar rootroot.TH FXOTUNE "8" "9 June 2007" "asterisk" "System Manager's Manuals: Asterisk" .SH NAME fxotune \- automatically tune DAHDI FXO channels .SH SYNOPSIS .B fxotune \-i .I [options] \- detect mode .B fxotune \-d .I [ options ] \- dump mode .B fxotune \-s .I [ options ] \- Startup mode .SH .SH DESCRIPTION .B fxotune is a script that fine-tune parameters of the FXO modules of the card. It has three modes of operation: .I Detect mode (\-i): it detects and tunes all the available FXO channels. It writes settings to a configuration file (/etc/fxotune.conf) from which it can be loaded (e.g: at startup) using \-s . .I Dump mode (\-d): Runs detection on a single DAHDI channel, and just dumps waveforms to .B fxotune_dump.vals is generated in the current directory. .I Startup mode (\-s): fxotune just reads the settings from fxotune.conf into the FXO modules. You are advised to run fxotune on all FXO ports you have that support it and that are connected. Note that the tunning is affected by e.g. the physical parameters of the connection, and thus if it has been radically changed, you may need to re-run fxotune. This program only works for the Digium TDM400P/800P/2400P cards and compatible and the Xorcom Astribank devices. Other cards (notably X100P cards and clones) do not have the hardware to support such tuning. The tuning process needs a clear line to do the tuning. In order to do that, it runs in cycles of the following: sets the line off-hook, dials a dial string (which should set the PSTN provider waiting for the next digit), and then starts tuning. It has a limited ammount of time for tuning before the PSTN gives up and gives a busy tone. So after a while it hangs up and starts a new cycle. .B fxotune has two operation modes: tune (\-i) and set (\-s). In the tune mode it generates /etc/fxotune.conf, and in the set mode it merely applies the parameters from fxotune.conf to device's ports. .SH OPTIONS The following options below except \-v (verbose) affect only the detection process and hence apply only to the .I detect and .I dump modes. In addition, to maintain compatibility with older versions of fxotune, if in detect or dump mode there is a parameter with option before it, it is considered to be the .I dialstring parameter (\-n). .B \-b .I startdev .RS Start tuning from dahdi channel num. \fI startdev\fR: skip all previous channels. By default starting from channel 1. In dump mode (\-d) this is the single channel that will be tested. .RE .B \-e .I stopdev .RS Tune only up to dahdi channel num. \fI stopdev\fR: skip all previous channels. By default stopping at channel 252. In dump mode (\-d) this parameter is ignored. .RE .B \-l .I delay-to-silence .RS Time in seconds to wait after dialing the dial-string to get a clear line. The default is 0. before .RE .B \-m .I silence-good-for .RS Time in seconds which states how long the PSTN will wait after we dialed the dial-string until it starts giving a busy tone. You can test this by connecting an analog phone to the line and dialing. The default is 18 (18 seconds). .RE .B \-n .I dial-string .RS Digits to dial to the PSTN in order to get it stop its dialtone and waiting for the next digit. The default is "4" (sending just the digit 4). It should work in most cases. Again, this can be tested by connecting a phone to the PSTN line and dialing the dial-string. .RE .B \-t .I detect-type .RS This option allows using the older detection method used by fxotune of Zaptel 1.2. use .B \-t 1 for that older method. whereas .B \-t 2 (the default) uses the current method. This option only applies to detect mode (\-i). .RE .B \-v[vvvv] .RS Sets debugging on. The more v-s, the higher debug level. Note that: \-vv \-v will actually set debug level to 1 instead of 3. .RE .B \-w .I wave-form .RS The default: \-1, for multitone waveform. Alternatively: a frequency of a single tone. This option only applies to dump mode (\-d). .RE .SH EXAMPLES .RS fxotune \-i 9 .RE if you need to dial 9 for an external line. If you always get a line, you can simply use any digit. .RE .B \-s .RS Load settings from the last test. Used at startup. .RE .SH FILES .I /etc/fxotune.conf .RS The configuration file generated by fxotune in detect mode and from which configuration is loaded when .B \-s is used. .SH NOTES Running fxotune takes approximately a minute per port. If you wish to only run fxotune for several ports, you can use the options \-b and \-e to set a specific range of ports. Another useful trick is to actually keep asterisk running, and only "destroy" the dahdi channels you wish to tune (dahdi destroy channel NNN): other channels will be used by Asterisk, and hence skipped. This can be useful if you have many FXO ports that are not connected. .B fxotune writes immediately to .B /etc/fxotune.conf so if you stop it half-way, you may get a half-configured system. If you have already tuned your FXO channels and wish to test-run fxotune again, you are advised to backup /etc/fxotune.conf . The default for \-m is 18 seconds. This asusmes that you get a clear line for at least 18 seconds. It is advised that you test that timeout earlier by connecting a phone to the FXO line, dialing 4 (or whatever dial string you put with \-n) and see how much time of silence you have. If you connect your device to a PSTN provider that is not in the US, there is a similar operation you should apply before even getting to fxotune: setting the opermode. The opermode sets a number of country-specific parameters. For the Digium analog cards this is set through the kernel module parameter 'opermode' . For the Xorcom Astribank this is set through the variable 'opermode' in /etc/dahdi/xpp.conf . For valid values of this parameter, see /usr/share/asterisk/init_fxo_modes (FIXME: this has changed and will change. Tzafrir). .SH SEE ALSO dahdi_cfg(8), dahdi_tool(8), dahdi_monitor(8), asterisk(8). .SH AUTHOR This manual page was written by Tzafrir Cohen Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common\-licenses/GPL. dahdi-tools-2.10.2/doc/dahdi_span_types.80000644000000000000000000001253712537624573016703 0ustar rootroot.TH "DAHDI_SPAN_TYPES" "8" "23 Jan 2014" "" "" .SH NAME dahdi_span_types \- set line modes of DAHDI spans before assignment .SH SYNOPSIS .B dahdi_span_types [\fIoptions\fB] \fB[\fIdevpath \fB...] .SH DESCRIPTION The span type (the line mode: E1/T1/J1) must be set to a span before DAHDI assigns it a span number, as E1 spans use more channels. \fBdahdi_span_types\fR applies the span type configuration to an un-assigned span. Using it only makes sense when the kernel module parameter \fBdahdi.auto_assign_span\fR is unset, otherwise DAHDI automatically assign span numbers during device registration. .B dahdi_span_types takes a command and an optional list of devices. If no device is given, the command is applied to all devices. The device is marked as a path in the SysFS tree. .SH OPTIONS .B \-h|\-\-help .RS Output usage message and exit .RE .B \-n|\-\-dry\-run .RS During \fB"set"\fR operation, only show what would be done, without actually changing anything. .RE .B \-v|\-\-verbose .RS During \fB"set"\fR operation, show the actions that are being performed. .RE .BI \-\-line\-mode= .RS During \fB"dumpconfig"\fR operation, force special generation mode: .IP \(bu 3 First, generates a "wildcard" entry with the fiven \fBline\-mode\fR. .IP \(bu 3 Comment out all span entries. Each of them may be manually un-commented to override the "wildcard". .RE .SH SUB-COMMANDS .B set .RS Reads settings from \fBspan\-types.conf\fR and applies them to the device(s) specified in the command line (or all devices, if none specified). .RE .B list .RS List line modes for all spans in the system which may be set with dahdi_span_types (E1/T1/J1 spans). .RE .B dumpconfig .RS List types for the spans in a format fit to be used in \fBspan\-types.conf\fR. Use this to generate a configuration file after you have (perhaps manually) set all existing spans. .B dahdi_genconf spantypes uses this command internally. .RE .SH CONFIGURATION .SS General structure .B span\-types.conf is a file with lines specifying line modes of spans. Empty lines or lines beginning with '#' are ignored. Each line is in the format of: .I ID spanspec ... The \fIID\fR field specifies the DAHDI device and the \fIspanspecs\fR define the line modes of its spans. A line may have multiple \fIspanspecs\fR in a single line (though dumpconfig generates a configuration with one per line). .SS Span Identifier A DAHDI device may be specified either by a hardware identifier (a software readable serial number or whatever) or the location in which it is installed on the system. The former makes it simpler to change connector / slot whereas the latter makes it simpler to replace a unit. The value in this field is matched (when the command \fBset\fR is used) to the following values: \fIhwid\fR \fB@\fIlocation\fR \fIdevpath\fR See above for their descriptions. The value may include shell wildcards: *, ? and [], which are used in the match. The values to be matched are first cleaned up: '!' is replaced with '/' and any character not in "a\-zA\-Z0\-9/:.\-" is replaced by "_". Note that while span\-types.conf allows an arbitrarily-complex combination of E1, J1 and T1 ports, it would normally have just a single wildcard line setting the line mode (the first line in the example below). .SS Span Specification Each line should have one or more span specifications: this is the value used to set span type with DAHDI in the SysFS interface. A specification has two colon-separated fields: .I rel_span_no:span_type for instance, the following are four span specifications specify ports 1 and 2 as E1 and ports 3 and 4 as T1: [12]:E1 [34]:T1 . .B rel_span_no .RS The relative number of the span in the device. E.g.: port number. This field may contain shell wildcards (*, ? and []) .RE .B span_type .RS E1/T1/J1 .RE .SS Multiple matches During \fBset\fR operation, the \fBdahdi_span_types\fR applies all matching settings to a span. This is done in the order of lines in the configuration files. Thus, if there are multiple matches to a span -- the last match will \fIwin\fR (all will be applied to the kernel in order. The last one in the file will be applied last). Example: .EX * *:T1 # All spans on all devices will be T1 usb:X1234567 [34]:E1 # Except spans 3,4 on the device which will be E1 .EE .SH ENVIRONMENT .B DAHDICONFDIR .RS The directory in which span\-types.conf resides. /etc/dahdi if not overridden from the environment. .RE .B DAHDISPANTYPESCONF .RS The path to span\-types.conf resides. /etc/dahdi/span\-types.conf if not overridden from the environment. .RE .SH FILES .B /etc/dahdi/span\-types.conf .RS The default location for the configuration file. .RE .B /sys/bus/dahdi_devices/devices/\fIdevice\fR .RS SysFS node for the device. In this directory reside the following files, among others: .B spantype .RS read/write file. Reading from it returns current configuration for spans of the device. Span-specifications can be written to it to change line modes (but only for a span that is not assigned yet). .RE .SH SEE ALSO dahdi_span_assignments(8), dahdi_genconf(8), dahdi_cfg(8) .SH AUTHOR dahdi_span_types was written by Oron Peled. This manual page was written by Tzafrir Cohen. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. dahdi-tools-2.10.2/doc/dahdi_diag.80000644000000000000000000000320312537624573015410 0ustar rootroot.TH dahdi_diag 8 "2008-01-07" .SH NAME dahdi_diag \(em Dump DAHDI channel parameters .SH SYNOPSIS .B dahdi_diag .I channel .SH DESCRIPTION .B dahdi_diag asks the kernel to dump parameters for DAHDI channel no. .I channel to the kernel logs. You will be able to see them using, e.g. dmesg(1). .SH OPTIONS .I channel .RS The number of the DAHDI channel whose parammeters should be dumped. May be any DAHDI channel (even if it is open). .RE .SH EXAMPLE # /tmp/dahdi_diag 5 # dmesg | tail \-n 15 Dump of DAHDI Channel 5 (XPP_BRI_TE/00/01/1,5,2): flags: 501 hex, writechunk: c5190948, readchunk: c5190954 rxgain: ccad2e80, txgain: ccad2e80, gainalloc: 0 span: c48a900c, sig: 80 hex, sigcap: 80 hex inreadbuf: \-1, outreadbuf: 0, inwritebuf: 0, outwritebuf: \-1 blocksize: 160, numbufs: 4, txbufpolicy: 0, txbufpolicy: 0 txdisable: 0, rxdisable: 0, iomask: 0 curzone: c78e7000, tonezone: 0, curtone: 00000000, tonep: 0 digitmode: 0, txdialbuf: , dialing: 0, aftdialtimer: 0, cadpos. 0 confna: 0, confn: 0, confmode: 0, confmute: 0 ec: 00000000, echocancel: 0, deflaw: 0, xlaw: ccab5e80 echostate: 00, echotimer: 0, echolastupdate: 0 itimer: 0, otimer: 0, ringdebtimer: 0 .SH SEE ALSO dahdi_cfg(8), asterisk(8), dmesg(1). .SH AUTHOR This manual page was written by Tzafrir Cohen Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common\-licenses/GPL. dahdi-tools-2.10.2/doc/dahdi_tool.80000644000000000000000000000131012537624573015456 0ustar rootroot.TH "DAHDI_TOOL" "8" "16 June 2008" "" "" .SH NAME dahdi_tool \- Shows status of DAHDI interfaces .SH SYNOPSIS .B dahdi_tool .SH DESCRIPTION dahdi_tool shows the current status the DAHDI inteface cards plugged to the computer. It displays values like Current Alarms, SyncSource, Tx/Rx Levels for each DAHDI interface. .SH SEE ALSO dahdi_monitor(8), asterisk (8). .SH AUTHOR This manual page was written by Santiago Ruano Rinc\['o]n for the Debian system (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation. dahdi-tools-2.10.2/dahdi.rules0000644000000000000000000000136012537624573014644 0ustar rootroot ACTION!="add", GOTO="dahdi_add_end" # DAHDI devices with ownership/permissions for running as non-root SUBSYSTEM=="dahdi", OWNER="asterisk", GROUP="asterisk", MODE="0660" # Backward compat names: /dev/dahdi/ SUBSYSTEM=="dahdi_channels", SYMLINK+="dahdi/%m" # Add persistant names as well SUBSYSTEM=="dahdi_channels", ATTRS{hardware_id}!="", SYMLINK+="dahdi/devices/%s{hardware_id}/%s{local_spanno}/%n" SUBSYSTEM=="dahdi_channels", ATTRS{location}!="", SYMLINK+="dahdi/devices/@%s{location}/%s{local_spanno}/%n" LABEL="dahdi_add_end" # hotplug scripts SUBSYSTEM=="dahdi_devices", RUN+="%E{DAHDI_TOOLS_ROOTDIR}/usr/share/dahdi/dahdi_handle_device" SUBSYSTEM=="dahdi_spans", RUN+="%E{DAHDI_TOOLS_ROOTDIR}/usr/share/dahdi/dahdi_span_config" dahdi-tools-2.10.2/wavformat.h0000644000000000000000000000224212537624573014676 0ustar rootroot/* * wavformat.h -- data structures and associated definitions for wav files * * By Michael Spiceland (mspiceland@digium.com) * * (C) 2009 Digium, Inc. */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #ifndef WAVFORMAT_H #define WAVFORMAT_H #include struct wavheader { /* riff type chunk */ char riff_chunk_id[4]; uint32_t riff_chunk_size; char riff_type[4]; /* format chunk */ char fmt_chunk_id[4]; uint32_t fmt_data_size; uint16_t fmt_compression_code; uint16_t fmt_num_channels; uint32_t fmt_sample_rate; uint32_t fmt_avg_bytes_per_sec; uint16_t fmt_block_align; uint16_t fmt_significant_bps; /* data chunk */ char data_chunk_id[4]; uint32_t data_data_size; } __attribute__((packed)); #endif dahdi-tools-2.10.2/makeopts.in0000644000000000000000000000150412537624573014672 0ustar rootrootCC=@CC@ LD=@LD@ HOSTCC=@HOSTCC@ CFLAGS=@CFLAGS@ LDFLAGS=@LDFLAGS@ INSTALL=@INSTALL@ GREP=@GREP@ SHELL=@SHELL@ LN=@LN@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ datarootdir = @datarootdir@ datadir = @datadir@ includedir = @includedir@ infodir = @infodir@ libdir = @libdir@ libexecdir = @libexecdir@ localstatedir = @localstatedir@ mandir = @mandir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ DOWNLOAD=@DOWNLOAD@ DAHDI_DEVMODE=@DAHDI_DEVMODE@ DAHDI_DECLARATION_AFTER_STATEMENT=@DAHDI_DECLARATION_AFTER_STATEMENT@ PBX_NEWT=@PBX_NEWT@ NEWT_LIB=@NEWT_LIB@ NEWT_INCLUDE=@NEWT_INCLUDE@ PBX_USB=@PBX_USB@ USB_LIB=@USB_LIB@ USB_INCLUDE=@USB_INCLUDE@ PBX_HDLC=@PBX_HDLC@ DAHDI_INCLUDE=@DAHDI_INCLUDE@ USE_SELINUX=@USE_SELINUX@ PPPD_VERSION=@PPPD_VERSION@ ASCIIDOC=@ASCIIDOC@ dahdi-tools-2.10.2/hdlcstress.c0000644000000000000000000001551112537624573015044 0ustar rootroot/* * Written by Mark Spencer * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #define FAST_HDLC_NEED_TABLES #include #include "bittest.h" #include "dahdi_tools_version.h" /* #define BLOCK_SIZE 2048 */ #define BLOCK_SIZE 2041 static int hdlcmode = 0; static int bri_delay = 0; static unsigned short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; #define PPP_INITFCS 0xffff /* Initial FCS value */ #define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) void print_packet(unsigned char *buf, int len) { int x; printf("{ "); for (x=0;x 7) outbuf[pos++] = fasthdlc_tx_run(&fs); } fcs ^= 0xffff; if (fasthdlc_tx_load(&fs, (fcs & 0xff))) fprintf(stderr, "Load error (fcs1)\n"); outbuf[pos++] = fasthdlc_tx_run(&fs); if (fs.bits > 7) outbuf[pos++] = fasthdlc_tx_run(&fs); if (fasthdlc_tx_load(&fs, ((fcs >> 8) & 0xff))) fprintf(stderr, "Load error (fcs2)\n"); outbuf[pos++] = fasthdlc_tx_run(&fs); if (fs.bits > 7) outbuf[pos++] = fasthdlc_tx_run(&fs); if (fasthdlc_tx_frame(&fs)) fprintf(stderr, "Frame error\n"); if (fs.bits > 7) outbuf[pos++] = fasthdlc_tx_run(&fs); if (fs.bits > 7) outbuf[pos++] = fasthdlc_tx_run(&fs); write(fd, outbuf, pos); } } int main(int argc, char *argv[]) { int res, ch, x; struct dahdi_params tp; struct dahdi_bufferinfo bi; int bs = BLOCK_SIZE; unsigned char c=0; unsigned char outbuf[BLOCK_SIZE]; while((ch = getopt(argc, argv, "b")) != -1) { switch(ch) { case 'b': bri_delay = 300000; break; case '?': exit(1); } } if (argc - optind != 1) { fprintf(stderr, "Usage: %s [-b] \n", argv[0]); exit(1); } fd = open(argv[optind], O_RDWR, 0600); if (fd < 0) { fprintf(stderr, "Unable to open %s: %s\n", argv[optind], strerror(errno)); exit(1); } if (ioctl(fd, DAHDI_SET_BLOCKSIZE, &bs)) { fprintf(stderr, "Unable to set block size to %d: %s\n", bs, strerror(errno)); exit(1); } if (ioctl(fd, DAHDI_GET_PARAMS, &tp)) { fprintf(stderr, "Unable to get channel parameters\n"); exit(1); } if ((tp.sigtype & DAHDI_SIG_HDLCRAW) == DAHDI_SIG_HDLCRAW) { printf("In HDLC mode\n"); hdlcmode = 1; } else if ((tp.sigtype & DAHDI_SIG_CLEAR) == DAHDI_SIG_CLEAR) { printf("In CLEAR mode\n"); hdlcmode = 0; } else { fprintf(stderr, "Not in a reasonable mode\n"); exit(1); } res = ioctl(fd, DAHDI_GET_BUFINFO, &bi); if (!res) { bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE; bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE; bi.numbufs = 4; res = ioctl(fd, DAHDI_SET_BUFINFO, &bi); if (res < 0) { fprintf(stderr, "Unable to set buf info: %s\n", strerror(errno)); exit(1); } } else { fprintf(stderr, "Unable to get buf info: %s\n", strerror(errno)); exit(1); } ioctl(fd, DAHDI_GETEVENT); fasthdlc_precalc(); fasthdlc_init(&fs, FASTHDLC_MODE_64); #if 0 print_packet(outbuf, res); printf("FCS is %x, PPP_GOODFCS is %x\n", fcs,PPP_GOODFCS); #endif for(;;) { if (c < 1) c = 1; for (x=0;x<50;x++) { outbuf[x] = c; } send_packet(outbuf, 50); #if 0 printf("Wrote %d of %d bytes\n", res, c); #endif /* The HFC chip can't be bombarded too much. If a write has failed, let it recover */ if (bri_delay) usleep(bri_delay); c = bit_next(c); #if 0 printf("(%d) Wrote %d bytes\n", packets++, res); #endif } } dahdi-tools-2.10.2/hdlcgen.c0000644000000000000000000000674412537624573014302 0ustar rootroot/* * Written by Mark Spencer * Based on previous works, designs, and architectures conceived and * written by Jim Dixon . * * Copyright (C) 2001 Jim Dixon / Zapata Telephony. * Copyright (C) 2001-2008 Digium, Inc. * * All rights reserved. * * Primary Author: Mark Spencer * Radio Support by Jim Dixon */ /* * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2 as published by the * Free Software Foundation. See the LICENSE file included with * this program for more details. */ #include #include #include #include #include #include #define FAST_HDLC_NEED_TABLES #include #include "dahdi_tools_version.h" #define RANDOM "/dev/urandom" /* Not genuinely random */ /* #define RANDOM "/dev/random" */ /* Quite genuinely random */ int myread(int fd, char *buf, int len) { int sofar; int res; sofar = 0; while(sofar < len) { res = read(fd, buf + sofar, len - sofar); if (res < 0) return res; sofar += res; } return sofar; } int main(int argc, char *argv[]) { unsigned char buf[1024]; unsigned char outbuf[2048]; int res; int randin; int randout; int hdlcout; int cnt; int hdlccnt; int x; int flags; struct fasthdlc_state transmitter; fasthdlc_precalc(); fasthdlc_init(&transmitter, FASTHDLC_MODE_64); randin = open(RANDOM, O_RDONLY); if (randin < 0) { fprintf(stderr, "Unable to open %s: %s\n", RANDOM, strerror(errno)); exit(1); } randout = open("random.raw", O_WRONLY|O_TRUNC|O_CREAT, 0666); if (randout < 0) { fprintf(stderr, "Unable to open random.raw: %s\n", strerror(errno)); exit(1); } hdlcout = open("random.hdlc", O_WRONLY|O_TRUNC|O_CREAT, 0666); if (hdlcout < 0) { fprintf(stderr, "Unable to open random.hdlc: %s\n", strerror(errno)); exit(1); } for (;;) { cnt = (rand() % 256) + 4; /* Read a pseudo-random amount of stuff */ res = myread(randin, buf, cnt); if (res != cnt) { fprintf(stderr, "Tried to read %d bytes, but read %d instead\n", cnt, res); exit(1); } res = write(randout, buf, cnt); if (res != cnt) { fprintf(stderr, "Tried to write %d bytes, but wrote %d instead\n", cnt, res); exit(1); } /* HDLC encode */ hdlccnt = 0; /* Start with a flag */ fasthdlc_tx_frame(&transmitter); if (transmitter.bits >= 8) outbuf[hdlccnt++] = fasthdlc_tx_run(&transmitter); for (x=0;x= 8) { outbuf[hdlccnt++] = fasthdlc_tx_run(&transmitter); } } flags = (rand() % 4); for (x=0;x 1) printf("Encoded %d byte message with %d bytes of HDLC and %d extra flags\n", cnt, hdlccnt, flags); res = write(hdlcout, outbuf, hdlccnt); if (res != hdlccnt) { fprintf(stderr, "Tried to write %d HDLC bytes, but wrote %d instead\n", cnt, res); exit(1); } } } dahdi-tools-2.10.2/xpp/0000755000000000000000000000000012537624573013326 5ustar rootrootdahdi-tools-2.10.2/xpp/mpptalk_defs.h0000644000000000000000000000716612537624573016162 0ustar rootroot#ifndef MPPTALK_DEFS_H #define MPPTALK_DEFS_H /* * Written by Oron Peled * Copyright (C) 2008,2009,2010 Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include /* * MPP - Managment Processor Protocol definitions */ /* * OP Codes: * MSB of op signifies a reply from device */ #define MPP_RENUM 0x0B /* Trigger USB renumeration */ #define MPP_EEPROM_SET 0x0D /* AB capabilities */ #define MPP_CAPS_GET 0x0E #define MPP_CAPS_GET_REPLY 0x8E #define MPP_CAPS_SET 0x0F #define MPP_DEV_SEND_START 0x05 #define MPP_DEV_SEND_SEG 0x07 #define MPP_DEV_SEND_END 0x09 /* Astribank Status */ #define MPP_STATUS_GET 0x11 #define MPP_STATUS_GET_REPLY 0x91 #define MPP_STATUS_GET_REPLY_V13 0x91 /* backward compat */ /* Get extra vendor information */ #define MPP_EXTRAINFO_GET 0x13 #define MPP_EXTRAINFO_GET_REPLY 0x93 #define MPP_EXTRAINFO_SET 0x15 /* Set extra vendor information */ #define MPP_EEPROM_BLK_RD 0x27 #define MPP_EEPROM_BLK_RD_REPLY 0xA7 #define MPP_SER_SEND 0x37 #define MPP_SER_RECV 0xB7 #define MPP_RESET 0x45 /* Reset both FPGA and USB firmwares */ #define MPP_HALF_RESET 0x47 /* Reset only FPGA firmware */ /* Twinstar */ #define MPP_TWS_WD_MODE_SET 0x31 /* Set watchdog off/on guard */ #define MPP_TWS_WD_MODE_GET 0x32 /* Current watchdog mode */ #define MPP_TWS_WD_MODE_GET_REPLY 0xB2 /* Current watchdog mode */ #define MPP_TWS_PORT_SET 0x34 /* USB-[0/1] */ #define MPP_TWS_PORT_GET 0x35 /* USB-[0/1] */ #define MPP_TWS_PORT_GET_REPLY 0xB5 /* USB-[0/1] */ #define MPP_TWS_PWR_GET 0x36 /* Power: bits -> USB ports */ #define MPP_TWS_PWR_GET_REPLY 0xB6 /* Power: bits -> USB ports */ /* * Statuses */ #define STAT_OK 0x00 /* acknowledges previous command */ #define STAT_FAIL 0x01 /* Last command failed */ #define STAT_RESET_FAIL 0x02 /* reset failed */ #define STAT_NODEST 0x03 /* No destination is selected */ #define STAT_MISMATCH 0x04 /* Data mismatch */ #define STAT_NOACCESS 0x05 /* No access */ #define STAT_BAD_CMD 0x06 /* Bad command */ #define STAT_TOO_SHORT 0x07 /* Packet is too short */ #define STAT_ERROFFS 0x08 /* Offset error */ #define STAT_NOCODE 0x09 /* Source was not burned before */ #define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */ #define STAT_NO_EEPROM 0x0B /* No EEPROM was found */ #define STAT_WRITE_FAIL 0x0C /* Writing to device failed */ #define STAT_FPGA_ERR 0x0D /* FPGA error */ #define STAT_KEY_ERR 0x0E /* Bad Capabilities Key */ #define STAT_NOCAPS_ERR 0x0F /* No matching capability */ #define STAT_NOPWR_ERR 0x10 /* No power on USB connector */ #define STAT_CAPS_FPGA_ERR 0x11 /* Setting of the capabilities while FPGA is loaded */ /* EEPROM_QUERY: i2cs(ID1, ID0) */ enum eeprom_type { EEPROM_TYPE_NONE = 0, EEPROM_TYPE_SMALL = 1, EEPROM_TYPE_LARGE = 2, EEPROM_TYPE_UNUSED = 3, }; enum dev_dest { DEST_NONE = 0x00, DEST_FPGA = 0x01, DEST_EEPROM = 0x02, }; #define EXTRAINFO_SIZE 24 #endif /* MPPTALK_DEFS_H */ dahdi-tools-2.10.2/xpp/dahdi_registration0000755000000000000000000001632612537624573017127 0ustar rootroot#! /usr/bin/perl -w # # Written by Oron Peled # Copyright (C) 2007, Xorcom # This program is free software; you can redistribute and/or # modify it under the same terms as Perl itself. # # $Id$ # use strict; use File::Basename; BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } use Dahdi; use Dahdi::Span; use Dahdi::Xpp; use Dahdi::Xpp::Xbus; use Dahdi::Xpp::Xpd; use Getopt::Std; sub usage { die "Usage: $0 [-v] [-R] [-s sort_order] [on|off|1|0]\n"; } sub check_param { my $param = shift || die; open(F, $param) || return ''; my $val = ; close F; chomp $val; return $val; } my %opts; getopts('vRs:', \%opts) || usage; my $dahdi_autoreg = check_param('/sys/module/xpp/parameters/dahdi_autoreg') eq 'Y'; my $auto_assign_spans = check_param('/sys/module/dahdi/parameters/auto_assign_spans') ne '0'; my $assigned_spans_config = $ENV{'ASSIGNED_SPANS_CONF_FILE'} || '/etc/dahdi/assigned-spans.conf'; my $span_types_config = $ENV{'SPAN_TYPES_CONF_FILE'} || '/etc/dahdi/span-types.conf'; my $have_assigned_spans_config = -f $assigned_spans_config || 0; my $have_span_types_config = -f $span_types_config || 0; # Spans will be auto-assigned by default if either: # - Driver $auto_assign_spans them or # - Udev script see that we $have_span_types_config and it "add" them my $default_auto_assign = $auto_assign_spans || $have_assigned_spans_config; my $sorter; my $sort_order = $opts{'s'}; if(defined $sort_order) { my $sorter = Dahdi::Xpp::sorters($sort_order); if(!defined $sorter) { my @sorter_names = Dahdi::Xpp::sorters; print STDERR "Unknown sort order $sort_order. Select from:\n\t"; print STDERR join("\n\t", @sorter_names); print STDERR "\n"; exit 1; } } @ARGV == 0 or @ARGV == 1 or usage; my $on = shift; my $verbose = $opts{'v'}; my $should_output = 1; #print "dahdi_autoreg=$dahdi_autoreg auto_assign_spans=$auto_assign_spans have_assigned_spans_config='$have_assigned_spans_config' have_span_types_config='$have_span_types_config'\n"; if(defined($on)) { # Translate to booleans $on = uc($on); $on =~ /^(ON|OFF|1|0)$/ or usage; $on = ($on eq 'ON') ? 1 : 0; $should_output = 0 unless $verbose; } sub state2str($) { return (shift)?"on":"off"; } sub myprintf { printf @_ if $should_output; } foreach my $xbus (Dahdi::Xpp::xbuses($sorter)) { my $prev = $xbus->dahdi_registration($on); if(!defined($prev)) { # Failure printf STDERR "%s: Failed %s\n", $xbus->name, $!; next; } my $reg_str; if (defined $on) { $reg_str = ($on) ? "registering" : "unregistering"; } else { $reg_str = ($prev) ? "registered" : "unregistered"; } myprintf "%-10s\t%3s-%s\t%s (%s)\n", $xbus->name, $xbus->xpporder, $xbus->label, $xbus->connector, $reg_str; next unless $xbus->status eq 'CONNECTED'; # Only assign if no default assignment, or forced by '-R' option if (defined($on) && $on) { if ($opts{'R'} || ! $default_auto_assign) { # Emulate /etc/dahdi/assigned-spans.conf: # - We iterate over $xbus according to /etc/dahdi/xpp_order # - We "auto" assign all spans of current $xbus my $devpath = sprintf "/sys/bus/dahdi_devices/devices/astribanks:xbus-%02d", $xbus->num; my @cmd = ('dahdi_span_assignments', 'auto', $devpath); system @cmd; warn "Failed '@cmd' (status=$?)\n" if $?; } # wait for UDEV to do its stuff system "dahdi_waitfor_span_assignments assigned"; } foreach my $xpd (Dahdi::Xpp::Xpd::telephony_devs($xbus->xpds())) { my $spanno = $xpd->xpd_getattr('span'); myprintf "\t%-10s: ", $xpd->fqn; my $spanstr = ($spanno) ? ("Span " . $spanno) : "unassigned"; myprintf "%s\n", $spanstr ; } } myprintf "# Sorted: $sort_order\n" if defined $sort_order; __END__ =head1 NAME dahdi_registration - Handle registration of Xorcom XPD modules in dahdi. =head1 SYNOPSIS dahdi_registration [-v] [-s sortorder] [-R] [on|off] =head1 DESCRIPTION Without parameters, show all connected XPDs sorted by physical connector order. Each one is show to be unregistered (off), or registered to a specific dahdi span (the span number is shown). All registerations/deregisterations are sorted by physical connector string. Span registration should generally always succeed. Span unregistration may fail if channels from the span are in use by e.g. asterisk. In such a case you'll also see those channels as '(In use)' in the output of lsdahdi(8). dahdi_registration is intended to be used when the kernel module parameter B is false (and implicitly: when the module parameter B is true). See also the NOTES section regarding C. If dahdi_autoreg is true, the program will normally do nothing. =head2 Parameters off -- deregisters all XPD's from dahdi. on -- registers all XPD's to dahdi. =head2 Options =over =item -v verbose output. =item -R Force operations (on/off) even if the module parameter B for xpp is enabled (which makes this program unneeded). =item -s I The sort order to use. =back If the option is not used, the sort order is taken from the environment variable XBUS_SORT and failing that: the hard-coded default of SORT_XPPORDER. The available sorting orders are documented in Dahdi::Xpp manual. =head2 Sample Output An example of the output of dahdi_registration for some registered Astribanks: $ dahdi_registration -s type XBUS-01 usb:0000153 usb-0000:00:10.4-2 XBUS-01/XPD-00: on Span 1 XBUS-01/XPD-01: on Span 2 XBUS-00 usb:0000157 usb-0000:00:10.4-4 XBUS-00/XPD-00: on Span 3 XBUS-00/XPD-01: on Span 4 XBUS-00/XPD-02: on Span 5 XBUS-00/XPD-03: on Span 6 XBUS-00/XPD-04: on Span 7 XBUS-00/XPD-05: on Span 8 XBUS-00/XPD-06: on Span 9 XBUS-00/XPD-07: on Span 10 XBUS-02 usb-0000:00:10.4-1 XBUS-02/XPD-00: on Span 11 XBUS-02/XPD-10: on Span 12 # Sorted: type =head1 FILES =over =item /proc/xpp/XBUS-nn/XPD-mm/dahdi_registration Reading from this file shows if if the if the specific XPD is registered. Writing to it 0 or 1 registers / unregisters the device. This should allow you to register / unregister a specific XPD rather than all of them. =back =head1 NOTES dahdi_registration is intended to be used when the kernel module parameter B is false (and implicitly: when the module parameter B is true), that is, Astribank devices as detected by XPP (xbus / xpd) do not register automatically with the DAHDI core. This tool is used to register tem in an explicit order. It works well, but only if you can arange for all of the Astribanks of the system to be available (and not already registered) at a specific point in time. Newer versions of DAHDI added support for registering a span to a specific span/channelss numbers specification. This allows registering them out of order. To use this capability, the module parameter B should be unset (set to 0) and thus spans of detected DAHDI devices could be registered using C (which may also be run automatically from a udev hook). In this case there is no point in delaying XPP device registration with dahdi and the parameter B should be set. dahdi_registration will simply become a no-op. =head1 SEE ALSO B(8), B(8). dahdi-tools-2.10.2/xpp/twinstar_setup0000755000000000000000000000721612537624573016355 0ustar rootroot#! /usr/bin/perl -w # # Written by Oron Peled # Copyright (C) 2009, Xorcom # This program is free software; you can redistribute and/or # modify it under the same terms as Perl itself. # # $Id$ # use strict; use File::Basename; BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); $ENV{PATH} = "$dir:$ENV{PATH}"; } use Dahdi::Config::Gen qw(is_true); use Dahdi::Hardware; use Dahdi::Xpp::Mpp; use Dahdi::Xpp::Xbus; my $xpporder_file = $ENV{XPPORDER_CONF} || "/etc/dahdi/xpp_order"; my @devices = Dahdi::Hardware->device_list; my @xbuses = Dahdi::Xpp::xbuses; my $format = "%-20s %-10s # %s\n"; sub bad_xpds($) { my $xbus = shift || die; my $bad_xpds = 0; foreach my $xpd ($xbus->xpds) { if(! $xpd->spanno) { my $fqn = $xpd->fqn; warn "\t$fqn -- Not registered with DAHDI\n"; $bad_xpds++; } } return $bad_xpds; } sub twinstar_checks() { my @twinstar_good; my $first_port; if(! -d "/sys/bus/astribanks") { die "CANNOT generate TwinStar setup -- xpp drivers are not loaded\n"; } foreach my $dev (@devices) { my $hwname = $dev->hardware_name; my $xbus; my $loaded; my $tws_port; my $tws_power; my $tws_watchdog; my $mppinfo; if(! $dev->is_astribank) { warn "SKIP $hwname -- Only Astribanks can be used for TwinStar\n"; next; } Dahdi::Xpp::Mpp->mpp_addinfo($dev); $mppinfo = $dev->mppinfo; if(! defined $mppinfo) { warn "SKIP $hwname -- is not TwinStar ready\n"; next; } if(! defined $mppinfo->{MPP_TALK}) { warn "SKIP $hwname -- USB firmware is not loaded\n"; next; } if(! $mppinfo->{TWINSTAR_CAPABLE}) { warn "SKIP $hwname -- is not TwinStar capable\n"; next; } $xbus = $dev->xbus; if(! defined $xbus) { warn "SKIP $hwname -- No XBUS for this device (FPGA firmware? Initialization?)\n"; next; } my $dev = $xbus->transport; my $connector = $xbus->connector; my $label = $xbus->label; my $xbusstr = sprintf "%s (%s) [%s]", $xbus->name, $connector, $label; if(bad_xpds($xbus)) { warn "SKIP $xbusstr -- Not registered with DAHDI\n"; next; } my $port = $mppinfo->{TWINSTAR_PORT}; if(! defined $port) { warn "SKIP $xbusstr -- Cannot read USB port info\n"; next; } my $power = $mppinfo->{TWINSTAR_POWER}; if(! defined $power) { warn "SKIP $xbusstr -- Cannot read USB power info\n"; next; } if(!$power->[0] || !$power->[1]) { warn "WARNING: Only one cable: $xbusstr\n"; } $first_port = $port unless defined $first_port; printf "GOOD: %-15s port=%d %s\n", $label, $port, $connector; push(@twinstar_good, $xbus); if($first_port != $port) { die "$0: ", "XBUS($connector, $label) ", "connected to PORT $port ", "(others to $first_port)\n"; } } return @twinstar_good; } my @twinstar_good = twinstar_checks; if(!@twinstar_good) { print STDERR "Abort. No Twinstar capable Astribanks found\n"; exit 1; } print "Generating Configuration\n"; system("dahdi_genconf -v xpporder"); die "Failed: $?\n" if $?; 1; __END__ =head1 NAME twinstar_setup - Prepares a server for Astribank TwinStar operation. =head1 DESCRIPTION This script prepares a server for Astribank TwinStar operation. The stages are: =over =item Preliminary checks Check that we have only TwinStar capable Astribanks, that the drivers are already loaded. =item Configuration Generation Indirectly generate the F file that describes the current configuration. This is done by running C This configuration file is used by twinstar_hook(8) to know when all Astribanks has reconnected to the backup server. =item Deployment to Backup Server Not implemented yet. Should be done manualy. =back dahdi-tools-2.10.2/xpp/pic_loader.c0000644000000000000000000001674212537624573015605 0ustar rootroot/* * Written by Oron Peled * Copyright (C) 2008, Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include "hexfile.h" #include "pic_loader.h" #include #include #define DBG_MASK 0x03 #define MAX_HEX_LINES 10000 #define TIMEOUT 500 enum xpp_packet_types { PIC_REQ_XOP = 0x09, PIC_REP_XOP = 0x0A }; struct xpp_packet_header { struct { uint16_t len; uint8_t op; uint8_t unit; } PACKED header; union { struct { struct { uint8_t flags; uint8_t card_type; uint16_t offs; } pic_header; uint8_t data[3]; } PACKED pic_packet; } d; } PACKED; int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic_command pcmd, int offs, uint8_t *data, int data_len) { int recv_answer = 0; char buf[PACKET_SIZE]; struct xpp_packet_header *phead = (struct xpp_packet_header *)buf; int pack_len; int ret; assert(astribank != NULL); pack_len = data_len + sizeof(phead->header) + sizeof(phead->d.pic_packet.pic_header); phead->header.len = pack_len; phead->header.op = PIC_REQ_XOP; phead->header.unit = 0x00; phead->d.pic_packet.pic_header.flags = pcmd; phead->d.pic_packet.pic_header.card_type = card_type; phead->d.pic_packet.pic_header.offs = offs; if(data) memcpy(phead->d.pic_packet.data, data, data_len); switch (pcmd) { case PIC_START_FLAG: break; case PIC_DATA_FLAG: break; case PIC_END_FLAG: recv_answer = 1; break; case PIC_ENDS_FLAG: break; } DBG("PICLINE: pack_len=%d pcmd=%d\n", pack_len, pcmd); dump_packet(LOG_DEBUG, DBG_MASK, "dump:picline[W]", (char *)phead, pack_len); ret = xusb_send(astribank->xusb, buf, pack_len, TIMEOUT); if(ret < 0) { ERR("xusb_send failed: %d\n", ret); return ret; } DBG("xusb_send: Written %d bytes\n", ret); if (recv_answer) { ret = xusb_recv(astribank->xusb, buf, sizeof(buf), TIMEOUT); if(ret <= 0) { ERR("No USB packs to read\n"); return ret; } else { phead = (struct xpp_packet_header *)buf; if(phead->header.op != PIC_REP_XOP) { ERR("Got unexpected reply OP=0x%02X\n", phead->header.op); dump_packet(LOG_ERR, DBG_MASK, "hexline[ERR]", buf, ret); return -EINVAL; } DBG("received OP=0x%02X, checksum=%02X\n", phead->header.op, phead->d.pic_packet.data[0]); if(phead->d.pic_packet.data[0] != 0) { ERR("PIC burning, bad checksum\n"); return -EINVAL; } } } return 0; } static const char *pic_basename(const char *fname, uint8_t *card_type) { const char *basename; regex_t regex; char ebuf[BUFSIZ]; const char re[] = "PIC_TYPE_([0-9]+)\\.hex"; regmatch_t pmatch[2]; /* One for the whole match, one for the number */ int nmatch = (sizeof(pmatch)/sizeof(pmatch[0])); int len; int ret; basename = strrchr(fname, '/'); if(!basename) basename = fname; if((ret = regcomp(®ex, re, REG_ICASE | REG_EXTENDED)) != 0) { regerror(ret, ®ex, ebuf, sizeof(ebuf)); ERR("regcomp: %s\n", ebuf); return NULL; } if((ret = regexec(®ex, basename, nmatch, pmatch, 0)) != 0) { regerror(ret, ®ex, ebuf, sizeof(ebuf)); ERR("regexec: %s\n", ebuf); regfree(®ex); return NULL; } /* * Should have both complete match and a parentheses match */ if(pmatch[0].rm_so == -1 || pmatch[1].rm_so == -1) { ERR("pic_basename: Bad match: pmatch[0].rm_so=%d pmatch[1].rm_so=%d\n", pmatch[0].rm_so, pmatch[1].rm_so == -1); regfree(®ex); return NULL; } len = pmatch[1].rm_eo - pmatch[1].rm_so; if(len >= sizeof(ebuf) - 1) len = sizeof(ebuf) - 1; memcpy(ebuf, basename + pmatch[1].rm_so, len); ebuf[len] = '\0'; DBG("match: %s\n", ebuf); ret = atoi(ebuf); if(ret <= 0 || ret > 9) { ERR("pic_basename: Bad type number %d\n", ret); regfree(®ex); return NULL; } *card_type = ret; regfree(®ex); return basename; } /* * Returns: true on success, false on failure */ static int pic_burn(struct astribank_device *astribank, const struct hexdata *hexdata) { const char *v = hexdata->version_info; const char *basename; uint8_t *data; unsigned char check_sum = 0; uint8_t card_type; int ret; unsigned int i; const char *devstr; v = (v[0]) ? v : "Unknown"; assert(astribank != NULL); assert(hexdata != NULL); devstr = xusb_devpath(astribank->xusb); if(!astribank->is_usb2) { ERR("%s: Skip PIC burning (not USB2)\n", devstr); return 0; } INFO("%s [%s]: Loading PIC Firmware: %s (version %s)\n", devstr, xusb_serial(astribank->xusb), hexdata->fname, hexdata->version_info); basename = pic_basename(hexdata->fname, &card_type); if(!basename) { ERR("%s: Bad PIC filename '%s'. Abort.\n", devstr, hexdata->fname); return 0; } DBG("basename=%s card_type=%d maxlines=%d\n", basename, card_type, hexdata->maxlines); /* * Try to read extra left-overs from USB controller */ for(i = 2; i; i--) { char buf[PACKET_SIZE]; if(xusb_recv(astribank->xusb, buf, sizeof(buf), 1) <= 0) break; } if((ret = send_picline(astribank, card_type, PIC_START_FLAG, 0, NULL, 0)) != 0) { perror("Failed sending start hexline"); return 0; } for(i = 0; i < hexdata->maxlines; i++) { struct hexline *hexline; unsigned int len; hexline = hexdata->lines[i]; if(!hexline) { ERR("%s: hexdata finished early (line %d)", devstr, i); return 0; } if(hexline->d.content.header.tt == TT_DATA) { len = hexline->d.content.header.ll; /* don't send checksum */ if(len != 3) { ERR("%s: Bad line len %d\n", devstr, len); return 0; } data = hexline->d.content.tt_data.data; check_sum ^= data[0] ^ data[1] ^ data[2]; ret = send_picline(astribank, card_type, PIC_DATA_FLAG, hexline->d.content.header.offset, data, len); if(ret) { perror("Failed sending data hexline"); return 0; } } else if(hexline->d.content.header.tt == TT_EOF) { break; } else { ERR("%s: Unexpected TT = %d in line %d\n", devstr, hexline->d.content.header.tt, i); return 0; } } if((ret = send_picline(astribank, card_type, PIC_END_FLAG, 0, &check_sum, 1)) != 0) { perror("Failed sending end hexline"); return 0; } DBG("Finished...\n"); return 1; } int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]) { int i; const char *devstr; devstr = xusb_devpath(astribank->xusb); DBG("%s: Loading %d PIC files...\n", devstr, numfiles); for(i = 0; i < numfiles; i++) { struct hexdata *picdata; const char *curr = filelist[i]; DBG("%s\n", curr); if((picdata = parse_hexfile(curr, MAX_HEX_LINES)) == NULL) { perror(curr); return -errno; } if(!pic_burn(astribank, picdata)) { ERR("%s: PIC %s burning failed\n", devstr, curr); return -ENODEV; } free_hexdata(picdata); } if((i = send_picline(astribank, 0, PIC_ENDS_FLAG, 0, NULL, 0)) != 0) { ERR("%s: PIC end burning failed\n", devstr); return -ENODEV; } return 0; } dahdi-tools-2.10.2/xpp/astribank_hook0000755000000000000000000001400012537624573016245 0ustar rootroot#! /bin/sh me=`basename $0` dir=`dirname $0` LOGGER="logger -i -t '$me'" # Always redirect stderr somewhere, otherwise the shell script will die # when it tries to do I/O related stuff on closed file descriptor. # Our default is to throw it down the bit-bucket. #exec 2> /dev/console ## If you wish to trace this script: #exec 2> "/tmp/${me}_$XBUS_NAME" 1>&2 # Our directory in the beginning, so we can use local lab setup PATH="$dir:/usr/sbin:/sbin:/usr/bin:/bin" set -e LOCK="/var/lock/twinstar_startup" [ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf # For lab testing liveconf="$dir/liveconf/dahdi" if [ -d "$liveconf" ]; then dahdi_conf="$liveconf" else dahdi_conf="/etc/dahdi" fi if [ "$XPP_HOTPLUG_DAHDI" != yes ]; then exit 0 fi export XPPORDER_CONF="$dahdi_conf/xpp_order" export DAHDI_CFG_CMD="dahdi_cfg -c $dahdi_conf/system.conf" export CALLED_FROM_ATRIBANK_HOOK=yes can_full_async() { # Can we work aynchronously: # - Need modern Asterisk that accept hotplug DAHDI devices. # - Need DAHDI with "auto_assign_spans" == 0 if [ "$ASTERISK_SUPPORTS_DAHDI_HOTPLUG" = yes ]; then aas_param='/sys/module/dahdi/parameters/auto_assign_spans' aas=`cat "$aas_param" 2>/dev/null` if [ "$aas" = 0 ]; then return 0 else $LOGGER "No async operation ($aas_param != 0)" fi else $LOGGER "No async operation (ASTERISK_SUPPORTS_DAHDI_HOTPLUG!=yes)" fi return 1 } check_xpporder_conf() { if [ ! -r "$XPPORDER_CONF" ]; then ( echo "Skip($ACTION): No '$XPPORDER_CONF'" echo "Removing uneeded startup semaphore" astribank_is_starting -v -r 2>&1 ) 2>&1 | $LOGGER exit 0 fi } clean_lines() { sed -e 's/#.*//' -e 'y/\t/ /' -e 's/^ *//' -e 's/ *$//' -e '$s/$/\n/' "$XPPORDER_CONF" } matched_devices() { ready=`grep -H READY /sys/bus/astribanks/devices/*/xbus_state | sed 's,/xbus_state.*,,'` for dev in $ready do label=`cat "$dev/label"` connector=`cat "$dev/connector"` xbus=`echo "$dev" | sed 's,.*/,,'` lineno=`clean_lines | egrep -n "^${label}$|^@${connector}$" | cut -d: -f1` if [ "$lineno" != "" ]; then #echo "$xbus: $XPPORDER_CONF:$lineno -- Match ${label} @${connector}" | $LOGGER printf "${xbus}\t${label}\n" else echo "${xbus}: ${label} @${connector} not found in $XPPORDER_CONF: Ignore($ACTION)" | $LOGGER fi done } # Wait until udev finished processing our requests # so we know the device files were actually created # before trying dahdi_cfg et-al. wait_for_udev() { UDEV_SETTLE_MAX_TIME=10 echo "Waiting for udev to settle down..." if [ -x /sbin/udevsettle ]; then # Old system, stand-alone udevsettle command /sbin/udevsettle --timeout="$UDEV_SETTLE_MAX_TIME" elif [ -x /sbin/udevadm ]; then # Assume modern system, udevadm has settle parameter if ! /sbin/udevadm settle --timeout="$UDEV_SETTLE_MAX_TIME" then echo "udevadm failed ($?)." echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds." sleep "$UDEV_SETTLE_MAX_TIME" fi else echo "No udevsettle/udevadm." echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds." sleep "$UDEV_SETTLE_MAX_TIME" fi sleep 1 # Wait a bit more (races) } start_dahdi() { wait_for_udev script=/etc/init.d/dahdi echo "Starting $script." "$script" start | logger -i -t "$script" status=$? echo "Status($script): $status" if [ -x "$dir/twinstar_hook" ]; then "$dir/twinstar_hook" fi # Finished astribanks echo "Removing semaphore" astribank_is_starting -v -r rm -f "$LOCK" } old_synchronous_start() { NUM_GOOD=`matched_devices | wc -l` NUM_WANTED=`clean_lines | sed '/^$/d' | wc -l` echo "$ACTION($XBUS_NAME): $NUM_GOOD/$NUM_WANTED from $XPPORDER_CONF" | $LOGGER if [ "$NUM_GOOD" -eq "$NUM_WANTED" ]; then ( # Delay the initialization of the Astribank until the filesystem # is mounted read-write: test_file="/var/lock/astribank_test_file" for i in `seq 1 20`; do if touch $test_file 2> /dev/null; then rm -f $test_file break else echo "$0: [$i] - Failed writing '$test_file'...waiting" | $LOGGER sleep 1; fi done if ln -s "$XBUS_NAME" "$LOCK"; then echo "START-DAHDI: Total $NUM_GOOD online." | $LOGGER # Fork services start_dahdi < /dev/null 2>&1 | $LOGGER else echo "$0: Was started: $(ls -l $LOCK)" | $LOGGER fi ) < /dev/null 2>&1 | $LOGGER & fi } old_synchronous_stop() { NUM_GOOD=`matched_devices | wc -l` NUM_WANTED=`clean_lines | sed '/^$/d' | wc -l` echo "$ACTION($XBUS_NAME): $NUM_GOOD/$NUM_WANTED from $XPPORDER_CONF" | $LOGGER if [ "$NUM_GOOD" -eq 0 ]; then echo "All Astribanks offline" | $LOGGER if [ -x "$dir/twinstar_hook" ]; then "$dir/twinstar_hook" || : fi rm -f "$LOCK" fi } ab_list() { find /sys/devices -name idVendor 2>/dev/null | \ xargs grep -H 'e4e4' 2>/dev/null | \ sed -e 's/idVendor.*/idProduct/' | xargs grep -H '11[3456]' | \ sed 's,/[^/]*$,,' || : } tws_watchdog_enable() { devdir="/sys$DEVPATH" label=`cat "$devdir/label"` connector=`cat "$devdir/connector"` xbus=`echo "$devdir" | sed 's,.*/,,'` prefix="${xbus}: [${label}] @${connector}" TWS_NOAUTOJUMPFILE="$TWS_DIR/twinstar_no_autojump" if [ -e "$TWS_NOAUTOJUMPFILE" ]; then $LOGGER "$prefix: ignore wd (found $TWS_NOAUTOJUMPFILE)" else # Re-arm Astribank watchdog transportdir="$devdir/transport" busnum=`cat "$transportdir/busnum" 2>/dev/null || :` devnum=`cat "$transportdir/devnum" 2>/dev/null || :` devaddr=`printf "%03d/%03d" "$busnum" "$devnum"` $LOGGER "$prefix: enabling twinstar watchdog" astribank_tool -D "$devaddr" -w 1 2>&1 | $LOGGER fi } #echo "$0: $ACTION($XBUS_NAME)" | $LOGGER case "$ACTION" in add) ;; remove) ab=`ab_list | wc -l` if [ "$ab" -eq 0 ]; then $LOGGER "$prefix: No more Astribanks -- remove astribank_is_starting semaphore" astribank_is_starting -v -r 2>&1 | $LOGGER fi ;; online) if can_full_async; then tws_watchdog_enable else old_synchronous_start fi ;; offline) if can_full_async; then : # Nothing to do else old_synchronous_stop fi ;; *) echo "$0: Unknown ACTION='$ACTION'" | $LOGGER echo "$0: ARGS='$*'" | $LOGGER echo "$0: ENV:" | $LOGGER env | $LOGGER exit 1 esac dahdi-tools-2.10.2/xpp/test_parse.c0000644000000000000000000000275012537624573015647 0ustar rootroot/* * Written by Oron Peled * Copyright (C) 2006, 2007, 2008, 2009 Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include "hexfile.h" static void default_report_func(int level, const char *msg, ...) { va_list ap; va_start(ap, msg); vfprintf(stderr, msg, ap); va_end(ap); } int main(int argc, char *argv[]) { struct hexdata *hd; int i; if(argc < 2) { fprintf(stderr, "Usage: program hexfile...\n"); return 1; } parse_hexfile_set_reporting(default_report_func); for(i = 1; i < argc; i++) { hd = parse_hexfile(argv[i], 2000); if(!hd) { fprintf(stderr, "Parsing failed\n"); return 1; } fprintf(stderr, "=== %s === (version: %s)\n", argv[i], hd->version_info); dump_hexfile2(hd, "-", 60 ); free_hexdata(hd); } return 0; } dahdi-tools-2.10.2/xpp/xtalk/0000755000000000000000000000000012537624573014451 5ustar rootrootdahdi-tools-2.10.2/xpp/xtalk/xusb.h0000644000000000000000000000575212537624573015614 0ustar rootroot#ifndef XUSB_H #define XUSB_H /* * Written by Oron Peled * Copyright (C) 2008, Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* * Xorcom usb handling */ #define PACKET_SIZE 512 /* * Specify the wanted interface */ struct xusb_spec { /* Sanity checks so we know it is our device indeed */ int num_interfaces; int num_endpoints; char *name; /* For debug/output purpose */ /* What we will actually use */ uint16_t my_vendor_id; uint16_t my_product_id; int my_interface_num; int my_ep_out; int my_ep_in; }; void xusb_init_spec(struct xusb_spec *xusb_spec, char *name, uint16_t vendor_id, uint16_t product_id, int nifaces, int iface, int nep, int ep_out, int ep_in); struct xusb; /* * Prototypes */ typedef int (*xusb_filter_t)(const struct xusb *xusb, void *data); struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, int numspecs, xusb_filter_t filterfunc, void *data); struct xusb *xusb_find_bypath(const struct xusb_spec *specs, int numspecs, const char *path); struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, xusb_filter_t filterfunc, void *data); struct xusb *xusb_find_iface(const char *devpath, int iface_num, int ep_out, int ep_in, struct xusb_spec *dummy); /* * A convenience filter */ int xusb_filter_bypath(const struct xusb *xusb, void *data); int xusb_interface(struct xusb *xusb); int xusb_claim_interface(struct xusb *xusb); void xusb_destroy(struct xusb *xusb); int xusb_close(struct xusb *xusb); size_t xusb_packet_size(const struct xusb *xusb); void xusb_showinfo(const struct xusb *xusb); const char *xusb_serial(const struct xusb *xusb); const char *xusb_manufacturer(const struct xusb *xusb); const char *xusb_product(const struct xusb *xusb); uint16_t xusb_vendor_id(const struct xusb *xusb); uint16_t xusb_product_id(const struct xusb *xusb); const char *xusb_devpath(const struct xusb *xusb); const struct xusb_spec *xusb_spec(const struct xusb *xusb); int xusb_send(struct xusb *xusb, char *buf, int len, int timeout); int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout); int xusb_flushread(struct xusb *xusb); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* XUSB_H */ dahdi-tools-2.10.2/xpp/xtalk/xusb.c0000644000000000000000000005474412537624573015614 0ustar rootroot/* * Written by Oron Peled * Copyright (C) 2008, Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #define _GNU_SOURCE /* for memrchr() */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define DBG_MASK 0x01 #define TIMEOUT 500 #define MAX_RETRIES 10 struct xusb { struct usb_device *dev; usb_dev_handle *handle; const struct xusb_spec *spec; char iManufacturer[BUFSIZ]; char iProduct[BUFSIZ]; char iSerialNumber[BUFSIZ]; char iInterface[BUFSIZ]; char devpath_tail[PATH_MAX + 1]; int bus_num; int device_num; int interface_num; int ep_out; int ep_in; int is_usb2; int is_claimed; int is_open; size_t packet_size; }; static void xusb_init(); /* * XTALK_OPTIONS: * A white-space separated list of options, read from the environment * variable of that name. Existing options: * * - "use-clear-halt" -- force USB "clear_halt" operation during * device initialization (this is the default) * - "no-use-clear-halt" -- force no USB "clear_halt" operation during * device initialization * - "no-lock" -- prevent using global sempahore to serialize libusb * initialization. Previously done via "XUSB_NOLOCK" * environment variable. */ int xtalk_parse_options(void); int xtalk_option_use_clear_halt(void); int xtalk_option_no_lock(void); void xusb_init_spec(struct xusb_spec *spec, char *name, uint16_t vendor_id, uint16_t product_id, int nifaces, int iface, int nep, int ep_out, int ep_in) { DBG("Initialize %s: interfaces=%d using interface num=%d endpoints=%d " "(OUT=0x%02X, IN=0x%02X)\n", name, nifaces, iface, nep, ep_out, ep_in); memset(spec, 0, sizeof(*spec)); spec->name = name; spec->num_interfaces = nifaces; spec->my_interface_num = iface; spec->num_endpoints = nep; spec->my_vendor_id = vendor_id; spec->my_product_id = product_id; spec->my_ep_in = ep_in; spec->my_ep_out = ep_out; } #define EP_OUT(xusb) ((xusb)->spec->my_ep_out) #define EP_IN(xusb) ((xusb)->spec->my_ep_in) /* * USB handling */ static int get_usb_string(struct xusb *xusb, uint8_t item, char *buf) { char tmp[BUFSIZ]; int ret; assert(xusb->handle); if (!item) return 0; ret = usb_get_string_simple(xusb->handle, item, tmp, BUFSIZ); if (ret <= 0) return ret; return snprintf(buf, BUFSIZ, "%s", tmp); } static const struct usb_interface_descriptor *get_interface( const struct usb_device *dev, int my_interface_num, int num_interfaces) { const struct usb_interface *interface; const struct usb_interface_descriptor *iface_desc; const struct usb_config_descriptor *config_desc; int num_altsetting; config_desc = dev->config; if (!config_desc) { ERR("No configuration descriptor: strange USB1 controller?\n"); return NULL; } if (num_interfaces && config_desc->bNumInterfaces != num_interfaces) { DBG("Wrong number of interfaces: have %d need %d\n", config_desc->bNumInterfaces, num_interfaces); return NULL; } interface = &config_desc->interface[my_interface_num]; assert(interface != NULL); iface_desc = interface->altsetting; num_altsetting = interface->num_altsetting; assert(num_altsetting != 0); assert(iface_desc != NULL); return iface_desc; } static int match_interface(const struct usb_device *dev, const struct xusb_spec *spec) { const struct usb_device_descriptor *dev_desc; const struct usb_interface_descriptor *iface_desc; dev_desc = &dev->descriptor; assert(dev_desc); DBG("Checking: %04X:%04X interfaces=%d interface num=%d endpoints=%d: " "\"%s\"\n", spec->my_vendor_id, spec->my_product_id, spec->num_interfaces, spec->my_interface_num, spec->num_endpoints, spec->name); if (dev_desc->idVendor != spec->my_vendor_id) { DBG("Wrong vendor id 0x%X\n", dev_desc->idVendor); return 0; } if (dev_desc->idProduct != spec->my_product_id) { DBG("Wrong product id 0x%X\n", dev_desc->idProduct); return 0; } iface_desc = get_interface(dev, spec->my_interface_num, spec->num_interfaces); if (!iface_desc) { ERR("Could not get interface descriptor of device: %s\n", usb_strerror()); return 0; } if (iface_desc->bInterfaceClass != 0xFF) { DBG("Wrong interface class 0x%X\n", iface_desc->bInterfaceClass); return 0; } if (iface_desc->bInterfaceNumber != spec->my_interface_num) { DBG("Wrong interface number %d (expected %d)\n", iface_desc->bInterfaceNumber, spec->my_interface_num); return 0; } if (iface_desc->bNumEndpoints != spec->num_endpoints) { DBG("Wrong number of endpoints %d\n", iface_desc->bNumEndpoints); return 0; } return 1; } #define GET_USB_STRING(xusb, from, item) \ get_usb_string((xusb), (from)->item, xusb->item) static int xusb_fill_strings(struct xusb *xusb) { const struct usb_device_descriptor *dev_desc; const struct usb_interface_descriptor *iface_desc; dev_desc = &xusb->dev->descriptor; assert(dev_desc); if (GET_USB_STRING(xusb, dev_desc, iManufacturer) < 0) { ERR("Failed reading iManufacturer string: %s\n", usb_strerror()); return 0; } if (GET_USB_STRING(xusb, dev_desc, iProduct) < 0) { ERR("Failed reading iProduct string: %s\n", usb_strerror()); return 0; } if (GET_USB_STRING(xusb, dev_desc, iSerialNumber) < 0) { ERR("Failed reading iSerialNumber string: %s\n", usb_strerror()); return 0; } iface_desc = get_interface(xusb->dev, xusb->interface_num, 0); if (!iface_desc) { ERR("Could not get interface descriptor of device: %s\n", usb_strerror()); return 0; } if (GET_USB_STRING(xusb, iface_desc, iInterface) < 0) { ERR("Failed reading iInterface string: %s\n", usb_strerror()); return 0; } return 1; } static int xusb_open(struct xusb *xusb) { assert(xusb); if (xusb->is_open) return 1; xusb->handle = usb_open(xusb->dev); if (!xusb->handle) { ERR("Failed to open usb device '%s': %s\n", xusb->devpath_tail, usb_strerror()); return 0; } xusb->is_open = 1; return 1; } int xusb_claim_interface(struct xusb *xusb) { const struct usb_device_descriptor *dev_desc; int ret; assert(xusb); xusb_open(xusb); /* If it's not open yet... */ if (usb_claim_interface(xusb->handle, xusb->interface_num) != 0) { ERR("usb_claim_interface %d in '%s': %s\n", xusb->interface_num, xusb->devpath_tail, usb_strerror()); return 0; } xusb->is_claimed = 1; xusb_fill_strings(xusb); dev_desc = &xusb->dev->descriptor; DBG("ID=%04X:%04X Manufacturer=[%s] Product=[%s] " "SerialNumber=[%s] Interface=[%s]\n", dev_desc->idVendor, dev_desc->idProduct, xusb->iManufacturer, xusb->iProduct, xusb->iSerialNumber, xusb->iInterface); if (xtalk_option_use_clear_halt()) { DBG("Using clear_halt()\n"); if (usb_clear_halt(xusb->handle, EP_OUT(xusb)) != 0) { ERR("Clearing output endpoint: %s\n", usb_strerror()); return 0; } if (usb_clear_halt(xusb->handle, EP_IN(xusb)) != 0) { ERR("Clearing input endpoint: %s\n", usb_strerror()); return 0; } } ret = xusb_flushread(xusb); if (ret < 0) { ERR("xusb_flushread failed: %d\n", ret); return 0; } return 1; } static void xusb_list_dump(struct xlist_node *xusb_list) { struct xlist_node *curr; struct xusb *xusb; for (curr = xusb_list->next; curr != xusb_list; curr = curr->next) { struct usb_device *dev; struct usb_bus *bus; struct usb_device_descriptor *dev_desc; xusb = curr->data; assert(xusb); dev = xusb->dev; assert(dev); bus = dev->bus; assert(bus); dev_desc = &dev->descriptor; assert(dev_desc); DBG("usb:ID=%04X:%04X [%s / %s / %s], (%s/%s)\n", dev_desc->idVendor, dev_desc->idProduct, xusb->iManufacturer, xusb->iProduct, xusb->iSerialNumber, bus->dirname, dev->filename ); } } void xusb_destroy(struct xusb *xusb) { if (xusb) { xusb_close(xusb); memset(xusb, 0, sizeof(*xusb)); free(xusb); } } static struct xusb *xusb_new(struct usb_device *dev, const struct xusb_spec *spec) { struct usb_device_descriptor *dev_desc; struct usb_config_descriptor *config_desc; struct usb_interface *interface; struct usb_interface_descriptor *iface_desc; struct usb_endpoint_descriptor *endpoint; size_t max_packet_size; int i; struct xusb *xusb = NULL; /* * Get information from the usb_device */ dev_desc = &dev->descriptor; if (!dev_desc) { ERR("usb device without a device descriptor\n"); goto fail; } config_desc = dev->config; if (!config_desc) { ERR("usb device without a configuration descriptor\n"); goto fail; } interface = &config_desc->interface[spec->my_interface_num]; iface_desc = interface->altsetting; endpoint = iface_desc->endpoint; /* Calculate max packet size */ max_packet_size = PACKET_SIZE; for (i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) { DBG("Validating endpoint @ %d (interface %d)\n", i, spec->my_interface_num); if (endpoint->bEndpointAddress == spec->my_ep_out || endpoint->bEndpointAddress == spec->my_ep_in) { if (endpoint->wMaxPacketSize > PACKET_SIZE) { ERR("EP #%d wMaxPacketSize too large (%d)\n", i, endpoint->wMaxPacketSize); goto fail; } if (endpoint->wMaxPacketSize < max_packet_size) max_packet_size = endpoint->wMaxPacketSize; } } /* Fill xusb */ xusb = malloc(sizeof(*xusb)); if (!xusb) { ERR("Out of memory"); goto fail; } memset(xusb, 0, sizeof(*xusb)); xusb->dev = dev; xusb->spec = spec; sscanf(dev->bus->dirname, "%d", &xusb->bus_num); sscanf(dev->filename, "%d", &xusb->device_num); snprintf(xusb->devpath_tail, PATH_MAX, "%03d/%03d", xusb->bus_num, xusb->device_num); xusb->interface_num = spec->my_interface_num; xusb->ep_out = spec->my_ep_out; xusb->ep_in = spec->my_ep_in; xusb->packet_size = max_packet_size; xusb->is_usb2 = (max_packet_size == 512); if (!xusb_open(xusb)) { ERR("Failed opening device: %04X:%04X - %s\n", dev_desc->idVendor, dev_desc->idProduct, xusb->devpath_tail); goto fail; } DBG("%04X:%04X - %s\n", dev_desc->idVendor, dev_desc->idProduct, xusb->devpath_tail); return xusb; fail: xusb_destroy(xusb); return NULL; } struct xusb *xusb_find_iface(const char *devpath, int iface_num, int ep_out, int ep_in, struct xusb_spec *dummy_spec) { struct usb_bus *bus; DBG("\n"); xusb_init(); for (bus = usb_get_busses(); bus; bus = bus->next) { int bus_num; char tmppath[PATH_MAX + 1]; struct usb_device *dev; tmppath[0] = '\0'; sscanf(bus->dirname, "%d", &bus_num); snprintf(tmppath, sizeof(tmppath), "%03d", bus_num); DBG("Check bus %d: %s ? %s\n", bus_num, tmppath, devpath); if (strncmp(tmppath, devpath, strlen(tmppath)) != 0) continue; DBG("Matched bus %d\n", bus_num); for (dev = bus->devices; dev; dev = dev->next) { struct usb_device_descriptor *dev_desc; struct usb_config_descriptor *config_desc; struct usb_interface *interface; struct xusb *xusb; int device_num; sscanf(dev->filename, "%d", &device_num); DBG("Check device %d\n", device_num); snprintf(tmppath, sizeof(tmppath), "%03d/%03d", bus_num, device_num); if (strncmp(tmppath, devpath, strlen(tmppath)) != 0) continue; dev_desc = &dev->descriptor; assert(dev_desc); config_desc = dev->config; assert(config_desc); interface = config_desc->interface; assert(interface); DBG("Matched device %s: %X:%X\n", tmppath, dev_desc->idVendor, dev_desc->idProduct); assert(dummy_spec); xusb_init_spec(dummy_spec, "", dev_desc->idVendor, dev_desc->idProduct, config_desc->bNumInterfaces, iface_num, interface->altsetting->bNumEndpoints, ep_out, ep_in); xusb = xusb_new(dev, dummy_spec); if (!xusb) ERR("xusb allocation failed\n"); return xusb; } } return NULL; } static const char *path_tail(const char *path) { const char *p; assert(path != NULL); /* Find last '/' */ p = memrchr(path, '/', strlen(path)); if (!p) { ERR("Missing a '/' in %s\n", path); return NULL; } /* Search for a '/' before that */ p = memrchr(path, '/', p - path); if (!p) p = path; /* No more '/' */ else p++; /* skip '/' */ return p; } int xusb_filter_bypath(const struct xusb *xusb, void *data) { const char *p; const char *path = data; DBG("%s\n", path); assert(path != NULL); p = path_tail(path); if (strcmp(xusb->devpath_tail, p) != 0) { DBG("device path missmatch: '%s' != '%s'\n", xusb->devpath_tail, p); return 0; } return 1; } struct xusb *xusb_find_bypath(const struct xusb_spec *specs, int numspecs, const char *path) { struct xlist_node *xlist; struct xlist_node *head; struct xusb *xusb; xlist = xusb_find_byproduct(specs, numspecs, xusb_filter_bypath, (void *)path); head = xlist_shift(xlist); if (!head) return NULL; if (!xlist_empty(xlist)) { ERR("Too many matches (extra %zd) to '%s'\n", xlist_length(xlist), path); return NULL; } xusb = head->data; xlist_destroy(xlist, NULL); return xusb; } struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, int numspecs, xusb_filter_t filterfunc, void *data) { struct xlist_node *xlist; struct usb_bus *bus; struct usb_device *dev; DBG("specs(%d)\n", numspecs); xlist = xlist_new(NULL); if (!xlist) { ERR("Failed allocation new xlist"); goto fail_xlist; } xusb_init(); for (bus = usb_get_busses(); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { struct usb_device_descriptor *dev_desc; struct xlist_node *item; int i; dev_desc = &dev->descriptor; assert(dev_desc); DBG("usb:%s/%s: ID=%04X:%04X\n", dev->bus->dirname, dev->filename, dev_desc->idVendor, dev_desc->idProduct); for (i = 0; i < numspecs; i++) { struct xusb *xusb; const struct xusb_spec *sp = &specs[i]; if (!match_interface(dev, sp)) continue; xusb = xusb_new(dev, sp); if (!xusb) { ERR("xusb allocation failed\n"); goto fail_malloc; } if (filterfunc && !filterfunc(xusb, data)) { xusb_destroy(xusb); continue; } item = xlist_new(xusb); xlist_append_item(xlist, item); break; } } } xusb_list_dump(xlist); return xlist; fail_malloc: xlist_destroy(xlist, NULL); fail_xlist: return NULL; } struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, xusb_filter_t filterfunc, void *data) { struct xlist_node *xusb_list; struct xlist_node *curr; int num; struct xusb *xusb = NULL; xusb_list = xusb_find_byproduct(specs, numspecs, filterfunc, data); num = xlist_length(xusb_list); DBG("total %d devices\n", num); switch (num) { case 0: ERR("No matching device.\n"); break; case 1: curr = xlist_shift(xusb_list); xusb = curr->data; xlist_destroy(curr, NULL); xlist_destroy(xusb_list, NULL); if (!xusb_claim_interface(xusb)) { xusb_destroy(xusb); return NULL; } xusb_showinfo(xusb); break; default: ERR("Too many devices (%d). Aborting.\n", num); break; } return xusb; } int xusb_interface(struct xusb *xusb) { return xusb->interface_num; } size_t xusb_packet_size(const struct xusb *xusb) { return xusb->packet_size; } /* * MP device handling */ void xusb_showinfo(const struct xusb *xusb) { struct usb_device_descriptor *dev_desc; struct usb_device *dev; assert(xusb != NULL); dev = xusb->dev; dev_desc = &dev->descriptor; if (verbose <= LOG_INFO) { INFO("usb:%s/%s: ID=%04X:%04X [%s / %s / %s]\n", dev->bus->dirname, dev->filename, dev_desc->idVendor, dev_desc->idProduct, xusb->iManufacturer, xusb->iProduct, xusb->iSerialNumber); } else { printf("USB Bus/Device: [%s/%s] (%s,%s)\n", dev->bus->dirname, dev->filename, (xusb->is_open) ? "open" : "closed", (xusb->is_claimed) ? "claimed" : "unused"); printf("USB Spec name: [%s]\n", xusb->spec->name); printf("USB iManufacturer: [%s]\n", xusb->iManufacturer); printf("USB iProduct: [%s]\n", xusb->iProduct); printf("USB iSerialNumber: [%s]\n", xusb->iSerialNumber); } } const char *xusb_serial(const struct xusb *xusb) { return xusb->iSerialNumber; } const char *xusb_devpath(const struct xusb *xusb) { return xusb->devpath_tail; } const char *xusb_manufacturer(const struct xusb *xusb) { return xusb->iManufacturer; } const char *xusb_product(const struct xusb *xusb) { return xusb->iProduct; } uint16_t xusb_vendor_id(const struct xusb *xusb) { return xusb->dev->descriptor.idVendor; } uint16_t xusb_product_id(const struct xusb *xusb) { return xusb->dev->descriptor.idProduct; } const struct xusb_spec *xusb_spec(const struct xusb *xusb) { return xusb->spec; } int xusb_close(struct xusb *xusb) { if (xusb) { if (xusb->handle) { assert(xusb->spec); assert(xusb->spec->name); DBG("Closing interface \"%s\"\n", xusb->spec->name); if (xusb->is_claimed) { if (usb_release_interface(xusb->handle, xusb->spec->my_interface_num) != 0) ERR("Releasing interface: usb: %s\n", usb_strerror()); xusb->is_claimed = 0; } if (xusb->is_open) { if (usb_close(xusb->handle) != 0) { ERR("Closing device: usb: %s\n", usb_strerror()); } xusb->is_open = 0; } xusb->handle = NULL; } xusb = NULL; } return 0; } int xusb_send(struct xusb *xusb, char *buf, int len, int timeout) { int ret; int retries = 0; dump_packet(LOG_DEBUG, DBG_MASK, __func__, buf, len); if (EP_OUT(xusb) & USB_ENDPOINT_IN) { ERR("%s called with an input endpoint 0x%x\n", __func__, EP_OUT(xusb)); return -EINVAL; } retry_write: ret = usb_bulk_write(xusb->handle, EP_OUT(xusb), buf, len, timeout); if (ret < 0) { /* * If the device was gone, it may be the * result of renumeration. Ignore it. */ if (ret != -ENODEV) { ERR("bulk_write to endpoint 0x%x failed: (%d) %s\n", EP_OUT(xusb), ret, usb_strerror()); dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", buf, len); /*exit(2);*/ } else { DBG("bulk_write to endpoint 0x%x got ENODEV\n", EP_OUT(xusb)); xusb_close(xusb); } return ret; } if (!ret) { ERR("bulk_write to endpoint 0x%x short write[%d]: (%d)\n", EP_OUT(xusb), retries, ret); if (retries++ > MAX_RETRIES) return -EFAULT; usleep(100); goto retry_write; } if (ret != len) { ERR("bulk_write to endpoint 0x%x short write: (%d) %s\n", EP_OUT(xusb), ret, usb_strerror()); dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", buf, len); return -EFAULT; } return ret; } int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout) { int ret; int retries = 0; if (EP_IN(xusb) & USB_ENDPOINT_OUT) { ERR("%s called with an output endpoint 0x%x\n", __func__, EP_IN(xusb)); return -EINVAL; } retry_read: ret = usb_bulk_read(xusb->handle, EP_IN(xusb), buf, len, timeout); if (ret < 0) { DBG("bulk_read from endpoint 0x%x failed: (%d) %s\n", EP_IN(xusb), ret, usb_strerror()); memset(buf, 0, len); return ret; } if (!ret) { ERR("bulk_read to endpoint 0x%x short read[%d]: (%d)\n", EP_IN(xusb), retries, ret); if (retries++ > MAX_RETRIES) return -EFAULT; usleep(100); goto retry_read; } dump_packet(LOG_DEBUG, DBG_MASK, __func__, buf, ret); return ret; } int xusb_flushread(struct xusb *xusb) { char tmpbuf[BUFSIZ]; int ret; DBG("starting...\n"); memset(tmpbuf, 0, BUFSIZ); ret = xusb_recv(xusb, tmpbuf, BUFSIZ, 1); if (ret < 0 && ret != -ETIMEDOUT) { ERR("ret=%d\n", ret); return ret; } else if (ret > 0) { DBG("Got %d bytes:\n", ret); dump_packet(LOG_DEBUG, DBG_MASK, __func__, tmpbuf, ret); } return 0; } /* * Serialize calls to usb_find_busses()/usb_find_devices() */ static const key_t SEM_KEY = 0x1a2b3c4d; static int semid = -1; /* Failure */ static void xusb_lock_usb() { struct sembuf sembuf; while (semid < 0) { /* Maybe it was already created? */ semid = semget(SEM_KEY, 1, 0); if (semid < 0) { /* No, let's create ourselves */ semid = semget(SEM_KEY, 1, IPC_CREAT | IPC_EXCL | 0644); if (semid < 0) { /* Someone else won the race to create it */ if (errno != ENOENT) ERR("%s: semget() failed: %s\n", __func__, strerror(errno)); /* Retry */ continue; } /* Initialize */ if (semctl(semid, 0, SETVAL, 1) < 0) ERR("%s: SETVAL() failed: %s\n", __func__, strerror(errno)); } } DBG("%d: LOCKING\n", getpid()); sembuf.sem_num = 0; sembuf.sem_op = -1; sembuf.sem_flg = SEM_UNDO; if (semop(semid, &sembuf, 1) < 0) ERR("%s: semop() failed: %s\n", __func__, strerror(errno)); DBG("%d: LOCKED\n", getpid()); } static void xusb_unlock_usb() { struct sembuf sembuf; DBG("%d: UNLOCKING\n", getpid()); sembuf.sem_num = 0; sembuf.sem_op = 1; sembuf.sem_flg = SEM_UNDO; if (semop(semid, &sembuf, 1) < 0) ERR("%s: semop() failed: %s\n", __func__, strerror(errno)); DBG("%d: UNLOCKED\n", getpid()); } static int initizalized; static void xusb_init() { if (!initizalized) { xtalk_parse_options(); if (!xtalk_option_no_lock()) xusb_lock_usb(); usb_init(); usb_find_busses(); usb_find_devices(); initizalized = 1; if (!xtalk_option_no_lock()) xusb_unlock_usb(); } } /* XTALK option handling */ static int use_clear_halt = 1; static int libusb_no_lock = 0; static int xtalk_one_option(const char *option_string) { if (strcmp(option_string, "use-clear-halt") == 0) { use_clear_halt = 1; return 0; } if (strcmp(option_string, "no-use-clear-halt") == 0) { use_clear_halt = 0; return 0; } if (strcmp(option_string, "no-lock") == 0) { libusb_no_lock = 1; return 0; } ERR("Unknown XTALK_OPTIONS content: '%s'\n", option_string); return -EINVAL; } int xtalk_option_use_clear_halt(void) { return use_clear_halt; } int xtalk_option_no_lock(void) { return libusb_no_lock; } int xtalk_parse_options(void) { char *xtalk_options; char *saveptr; char *token; int ret; xtalk_options = getenv("XTALK_OPTIONS"); if (!xtalk_options) return 0; token = strtok_r(xtalk_options, " \t", &saveptr); while (token) { ret = xtalk_one_option(token); if (ret < 0) return ret; token = strtok_r(NULL, " \t", &saveptr); } return 0; } dahdi-tools-2.10.2/xpp/xtalk/xtalk_defs.h0000644000000000000000000000317212537624573016751 0ustar rootroot#ifndef XTALK_DEFS_H #define XTALK_DEFS_H #define MAX_OPS 256 /* single byte */ #define MAX_STATUS 256 /* single byte */ #define XTALK_REPLY_MASK 0x80 /* Every reply has this bit */ #define PRIVATE_OP_FIRST 0x05 #define PRIVATE_OP_LAST 0x7F #define IS_PRIVATE_OP(x) ( \ (((x) & ~(XTALK_REPLY_MASK)) >= PRIVATE_OP_FIRST) && \ (((x) & ~(XTALK_REPLY_MASK)) <= PRIVATE_OP_LAST) \ ) #define XTALK_ACK 0x80 #define XTALK_PROTO_GET 0x01 #define XTALK_PROTO_GET_REPLY (XTALK_PROTO_GET | XTALK_REPLY_MASK) #define XTALK_FWVERS_GET 0x11 #define XTALK_FWVERS_GET_REPLY (XTALK_FWVERS_GET | XTALK_REPLY_MASK) /* Get EEPROM table contents Product/Vendor Id ... */ #define XTALK_CAPS_GET 0x0E #define XTALK_CAPS_GET_REPLY (XTALK_CAPS_GET | XTALK_REPLY_MASK) /*------------- XTALK: statuses in ACK ---------------------------------------*/ #define STAT_OK 0x00 /* OK */ #define STAT_FAIL 0x01 /* last command failed */ #define STAT_RESET_FAIL 0x02 /* reset failed */ #define STAT_NODEST 0x03 /* No destination is selected */ #define STAT_MISMATCH 0x04 /* Data mismatch */ #define STAT_NOACCESS 0x05 /* No access */ #define STAT_BAD_CMD 0x06 /* Bad command */ #define STAT_TOO_SHORT 0x07 /* Packet is too short */ #define STAT_ERROFFS 0x08 /* Offset error (not used) */ #define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */ #define STAT_NO_EEPROM 0x0B /* No EEPROM was found */ #define STAT_WRITE_FAIL 0x0C /* Writing to device failed */ #define STAT_NOPWR_ERR 0x10 /* No power on USB connector */ #endif /* XTALK_DEFS_H */ dahdi-tools-2.10.2/xpp/xtalk/debug.c0000644000000000000000000000340212537624573015702 0ustar rootroot/* * Written by Oron Peled * Copyright (C) 2008, Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include #include int verbose = LOG_INFO; int debug_mask; void log_function(int level, int mask, const char *msg, ...) { va_list ap; va_start(ap, msg); if (verbose >= level) { if (level < LOG_DEBUG || (mask & debug_mask)) vfprintf(stderr, msg, ap); } va_end(ap); } void dump_packet(int loglevel, int mask, const char *msg, const char *buf, int len) { int i; if (!mask || (mask & debug_mask)) { log_function(loglevel, ~0, "%-15s:", msg); for (i = 0; i < len; i++) log_function(loglevel, ~0, " %02X", (uint8_t)buf[i]); log_function(loglevel, ~0, "\n"); } } /* from glibc info(1) */ void print_backtrace(FILE *fp) { void *array[10]; size_t size; char **strings; size_t i; size = backtrace(array, 10); strings = backtrace_symbols(array, size); for (i = 0; i < size; i++) fprintf(fp, "%s\n", strings[i]); free(strings); } dahdi-tools-2.10.2/xpp/xtalk/xtalk.h0000644000000000000000000001144512537624573015752 0ustar rootroot#ifndef XTALK_H #define XTALK_H /* * Written by Oron Peled * Copyright (C) 2009, Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* * XTALK - Base protocol for our USB devices * It is meant to provide a common base for layered * protocols (dialects) */ #include #include /* Definitions common to the firmware (in include/ directory) */ #include #ifdef __GNUC__ #define PACKED __attribute__((packed)) #else #error "We do not know how your compiler packs structures" #endif struct xtalk_device; struct xtalk_command_desc; typedef int (*xtalk_cmd_callback_t)( struct xtalk_device *xtalk_dev, struct xtalk_command_desc *xtalk_cmd); /* Describe a single xtalk command */ struct xtalk_command_desc { uint8_t op; const char *name; xtalk_cmd_callback_t callback; uint16_t len; /* Minimal length */ }; /* Define a complete protocol */ struct xtalk_protocol { const char *name; uint8_t proto_version; struct xtalk_command_desc commands[MAX_OPS]; const char *ack_statuses[MAX_STATUS]; }; /* * The common header of every xtalk command * in every xtalk dialect. */ struct xtalk_header { uint16_t len; uint16_t seq; uint8_t op; /* MSB: 0 - to device, 1 - from device */ } PACKED; struct xtalk_command { /* Common part */ struct xtalk_header header; /* Each dialect has its own data members */ union private_data { uint8_t raw_data[0]; } PACKED alt; } PACKED; /* * Macros to unify access to protocol packets and fields: * p - signify the dialect prefix (XTALK for base protocol) * o - signify command op (e.g: ACK) * cmd - A pointer to struct xtalk_command * field - field name (e.g: raw_data) */ #define XTALK_STRUCT(p, o) p ## _struct_ ## o #define XTALK_PDATA(o) xtalk_privdata_ ## o #define XTALK_CMD_PTR(cmd, p) ((union XTALK_PDATA(p)*)&((cmd)->alt)) #define CMD_FIELD(cmd, p, o, field) \ (XTALK_CMD_PTR(cmd, p)->XTALK_STRUCT(p, o).field) #define CMD_DEF(p, o, ...) struct XTALK_STRUCT(p, o) { \ __VA_ARGS__ \ } PACKED XTALK_STRUCT(p, o) #define MEMBER(p, o) struct XTALK_STRUCT(p, o) XTALK_STRUCT(p, o) /* Wrappers for transport (xusb) functions */ struct xtalk_ops { int (*send_func)(void *transport_priv, void *data, size_t len, int timeout); int (*recv_func)(void *transport_priv, void *data, size_t maxlen, int timeout); int (*close_func)(void *transport_priv); }; /* * Base XTALK device. A pointer to this struct * should be included in the struct representing * the dialect. */ struct xtalk_device; /* high-level */ struct xtalk_device *xtalk_new(const struct xtalk_ops *ops, size_t packet_size, void *transport_priv); void xtalk_delete(struct xtalk_device *dev); int xtalk_set_protocol(struct xtalk_device *xtalk_dev, const struct xtalk_protocol *xproto); int xtalk_proto_query(struct xtalk_device *dev); void xtalk_dump_command(struct xtalk_command *cmd); /* low-level */ int process_command( struct xtalk_device *dev, struct xtalk_command *cmd, struct xtalk_command **reply_ref); struct xtalk_command *new_command( const struct xtalk_device *xtalk_dev, uint8_t op, uint16_t extra_data); void free_command(struct xtalk_command *cmd); /* * Convenience macros to define entries in a protocol command table: * p - signify the dialect prefix (XTALK for base protocol) * o - signify command op (e.g: ACK) * cb - A callback function (type xtalk_cmd_callback_t) */ #define CMD_RECV(p, o, cb) \ [p ## _ ## o | XTALK_REPLY_MASK] = { \ .op = (p ## _ ## o) | XTALK_REPLY_MASK, \ .name = (#o "_reply"), \ .callback = (cb), \ .len = \ sizeof(struct xtalk_header) + \ sizeof(struct XTALK_STRUCT(p, o)), \ } #define CMD_SEND(p, o) \ [p ## _ ## o] = { \ .op = (p ## _ ## o), \ .name = (#o), \ .callback = NULL, \ .len = \ sizeof(struct xtalk_header) + \ sizeof(struct XTALK_STRUCT(p, o)), \ } /* * Convenience macro to define statuses: * x - status code (e.g: OK) * m - status message (const char *) */ #define ACK_STAT(x, m) [STAT_ ## x] = (m) #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* XTALK_H */ dahdi-tools-2.10.2/xpp/xtalk/xlist.h0000644000000000000000000000127212537624573015767 0ustar rootroot#ifndef XLIST_H #define XLIST_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct xlist_node { void *data; struct xlist_node *next; struct xlist_node *prev; }; typedef void (*xlist_destructor_t)(void *data); struct xlist_node *xlist_new(void *data); void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor); void xlist_append_item(struct xlist_node *list, struct xlist_node *item); void xlist_remove_item(struct xlist_node *item); struct xlist_node *xlist_shift(struct xlist_node *list); int xlist_empty(const struct xlist_node *list); size_t xlist_length(const struct xlist_node *list); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* XLIST_H */ dahdi-tools-2.10.2/xpp/xtalk/debug.h0000644000000000000000000000315412537624573015713 0ustar rootroot#ifndef DEBUG_H #define DEBUG_H /* * Written by Oron Peled * Copyright (C) 2008, Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include /* * Each module should define a unique DBG_MASK */ extern int verbose; extern int debug_mask; /* * Logging */ void log_function(int level, int mask, const char *msg, ...) __attribute__((format(printf, 3, 4))); #define ERR(fmt, arg...) log_function(LOG_ERR, 0, "%s:%d: ERROR(%s): " fmt, \ __FILE__, __LINE__, __func__, ## arg) #define WARN(fmt, arg...) log_function(LOG_WARNING, 0, "WARNING: " fmt, ## arg) #define INFO(fmt, arg...) log_function(LOG_INFO, 0, "INFO: " fmt, ## arg) #define DBG(fmt, arg...) log_function(LOG_DEBUG, DBG_MASK, \ "%s:%d: DBG(%s): " fmt, __FILE__, __LINE__, __func__, ## arg) void dump_packet(int loglevel, int mask, const char *msg, const char *buf, int len); void print_backtrace(FILE *fp); #endif /* DEBUG_H */ dahdi-tools-2.10.2/xpp/xtalk/xlist.c0000644000000000000000000000335412537624573015765 0ustar rootroot#include #include #include #include struct xlist_node *xlist_new(void *data) { struct xlist_node *list; list = malloc(sizeof(*list)); if (!list) return NULL; list->next = list; list->prev = list; list->data = data; return list; } void xlist_destroy(struct xlist_node *list, xlist_destructor_t destructor) { struct xlist_node *curr; struct xlist_node *next; if (!list) return; curr = list->next; while (curr != list) { next = curr->next; if (destructor) destructor(curr->data); memset(curr, 0, sizeof(*curr)); free(curr); curr = next; } memset(list, 0, sizeof(*list)); free(list); } void xlist_append_item(struct xlist_node *list, struct xlist_node *item) { assert(list); assert(xlist_empty(item)); item->next = list; item->prev = list->prev; list->prev->next = item; list->prev = item; } void xlist_prepend_item(struct xlist_node *list, struct xlist_node *item) { assert(list); assert(xlist_empty(item)); item->prev = list; item->next = list->next; list->next->prev = item; list->next = item; } void xlist_remove_item(struct xlist_node *item) { assert(item); item->prev->next = item->next; item->next->prev = item->prev; item->next = item->prev = item; } struct xlist_node *xlist_shift(struct xlist_node *list) { struct xlist_node *item; if (!list) return NULL; if (xlist_empty(list)) return NULL; item = list->next; xlist_remove_item(item); return item; } int xlist_empty(const struct xlist_node *list) { assert(list); return list->next == list && list->prev == list; } size_t xlist_length(const struct xlist_node *list) { struct xlist_node *curr; size_t count = 0; for (curr = list->next; curr != list; curr = curr->next) count++; return count; } dahdi-tools-2.10.2/xpp/xtalk/xtalk.c0000644000000000000000000003006312537624573015742 0ustar rootroot/* * Written by Oron Peled * Copyright (C) 2009, Xorcom * * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include #include #include #define DBG_MASK 0x02 #define TIMEOUT 6000 /* * Base XTALK device. A pointer to this struct * should be included in the struct representing * the dialect. */ struct xtalk_device { void *transport_priv; /* e.g: struct xusb */ struct xtalk_ops ops; struct xtalk_protocol xproto; uint8_t xtalk_proto_version; uint8_t status; size_t packet_size; uint16_t tx_sequenceno; }; CMD_DEF(XTALK, ACK, uint8_t stat; ); CMD_DEF(XTALK, PROTO_GET, uint8_t proto_version; uint8_t reserved; ); CMD_DEF(XTALK, PROTO_GET_REPLY, uint8_t proto_version; uint8_t reserved; ); union XTALK_PDATA(XTALK) { MEMBER(XTALK, ACK); MEMBER(XTALK, PROTO_GET); MEMBER(XTALK, PROTO_GET_REPLY); } PACKED members; struct xtalk_protocol xtalk_base = { .name = "XTALK", .proto_version = 0, .commands = { CMD_RECV(XTALK, ACK, NULL), CMD_SEND(XTALK, PROTO_GET), CMD_RECV(XTALK, PROTO_GET_REPLY, NULL), }, .ack_statuses = { ACK_STAT(OK, "Acknowledges previous command"), ACK_STAT(FAIL, "Last command failed"), ACK_STAT(RESET_FAIL, "reset failed"), ACK_STAT(NODEST, "No destination is selected"), ACK_STAT(MISMATCH, "Data mismatch"), ACK_STAT(NOACCESS, "No access"), ACK_STAT(BAD_CMD, "Bad command"), ACK_STAT(TOO_SHORT, "Packet is too short"), ACK_STAT(ERROFFS, "Offset error (not used)"), ACK_STAT(NO_LEEPROM, "Large EEPROM was not found"), ACK_STAT(NO_EEPROM, "No EEPROM was found"), ACK_STAT(WRITE_FAIL, "Writing to device failed"), ACK_STAT(NOPWR_ERR, "No power on USB connector"), } }; void free_command(struct xtalk_command *cmd) { if (!cmd) return; memset(cmd, 0, cmd->header.len); free(cmd); } static const struct xtalk_command_desc *get_command_desc( const struct xtalk_protocol *xproto, uint8_t op) { const struct xtalk_command_desc *desc; if (!xproto) return NULL; desc = &xproto->commands[op]; if (!desc->name) return NULL; #if 0 DBG("%s version=%d, op=0x%X (%s)\n", xproto->name, xproto->proto_version, op, desc->name); #endif return desc; } static const char *ack_status_msg(const struct xtalk_protocol *xproto, uint8_t status) { const char *ack_status; if (!xproto) return NULL; ack_status = xproto->ack_statuses[status]; DBG("%s status=0x%X (%s)\n", xproto->name, status, ack_status); return ack_status; } int xtalk_set_protocol(struct xtalk_device *xtalk_dev, const struct xtalk_protocol *xproto) { const char *protoname = (xproto) ? xproto->name : "GLOBAL"; int i; DBG("%s\n", protoname); memset(&xtalk_dev->xproto, 0, sizeof(xtalk_dev->xproto)); for (i = 0; i < MAX_OPS; i++) { const struct xtalk_command_desc *desc; desc = get_command_desc(xproto, i); if (desc) { if (!IS_PRIVATE_OP(i)) { ERR("Bad op=0x%X " "(should be in the range [0x%X-0x%X]\n", i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST); return -EINVAL; } xtalk_dev->xproto.commands[i] = *desc; DBG("private: op=0x%X (%s)\n", i, desc->name); } else { if (!IS_PRIVATE_OP(i)) { const char *name; xtalk_dev->xproto.commands[i] = xtalk_base.commands[i]; name = xtalk_dev->xproto.commands[i].name; if (name) DBG("global: op=0x%X (%s)\n", i, name); } } } for (i = 0; i < MAX_STATUS; i++) { const char *stat_msg; stat_msg = (xproto) ? xproto->ack_statuses[i] : NULL; if (stat_msg) { if (!IS_PRIVATE_OP(i)) { ERR("Bad status=0x%X " "(should be in the range [0x%X-0x%X]\n", i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST); return -EINVAL; } xtalk_dev->xproto.ack_statuses[i] = stat_msg; DBG("private: status=0x%X (%s)\n", i, stat_msg); } else { if (!IS_PRIVATE_OP(i)) { const char *stat_msg; xtalk_dev->xproto.ack_statuses[i] = xtalk_base.ack_statuses[i]; stat_msg = xtalk_dev->xproto.ack_statuses[i]; if (stat_msg) DBG("global: status=0x%X (%s)\n", i, stat_msg); } } } xtalk_dev->xproto.name = protoname; xtalk_dev->xproto.proto_version = (xproto) ? xproto->proto_version : 0; return 0; } struct xtalk_command *new_command( const struct xtalk_device *xtalk_dev, uint8_t op, uint16_t extra_data) { const struct xtalk_protocol *xproto; struct xtalk_command *cmd; const struct xtalk_command_desc *desc; uint16_t len; xproto = &xtalk_dev->xproto; desc = get_command_desc(xproto, op); if (!desc) { ERR("Unknown op=0x%X.\n", op); return NULL; } DBG("OP=0x%X [%s] (extra_data %d)\n", op, desc->name, extra_data); len = desc->len + extra_data; cmd = malloc(len); if (!cmd) { ERR("Out of memory\n"); return NULL; } if (extra_data) { uint8_t *ptr = (uint8_t *)cmd; DBG("clear extra_data (%d bytes)\n", extra_data); memset(ptr + desc->len, 0, extra_data); } cmd->header.op = op; cmd->header.len = len; cmd->header.seq = 0; /* Overwritten in send_usb() */ return cmd; } void xtalk_dump_command(struct xtalk_command *cmd) { uint16_t len; int i; len = cmd->header.len; if (len < sizeof(struct xtalk_header)) { ERR("Command too short (%d)\n", len); return; } INFO("DUMP: OP=0x%X len=%d seq=%d\n", cmd->header.op, cmd->header.len, cmd->header.seq); for (i = 0; i < len - sizeof(struct xtalk_header); i++) INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]); } static int send_command(struct xtalk_device *xtalk_dev, struct xtalk_command *cmd, int timeout) { int ret; int len; void *priv = xtalk_dev->transport_priv; len = cmd->header.len; cmd->header.seq = xtalk_dev->tx_sequenceno; ret = xtalk_dev->ops.send_func(priv, (char *)cmd, len, timeout); if (ret < 0) DBG("send_func failed ret=%d\n", ret); xtalk_dev->tx_sequenceno++; return ret; } static struct xtalk_command *recv_command(struct xtalk_device *xtalk_dev, int timeout) { struct xtalk_command *reply; void *priv = xtalk_dev->transport_priv; size_t psize = xtalk_dev->packet_size; int ret; reply = malloc(psize); if (!reply) { ERR("Out of memory\n"); goto err; } reply->header.len = 0; ret = xtalk_dev->ops.recv_func(priv, (char *)reply, psize, timeout); if (ret < 0) { ERR("Receive from usb failed.\n"); goto err; } else if (ret == 0) { goto err; /* No reply */ } if (ret != reply->header.len) { ERR("Wrong length received: got %d bytes, " "but length field says %d bytes%s\n", ret, reply->header.len, (ret == 1) ? ". Old USB firmware?" : ""); goto err; } /* dump_packet(LOG_DEBUG, DBG_MASK, __func__, (char *)reply, ret); */ return reply; err: if (reply) { memset(reply, 0, psize); free_command(reply); } return NULL; } __attribute__((warn_unused_result)) int process_command( struct xtalk_device *xtalk_dev, struct xtalk_command *cmd, struct xtalk_command **reply_ref) { const struct xtalk_protocol *xproto; struct xtalk_command *reply = NULL; const struct xtalk_command_desc *reply_desc; const struct xtalk_command_desc *expected; const struct xtalk_command_desc *cmd_desc; uint8_t reply_op; const char *protoname; int ret; xproto = &xtalk_dev->xproto; protoname = (xproto) ? xproto->name : "GLOBAL"; /* So the caller knows if a reply was received */ if (reply_ref) *reply_ref = NULL; reply_op = cmd->header.op | XTALK_REPLY_MASK; cmd_desc = get_command_desc(xproto, cmd->header.op); expected = get_command_desc(xproto, reply_op); ret = send_command(xtalk_dev, cmd, TIMEOUT); if (!reply_ref) { DBG("No reply requested\n"); goto out; } if (ret < 0) { ERR("send_command failed: %d\n", ret); goto out; } reply = recv_command(xtalk_dev, TIMEOUT); if (!reply) { ERR("recv_command failed\n"); ret = -EPROTO; goto out; } *reply_ref = reply; if ((reply->header.op & 0x80) != 0x80) { ERR("Unexpected reply op=0x%02X, should have MSB set.\n", reply->header.op); ret = -EPROTO; goto out; } DBG("REPLY OP: 0x%X\n", reply->header.op); reply_desc = get_command_desc(xproto, reply->header.op); if (!reply_desc) { ERR("Unknown reply (proto=%s) op=0x%02X\n", protoname, reply->header.op); ret = -EPROTO; goto out; } DBG("REPLY NAME: %s\n", reply_desc->name); if (reply->header.op == XTALK_ACK) { int status = CMD_FIELD(reply, XTALK, ACK, stat); if (expected) { ERR("Expected OP=0x%02X: Got ACK(%d): %s\n", reply_op, status, ack_status_msg(xproto, status)); ret = -EPROTO; goto out; } else if (status != STAT_OK) { ERR("Got ACK (for OP=0x%X [%s]): %d %s\n", cmd->header.op, cmd_desc->name, status, ack_status_msg(xproto, status)); ret = -EPROTO; goto out; } /* Good expected ACK ... */ } else if (reply->header.op != reply_op) { ERR("Expected OP=0x%02X: Got OP=0x%02X\n", reply_op, reply->header.op); ret = -EPROTO; goto out; } if (expected && expected->len > reply->header.len) { ERR("Expected len=%d: Got len=%d\n", expected->len, reply->header.len); ret = -EPROTO; goto out; } if (cmd->header.seq != reply->header.seq) { ERR("Expected seq=%d: Got seq=%d\n", cmd->header.seq, reply->header.seq); ret = -EPROTO; goto out; } ret = reply->header.len; /* All good, return the length */ DBG("returning reply op 0x%X (%d bytes)\n", reply->header.op, ret); out: free_command(cmd); if (!reply_ref && reply) free_command(reply); return ret; } /* * Protocol Commands */ int xtalk_proto_query(struct xtalk_device *xtalk_dev) { struct xtalk_command *cmd; struct xtalk_command *reply; uint8_t proto_version; int ret; DBG("\n"); assert(xtalk_dev != NULL); proto_version = xtalk_dev->xproto.proto_version; cmd = new_command(xtalk_dev, XTALK_PROTO_GET, 0); if (!cmd) { ERR("new_command failed\n"); return -ENOMEM; } /* Protocol Version */ CMD_FIELD(cmd, XTALK, PROTO_GET, proto_version) = proto_version; ret = process_command(xtalk_dev, cmd, &reply); if (ret < 0) { ERR("process_command failed: %d\n", ret); goto out; } xtalk_dev->xtalk_proto_version = CMD_FIELD(reply, XTALK, PROTO_GET_REPLY, proto_version); if (xtalk_dev->xtalk_proto_version != proto_version) { DBG("Got %s protocol version: 0x%02x (expected 0x%02x)\n", xtalk_dev->xproto.name, xtalk_dev->xtalk_proto_version, proto_version); ret = xtalk_dev->xtalk_proto_version; goto out; } DBG("Protocol version: %02x\n", xtalk_dev->xtalk_proto_version); ret = xtalk_dev->xtalk_proto_version; out: free_command(reply); return ret; } /* * Wrappers */ struct xtalk_device *xtalk_new(const struct xtalk_ops *ops, size_t packet_size, void *priv) { struct xtalk_device *xtalk_dev; int ret; DBG("\n"); assert(ops != NULL); xtalk_dev = malloc(sizeof(*xtalk_dev)); if (!xtalk_dev) { ERR("Allocating XTALK device memory failed\n"); return NULL; } memset(xtalk_dev, 0, sizeof(*xtalk_dev)); memcpy((void *)&xtalk_dev->ops, (const void *)ops, sizeof(xtalk_dev->ops)); xtalk_dev->transport_priv = priv; xtalk_dev->packet_size = packet_size; xtalk_dev->tx_sequenceno = 1; ret = xtalk_set_protocol(xtalk_dev, NULL); if (ret < 0) { ERR("GLOBAL Protocol registration failed: %d\n", ret); goto err; } return xtalk_dev; err: if (xtalk_dev) xtalk_delete(xtalk_dev); return NULL; } void xtalk_delete(struct xtalk_device *xtalk_dev) { void *priv; if (!xtalk_dev) return; DBG("\n"); priv = xtalk_dev->transport_priv; assert(priv); xtalk_dev->tx_sequenceno = 0; assert(&xtalk_dev->ops != NULL); assert(&xtalk_dev->ops.close_func != NULL); xtalk_dev->ops.close_func(priv); } dahdi-tools-2.10.2/xpp/xpp_blink0000755000000000000000000001014312537624573015241 0ustar rootroot#! /usr/bin/perl -w # # Written by Oron Peled # Copyright (C) 2007, Xorcom # This program is free software; you can redistribute and/or # modify it under the same terms as Perl itself. # # $Id$ # use strict; use File::Basename; BEGIN { my $dir = dirname($0); unshift(@INC, "$dir", "$dir/perl_modules"); } use Dahdi; use Dahdi::Span; use Dahdi::Xpp; use Dahdi::Xpp::Xbus; sub usage { die "Usage: $0 {on|off|bzzt} {span | chan | xpd [] | label