]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - usr.sbin/i4b/isdnphone/main.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / usr.sbin / i4b / isdnphone / main.c
1 /*
2  * Copyright (c) 1999, 2002 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      isdnphone - main module
28  *      =======================
29  *
30  * $FreeBSD$
31  *
32  *      last edit-date: [Tue Aug 27 16:38:55 2002]
33  *
34  *---------------------------------------------------------------------------*/
35
36 #define MAIN
37 #include "defs.h"
38
39 static void kbd_hdlr(void);
40
41 /*---------------------------------------------------------------------------*
42  *      usage display and exit
43  *---------------------------------------------------------------------------*/
44 static void
45 usage(void)
46 {
47         fprintf(stderr, "\n");
48         fprintf(stderr, "isdnphone - i4b phone program, version %d.%d.%d\n",VERSION, REL, STEP);
49         fprintf(stderr, "usage: isdnphone -d -h -k <string> -n <number> -u <unit> -v -w\n");
50         fprintf(stderr, "       -d            debug\n");
51         fprintf(stderr, "       -h            hangup\n");
52         fprintf(stderr, "       -k string     keypad string\n");
53         fprintf(stderr, "       -n number     dial number\n");
54         fprintf(stderr, "       -u unit       set unit number\n");
55         fprintf(stderr, "       -v            be verbose\n");
56         fprintf(stderr, "       -w            wait for response (with -n)\n");
57         fprintf(stderr, "\n");
58         exit(1);
59 }
60
61 /*---------------------------------------------------------------------------*
62  *      program entry
63  *---------------------------------------------------------------------------*/
64 int
65 main(int argc, char **argv)
66 {
67         int c;
68         char namebuffer[128];
69         int bschar;
70         int ret;
71         int opt_n = 0;
72         int opt_s = 0;
73         int opt_h = 0;
74         int opt_k = 0;
75         int opt_v = 0;
76         int opt_w = 0;
77         char *number = "";
78         char *subaddr = "";
79         
80         numberbuffer[0] = '\0'; 
81
82         while ((c = getopt(argc, argv, "dhk:n:s:u:w")) != -1)
83         {
84                 switch(c)
85                 {
86                         case 'd':
87                                 opt_d = 1;
88                                 break;
89                                 
90                         case 'h':
91                                 opt_h = 1;
92                                 break;
93                                 
94                         case 'k':
95                                 number = optarg;
96                                 opt_k = 1;
97                                 break;
98                                 
99                         case 'n':
100                                 number = optarg;
101                                 opt_n = 1;
102                                 break;
103
104                         case 's':
105                                 subaddr = optarg;
106                                 opt_s = 1;
107                                 break;
108                                 
109                         case 'u':
110                                 opt_unit = atoi(optarg);
111                                 if(opt_unit < 0 || opt_unit > 9)
112                                         usage();
113                                 break;
114
115                         case 'v':
116                                 opt_v = 1;
117                                 break;
118                                 
119                         case 'w':
120                                 opt_w = 1;
121                                 break;
122                                 
123                         case '?':
124                         default:
125                                 usage();
126                                 break;
127                 }
128         }
129
130         sprintf(namebuffer,"%s%d", I4BTELDDEVICE, opt_unit);
131         
132         if((dialerfd = init_dial(namebuffer)) == -1)
133                 exit(1);
134
135         if(opt_n || opt_h || opt_k)
136         {
137                 char commandbuffer[80];
138                 int exitval = 0;
139                 
140                 /* commandline operation goes here */
141                 
142                 if(opt_n)
143                 {
144                         if(opt_s)
145                                 sprintf(commandbuffer, "D%s*%s", number, subaddr);
146                         else
147                                 sprintf(commandbuffer, "D%s", number);
148         
149                 }
150                 else if(opt_k)
151                 {
152                         sprintf(commandbuffer, "K%s", number);
153         
154                 }
155                 else if(opt_h)
156                 {
157                         sprintf(commandbuffer, "H");
158                 }
159         
160                 if((ret = write(dialerfd, commandbuffer, strlen(commandbuffer))) < 0)
161                 {
162                         fprintf(stderr, "write commandbuffer failed: %s", strerror(errno));
163                         exit(1);
164                 }
165         
166                 if(opt_n && opt_w)
167                 {
168                         char result;
169
170                         if((read (dialerfd, &result, 1) < 0))
171                         {
172                                 exitval = 99;
173                                 if(opt_v)
174                                         printf("error\n");
175                                 fprintf(stderr, "error, read failed: %s\n", strerror(errno));
176                         }
177                         else
178                         {
179                                 switch(result)
180                                 {
181                                         case RSP_CONN:
182                                                 exitval = 0;
183                                                 if(opt_v)
184                                                         printf("connected\n");
185                                                 break;
186                                                 
187                                         case RSP_BUSY:
188                                                 exitval = 1;
189                                                 if(opt_v)
190                                                         printf("busy\n");
191                                                 break;
192                         
193                                         case RSP_HUP:
194                                                 exitval = 2;
195                                                 if(opt_v)
196                                                         printf("disconnected\n");
197                                                 break;
198                         
199                                         case RSP_NOA:
200                                                 exitval = 3;
201                                                 if(opt_v)
202                                                         printf("noanswer\n");
203                                                 break;
204                         
205                                         default:
206                                                 exitval = 99;
207                                                 if(opt_v)
208                                                         printf("error\n");
209                                                 fprintf(stderr, "unknown response = 0x%2x!", result);
210                                                 break;
211                                 }
212                         }
213                 }
214
215                 close(dialerfd);
216                 
217                 exit(exitval);
218         }
219
220         if((audiofd = init_audio(AUDIODEVICE)) == -1)
221                 exit(1);
222         
223         /* fullscreen operation here */ 
224
225         init_mainw();
226
227         bschar = erasechar();
228         curx = 0;
229
230         wmove(main_w, MW_NUMY, MW_NUX + curx);
231         
232         /* go into loop */
233
234         for (;;)
235         {
236                 int maxfd = 0;
237                 fd_set set;
238                 struct timeval timeout;
239
240                 FD_ZERO(&set);
241                 
242                 FD_SET(STDIN_FILENO, &set);
243                 if(STDIN_FILENO > maxfd)
244                         maxfd = STDIN_FILENO;
245                 
246                 FD_SET(dialerfd, &set);
247                 if(dialerfd > maxfd)
248                         maxfd = dialerfd;
249                 
250                 if(state == ST_ACTIVE)
251                 {
252                         if(audiofd != -1)
253                         {
254                                 FD_SET(audiofd, &set);
255                                 if(audiofd > maxfd)
256                                         maxfd = audiofd;
257                         }
258                         
259                         if(telfd != -1)
260                         {
261                                 FD_SET(telfd, &set);
262                                 if(telfd > maxfd)
263                                         maxfd = telfd;
264                         }
265                 }
266                 
267                 timeout.tv_sec = 2;
268                 timeout.tv_usec = 0;
269
270                 wrefresh(main_w);
271                 
272                 /* if no char is available within timeout, do something */
273                 
274 #ifdef NOTDEF
275                 ret = select(maxfd+1, &set, NULL, NULL, &timeout);
276 #else
277                 ret = select(maxfd+1, &set, NULL, NULL, NULL);
278 #endif
279
280                 if(ret > 0)
281                 {
282                         if((telfd != -1) && (FD_ISSET(telfd, &set)))
283                         {
284                                 message("select from ISDN");
285                                 tel_hdlr();
286                         }
287                         if((audiofd != -1) && (FD_ISSET(audiofd, &set)))
288                         {
289                                 message("select from audio");
290                                 audio_hdlr();
291                         }
292                         if(FD_ISSET(dialerfd, &set))
293                         {
294                                 message("select from tel");
295                                 dial_hdlr();
296                         }
297                         if(FD_ISSET(STDIN_FILENO, &set))
298                         {
299                                 message("select from kbd");
300                                 kbd_hdlr();
301                         }
302                 }
303         }
304         do_quit(0);
305         
306         return(0);
307 }
308
309 /*---------------------------------------------------------------------------*
310  *      keyboard character available handler
311  *---------------------------------------------------------------------------*/
312 static void
313 kbd_hdlr(void)
314 {               
315         int kchar;
316
317         kchar = wgetch(main_w);         /* get char */
318                                 
319         switch (kchar)
320         {
321                 case CR:
322                 case LF:
323 #ifdef KEY_ENTER
324                 case KEY_ENTER:
325 #endif
326                         if((state == ST_IDLE) &&
327                            (numberbuffer[0] != '\0'))
328                         {
329                                 message("dialing .....");
330                                 do_dial(&numberbuffer[0]);
331                         }
332                         else
333                         {
334                                 do_menu();
335                         }
336                         break;
337
338                 case CNTRL_D:
339                         if(state == ST_IDLE)
340                         {
341                                 do_quit(0);
342                         }
343                         else
344                         {
345                                 message("cannot exit while not idle!");
346                                 beep();
347                         }
348                         
349                         break;
350
351                 case CNTRL_L:   /* refresh */
352                         touchwin(curscr);
353                         wrefresh(curscr);
354                         break;
355
356                 case KEY_BACKSPACE:
357                 case KEY_DC:
358                         if (curx == 0)
359                                 break;
360
361                         curx--;
362                         mvwaddch(main_w, MW_NUMY, MW_NUX + curx, ' ');
363                         numberbuffer[curx] = '\0';
364                         wmove(main_w, MW_NUMY, MW_NUX + curx);
365
366                         if(curx == 0)
367                                 message(" ");
368                         
369                         break;
370                         
371                 case '0':
372                 case '1':
373                 case '2':
374                 case '3':
375                 case '4':
376                 case '5':
377                 case '6':
378                 case '7':
379                 case '8':
380                 case '9':
381                         if(curx > (TELNO_MAX-1))
382                                 break;
383
384                         mvwaddch(main_w, MW_NUMY, MW_NUX + curx, kchar);
385                         
386                         numberbuffer[curx] = kchar;
387
388                         curx++;
389
390                         numberbuffer[curx] = '\0';
391                         
392                         message("press ENTER to dial number .....");
393                         break;
394         }
395 }
396
397 /*---------------------------------------------------------------------------*
398  *      exit program
399  *---------------------------------------------------------------------------*/
400 void
401 do_quit(int exitval)
402 {
403         close(dialerfd);
404         move(LINES-1, 0);
405         clrtoeol();
406         refresh();
407         endwin();
408         exit(exitval);
409 }
410
411 /*---------------------------------------------------------------------------*
412  *      fatal error exit
413  *---------------------------------------------------------------------------*/
414 void
415 fatal(char *fmt, ...)
416 {
417         va_list ap;
418
419         va_start(ap, fmt);
420
421         do_hangup();            /* failsafe */
422         
423         if(curses_ready)
424         {       
425                 close(dialerfd);
426                 move(LINES-1, 0);
427                 clrtoeol();
428                 refresh();
429                 endwin();
430         }
431
432         fprintf(stderr, "\nFatal error: ");
433         vfprintf(stderr, fmt, ap);
434         fprintf(stderr, "\n\n");
435                 
436         va_end(ap);
437
438         exit(1);
439 }
440
441 /*---------------------------------------------------------------------------*
442  *      message printing
443  *---------------------------------------------------------------------------*/
444 void
445 message(char *fmt, ...)
446 {
447         va_list ap;
448
449         va_start(ap, fmt);
450
451         if(curses_ready)
452         {
453                 int i;
454                 char sbuf[MW_WIDTH];
455                 
456                 wmove(main_w, MW_MSGY, MW_MSX);
457                 vsnprintf(sbuf, MW_WIDTH-MW_MSX-1, fmt, ap);
458                 waddstr(main_w, sbuf);
459                 for(i=strlen(sbuf);i < MW_WIDTH-MW_MSX-2; i++)
460                         waddch(main_w, ' ');
461                 wmove(main_w, MW_NUMY, MW_NUX + curx);                  
462                 wrefresh(main_w);
463         }
464         else
465         {
466                 fprintf(stderr, "ERROR: ");
467                 vfprintf(stderr, fmt, ap);
468                 fprintf(stderr, "\n");
469         }
470                 
471         va_end(ap);
472 }
473
474 /*---------------------------------------------------------------------------*
475  *      message printing
476  *---------------------------------------------------------------------------*/
477 void
478 debug(char *fmt, ...)
479 {
480         va_list ap;
481
482         if(opt_d == 0)
483                 return;
484                 
485         va_start(ap, fmt);
486
487         vwprintw(dbg_w, fmt, ap);
488         wrefresh(dbg_w);
489                 
490         va_end(ap);
491 }
492
493 /*---------------------------------------------------------------------------*
494  *      go to new state
495  *---------------------------------------------------------------------------*/
496 void
497 newstate(int newstate)
498 {
499         int i;
500         
501         if(newstate < 0 || newstate > ST_MAX)
502         {
503                 message("newstate %d undefined!", newstate);
504                 return;
505         }
506
507         state = newstate;
508
509         if(newstate == ST_ACTIVE)
510         {
511                 char namebuffer[128];
512                 
513                 sprintf(namebuffer,"%s%d", I4BTELDEVICE, opt_unit);
514                 telfd = init_tel(namebuffer);
515         }
516
517         if(newstate == ST_IDLE)
518         {
519                 close(telfd);
520                 telfd = -1;
521         }
522         
523         wmove(main_w, MW_STATEY, MW_STX);
524         waddstr(main_w, states[newstate]);
525
526         for(i=strlen(states[newstate]);i < MW_WIDTH-MW_STX-2; i++)
527                 waddch(main_w, ' ');
528
529         wmove(main_w, MW_NUMY, MW_NUX + curx);                  
530         wrefresh(main_w);
531 }
532
533 /* EOF */