home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / modempool / part01 / modem.c < prev    next >
C/C++ Source or Header  |  1993-04-05  |  6KB  |  285 lines

  1. /*******************************************************************
  2.  * 
  3.  * Module: @(#)modem.c    4.2 92/04/16
  4.  *
  5.  * Description:
  6.  *    Handle various modem functions.
  7.  *
  8.  * Revision:
  9.  *    Date    By            Reason    
  10.  *    ----    --            ------    
  11.  *    920306    Lars Berntzon        Created
  12.  *
  13.  *******************************************************************/
  14. static char SccsId[] = "@(#)modem.c    4.2 92/04/16";
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <stdarg.h>
  19. #include <ctype.h>
  20.  
  21. #include "modempool.h"
  22.  
  23. #define N_MOD_CMDS (sizeof mod_cmds / sizeof mod_cmds[0])
  24. static char *mod_cmds[] = { 
  25.   "*", "CONNECT\r", "CONNECT 300\r", "CONNECT 1200\r", "CONNECT 2400\r",
  26.   "RING\r", "BUSY\r", "ERROR\r", "NO CARRIER\r", "OK\r",
  27.   "CONNECT 4800\r", "CONNECT 9600\r"
  28. };
  29.  
  30. static char *cmd_str(int n);
  31.  
  32. /*
  33.  * Routines.
  34.  */
  35.  
  36. /*******************************************************************
  37.  *
  38.  *         M O D _ S E T U P
  39.  *        -----------------
  40.  *
  41.  * Description:
  42.  *    Sets the modem to a correct state.
  43.  *
  44.  *******************************************************************/
  45.  
  46. int
  47. mod_setup(void)
  48. {
  49.     int retry;
  50.     int rc = 0;
  51.  
  52.     for(retry = 0; retry < 2; retry++) {
  53.     if ((rc = mod_put(initstr)) == E_OK   &&
  54.         (rc = mod_put("\r")) == E_OK   &&
  55.         (rc = mod_exp(MOD_OK, 0)) == E_OK) return E_OK;
  56.     }
  57.  
  58.     logerr("setup_modem: failed ( %d)", rc);
  59.     return rc;
  60. }
  61.  
  62. /*******************************************************************
  63.  *        M O D _ P U T
  64.  *        -------------
  65.  *
  66.  * Description:
  67.  *    Initialize the modem (hayes commands).
  68.  *
  69.  *******************************************************************/
  70. mod_put(char *msg)
  71. {
  72.     int rc;
  73.  
  74.     debug("mod_put(\"%s\")", msg);
  75.  
  76.     trig(2);
  77.     rc = tty_write(msg, strlen(msg));
  78.     if (istimeout()) {
  79.     return E_TMOUT;
  80.     }
  81.     
  82.     if (rc < 0) {
  83.         logerr("mod_put: failed to write");
  84.         return E_WRITE;
  85.     }
  86.     
  87.     return E_OK;
  88. }
  89.  
  90. /*******************************************************************
  91.  *        M O D _ E X P
  92.  *        -------------
  93.  *
  94.  * Description:
  95.  *    Expect answer from modem.
  96.  *
  97.  * Arguments:
  98.  *    expected    - Answer type (integern enumeration)
  99.  *    tmout        - Timeout (0 means default)
  100.  *
  101.  *******************************************************************/
  102. mod_exp(int expected, int tmout)
  103. {
  104.     va_list arg = NULL;
  105.     int exp_len = 0;
  106.     char buf[MATCH_SIZE];
  107.     int buf_len;
  108.     int pos = 0;
  109.     int i = 0;
  110.  
  111.     /* Used default timeout if none specified */
  112.     if (tmout == 0) tmout = MODEM_TMOUT;
  113.  
  114.     debug("expecting(\"%s\")", cmd_str(expected));
  115.     /* Read until text matches but not more than can fit into bufer */
  116.     while(pos < MATCH_SIZE)
  117.     {
  118.     buf[pos] = 0;
  119.  
  120.         /* Read with timeout */
  121.         trig(tmout);
  122.         buf_len = tty_read(buf + pos++, 1);
  123.     if(istimeout()) {
  124.         return E_TMOUT;
  125.     }
  126.  
  127.     /*
  128.      * Some one called us ?.
  129.      */
  130.     if (buf_len <= 0 && signalled) {
  131.         return E_TMOUT;
  132.     }
  133.  
  134.         if (buf_len < 0) return E_READ;
  135.  
  136.     if (!isprint(buf[pos - 1])) {
  137.         debugnonl("(0x%X)",  buf[pos - 1]);
  138.     }
  139.     else {
  140.         debugnonl("%c",  buf[pos - 1]);
  141.     }
  142.     
  143.         /* Check if any was right */
  144.         for(i = 0; i < N_MOD_CMDS; i++)
  145.         {
  146.         exp_len = strlen(mod_cmds[i]);
  147.         if (pos < exp_len) continue;
  148.             if (memcmp(mod_cmds[i], buf + pos - exp_len, exp_len) == 0) break;
  149.         }
  150.         if (i < N_MOD_CMDS)
  151.         {
  152.             buf[pos + 1] = 0;
  153.         debug("gotten(\"%s\")", cmd_str(i));
  154.         if (expected == MOD_ANY || expected == i)
  155.         {
  156.         /* Return what arrived if awaited for any */
  157.         if (expected == MOD_ANY) return i;
  158.  
  159.         /*
  160.          * Otherwise just return that what had been awaited for
  161.          * has arrived OK.
  162.          */
  163.                 return E_OK;
  164.         }
  165.         }
  166.     }
  167.  
  168.     logerr("mod_exp: never got any sane answer from modem (%s)", buf);
  169.     return E_FAIL;
  170. }
  171.  
  172. /************************************************************************
  173.  *
  174.  *            MOD_DIAL
  175.  *            --------
  176.  * Description:
  177.  *     Dials a number
  178.  *
  179.  * Arguments:
  180.  *    prefix    - Prefix telephone number, like '0w' to get external line.
  181.  *    phone    - The phone number.
  182.  *
  183.  ************************************************************************/
  184. mod_dial(char *prefix, char *phone)
  185. {
  186.     int rc;
  187.     int i;
  188.  
  189.     /* Retry 3 times*/
  190.     for(i = 0; i < 5; i++)
  191.     {
  192.         /* Dialup */
  193.         mod_put("ATDT");
  194.         mod_put(prefix);
  195.         mod_put(phone);
  196.     mod_put("\r");
  197.  
  198.     /* Wait for answer */
  199.         switch(mod_exp(MOD_ANY, 15))
  200.         {
  201.     case MOD_CONNECT:
  202.     case MOD_CONNECT_1200:
  203.     case MOD_CONNECT_2400:
  204.         log("dialup: succeded to dial '%s'", phone);
  205.         return E_OK;
  206.  
  207.     case MOD_BUSY:
  208.         log("dialup: busy");
  209.         break;
  210.  
  211.     case MOD_NO_CARRIER:
  212.         logerr("dialup: no carrier for phone '%s'", phone);
  213.     }
  214.     }    
  215. }
  216.  
  217. /*******************************************************************
  218.  *
  219.  *         PROMPT
  220.  *        ------
  221.  *
  222.  * Description:
  223.  *    Writes prompt to port and reads line.
  224.  *
  225.  * Arguments:
  226.  *    msg    - Prompt message.
  227.  *    dest    - Where to store answer.
  228.  *    size    - Dont read more than this.
  229.  *    tmout    - Timeout, 0 means no timeout.
  230.  *
  231.  *******************************************************************/
  232. int prompt(char *msg, char *dest, int size, int tmout)
  233. {
  234.     int i;
  235.     if (mod_put(msg) < 0)
  236.     {
  237.     logerr("prompt: failed to write to port");            
  238.     return E_FAIL;
  239.     }
  240.  
  241.     trig(tmout);
  242.     size = tty_read(dest, size);
  243.     if (istimeout()) {
  244.     return E_TMOUT;
  245.     }
  246.  
  247.     if (size < 0) {
  248.         logerr("prompt: failed to read");
  249.         return E_READ;
  250.     }
  251.  
  252.     /* User pressed EOF */
  253.     if (size == 0)
  254.     {
  255.     mod_put(MSG_ABORTED);
  256.     return E_FAIL;
  257.     }
  258.  
  259.     /* Remove leading blanks */
  260.     for(i = 0; i < size && isspace(dest[i]); i++)
  261.     ;
  262.  
  263.     memcpy(dest, dest + i, size -= i);
  264.  
  265.     /* Remove trailing blanks */    
  266.     for(i = size - 1; i >= 0 && isspace(dest[i]); i--,size --)
  267.     ;
  268.  
  269.     dest[i + 1] = 0;
  270.  
  271.     return E_OK;
  272. }
  273.  
  274. /***************************************
  275.  * Return ascii value for modem answers.
  276.  ***************************************/
  277. static char *cmd_str(int n)
  278. {
  279.     if (n < 0 || n > N_MOD_CMDS) {
  280.     return "[unknown]";
  281.     }
  282.  
  283.     return mod_cmds[n];
  284. }
  285.