patlooptest: Ignore the first buffered event
[dahdi/tools.git] / dahdi_tool.c
1 /*
2  * Configuration program for Zapata Telephony Interface
3  *
4  * Written by Mark Spencer <markster@digium.com>
5  * Based on previous works, designs, and architectures conceived and
6  * written by Jim Dixon <jim@lambdatel.com>.
7  *
8  * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
9  * Copyright (C) 2001-2010 Digium, Inc.
10  *
11  * All rights reserved.
12  *
13  */
14
15 /*
16  * See http://www.asterisk.org for more information about
17  * the Asterisk project. Please do not directly contact
18  * any of the maintainers of this project for assistance;
19  * the project provides a web site, mailing lists and IRC
20  * channels for your use.
21  *
22  * This program is free software, distributed under the terms of
23  * the GNU General Public License Version 2 as published by the
24  * Free Software Foundation. See the LICENSE file included with
25  * this program for more details.
26  */
27
28 /*** MODULEINFO
29         <depend>newt</depend>
30  ***/
31
32 #include <stdio.h> 
33 #include <getopt.h>
34 #include <string.h>
35 #include <stdarg.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <sys/ioctl.h>
39 #include <fcntl.h>
40 #include <errno.h>
41 #include <newt.h>
42
43 #include <dahdi/user.h>
44 #include "dahdi_tools_version.h"
45
46 static int ctl = -1;
47 static int span_max_chan_pos;
48
49 static struct dahdi_spaninfo s[DAHDI_MAX_SPANS];
50
51 static char *dahdi_txlevelnames[] = {
52 "0 db (CSU)/0-133 feet (DSX-1)",
53 "133-266 feet (DSX-1)",
54 "266-399 feet (DSX-1)",
55 "399-533 feet (DSX-1)",
56 "533-655 feet (DSX-1)",
57 "-7.5db (CSU)",
58 "-15db (CSU)",
59 "-22.5db (CSU)"
60 } ;
61
62 static char *alarmstr(int span)
63 {
64         static char alarms[80];
65         strcpy(alarms, "");
66         if (s[span].alarms > 0) {
67                 if (s[span].alarms & DAHDI_ALARM_BLUE)
68                         strcat(alarms,"Blue Alarm/");
69                 if (s[span].alarms & DAHDI_ALARM_YELLOW)
70                         strcat(alarms, "Yellow Alarm/");
71                 if (s[span].alarms & DAHDI_ALARM_RED)
72                         strcat(alarms, "Red Alarm/");
73                 if (s[span].alarms & DAHDI_ALARM_LOOPBACK)
74                         strcat(alarms,"Loopback/");
75                 if (s[span].alarms & DAHDI_ALARM_RECOVER)
76                         strcat(alarms,"Recovering/");
77                 if (s[span].alarms & DAHDI_ALARM_NOTOPEN)
78                         strcat(alarms, "Not Open/");
79                 if (!strlen(alarms))
80                         strcat(alarms, "<unknown>/");
81                 if (strlen(alarms)) {
82                         /* Strip trailing / */
83                         alarms[strlen(alarms)-1]='\0';
84                 }
85         } else
86                 strcpy(alarms, "No alarms.");
87         return alarms;
88 }
89
90 static char *getalarms(int span, int err)
91 {
92         int res;
93         static char tmp[256];
94         char alarms[50];
95         s[span].spanno = span;
96         res = ioctl(ctl, DAHDI_SPANSTAT, &s[span]);
97         if (res) {
98                 if (err)
99                         fprintf(stderr, "Unable to get span info on span %d: %s\n", span, strerror(errno)); 
100                 return NULL;
101         }
102         strcpy(alarms, "");
103         if (s[span].alarms > 0) {
104                 if (s[span].alarms & DAHDI_ALARM_BLUE)
105                         strcat(alarms,"BLU/");
106                 if (s[span].alarms & DAHDI_ALARM_YELLOW)
107                         strcat(alarms, "YEL/");
108                 if (s[span].alarms & DAHDI_ALARM_RED)
109                         strcat(alarms, "RED/");
110                 if (s[span].alarms & DAHDI_ALARM_LOOPBACK)
111                         strcat(alarms,"LB/");
112                 if (s[span].alarms & DAHDI_ALARM_RECOVER)
113                         strcat(alarms,"REC/");
114                 if (s[span].alarms & DAHDI_ALARM_NOTOPEN)
115                         strcat(alarms, "NOP/");
116                 if (!strlen(alarms))
117                         strcat(alarms, "UUU/");
118                 if (strlen(alarms)) {
119                         /* Strip trailing / */
120                         alarms[strlen(alarms)-1]='\0';
121                 }
122         } else {
123                 if (s[span].numchans)
124                         strcpy(alarms, "OK");
125                 else
126                         strcpy(alarms, "UNCONFIGURED");
127         }
128                 
129         snprintf(tmp, sizeof(tmp), "%-15s %s", alarms, s[span].desc);
130         return tmp;
131 }
132
133 static void add_cards(newtComponent spans)
134 {
135         int x;
136         char *s;
137         void *prev=NULL;
138         
139         if (spans)
140                 prev = newtListboxGetCurrent(spans);
141         newtListboxClear(spans);
142         for (x=0;x<DAHDI_MAX_SPANS;x++) {
143                 s = getalarms(x, 0);
144                 if (s && spans) {
145                         /* Found one! */
146                         newtListboxAppendEntry(spans, s, (void *)(long)x);
147                 }
148         }
149         if (spans)
150                 newtListboxSetCurrentByKey(spans, prev);
151         
152 }
153
154 static void sel_callback(newtComponent c, void *cbdata)
155 {
156         int span;
157         char info[256];
158         char info2[256];
159         cbdata = newtListboxGetCurrent(c);
160         if (cbdata) {
161                 span = (long)(cbdata);
162                 snprintf(info, sizeof (info), "Span %d: %d total channels, %d configured", span, s[span].totalchans, s[span].numchans);
163                 snprintf(info2, sizeof(info2), "%-59s F1=Details F10=Quit", info);
164         } else {
165                 span = -1;
166                 strcpy(info, "There are no DAHDI spans on this system.");
167                 snprintf(info2, sizeof(info2), "%-59s            F10=Quit", info);
168         }
169         newtPopHelpLine();
170         newtPushHelpLine(info2);
171 }
172
173 static void show_bits(int span, newtComponent bitbox, newtComponent inuse, newtComponent levels, newtComponent bpvcount,
174                                                 newtComponent alarms, newtComponent syncsrc, newtComponent irqmisses)
175 {
176         struct dahdi_params zp;
177         int x;
178         int res;
179         char c;
180         char tabits[80];
181         char tbbits[80];
182         char tcbits[80];
183         char tdbits[80];
184         char rabits[80];
185         char rbbits[80];
186         char rcbits[80];
187         char rdbits[80];
188         char tmp[1024];
189         
190         int use = 0;
191         
192         memset(tabits,0, sizeof(tabits));
193         memset(tbbits,0, sizeof(tbbits));
194         memset(rabits,0, sizeof(rabits));
195         memset(rbbits,0, sizeof(rbbits));
196         memset(tcbits,0, sizeof(tcbits));
197         memset(tdbits,0, sizeof(tdbits));
198         memset(rcbits,0, sizeof(rcbits));
199         memset(rdbits,0, sizeof(rdbits));
200         memset(tabits,32, span_max_chan_pos);
201         memset(tbbits,32, span_max_chan_pos);
202         memset(rabits,32, span_max_chan_pos);
203         memset(rbbits,32, span_max_chan_pos);
204         memset(tcbits,32, span_max_chan_pos);
205         memset(tdbits,32, span_max_chan_pos);
206         memset(rcbits,32, span_max_chan_pos);
207         memset(rdbits,32, span_max_chan_pos);
208         
209         for (x=0;x<DAHDI_MAX_CHANNELS;x++) {
210                 memset(&zp, 0, sizeof(zp));
211                 zp.channo = x;
212                 res = ioctl(ctl, DAHDI_GET_PARAMS, &zp);
213                 if (!res) {
214                         if (zp.spanno == span) {
215                                 if (zp.sigtype && (zp.rxbits > -1)) {
216                                         if (zp.rxbits & DAHDI_ABIT)
217                                                 rabits[zp.chanpos - 1] = '1';
218                                         else
219                                                 rabits[zp.chanpos - 1] = '0';
220                                         if (zp.rxbits & DAHDI_BBIT)
221                                                 rbbits[zp.chanpos - 1] = '1';
222                                         else
223                                                 rbbits[zp.chanpos - 1] = '0';
224
225                                         if (zp.rxbits & DAHDI_CBIT)
226                                                 rcbits[zp.chanpos - 1] = '1';
227                                         else
228                                                 rcbits[zp.chanpos - 1] = '0';
229                                         if (zp.rxbits & DAHDI_DBIT)
230                                                 rdbits[zp.chanpos - 1] = '1';
231                                         else
232                                                 rdbits[zp.chanpos - 1] = '0';
233
234                                         if (zp.txbits & DAHDI_ABIT)
235                                                 tabits[zp.chanpos - 1] = '1';
236                                         else
237                                                 tabits[zp.chanpos - 1] = '0';
238                                         if (zp.txbits & DAHDI_BBIT)
239                                                 tbbits[zp.chanpos - 1] = '1';
240                                         else
241                                                 tbbits[zp.chanpos - 1] = '0';
242                                         if (zp.txbits & DAHDI_CBIT)
243                                                 tcbits[zp.chanpos - 1] = '1';
244                                         else
245                                                 tcbits[zp.chanpos - 1] = '0';
246                                         if (zp.txbits & DAHDI_DBIT)
247                                                 tdbits[zp.chanpos - 1] = '1';
248                                         else
249                                                 tdbits[zp.chanpos - 1] = '0';
250                                 } else {
251                                         c = '-';
252                                         if (!zp.sigtype)
253                                                 c = ' ';
254                                         tabits[zp.chanpos - 1] = c;
255                                         tbbits[zp.chanpos - 1] = c;
256                                         tcbits[zp.chanpos - 1] = c;
257                                         tdbits[zp.chanpos - 1] = c;
258                                         rabits[zp.chanpos - 1] = c;
259                                         rbbits[zp.chanpos - 1] = c;
260                                         rcbits[zp.chanpos - 1] = c;
261                                         rdbits[zp.chanpos - 1] = c;
262                                 }
263                                 if (zp.rxisoffhook)
264                                         use++;
265                         }
266                 }
267         }
268         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);
269         newtTextboxSetText(bitbox, tmp);        
270         sprintf(tmp, "%3d/%3d/%3d", s[span].totalchans, s[span].numchans, use);
271         newtTextboxSetText(inuse, tmp);
272         sprintf(tmp, "%s/", dahdi_txlevelnames[s[span].txlevel]);
273         strcat(tmp, dahdi_txlevelnames[s[span].rxlevel]);
274         sprintf(tmp, "%3d/%3d", s[span].txlevel, s[span].rxlevel);
275         newtTextboxSetText(levels, tmp);
276         sprintf(tmp, "%7d", s[span].bpvcount);
277         newtTextboxSetText(bpvcount, tmp);
278         sprintf(tmp, "%7d", s[span].irqmisses);
279         newtTextboxSetText(irqmisses, tmp);
280         newtTextboxSetText(alarms, alarmstr(span));     
281         if (s[span].syncsrc > 0)
282                 strcpy(tmp, s[s[span].syncsrc].desc);
283         else
284                 strcpy(tmp, "Internally clocked");
285         newtTextboxSetText(syncsrc, tmp);
286         
287         
288 }
289
290 static newtComponent spans;
291 static void show_span(int span)
292 {
293         newtComponent form;
294         newtComponent back;
295         newtComponent label;
296         newtComponent bitbox;
297         newtComponent inuse;
298         newtComponent levels;
299         newtComponent bpvcount;
300         newtComponent alarms;
301         newtComponent syncsrc;
302         newtComponent irqmisses;
303         
304         char s1[] = "         1111111111222222222233";
305         char s2[] = "1234567890123456789012345678901";
306         int x;
307         struct newtExitStruct es;
308
309         void *ss;
310         char info2[256];
311
312         if (span < 0) {
313                 /* Display info on a span */
314                 ss = newtListboxGetCurrent(spans);
315                 if (ss) {
316                         span = (long)(ss);
317                 }
318         }
319
320         snprintf(info2, sizeof(info2), "%-59s            F10=Back", s[span].desc);
321         newtCenteredWindow(60,20, s[span].desc);
322         newtPushHelpLine(info2);
323
324         back = newtButton(48,8,"Back");
325         form = newtForm(NULL, NULL, 0);
326
327         newtFormAddComponents(form, back, NULL);
328
329         span_max_chan_pos = s[span].totalchans;
330         for (x=0;x<DAHDI_MAX_CHANNELS;x++) {
331                 struct dahdi_params zp;
332                 int res;
333                 memset(&zp, 0, sizeof(zp));
334                 zp.channo = x;
335                 res = ioctl(ctl, DAHDI_GET_PARAMS, &zp);
336                 if (!res && zp.spanno == span && zp.chanpos > span_max_chan_pos )
337                         span_max_chan_pos = zp.chanpos;
338         }
339
340         if (span_max_chan_pos > 32)
341                 span_max_chan_pos = 32;
342
343         s1[span_max_chan_pos] = '\0';
344         s2[span_max_chan_pos] = '\0';
345
346         bitbox = newtTextbox(8,10,span_max_chan_pos,9,0);
347         newtFormAddComponent(form, bitbox);
348
349         label = newtLabel(8,8,s1);
350         newtFormAddComponent(form, label);
351
352         label = newtLabel(8,9,s2);
353         newtFormAddComponent(form, label);
354
355         newtFormAddHotKey(form, NEWT_KEY_F10);
356         newtFormSetTimer(form, 200);
357
358         label = newtLabel(4,10,"TxA");
359         newtFormAddComponent(form, label);
360
361         label = newtLabel(4,11,"TxB");
362         newtFormAddComponent(form, label);
363
364         label = newtLabel(4,12,"TxC");
365         newtFormAddComponent(form, label);
366
367         label = newtLabel(4,13,"TxD");
368         newtFormAddComponent(form, label);
369
370         label = newtLabel(4,15,"RxA");
371         newtFormAddComponent(form, label);
372
373         label = newtLabel(4,16,"RxB");
374         newtFormAddComponent(form, label);
375
376         label = newtLabel(4,17,"RxC");
377         newtFormAddComponent(form, label);
378
379         label = newtLabel(4,18,"RxD");
380         newtFormAddComponent(form, label);
381         
382         
383         label = newtLabel(4,7,"Total/Conf/Act: ");
384         newtFormAddComponent(form, label);
385         
386         inuse = newtTextbox(24,7,12,1,0);
387         newtFormAddComponent(form, inuse);
388
389         label = newtLabel(4,6,"Tx/Rx Levels: ");
390         newtFormAddComponent(form, label);
391
392         levels = newtTextbox(24,6,30,1,0);
393         newtFormAddComponent(form, levels);
394         
395         label = newtLabel(4,5,"Bipolar Viol: ");
396         newtFormAddComponent(form, label);
397
398         bpvcount = newtTextbox(24,5,30,1,0);
399         newtFormAddComponent(form, bpvcount);
400         
401         label = newtLabel(4,4,"IRQ Misses: ");
402         newtFormAddComponent(form, label);
403
404         irqmisses = newtTextbox(24,4,30,1,0);
405         newtFormAddComponent(form, irqmisses);
406
407         label = newtLabel(4,3,"Sync Source: ");
408         newtFormAddComponent(form, label);
409
410         syncsrc = newtTextbox(24,3,30,1,0);
411         newtFormAddComponent(form, syncsrc);
412
413         label = newtLabel(4,2,"Current Alarms: ");
414         newtFormAddComponent(form, label);
415
416         alarms = newtTextbox(24,2,30,1,0);
417         newtFormAddComponent(form, alarms);
418         
419         for(;;) {
420                 /* Wait for user to select something */
421                 do {
422                         add_cards(NULL);
423                         show_bits(span, bitbox, inuse, levels, bpvcount, alarms, syncsrc, irqmisses);
424                         newtFormRun(form, &es);
425                 } while(es.reason == NEWT_EXIT_TIMER);
426                 switch(es.reason) {
427                 case NEWT_EXIT_COMPONENT:
428                         if (es.u.co == back) {
429                                 goto out;
430                         }
431                         break;
432                 case NEWT_EXIT_HOTKEY:
433                         switch(es.u.key) {
434 #if 0
435                         case NEWT_KEY_F1:
436                                 show_span(-1);
437                                 break;
438 #endif                          
439                         case NEWT_KEY_F10:
440                                 goto out;
441                         }
442                         break;
443                 default:
444                         break;
445                 }
446         }       
447
448 out:    
449         newtFormDestroy(form);
450         newtPopWindow();
451         newtPopHelpLine();
452         span_max_chan_pos = 0;
453 }
454
455 static void show_spans(void)
456 {
457         newtComponent form;
458         newtComponent quit;
459         newtComponent label;
460         newtComponent sel;
461
462         
463         struct newtExitStruct es;
464         
465         
466         quit = newtButton(50,14,"Quit");
467         sel = newtButton(10,14,"Select");
468         
469         spans = newtListbox(5, 2, 10, NEWT_FLAG_SCROLL);
470         newtListboxSetWidth(spans, 65);
471         
472         label = newtLabel(5,1,"Alarms          Span");
473         
474         newtCenteredWindow(72,18, "DAHDI Telephony Interfaces");
475         form = newtForm(NULL, NULL, 0);
476         
477         newtFormSetTimer(form, 200);
478         
479         newtFormAddComponents(form, spans, sel, quit, label, NULL);
480
481         newtComponentAddCallback(spans, sel_callback, NULL);
482
483         newtFormAddHotKey(form, NEWT_KEY_F1);
484         newtFormAddHotKey(form, NEWT_KEY_F10);
485         
486         for(;;) {
487                 /* Wait for user to select something */
488                 do {
489                         add_cards(spans);
490                         newtFormRun(form, &es);
491                 } while(es.reason == NEWT_EXIT_TIMER);
492
493                 switch(es.reason) {
494                 case NEWT_EXIT_COMPONENT:
495                         if (es.u.co == quit) {
496                                 /* Quit if appropriate */
497                                 newtFormDestroy(form);
498                                 return;
499                         } else if (es.u.co == sel) {
500                                 show_span(-1);
501                         }
502                         break;
503                 case NEWT_EXIT_HOTKEY:
504                         switch(es.u.key) {
505                         case NEWT_KEY_F1:
506                                 show_span(-1);
507                                 break;
508                         case NEWT_KEY_F10:
509                                 newtFormDestroy(form);
510                                 return;
511                         }
512                         break;
513                 default:
514                         break;
515                 }
516         }
517 }
518
519 static void cleanup(void)
520 {
521         newtPopWindow();
522 }
523
524 int main(int argc, char *argv[])
525 {
526
527         ctl = open("/dev/dahdi/ctl", O_RDWR);
528         if (ctl < 0) {
529                 fprintf(stderr, "Unable to open /dev/dahdi/ctl: %s\n", strerror(errno));
530                 exit(1);
531         }
532         newtInit();
533         newtCls();
534         
535         newtDrawRootText(0,0,"DAHDI Tool (C)2002-2008 Digium, Inc.");
536         newtPushHelpLine("Welcome to the DAHDI Tool!");
537         show_spans();
538         cleanup();
539         newtFinished();
540         return 0;
541 }