home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BTMTSRC3.ZIP / MDM_PROC.C < prev    next >
Text File  |  1991-08-15  |  17KB  |  599 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                            */
  3. /*                                                                            */
  4. /*        ------------         Bit-Bucket Software, Co.                        */
  5. /*        \ 10001101 /         Writers and Distributors of                    */
  6. /*         \ 011110 /          Freely Available<tm> Software.                 */
  7. /*          \ 1011 /                                                            */
  8. /*           ------                                                            */
  9. /*                                                                            */
  10. /*    (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                            */
  12. /*                                                                            */
  13. /*                 This module was written by Vince Perriello                 */
  14. /*                                                                            */
  15. /*                                                                            */
  16. /*                      BinkleyTerm Modem Handler Module                        */
  17. /*                                                                            */
  18. /*                                                                            */
  19. /*      For complete    details  of the licensing restrictions, please refer    */
  20. /*      to the License  agreement,  which  is published in its entirety in    */
  21. /*      the MAKEFILE and BT.C, and also contained in the file LICENSE.240.    */
  22. /*                                                                            */
  23. /*      USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*      BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*      THIS    AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,    OR IF YOU DO    */
  26. /*      NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  27. /*      SOFTWARE CO.    AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  28. /*      SHOULD YOU  PROCEED TO USE THIS FILE    WITHOUT HAVING    ACCEPTED THE    */
  29. /*      TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  30. /*      AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.        */
  31. /*                                                                            */
  32. /*                                                                            */
  33. /* You can contact Bit Bucket Software Co. at any one of the following        */
  34. /* addresses:                                                                */
  35. /*                                                                            */
  36. /* Bit Bucket Software Co.          FidoNet  1:104/501, 1:132/491, 1:141/491    */
  37. /* P.O. Box 460398                  AlterNet 7:491/0                            */
  38. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  39. /*                                  Internet f491.n132.z1.fidonet.org         */
  40. /*                                                                            */
  41. /* Please feel free to contact us at any time to share your comments about    */
  42. /* our software and/or licensing policies.                                    */
  43. /*                                                                            */
  44. /*--------------------------------------------------------------------------*/
  45.  
  46. #include <stdio.h>
  47. #include <signal.h>
  48. #include <ctype.h>
  49. #include <conio.h>
  50. #include <string.h>
  51. #include <stdlib.h>
  52.  
  53. #include "com.h"
  54. #include "xfer.h"
  55. #include "zmodem.h"
  56. #include "keybd.h"
  57. #include "sbuf.h"
  58. #include "sched.h"
  59. #include "externs.h"
  60. #include "prototyp.h"
  61.  
  62. static int dial_modem (char *);
  63. static void phone_translate (char *, char *);
  64. static char *get_response (long);
  65. static int parse_response (char *);
  66. static void empty_delay (void);
  67.  
  68. #define FAILURE 0
  69. #define IGNORE    1
  70. #define SUCCESS 2
  71.  
  72. extern unsigned int actual_baud;            /* CML */
  73.  
  74.  
  75. struct resp_str
  76. {
  77.    char *resp;
  78.    unsigned disp;
  79. };
  80.  
  81. static struct resp_str mdm_resps[] = {
  82.                                       {"RINGING", 1},
  83.                                       {"RING RESPONSE", 1},
  84.                                       {"RING", 3},
  85.                                       {"CONNECT", 2},
  86.                                       {"RRING", 1},
  87.                                       {"BUSY", 0},
  88.                                       {"VOICE", 0},
  89.                                       {"ERROR", 0},
  90.                                       {"OK", 0},
  91.                                       {"NO CARRIER", 0},
  92. /* "NO DIAL TONE" or "NO DIALTONE" */ {"NO DIAL", 0},
  93.                                       {"DIALING", 1},
  94.                                       {"NO ANSWER", 0},
  95.                                       {"DIAL TONE", 1},
  96.                                       {NULL, 0}
  97. };
  98.  
  99. static char *response_string = "                                                  ";
  100.  
  101. void do_dial_strings ()
  102. {
  103.    MDM_TRNS *m;
  104.  
  105.    predial = normprefix;
  106.    postdial = normsuffix;
  107.  
  108.    m = mm_head;
  109.    while (m != NULL)
  110.       {
  111.       if (m->mdm & newnodedes.ModemType)
  112.          {
  113.          predial = m->pre;
  114.          postdial = m->suf;
  115.          return;
  116.          }
  117.       m = m->next;
  118.       }
  119. }
  120.  
  121. void try_2_connect (phnum)
  122. char *phnum;
  123. {
  124.    long t1;
  125.    int j, k;
  126.  
  127.    for (j = 0; (j < poll_tries && !KEYPRESS ()); j++) /* do polltries or till keypress */
  128.       {
  129.       CLEAR_INBOUND ();
  130.       k = dial_modem (phnum);
  131.  
  132.       if ((un_attended || doing_poll) && fullscreen)
  133.          {
  134.          ++hist.calls_made;
  135.          sb_move (historywin, HIST_ATT_ROW, HIST_COL);
  136.          (void) sprintf (junk, "%-4d", hist.calls_made);
  137.          sb_puts (historywin, (unsigned char *) junk);
  138.          }
  139.  
  140.       if ((k > 0) || KEYPRESS ())
  141.          break;
  142.       t1 = timerset (200);
  143.       while (!timeup (t1) && !KEYPRESS ())
  144.          time_release ();                         /* pause for 2 seconds */
  145.       }
  146.    if (KEYPRESS ())                              /* If user's been busy */
  147.       {
  148.       if (!caller)
  149.          (void) FOSSIL_CHAR ();                         /* Eat the character   */
  150.       if (!CARRIER)                              /* Abort if no carrier */
  151.          {
  152.          status_line (msgtxt[M_CONNECT_ABORTED]);
  153.          mdm_hangup ();
  154.          }
  155.       }
  156.  
  157.    predial = normprefix;
  158.    postdial = normsuffix;
  159. }
  160.  
  161. int try_1_connect (phnum)
  162. char *phnum;
  163. {
  164.    int k;
  165.  
  166.    if ((k = dial_modem (phnum)) <= 0)
  167.       {
  168.       mdm_hangup ();
  169.       }
  170.  
  171.    if ((un_attended || doing_poll) && fullscreen)
  172.       {
  173.       ++hist.calls_made;
  174.       sb_move (historywin, HIST_ATT_ROW, HIST_COL);
  175.       (void) sprintf (junk, "%-4d", hist.calls_made);
  176.       sb_puts (historywin, (unsigned char *) junk);
  177.       }
  178.  
  179.    predial = normprefix;
  180.    postdial = normsuffix;
  181.  
  182.    return (k);
  183. }
  184.  
  185. static void phone_translate (number, translated)
  186. char *number;
  187. char *translated;
  188. {
  189.    PN_TRNS *p;
  190.  
  191.    (void) strcpy (translated, number);
  192.    for (p = pn_head; p != NULL; p = p->next)
  193.       {
  194.       if (strncmp (p->num, number, (unsigned int) (p->len)) == 0)
  195.          {
  196.          (void) sprintf (translated, "%s%s%s", p->pre, &(number[p->len]), p->suf);
  197.          break;
  198.          }
  199.       }
  200. }
  201.  
  202. static int dial_modem (number)
  203. char *number;
  204. {
  205.    int resp;
  206.    long t;
  207.    char translated[50];
  208.  
  209.    janus_OK = 0;
  210.    phone_translate (number, translated);
  211.    if (translated[0] == '\"')                    /* If it's a script          */
  212.       return (do_script (translated));             /* then do it that way       */
  213.  
  214.    status_line (msgtxt[M_DIALING_NUMBER], translated);
  215.    if (un_attended && fullscreen)
  216.       {
  217.       do_ready (msgtxt[M_READY_DIALING]);
  218.       }
  219.  
  220.    /* First of all, if we have something, don't hang up on the guy! */
  221.    if (!no_collide && CHAR_AVAIL ())
  222.       return (-1);
  223.  
  224.    if (dial_setup != NULL)
  225.       {
  226.       mdm_cmd_string (dial_setup, 1);
  227.       }
  228.    else
  229.       {
  230.       DTR_OFF ();                                    /* drop DTR to reset modem     */
  231.       timer (10);                                    /* leave it down 1 second CML (2 seconds) */
  232.       DTR_ON ();                                    /* then raise DTR again      */
  233.       timer (5);                                    /* and wait .5 sec for modem */
  234.       }
  235.  
  236.    if (!no_collide && CHAR_AVAIL ())             /* If we have something
  237.                                                   * here, return */
  238.       return (-1);
  239.  
  240.    mdm_cmd_string (predial, 0);                  /* transmit the dial prefix  */
  241.    mdm_cmd_string (translated, 0);                 /* then the phone number      */
  242.    mdm_cmd_string (postdial, 0);                 /* finally the dial suffix   */
  243.    if (no_collide)
  244.       CLEAR_INBOUND ();                          /* Throw out all echo to
  245.                                                   * this point    */
  246.    mdm_cmd_char (CR);                             /* terminate the string      */
  247.  
  248.    resp = modem_response (7500);
  249.    if (resp)                                     /* we got a good response,   */
  250.       {
  251.       if (resp == 3)                             /* Incoming ring to be
  252.                                                   * processed higher up */
  253.          return (-1);
  254.  
  255.       t = timerset (200);                         /* Wait up to 2 seconds      */
  256.       while (!timeup (t))
  257.          {                                         /* If carrier detect, AND      */
  258.          if ((CHAR_AVAIL ()) && CARRIER)         /* some sign of life, */
  259.             break;                                 /* leave early...              */
  260. //        time_release();            /* CML -- stop hogging my CPU! */
  261.          }
  262.       return ((int) CARRIER);                           /* Carrier should be on now    */
  263.       }
  264.    return (0);                                     /* no good */
  265. }
  266.  
  267. static char *get_response (end_time)
  268. long end_time;                                     /* timeout parameters          */
  269. {
  270.    char *p = response_string;                     /* points to character cell  */
  271.    char c;                                         /* current modem character   */
  272.    int count = 0;                                 /* count of characters       */
  273.  
  274.    while ((count < 50)                             /* until we have 50 chars,   */
  275.           && (!timeup (end_time))                 /* or out of time,           */
  276.           && (!KEYPRESS ()))                     /* or user gets impatient      */
  277.       {
  278.       if (!CHAR_AVAIL ())                         /* if nothing ready yet,      */
  279.          {
  280.          time_release ();
  281.          continue;                                 /* just process timeouts      */
  282.          }
  283.       c = (char) (MODEM_IN () & 0xff);             /* get a character           */
  284.       if (c == '\r' || c == '\n')                /* if a line ending          */
  285.          {
  286.          if (count != 0)                         /* and we have something,      */
  287.             break;                                 /* get out                   */
  288.          else continue;                          /* otherwise just keep going */
  289.          }
  290.       *p++ = c;                                  /* store the character       */
  291.       ++count;                                     /* increment the counter      */
  292.       }
  293.    *p = '\0';                                    /* terminate the new string  */
  294.  
  295.    if (count != 0 && strnicmp (response_string, "AT", 2))
  296.       {
  297.       (void) fancy_str (response_string);                /* make it pretty             */
  298.       status_line ("#%s", response_string);     /* pop it out on the screen  */
  299.       }
  300.  
  301.    return (response_string);                     /* return the pointer          */
  302. }
  303.  
  304. static int parse_response (response)
  305. char *response;
  306. {
  307.    char *p;                                      /* temp character pointer      */
  308.    register int i;                                 /* array pointer              */
  309.  
  310.    for (i = 0; mdm_resps[i].resp != NULL; i++)     /* scan through array          */
  311.       {
  312.       p = mdm_resps[i].resp;                     /* point at possible
  313.                                                   * response */
  314.       if (strnicmp (response, p, strlen (p)) == 0)        /* if a match,                 */
  315.          return ((int) (mdm_resps[i].disp));             /* return disposition of it  */
  316.       }
  317.    return (1);                                     /* ignore all unknowns       */
  318. }
  319.  
  320.  
  321. int modem_response (ths)
  322. int ths;                                         /* millisecs to wait          */
  323. {
  324.    unsigned int baudrate;
  325.    long end_time;                                 /* holds time at end of 2min */
  326.    char *response;                                 /* pointer to modem response */
  327.    char *c, *skip_blanks ();                     /* miscellaneous pointer      */
  328.    int result = IGNORE;                          /* result code               */
  329.  
  330.    /* If this modem doesn't differentiate between RING and RINGING */
  331.    if (modemring)
  332.       mdm_resps[0].disp = 1;
  333.  
  334.    end_time = timerset ((unsigned int) ths);                    /* arm the timeout             */
  335.    while ((result == IGNORE)                     /* until success or failure, */
  336.           && (!timeup (end_time))                 /* or out of time,           */
  337.           && (!KEYPRESS ()))                     /* or user gets impatient      */
  338.       {
  339.       response = get_response (end_time);         /* get a response              */
  340.       result = parse_response (response);         /* parse, determine status   */
  341.       time_release ();
  342.       }
  343.  
  344.    if (result == SUCCESS)                         /* Got to be a CONNECT msg   */
  345.       {
  346.       if (strnicmp (response, "connect", 7) == 0)/* if this is a CONNECT,     */
  347.          {
  348.          c = skip_blanks (&response[7]);         /* get past the blanks       */
  349.          mdm_reliable[0] = '\0';                 /* Start with nothing        */
  350.  
  351.          if (*c == '\0')                         /* if nothing there,         */
  352.             {
  353.             baudrate = (unsigned int) 300;         /* say that it's 300 baud    */
  354.             }
  355.          else
  356.             {
  357.             baudrate = (unsigned int) atoi (c);  /* else do baudrate fallback */
  358.  
  359.             /* For 1200/75 split speed modems and "Connect 212" */
  360.  
  361.             if ((baudrate == 1275) || (baudrate == 7512)
  362.             ||    (baudrate == 75) || (baudrate == 212) || (baudrate == 12))
  363.                baudrate = 1200;
  364.  
  365.             /* For "Connect 103" */
  366.             if (baudrate == 103)
  367.                baudrate = 300;
  368.  
  369.             if (baudrate > 9600)        /* CML */
  370.                 baudrate = 19200;
  371.             }
  372.  
  373.          if (baudrate)
  374.             {
  375.             if (!lock_baud)        /* CML added lockbaud and actual_baud */
  376.                 set_baud (baudrate, 1);
  377.             else
  378.                 actual_baud = baudrate;
  379.             }
  380.  
  381.  
  382.             while (isdigit (*c))                 /* Get past digits           */
  383.                ++c;
  384.             c = skip_blanks (c);                 /* Get rid of blanks          */
  385.             if (*c != '\0')                      /* We have "reliable" info.  */
  386.                {
  387.                (void) strcpy (mdm_reliable, c);         /* Copy in the info          */
  388.                can_Janus (mdm_reliable);         /* Set the flag for Janus      */
  389.                }
  390.          }
  391.  
  392.       MNP_Filter ();
  393.       }
  394.  
  395.    return (result);                              /* timeout or failure or OK  */
  396. }
  397.  
  398. void mdm_cmd_string (mdm_cmd, dospace)
  399. char *mdm_cmd;
  400. int dospace;
  401. {
  402.    register char *c;
  403.  
  404.    if (mdm_cmd == NULL)                          /* defense from shit          */
  405.       return;
  406.  
  407.    for (c = mdm_cmd; *c; c++)
  408.       {
  409.       if (dospace || !isspace (*c))              /* don't output spaces       */
  410.          mdm_cmd_char (*c);                      /* output the next character */
  411.       }
  412. }
  413.  
  414. static void empty_delay ()
  415. {
  416.    long t;
  417.  
  418.    t = timerset (500);
  419.    while ((!OUT_EMPTY ()) && (!timeup (t)))
  420.       time_release ();                             /* wait for output to finish */
  421.  
  422.    if (!OUT_EMPTY ())
  423.       {
  424.       MDM_DISABLE ();
  425.       Cominit (port_ptr);
  426. //        if (!com_reinit())            /* CML */
  427. //            {
  428. //            printf ("\n%s\n", msgtxt[M_FOSSIL_GONE]);
  429. //            exit (1);
  430. //            }
  431.       MDM_ENABLE (lock_baud && (btypes[baud].rate_value >= lock_baud) ? max_baud.rate_mask : btypes[baud].rate_mask);
  432.       DTR_ON ();
  433.       CLEAR_OUTBOUND ();
  434.       CLEAR_INBOUND ();
  435.       if (un_attended && fullscreen)
  436.          {
  437.          sb_dirty ();
  438.          sb_show ();
  439.          }
  440.       }
  441. }
  442.  
  443. void mdm_cmd_char (outchr)
  444. int outchr;
  445. {
  446.  
  447.    switch (outchr)
  448.       {
  449.       case '-':                                /* if it's a dash (phone no) */
  450.          return;                                 /* ignore it                  */
  451.  
  452.       case '|':                                /* if the CR character,      */
  453.          outchr = CR;                             /* substitute a real CR here */
  454.          break;
  455.  
  456.       case '.':                                 /* Substitute ',' for '.'    */
  457.          outchr = ',';                           /* for compatibility         */
  458.          break;
  459.  
  460.       case '~':                                /* if the "delay" character, */
  461.          empty_delay ();                         /* wait for buffer to clear, */
  462.          timer (10);                             /* then wait 1 second          */
  463.          return;                                 /* and return                  */
  464.  
  465.       case '^':                                 /* Raise DTR                 */
  466.          empty_delay ();                         /* wait for buffer to clear, */
  467.          DTR_ON ();                              /* Turn on DTR               */
  468.          return;                                 /* and return                  */
  469.  
  470.       case 'v':                                 /* Lower DTR             */
  471.          empty_delay ();                         /* wait for buffer to clear, */
  472.          DTR_OFF ();                             /* Turn off DTR              */
  473.          return;                                 /* and return                  */
  474.  
  475.       case '`':                                 /* Short delay           */
  476.          timer (1);                              /* short pause, .1 second      */
  477.          return;                                 /* and return                  */
  478.  
  479.       default:
  480.          break;
  481.       }
  482.  
  483.    SENDBYTE ((unsigned char) outchr);             /* then write the character  */
  484.  
  485.    if (outchr == CR)                             /* if it was a CR,           */
  486.       {
  487.       empty_delay ();
  488.       timer (1);                                 /* allow .1 sec line quiet   */
  489.       }
  490.    else if (slowmodem)
  491.       {
  492.       timer (1);                                 /* wait .1 sec for output      */
  493.       }
  494. }
  495.  
  496. void mdm_hangup ()
  497. {
  498.  
  499.    /*
  500.     * First, if a dial command is in progress, try to get the modem to abort
  501.     * it...
  502.     */
  503.  
  504.    CLEAR_OUTBOUND ();
  505.    CLEAR_INBOUND ();
  506.  
  507.    if (un_attended && fullscreen)
  508.       {
  509.       do_ready (msgtxt[M_READY_HANGUP]);
  510.       }
  511.    else
  512.       {
  513.       status_line (msgtxt[M_MODEM_HANGUP]);      /* Tell what we are doing */
  514.       }
  515.  
  516.    mdm_init (modem_init);                         /* re-initialize the modem   */
  517.    timer (5);                                     /* Wait another .5 sec       */
  518.  
  519.    set_xy ("");
  520.    CLEAR_INBOUND ();                             /* then flush input and exit */
  521. }
  522.  
  523. void mdm_init (str)
  524. char *str;
  525. {
  526.    CLEAR_OUTBOUND ();
  527.    CLEAR_INBOUND ();
  528.    if (init_setup != NULL)
  529.       {
  530.       (void) set_baud (max_baud.rate_value, 0);
  531.       mdm_cmd_string (init_setup, 1);
  532.       }
  533.    else
  534.       {
  535.       mdm_cmd_char (CR);                            /* output a CR, then         */
  536.       DTR_OFF ();                                    /* Drop DTR to hangup         */
  537.       timer (10);                                    /* Hold it down for 1 sec     */
  538.  
  539.       DTR_ON ();                                    /* Raise DTR,                 */
  540.       timer (5);                                    /* Then hold it up for .5 sec */
  541.       (void) set_baud (max_baud.rate_value, 0);
  542.  
  543.       mdm_cmd_char (' ');                           /* output a space            */
  544.       mdm_cmd_char (CR);                            /* then another CR             */
  545.       }
  546.    mdm_cmd_string (str, 0);                      /* then the modem init
  547.                                                   * string */
  548.    timer (5);                                     /* Hold DTR for .5 sec more  */
  549.    CLEAR_INBOUND ();                             /* then flush input and exit */
  550. }
  551.  
  552. void send_break (t)
  553. int t;
  554. {
  555.    long t1;
  556.  
  557.    t1 = timerset ((unsigned int) t);
  558.    do_break (1);
  559.    while (!timeup (t1))
  560.       time_release ();
  561.    do_break (0);
  562. }
  563.  
  564. void exit_DTR ()
  565. {
  566.    if (!leave_dtr_high)
  567.       DTR_OFF ();
  568. }
  569.  
  570. void MNP_Filter ()
  571. {
  572.    long t, t1;
  573.    int c;
  574.  
  575.    t1 = timerset (1000);   /* 10 second drop dead timer */
  576.    t = timerset (300);        /* at most a one second delay */
  577.    while (!timeup (t))
  578.       {
  579.       if (timeup (t1))
  580.          break;
  581.  
  582.       if ((c = PEEKBYTE ()) != -1)            /* CML changed 0xffff to -1 */
  583.          {
  584.          TIMED_READ(0);
  585.  
  586.          /* If we get an MNP or v.42 character, eat it and wait for clear line */
  587.          if ((c != 0) && ((strchr (BadChars, c) != NULL) || (strchr (BadChars, c&0x7f) != NULL)))
  588.             {
  589.             t = timerset (300);
  590.             status_line (msgtxt[M_FILTER]);
  591.             }
  592.          }
  593. //        time_release();            /* CML -- stop hogging my CPU! */
  594.       }
  595. }
  596.  
  597.  
  598. 
  599.