home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / pcomm / part03 / dial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-17  |  6.3 KB  |  323 lines

  1. /*
  2.  * The routines that dial the modem and listen for the return codes.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <termio.h>
  7. #ifdef UNIXPC
  8. #include <sys/phone.h>
  9. #endif /* UNIXPC */
  10. #include "dial_dir.h"
  11. #include "modem.h"
  12. #include "param.h"
  13. #include "status.h"
  14.  
  15. /*
  16.  * Get the dial string ready, send it to the modem.  The parameter is not
  17.  * the actual entry number, it is an index into the queue.
  18.  */
  19.  
  20. void
  21. dial_it(num)
  22. int num;
  23. {
  24.     int i;
  25.     char s[100], number[40], *strcpy(), *strcat(), *n, *strchr();
  26.     void send_str();
  27. #ifdef UNIXPC
  28.     struct updata pbuf;
  29.     unsigned int sleep();
  30. #endif /* UNIXPC */
  31.  
  32.     /*
  33.      * Create the string to be sent to the modem.  The long distance
  34.      * codes are added if they are requested.
  35.      */
  36.     s[0] = NULL;
  37.     strcpy(s, modem->dial[modem->m_cur]);
  38.  
  39.     switch (dir->q_ld[num]) {
  40.         case 0:            /* no ld code requested */
  41.             break;
  42.         case '+':
  43.             strcat(s, param->ld_plus);
  44.             break;
  45.         case '-':
  46.             strcat(s, param->ld_minus);
  47.             break;
  48.         case '@':
  49.             strcat(s, param->ld_at);
  50.             break;
  51.         case '#':
  52.             strcat(s, param->ld_pound);
  53.             break;
  54.     }
  55.     /*
  56.      * Purify the phone number by removing all the pretty characters
  57.      * that don't need to be sent to the modem.  Typically the '-',
  58.      * '(', ')', and space characters are just for looks.
  59.      */
  60.     i = 0;
  61.     n = dir->number[dir->q_num[num]];
  62.     while (*n) {
  63.         if (!strchr("-() ", *n))
  64.             number[i++] = *n;
  65.         n++;
  66.     }
  67.     number[i] = NULL;
  68.                     /* add it to the string */
  69.     strcat(s, number);
  70.     strcat(s, modem->suffix[modem->m_cur]);
  71.  
  72. #ifdef UNIXPC
  73.                     /* special case for OBM */
  74.     if (!strcmp(modem->mname[modem->m_cur], "OBM")) {
  75.                     /* prepare the modem */
  76.         pbuf.c_lineparam = DATA|DTMF;
  77.         pbuf.c_waitdialtone = 5;
  78.         pbuf.c_linestatus = 0;
  79.         pbuf.c_feedback = SPEAKERON|NORMSPK;
  80.         pbuf.c_waitflash = 500;
  81.         ioctl(status->fd, PIOCSETP, &pbuf);
  82.  
  83.                     /* connect the dialer */
  84.         ioctl(status->fd, PIOCRECONN);
  85.         sleep(1);
  86.                     /* dial each digit */
  87.         n = s;
  88.         while(*n) {
  89.                     /* switch tone/pulse dialing ? */
  90.             switch(*n) {
  91.                 case '^':
  92.                     pbuf.c_lineparam = DATA|PULSE;
  93.                     ioctl(status->fd, PIOCSETP, &pbuf);
  94.                     break;
  95.                 case '%':
  96.                     pbuf.c_lineparam = DATA|DTMF;
  97.                     ioctl(status->fd, PIOCSETP, &pbuf);
  98.                     break;
  99.                 default:
  100.                     ioctl(status->fd, PIOCDIAL, n);
  101.                     break;
  102.             }
  103.             n++;
  104.         }
  105.     }
  106.  
  107. #else /* UNIXPC */
  108.     send_str(s);
  109. #endif /* UNIXPC */
  110.     return;
  111. }
  112.  
  113. /*
  114.  * Send a string to the modem.  Performs all the character synonym
  115.  * translations.  No sanity checking on the "m_cur" value.
  116.  */
  117.  
  118. void
  119. send_str(s)
  120. char *s;
  121. {
  122.     int skip;
  123.     char c;
  124.     unsigned int sleep();
  125.                     /* empty string ?? */
  126.     if (s == NULL || *s == NULL)
  127.         return;
  128.  
  129.     ioctl(status->fd, TCFLSH, 1);    
  130.     /*
  131.      * Change the character synonyms to their real values.  Writes
  132.      * the characters to the modem.  To remove the special meaning
  133.      * of one of the characters, prepend a '\' to it.
  134.      */
  135.     skip = 0;
  136.     while (*s) {
  137.         c = *s;
  138.                     /* send the literal character */
  139.         if (skip) {
  140.             skip = 0;
  141.             write(status->fd, &c, 1);
  142.             ioctl(status->fd, TCSBRK, 1);
  143.             s++;
  144.             continue;
  145.         }
  146.                     /* turn off the special meaning */
  147.         if (c == '\\') {
  148.             skip = 1;
  149.             s++;
  150.             continue;
  151.         }
  152.                     /* carriage return synonym */
  153.         if (c == param->cr_char)
  154.             c = '\r';
  155.                     /* 2 character control sequence */
  156.         if (c == param->ctrl_char) {
  157.             s++;
  158.             c = *s;
  159.                     /* premature EOF? */
  160.             if (c == NULL)
  161.                 break;
  162.             if (c > '_')
  163.                 c -= 96;
  164.             else
  165.                 c -= 64;
  166.         }
  167.                     /* escape synonym */
  168.         if (c == param->esc_char)
  169.             c = 27;
  170.                     /* pause synonym */
  171.         if (c == param->pause_char) {
  172.             sleep(1);
  173.             s++;
  174.             continue;
  175.         }
  176.         write(status->fd, &c, 1);
  177.         /*
  178.          * Because the pause char makes the timing critical, we
  179.          * wait until the buffer is clear before we continue.
  180.          */
  181.         ioctl(status->fd, TCSBRK, 1);
  182.         s++;
  183.     }
  184.     return;
  185. }
  186.  
  187. /*
  188.  * Read the result codes coming back from the modem.  Test for the 6
  189.  * "connect" strings and the 4 "no connect" strings.  Return the connected
  190.  * baud rate (as a string) or the error message.
  191.  */
  192.  
  193. char rc_buf[512];
  194. int rc_index;
  195.  
  196. char *
  197. read_codes()
  198. {
  199.     char c;
  200. #ifdef UNIXPC
  201.     unsigned int sleep();
  202.     struct updata pbuf;
  203.                     /* special case for OBM */
  204.     if (!strcmp(modem->mname[modem->m_cur], "OBM")) {
  205.         ioctl(status->fd, PIOCGETP, &pbuf);
  206.  
  207.                     /* fake the return code */
  208.         if (pbuf.c_linestatus & MODEMCONNECTED)
  209.             return("1200");
  210.  
  211.         sleep(1);
  212.         return(NULL);
  213.     }
  214. #endif /* UNIXPC */
  215.                     /* search for key words */
  216.     for (; rc_index<511; rc_index++) {
  217.         if (read(status->fd, &c, 1) <= 0)
  218.             return(NULL);
  219.  
  220.         rc_buf[rc_index] = c;
  221.         rc_buf[rc_index+1] = NULL;
  222.                     /* the connect strings */
  223.         if (match(rc_buf, modem->con_3[modem->m_cur]))
  224.             return("300");
  225.  
  226.         if (match(rc_buf, modem->con_12[modem->m_cur]))
  227.             return("1200");
  228.  
  229.         if (match(rc_buf, modem->con_24[modem->m_cur]))
  230.             return("2400");
  231.  
  232.         if (match(rc_buf, modem->con_48[modem->m_cur]))
  233.             return("4800");
  234.  
  235.         if (match(rc_buf, modem->con_96[modem->m_cur]))
  236.             return("9600");
  237.  
  238.         if (match(rc_buf, modem->con_192[modem->m_cur]))
  239.             return("19200");
  240.  
  241.                     /* the no connect strings */
  242.         if (match(rc_buf, modem->no_con1[modem->m_cur]))
  243.             return(modem->no_con1[modem->m_cur]);
  244.  
  245.         if (match(rc_buf, modem->no_con2[modem->m_cur]))
  246.             return(modem->no_con2[modem->m_cur]);
  247.  
  248.         if (match(rc_buf, modem->no_con3[modem->m_cur]))
  249.             return(modem->no_con3[modem->m_cur]);
  250.  
  251.         if (match(rc_buf, modem->no_con4[modem->m_cur]))
  252.             return(modem->no_con4[modem->m_cur]);
  253.     }
  254.                     /* ran out of buffer ? */
  255.     return("ERROR");
  256. }
  257.  
  258. /*
  259.  * Test for a match between two character strings.  A return code of 1
  260.  * means that s2 was found at the end of s1
  261.  */
  262.  
  263. int
  264. match(s1, s2)
  265. char *s1, *s2;
  266. {
  267.     int i, skip, diff;
  268.     char c, new[40];
  269.                     /* if no string to match */
  270.     if (*s2 == NULL)
  271.         return(0);
  272.                     /* translate synonyms */
  273.     i = 0;
  274.     skip = 0;
  275.     while (*s2) {
  276.         c = *s2;
  277.                     /* literal character */
  278.         if (skip) {
  279.             skip = 0;
  280.             new[i++] = c;
  281.             s2++;
  282.             continue;
  283.         }
  284.                     /* turn off the special meaning */
  285.         if (c == '\\') {
  286.             skip = 1;
  287.             s2++;
  288.             continue;
  289.         }
  290.                     /* carriage return synonym */
  291.         if (c == param->cr_char)
  292.             c = '\r';
  293.  
  294.                     /* 2 character control sequence */
  295.         if (c == param->ctrl_char) {
  296.             s2++;
  297.             c = *s2;
  298.             if (c == NULL)
  299.                 break;
  300.             if (c > '_')
  301.                 c -= 96;
  302.             else
  303.                 c -= 64;
  304.         }
  305.                     /* escape synonym */
  306.         if (c == param->esc_char)
  307.             c = 27;
  308.  
  309.         new[i++] = c;
  310.         s2++;
  311.     }
  312.     new[i] = NULL;
  313.  
  314.     diff = strlen(s1) - strlen(new);
  315.                     /* is it possible ? */
  316.     if (diff < 0)
  317.         return(0);
  318.                     /* test it out */
  319.     if (!strcmp(&s1[diff], new))
  320.         return(1);
  321.     return(0);
  322. }
  323.