home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / SUN / SLIP / CSN_SLIP.TAR / slip-tip / libacu / telebit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-05  |  8.0 KB  |  361 lines

  1. /*
  2.  * Dialer support for Telebit Trailblazer Plus modem.
  3.  */
  4.  
  5. #ifndef lint
  6. static char *RCSid = "$Header: telebit.c,v 1.13 88/05/25 19:48:06 rayan Exp $";
  7. #endif
  8.  
  9. #undef DEBUG
  10.  
  11. #ifdef    DEBUG
  12. int debug = 1;
  13. #define STATIC
  14. #else
  15. #define STATIC static
  16. #endif
  17.  
  18. #include "tip.h"
  19. #include <sys/time.h>
  20.  
  21. /*
  22.  * The following is the Telebit register setup used here with this code, with
  23.  * the TB+ attached to a fixed-speed interface on a remote terminal server.
  24.  * When attaching to a computer the appropriate register should be set so
  25.  * the TB+ interface speed matches the connect baud rate.
  26.  *
  27. E0 F1 M1 Q1 P V1 X1     Version BA4.00
  28. S00=001 S01=000 S02=043 S03=013 S04=010 S05=008 S06=002 S07=040 S08=002 S09=006
  29. S10=007 S11=070 S12=050 
  30. S45=255 S47=004 S48=000 S49=000
  31. S50=000 S51=005 S52=002 S53=004 S54=003 S55=000 S56=017 S57=019 S58=000 S59=000
  32. S60=000 S61=000 S62=003 S63=001 S64=000 S65=000 S66=000 S67=000 S68=255 
  33. S90=000 S91=000 S92=000 S95=000 
  34. S100=000 S101=000 S102=000 S104=000 
  35. S110=001 S111=030 S112=001 
  36. S121=000 
  37.  *
  38.  */
  39.  
  40.     /* commands */
  41. STATIC char    NAME[] =        "telebit";
  42. STATIC char    WARMUP[] =        "\rat\r";
  43. STATIC char    RESULT_CODES[] =    "\ratq0\r";
  44. STATIC char    DONT_ANSWER[] =        "\rats0=0\r";
  45. STATIC char    IGN_ESCAPE[] =        "\rats55=3\r";
  46. STATIC char    CODES_4[] =        "\ratx1\r";
  47. STATIC char    DIAL_PREFIX[] =        "\ratdt8,";
  48.  
  49.     /* result codes */;
  50. STATIC char    MDM_OK[] =        "\r\nOK\r\n";
  51. STATIC char    RING[] =        "\r\nRING\r\n";
  52. STATIC char    RRING[] =        "\r\nRRING\r\n";
  53. STATIC char    NO_CARRIER[] =        "\r\nNO CARRIER\r\n";
  54. STATIC char    ERROR[] =        "\r\nERROR\r\n";
  55. STATIC char    CONNECT[] =        "\r\nCONNECT 300\r\n";
  56. STATIC char    CONNECT_1200[] =    "\r\nCONNECT 1200\r\n";
  57. STATIC char    CONNECT_2400[] =    "\r\nCONNECT 2400\r\n";
  58. STATIC char    CONNECT_9600[] =    "\r\nCONNECT 9600\r\n";
  59. STATIC char    CONNECT_FAST[] =    "\r\nCONNECT FAST\r\n";
  60. STATIC char    NO_DIALTONE[] =        "\r\nNO DIALTONE\r\n";
  61. STATIC char    NO_ANSWER[] =        "\r\nNO ANSWER\r\n";
  62. STATIC char    BUSY[] =        "\r\nBUSY\r\n";
  63.  
  64. STATIC char    *notbcon[] =    {    BUSY,
  65.                     NO_DIALTONE,
  66.                     NO_ANSWER,
  67.                     ERROR,
  68.                     RING,
  69.                     NO_CARRIER,
  70.                     0
  71.                 };
  72.  
  73. /* The baudrate starts at 300, and doubles for next element of array */
  74. STATIC char    *tbcon[] =    {    CONNECT,
  75.                     "ignore",
  76.                     CONNECT_1200,
  77.                     CONNECT_2400,
  78.                     "ignore",
  79.                     CONNECT_9600,
  80.                     CONNECT_FAST,
  81.                     0
  82.                 };
  83. #ifdef    USG
  84. STATIC struct termio termio;        /* needed on USG to set HUPCL */
  85. #endif    /* USG */
  86.  
  87. #define    CMD_DELAY    5    /* number of seconds to wait for response
  88.                     while in command mode */
  89. #define DIAL_DELAY    120    /* number of seconds to wait for response
  90.                     after sending dial string */
  91. #define    MAXSTR    100
  92.  
  93. static jmp_buf    jmpbuf;
  94.  
  95. int     tbread(), tbwrite();
  96.  
  97. tb_dialer(num, acu)
  98. register char    *num;
  99. char    *acu;
  100. {
  101.     int    ret;
  102.     int    i, j;
  103.     char    buf1[MAXSTR], buf2[MAXSTR], buf3[MAXSTR];
  104. #ifdef ACULOG
  105.     char    line[MAXSTR];
  106. #endif
  107.  
  108.     /*
  109.      * wake up the modem if it's listening...
  110.      */
  111.     if (boolean(value(VERBOSE)))
  112.         printf("diddling dialer...");
  113. #ifdef DEBUG
  114.     if (debug)
  115.         fprintf(stderr, "BR=%d\n", BR);
  116. #endif
  117.  
  118.     sleep(1);    /* Give modem time to settle down after reset */
  119.     if ((!tbset(RESULT_CODES, buf1, num, "is naughty")
  120.              && !tbset(RESULT_CODES, buf1, num, "not listening"))
  121.         || !tbset(DONT_ANSWER, buf1, num, "auto-answer not turned off")
  122.         || !tbset(IGN_ESCAPE, buf1, num, "escape code not turned off")
  123.         || !tbset(CODES_4, buf1, num, "result codes not set"))
  124.         return 0;
  125.  
  126.     /* insurance ? */
  127. #ifdef    USG
  128.     if (ioctl(FD, TCGETA, &termio) < 0)
  129.         perror("tip: TCGETA ioctl");
  130.     termio.c_cflag |= HUPCL;
  131.     if (ioctl(FD, TCSETA, &termio) < 0)
  132.         perror("tip: TCSETA ioctl");
  133. #else    /* USG */
  134.     if (ioctl(FD, TIOCHPCL, 0) < 0)
  135.         perror("tip: TIOCHPCL ioctl");
  136. #endif    /* USG */
  137.  
  138.     buf2[0] = '\0';
  139.     for (i = 0, j = 300; tbcon[i] != (char *)0; i++, j*=2) {
  140.         if (BR == j) {
  141.             strcpy(buf2, tbcon[i]);
  142.             break;
  143.         }
  144.     }
  145.     if (buf2[0] == '\0') {
  146.         sprintf(buf2, "unsupported baud rate (%d)", BR);
  147.         goto error;
  148.     }
  149.  
  150.     /* Is it safe to just say ATD and let the options setting rule? */
  151.     tbwrite(DIAL_PREFIX);
  152.     tbwrite(num);
  153.     tbwrite("\r");
  154.     if (boolean(value(VERBOSE)))
  155.         printf(" dialing... ");
  156.     do {
  157.         if (ret = tbread(buf1, DIAL_DELAY, 64) == 0) {
  158.             strcpy(buf2, "TIMEOUT on dial");
  159.             goto error;
  160.         }
  161.         if (ret == -1) {
  162.             strcpy(buf2, "ioctl failed");
  163.             goto error;
  164.         }
  165.     } while (strncmp(buf1, RRING, strlen(RRING)) == 0
  166.         && (!boolean(value(VERBOSE)) || (printf("rrring... "), 1)));
  167.     if (strncmp(buf1, buf2, strlen(buf2)) != 0) {
  168.         for (i = 0, j = 300; tbcon[i] != (char *)0; i++, j *= 2) {
  169.             if (!strncmp(buf1, tbcon[i], strlen(tbcon[i]))) {
  170.                 /* This should never fail */
  171.                 if ((i = speed(j)) != NULL) {
  172.                     BR = j;
  173.                     ttysetup(i);
  174.                 } else {
  175.                     printf("speed(%d) failed\n", j);
  176.                     return 0;
  177.                 }
  178.                 goto ok;
  179.             }
  180.         }
  181.         for (i = 0; notbcon[i] != (char *)0; i++) {
  182.             if (!strncmp(buf1, notbcon[i], strlen(notbcon[i]))){
  183.                 char    *bp, *cp;
  184.                 for (bp = buf2, cp = notbcon[i]; *cp; cp++) {
  185.                     if (*cp != '\r' && *cp != '\n')
  186.                         *bp++ = *cp;
  187.                 }
  188.                 *bp = '\0';
  189.                 goto error;
  190.             }
  191.         }
  192.         (void) strcpy(buf2, "UNKNOWN ERROR [");
  193.         (void) strcat(buf2, buf1);
  194.         (void) strcat(buf2, "]");
  195. error:
  196.         printf("dial failed (%s)\n", buf2);
  197.         sprintf(buf3, "dial failed (%s)", buf2);
  198. #ifdef ACULOG
  199.         logent(value(HOST), num, NAME, buf3);
  200. #endif
  201.         return 0;
  202.     }
  203. ok:
  204.     if (boolean(value(VERBOSE)))
  205.         printf("(%d baud) ", BR);
  206.     i = 2;
  207. #ifdef    USG
  208.     if (ioctl(FD, TCFLSH, i) < 0)
  209.         perror("tip: TCFLSH ioctl");
  210. #else    /* USG */
  211.     if (ioctl(FD, TIOCFLUSH, &i) < 0)
  212.         perror("tip: TIOCFLUSH ioctl");
  213. #endif    /* USG */
  214.     return 1;
  215. }
  216.  
  217.  
  218. tb_disconnect()
  219. {
  220. #ifdef    USG
  221.     if (ioctl(FD, TCGETA, &termio) < 0)
  222.         perror("tip: TCGETA ioctl");
  223.     termio.c_cflag &= (CBAUD & B0);
  224.     if (ioctl(FD, TCSETA, &termio) < 0)
  225.         perror("tip: TCSETA ioctl");
  226.     sleep(2);
  227. #endif    /* USG */
  228.     (void) close(FD);
  229. }
  230.  
  231.  
  232. tb_abort()
  233. {
  234.     tb_disconnect();
  235. }
  236.  
  237. STATIC
  238. tbwrite(cp)
  239. register char    *cp;
  240. {
  241.     struct timeval t;
  242.  
  243.     for (; *cp != '\0' ; cp++) {
  244.         if (write(FD, cp, 1) != 1) {
  245.             perror("tip: tbwrite: write error");
  246.             return;
  247.         }
  248. #ifdef    DEBUG
  249.         if (debug) {
  250.             fprintf(stderr, "written '%c'\n", *cp);
  251.         }
  252. #endif
  253.         t.tv_sec = 0;
  254.         t.tv_usec = (20 * 10 * 1000000)/BR;
  255.         (void) select(32, 0, 0, 0, &t);
  256.     }
  257. }
  258.  
  259. STATIC
  260. tbread(buf, timeout, max)
  261. register char    *buf;
  262. unsigned int timeout, max;
  263. {
  264.     int    alarmtr();
  265.     struct timeval t;
  266.     register char    *rp;
  267.     unsigned int numread, numprev = 0, numpndg = 0;
  268.     unsigned int toread;
  269.  
  270. #ifdef    DEBUG
  271.     if (debug)
  272.         fprintf(stderr, "\n---------\nentering tbread(): timeout is: %d, max is: %d\n", timeout, max);
  273. #endif
  274.     rp = buf;
  275.     *rp = '\0';
  276.     (void) signal(SIGALRM, alarmtr);
  277.     if (setjmp(jmpbuf)) {
  278.         *rp = '\0';
  279.         return 0;
  280.     }
  281.     (void) alarm(timeout);
  282.         /* wait till modem says something or until timeout */
  283.     while (numpndg == 0 || numpndg != numprev) {
  284.         numprev = numpndg;
  285.         if (ioctl(FD, FIONREAD, &numpndg) == -1) {
  286.             perror("tip: FIONREAD ioctl");
  287.             return -1;
  288.         }
  289.         t.tv_sec = 0;
  290.         t.tv_usec = (100 * 10 * 1000000)/BR;
  291.         (void) select(32, 0, 0, 0, &t);
  292.     }
  293.     (void) alarm(0);
  294. #ifdef    DEBUG
  295.     if (debug)
  296.         fprintf(stderr, "number of chars waiting is: %d\n", numpndg);
  297. #endif
  298.     toread = ((numpndg > max) ? max : numpndg);
  299.       if ((numread = read(FD, rp, toread)) < toread)
  300.         perror("read error");
  301. #ifdef    DEBUG
  302.     if (debug) {
  303.         int i; char *p;
  304.         fprintf(stderr, "read %d chars:", numread);
  305.         for (i=0, p=rp; i<numread; i++, p++)
  306.             fprintf(stderr, "%0.2x ", *p);
  307.         fprintf(stderr, "\n");
  308.         fflush(stderr);
  309.     }
  310. #endif
  311.     rp += numread;
  312.     *rp = '\0';
  313. #ifdef    DEBUG
  314.     if (debug) {
  315.         fprintf(stderr, "\nbuf contains: ->%s<-\n", buf);
  316.         fprintf(stderr, "leaving tbread()\n-----------\n");
  317.         fflush(stderr);
  318.     }
  319. #endif
  320.     return 1;
  321. }
  322.  
  323.  
  324. STATIC
  325. accept(baudrate)
  326. int    baudrate;
  327. {
  328.     int i;
  329.  
  330.     BR = baudrate;
  331.     if ((i = speed(baudrate)) != NULL)
  332.         ttysetup(i);
  333. }
  334.  
  335.  
  336. STATIC
  337. alarmtr()
  338. {
  339. #ifdef    DEBUG
  340.     if (debug)
  341.         fprintf(stderr, "alarm went off!\n");
  342. #endif
  343.     longjmp(jmpbuf, 1);
  344. }
  345.  
  346. STATIC int
  347. tbset(tosend, buf, num, errmsg)
  348. char    *tosend, *buf, *num, *errmsg;
  349. {
  350.     tbwrite(tosend);
  351.     tbread(buf, CMD_DELAY, (u_int) (sizeof MDM_OK) - 1);
  352.     if (strncmp(buf, MDM_OK, (sizeof MDM_OK) - 1) != 0) {
  353.         printf(" %s modem %s\n", NAME, errmsg);
  354. #ifdef ACULOG
  355.         logent(value(HOST), num, NAME, errmsg);
  356. #endif
  357.         return 0;
  358.     }
  359.     return 1;
  360. }
  361.