home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / tip / aculib / hayes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-18  |  7.0 KB  |  306 lines

  1. /*
  2.  * Copyright (c) 1983 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)hayes.c    5.4 (Berkeley) 3/2/91";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  * Routines for calling up on a Hayes Modem
  40.  * (based on the old VenTel driver).
  41.  * The modem is expected to be strapped for "echo".
  42.  * Also, the switches enabling the DTR and CD lines
  43.  * must be set correctly.
  44.  * NOTICE:
  45.  * The easy way to hang up a modem is always simply to
  46.  * clear the DTR signal. However, if the +++ sequence
  47.  * (which switches the modem back to local mode) is sent
  48.  * before modem is hung up, removal of the DTR signal
  49.  * has no effect (except that it prevents the modem from
  50.  * recognizing commands).
  51.  * (by Helge Skrivervik, Calma Company, Sunnyvale, CA. 1984) 
  52.  */
  53. /*
  54.  * TODO:
  55.  * It is probably not a good idea to switch the modem
  56.  * state between 'verbose' and terse (status messages).
  57.  * This should be kicked out and we should use verbose 
  58.  * mode only. This would make it consistent with normal
  59.  * interactive use thru the command 'tip dialer'.
  60.  */
  61. #include "tip.h"
  62.  
  63. #define    min(a,b)    ((a < b) ? a : b)
  64.  
  65. static    void sigALRM();
  66. static    int timeout = 0;
  67. static    jmp_buf timeoutbuf;
  68. static     char gobble();
  69. #define DUMBUFLEN    40
  70. static char dumbuf[DUMBUFLEN];
  71.  
  72. #define    DIALING        1
  73. #define IDLE        2
  74. #define CONNECTED    3
  75. #define    FAILED        4
  76. static    int state = IDLE;
  77.  
  78. hay_dialer(num, acu)
  79.     register char *num;
  80.     char *acu;
  81. {
  82.     register char *cp;
  83.     register int connected = 0;
  84.     char dummy;
  85. #ifdef ACULOG
  86.     char line[80];
  87. #endif
  88.     if (hay_sync() == 0)        /* make sure we can talk to the modem */
  89.         return(0);
  90.     if (boolean(value(VERBOSE)))
  91.         printf("\ndialing...");
  92.     fflush(stdout);
  93.     ioctl(FD, TIOCHPCL, 0);
  94.     ioctl(FD, TIOCFLUSH, 0);    /* get rid of garbage */
  95.     write(FD, "ATv0\r", 5);    /* tell modem to use short status codes */
  96.     gobble("\r");
  97.     gobble("\r");
  98.     write(FD, "ATTD", 4);    /* send dial command */
  99.     write(FD, num, strlen(num));
  100.     state = DIALING;
  101.     write(FD, "\r", 1);
  102.     connected = 0;
  103.     if (gobble("\r")) {
  104.         if ((dummy = gobble("01234")) != '1')
  105.             error_rep(dummy);
  106.         else
  107.             connected = 1;
  108.     }
  109.     if (connected)
  110.         state = CONNECTED;
  111.     else {
  112.         state = FAILED;
  113.         return (connected);    /* lets get out of here.. */
  114.     }
  115.     ioctl(FD, TIOCFLUSH, 0);
  116. #ifdef ACULOG
  117.     if (timeout) {
  118.         sprintf(line, "%d second dial timeout",
  119.             number(value(DIALTIMEOUT)));
  120.         logent(value(HOST), num, "hayes", line);
  121.     }
  122. #endif
  123.     if (timeout)
  124.         hay_disconnect();    /* insurance */
  125.     return (connected);
  126. }
  127.  
  128.  
  129. hay_disconnect()
  130. {
  131.     char c;
  132.     int len, rlen;
  133.  
  134.     /* first hang up the modem*/
  135. #ifdef DEBUG
  136.     printf("\rdisconnecting modem....\n\r");
  137. #endif
  138.     ioctl(FD, TIOCCDTR, 0);
  139.     sleep(1);
  140.     ioctl(FD, TIOCSDTR, 0);
  141.     goodbye();
  142. }
  143.  
  144. hay_abort()
  145. {
  146.  
  147.     char c;
  148.  
  149.     write(FD, "\r", 1);    /* send anything to abort the call */
  150.     hay_disconnect();
  151. }
  152.  
  153. static void
  154. sigALRM()
  155. {
  156.  
  157.     printf("\07timeout waiting for reply\n\r");
  158.     timeout = 1;
  159.     longjmp(timeoutbuf, 1);
  160. }
  161.  
  162. static char
  163. gobble(match)
  164.     register char *match;
  165. {
  166.     char c;
  167.     sig_t f;
  168.     int i, status = 0;
  169.  
  170.     f = signal(SIGALRM, sigALRM);
  171.     timeout = 0;
  172. #ifdef DEBUG
  173.     printf("\ngobble: waiting for %s\n", match);
  174. #endif
  175.     do {
  176.         if (setjmp(timeoutbuf)) {
  177.             signal(SIGALRM, f);
  178.             return (0);
  179.         }
  180.         alarm(number(value(DIALTIMEOUT)));
  181.         read(FD, &c, 1);
  182.         alarm(0);
  183.         c &= 0177;
  184. #ifdef DEBUG
  185.         printf("%c 0x%x ", c, c);
  186. #endif
  187.         for (i = 0; i < strlen(match); i++)
  188.             if (c == match[i])
  189.                 status = c;
  190.     } while (status == 0);
  191.     signal(SIGALRM, SIG_DFL);
  192. #ifdef DEBUG
  193.     printf("\n");
  194. #endif
  195.     return (status);
  196. }
  197.  
  198. error_rep(c)
  199.     register char c;
  200. {
  201.     printf("\n\r");
  202.     switch (c) {
  203.  
  204.     case '0':
  205.         printf("OK");
  206.         break;
  207.  
  208.     case '1':
  209.         printf("CONNECT");
  210.         break;
  211.     
  212.     case '2':
  213.         printf("RING");
  214.         break;
  215.     
  216.     case '3':
  217.         printf("NO CARRIER");
  218.         break;
  219.     
  220.     case '4':
  221.         printf("ERROR in input");
  222.         break;
  223.     
  224.     case '5':
  225.         printf("CONNECT 1200");
  226.         break;
  227.     
  228.     default:
  229.         printf("Unknown Modem error: %c (0x%x)", c, c);
  230.     }
  231.     printf("\n\r");
  232.     return;
  233. }
  234.  
  235. /*
  236.  * set modem back to normal verbose status codes.
  237.  */
  238. goodbye()
  239. {
  240.     int len, rlen;
  241.     char c;
  242.  
  243.     ioctl(FD, TIOCFLUSH, &len);    /* get rid of trash */
  244.     if (hay_sync()) {
  245.         sleep(1);
  246. #ifndef DEBUG
  247.         ioctl(FD, TIOCFLUSH, 0);
  248. #endif
  249.         write(FD, "ATH0\r", 5);        /* insurance */
  250. #ifndef DEBUG
  251.         c = gobble("03");
  252.         if (c != '0' && c != '3') {
  253.             printf("cannot hang up modem\n\r");
  254.             printf("please use 'tip dialer' to make sure the line is hung up\n\r");
  255.         }
  256. #endif
  257.         sleep(1);
  258.         ioctl(FD, FIONREAD, &len);
  259. #ifdef DEBUG
  260.         printf("goodbye1: len=%d -- ", len);
  261.         rlen = read(FD, dumbuf, min(len, DUMBUFLEN));
  262.         dumbuf[rlen] = '\0';
  263.         printf("read (%d): %s\r\n", rlen, dumbuf);
  264. #endif
  265.         write(FD, "ATv1\r", 5);
  266.         sleep(1);
  267. #ifdef DEBUG
  268.         ioctl(FD, FIONREAD, &len);
  269.         printf("goodbye2: len=%d -- ", len);
  270.         rlen = read(FD, dumbuf, min(len, DUMBUFLEN));
  271.         dumbuf[rlen] = '\0';
  272.         printf("read (%d): %s\r\n", rlen, dumbuf);
  273. #endif
  274.     }
  275.     ioctl(FD, TIOCFLUSH, 0);    /* clear the input buffer */
  276.     ioctl(FD, TIOCCDTR, 0);        /* clear DTR (insurance) */
  277.     close(FD);
  278. }
  279.  
  280. #define MAXRETRY    5
  281.  
  282. hay_sync()
  283. {
  284.     int len, retry = 0;
  285.  
  286.     while (retry++ <= MAXRETRY) {
  287.         write(FD, "AT\r", 3);
  288.         sleep(1);
  289.         ioctl(FD, FIONREAD, &len);
  290.         if (len) {
  291.             len = read(FD, dumbuf, min(len, DUMBUFLEN));
  292.             if (index(dumbuf, '0') || 
  293.                (index(dumbuf, 'O') && index(dumbuf, 'K')))
  294.                 return(1);
  295. #ifdef DEBUG
  296.             dumbuf[len] = '\0';
  297.             printf("hay_sync: (\"%s\") %d\n\r", dumbuf, retry);
  298. #endif
  299.         }
  300.         ioctl(FD, TIOCCDTR, 0);
  301.         ioctl(FD, TIOCSDTR, 0);
  302.     }
  303.     printf("Cannot synchronize with hayes...\n\r");
  304.     return(0);
  305. }
  306.