home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / OS2 / BSRCP240.ZIP / MDM_PROC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-22  |  16.2 KB  |  582 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. struct resp_str
  73. {
  74.    char *resp;
  75.    unsigned disp;
  76. };
  77.  
  78. static struct resp_str mdm_resps[] = {
  79.                                       {"RINGING", 1},
  80.                                       {"RING RESPONSE", 1},
  81.                                       {"RING", 3},
  82.                                       {"CONNECT", 2},
  83.                                       {"RRING", 1},
  84.                                       {"BUSY", 0},
  85.                                       {"VOICE", 0},
  86.                                       {"ERROR", 0},
  87.                                       {"OK", 0},
  88.                                       {"NO CARRIER", 0},
  89. /* "NO DIAL TONE" or "NO DIALTONE" */ {"NO DIAL", 0},
  90.                                       {"DIALING", 1},
  91.                                       {"NO ANSWER", 0},
  92.                                       {"DIAL TONE", 1},
  93.                                       {NULL, 0}
  94. };
  95.  
  96. static char *response_string = "                                                  ";
  97.  
  98. void do_dial_strings ()
  99. {
  100.    MDM_TRNS *m;
  101.  
  102.    predial = normprefix;
  103.    postdial = normsuffix;
  104.  
  105.    m = mm_head;
  106.    while (m != NULL)
  107.       {
  108.       if (m->mdm & newnodedes.ModemType)
  109.          {
  110.          predial = m->pre;
  111.          postdial = m->suf;
  112.          return;
  113.          }
  114.       m = m->next;
  115.       }
  116. }
  117.  
  118. void try_2_connect (phnum)
  119. char *phnum;
  120. {
  121.    long t1, timerset ();
  122.    int j, k;
  123.  
  124.    for (j = 0; (j < poll_tries && !KEYPRESS ()); j++) /* do polltries or till keypress */
  125.       {
  126.       CLEAR_INBOUND ();
  127.       k = dial_modem (phnum);
  128.  
  129.       if ((un_attended || doing_poll) && fullscreen)
  130.          {
  131.          ++hist.calls_made;
  132.          sb_move (historywin, HIST_ATT_ROW, HIST_COL);
  133.          (void) sprintf (junk, "%-4d", hist.calls_made);
  134.          sb_puts (historywin, (unsigned char *) junk);
  135.          }
  136.  
  137.       if ((k > 0) || KEYPRESS ())
  138.          break;
  139.       t1 = timerset (200);
  140.       while (!timeup (t1) && !KEYPRESS ())
  141.          time_release ();                         /* pause for 2 seconds */
  142.       }
  143.    if (KEYPRESS ())                              /* If user's been busy */
  144.       {
  145.       if (!caller)
  146.          (void) FOSSIL_CHAR ();                         /* Eat the character   */
  147.       if (!CARRIER)                              /* Abort if no carrier */
  148.          {
  149.          status_line (msgtxt[M_CONNECT_ABORTED]);
  150.          mdm_hangup ();
  151.          }
  152.       }
  153.  
  154.    predial = normprefix;
  155.    postdial = normsuffix;
  156. }
  157.  
  158. int try_1_connect (phnum)
  159. char *phnum;
  160. {
  161.    int k;
  162.  
  163.    if ((k = dial_modem (phnum)) <= 0)
  164.       {
  165.       mdm_hangup ();
  166.       }
  167.  
  168.    if ((un_attended || doing_poll) && fullscreen)
  169.       {
  170.       ++hist.calls_made;
  171.       sb_move (historywin, HIST_ATT_ROW, HIST_COL);
  172.       (void) sprintf (junk, "%-4d", hist.calls_made);
  173.       sb_puts (historywin, (unsigned char *) junk);
  174.       }
  175.  
  176.    predial = normprefix;
  177.    postdial = normsuffix;
  178.  
  179.    return (k);
  180. }
  181.  
  182. static void phone_translate (number, translated)
  183. char *number;
  184. char *translated;
  185. {
  186.    PN_TRNS *p;
  187.  
  188.    (void) strcpy (translated, number);
  189.    for (p = pn_head; p != NULL; p = p->next)
  190.       {
  191.       if (strncmp (p->num, number, (unsigned int) (p->len)) == 0)
  192.          {
  193.          (void) sprintf (translated, "%s%s%s", p->pre, &(number[p->len]), p->suf);
  194.          break;
  195.          }
  196.       }
  197. }
  198.  
  199. static int dial_modem (number)
  200. char *number;
  201. {
  202.    int resp;
  203.    long t;
  204.    char translated[50];
  205.    extern long timerset ();
  206.  
  207.    janus_OK = 0;
  208.    phone_translate (number, translated);
  209.    if (translated[0] == '\"')                    /* If it's a script          */
  210.       return (do_script (translated));             /* then do it that way       */
  211.  
  212.    status_line (msgtxt[M_DIALING_NUMBER], translated);
  213.    if (un_attended && fullscreen)
  214.       {
  215.       do_ready (msgtxt[M_READY_DIALING]);
  216.       }
  217.  
  218.    /* First of all, if we have something, don't hang up on the guy! */
  219.    if (!no_collide && CHAR_AVAIL ())
  220.       return (-1);
  221.  
  222.    if (dial_setup != NULL)
  223.       {
  224.       mdm_cmd_string (dial_setup, 1);
  225.       }
  226.    else
  227.       {
  228.       DTR_OFF ();                                    /* drop DTR to reset modem     */
  229.       timer (20);                                    /* leave it down 2 seconds     */
  230.       DTR_ON ();                                    /* then raise DTR again      */
  231.       timer (5);                                    /* and wait .5 sec for modem */
  232.       }
  233.  
  234.    if (!no_collide && CHAR_AVAIL ())             /* If we have something
  235.                                                   * here, return */
  236.       return (-1);
  237.  
  238.    mdm_cmd_string (predial, 0);                  /* transmit the dial prefix  */
  239.    mdm_cmd_string (translated, 0);                 /* then the phone number      */
  240.    mdm_cmd_string (postdial, 0);                 /* finally the dial suffix   */
  241.    if (no_collide)
  242.       CLEAR_INBOUND ();                          /* Throw out all echo to
  243.                                                   * this point    */
  244.    mdm_cmd_char (CR);                             /* terminate the string      */
  245.  
  246.    resp = modem_response (7500);
  247.    if (resp)                                     /* we got a good response,   */
  248.       {
  249.       if (resp == 3)                             /* Incoming ring to be
  250.                                                   * processed higher up */
  251.          return (-1);
  252.  
  253.       t = timerset (200);                         /* Wait up to 2 seconds      */
  254.       while (!timeup (t))
  255.          {                                         /* If carrier detect, AND      */
  256.          if ((CHAR_AVAIL ()) && CARRIER)         /* some sign of life, */
  257.             break;                                 /* leave early...              */
  258.          }
  259.       return ((int) CARRIER);                           /* Carrier should be on now    */
  260.       }
  261.    return (0);                                     /* no good */
  262. }
  263.  
  264. static char *get_response (end_time)
  265. long end_time;                                     /* timeout parameters          */
  266. {
  267.    char *p = response_string;                     /* points to character cell  */
  268.    char c;                                         /* current modem character   */
  269.    int count = 0;                                 /* count of characters       */
  270.  
  271.    while ((count < 50)                             /* until we have 50 chars,   */
  272.           && (!timeup (end_time))                 /* or out of time,           */
  273.           && (!KEYPRESS ()))                     /* or user gets impatient      */
  274.       {
  275.       if (!CHAR_AVAIL ())                         /* if nothing ready yet,      */
  276.          {
  277.          time_release ();
  278.          continue;                                 /* just process timeouts      */
  279.          }
  280.       c = (char) (MODEM_IN () & 0xff);             /* get a character           */
  281.       if (c == '\r' || c == '\n')                /* if a line ending          */
  282.          {
  283.          if (count != 0)                         /* and we have something,      */
  284.             break;                                 /* get out                   */
  285.          else continue;                          /* otherwise just keep going */
  286.          }
  287.       *p++ = c;                                  /* store the character       */
  288.       ++count;                                     /* increment the counter      */
  289.       }
  290.    *p = '\0';                                    /* terminate the new string  */
  291.  
  292.    if (count != 0 && strnicmp (response_string, "AT", 2))
  293.       {
  294.       (void) fancy_str (response_string);                /* make it pretty             */
  295.       status_line ("#%s", response_string);     /* pop it out on the screen  */
  296.       }
  297.  
  298.    return (response_string);                     /* return the pointer          */
  299. }
  300.  
  301. static int parse_response (response)
  302. char *response;
  303. {
  304.    char *p;                                      /* temp character pointer      */
  305.    register int i;                                 /* array pointer              */
  306.  
  307.    for (i = 0; mdm_resps[i].resp != NULL; i++)     /* scan through array          */
  308.       {
  309.       p = mdm_resps[i].resp;                     /* point at possible
  310.                                                   * response */
  311.       if (strnicmp (response, p, strlen (p)) == 0)        /* if a match,                 */
  312.          return ((int) (mdm_resps[i].disp));             /* return disposition of it  */
  313.       }
  314.    return (1);                                     /* ignore all unknowns       */
  315. }
  316.  
  317.  
  318. int modem_response (ths)
  319. int ths;                                         /* millisecs to wait          */
  320. {
  321.    unsigned int baudrate;
  322.    long end_time;                                 /* holds time at end of 2min */
  323.    extern long timerset ();
  324.    char *response;                                 /* pointer to modem response */
  325.    char *c, *skip_blanks ();                     /* miscellaneous pointer      */
  326.    int result = IGNORE;                          /* result code               */
  327.  
  328.    /* If this modem doesn't differentiate between RING and RINGING */
  329.    if (modemring)
  330.       mdm_resps[0].disp = 1;
  331.  
  332.    end_time = timerset ((unsigned int) ths);                    /* arm the timeout             */
  333.    while ((result == IGNORE)                     /* until success or failure, */
  334.           && (!timeup (end_time))                 /* or out of time,           */
  335.           && (!KEYPRESS ()))                     /* or user gets impatient      */
  336.       {
  337.       response = get_response (end_time);         /* get a response              */
  338.       result = parse_response (response);         /* parse, determine status   */
  339.       time_release ();
  340.       }
  341.  
  342.    if (result == SUCCESS)                         /* Got to be a CONNECT msg   */
  343.       {
  344.       if (strnicmp (response, "connect", 7) == 0)/* if this is a CONNECT,     */
  345.          {
  346.          c = skip_blanks (&response[7]);         /* get past the blanks       */
  347.          mdm_reliable[0] = '\0';                 /* Start with nothing        */
  348.  
  349.          if (*c == '\0')                         /* if nothing there,         */
  350.             {
  351.             baudrate = (unsigned int) 300;         /* say that it's 300 baud    */
  352.             }
  353.          else
  354.             {
  355.             baudrate = (unsigned int) atoi (c);  /* else do baudrate fallback */
  356.  
  357.             /* For 1200/75 split speed modems and "Connect 212" */
  358.  
  359.             if ((baudrate == 1275) || (baudrate == 7512)
  360.             ||    (baudrate == 75) || (baudrate == 212) || (baudrate == 12))
  361.                baudrate = 1200;
  362.  
  363.             /* For "Connect 103" */
  364.             if (baudrate == 103)
  365.                baudrate = 300;
  366.             }
  367.  
  368.          if (baudrate)
  369.             (void) set_baud (baudrate, 1);
  370.  
  371.             while (isdigit (*c))                 /* Get past digits           */
  372.                ++c;
  373.             c = skip_blanks (c);                 /* Get rid of blanks          */
  374.             if (*c != '\0')                      /* We have "reliable" info.  */
  375.                {
  376.                (void) strcpy (mdm_reliable, c);         /* Copy in the info          */
  377.                can_Janus (mdm_reliable);         /* Set the flag for Janus      */
  378.                }
  379.          }
  380.  
  381.       MNP_Filter ();
  382.       }
  383.  
  384.    return (result);                              /* timeout or failure or OK  */
  385. }
  386.  
  387. void mdm_cmd_string (mdm_cmd, dospace)
  388. char *mdm_cmd;
  389. int dospace;
  390. {
  391.    register char *c;
  392.  
  393.    if (mdm_cmd == NULL)                          /* defense from shit          */
  394.       return;
  395.  
  396.    for (c = mdm_cmd; *c; c++)
  397.       {
  398.       if (dospace || !isspace (*c))              /* don't output spaces       */
  399.          mdm_cmd_char (*c);                      /* output the next character */
  400.       }
  401. }
  402.  
  403. static void empty_delay ()
  404. {
  405.    long t, timerset ();
  406.  
  407.    t = timerset (500);
  408.    while ((!OUT_EMPTY ()) && (!timeup (t)))
  409.       time_release ();                             /* wait for output to finish */
  410.  
  411.    if (!OUT_EMPTY ())
  412.       {
  413.       MDM_DISABLE ();
  414.       (void) Cominit (port_ptr);
  415.       MDM_ENABLE (lock_baud && (btypes[baud].rate_value >= lock_baud) ? max_baud.rate_mask : btypes[baud].rate_mask);
  416.       DTR_ON ();
  417.       CLEAR_OUTBOUND ();
  418.       CLEAR_INBOUND ();
  419.       if (un_attended && fullscreen)
  420.          {
  421.          sb_dirty ();
  422.          sb_show ();
  423.          }
  424.       }
  425. }
  426.  
  427. void mdm_cmd_char (outchr)
  428. int outchr;
  429. {
  430.  
  431.    switch (outchr)
  432.       {
  433.       case '-':                                /* if it's a dash (phone no) */
  434.          return;                                 /* ignore it                  */
  435.  
  436.       case '|':                                /* if the CR character,      */
  437.          outchr = CR;                             /* substitute a real CR here */
  438.          break;
  439.  
  440.       case '.':                                 /* Substitute ',' for '.'    */
  441.          outchr = ',';                           /* for compatibility         */
  442.          break;
  443.  
  444.       case '~':                                /* if the "delay" character, */
  445.          empty_delay ();                         /* wait for buffer to clear, */
  446.          timer (10);                             /* then wait 1 second          */
  447.          return;                                 /* and return                  */
  448.  
  449.       case '^':                                 /* Raise DTR                 */
  450.          empty_delay ();                         /* wait for buffer to clear, */
  451.          DTR_ON ();                              /* Turn on DTR               */
  452.          return;                                 /* and return                  */
  453.  
  454.       case 'v':                                 /* Lower DTR             */
  455.          empty_delay ();                         /* wait for buffer to clear, */
  456.          DTR_OFF ();                             /* Turn off DTR              */
  457.          return;                                 /* and return                  */
  458.  
  459.       case '`':                                 /* Short delay           */
  460.          timer (1);                              /* short pause, .1 second      */
  461.          return;                                 /* and return                  */
  462.  
  463.       default:
  464.          break;
  465.       }
  466.  
  467.    SENDBYTE ((unsigned char) outchr);             /* then write the character  */
  468.  
  469.    if (outchr == CR)                             /* if it was a CR,           */
  470.       {
  471.       empty_delay ();
  472.       timer (1);                                 /* allow .1 sec line quiet   */
  473.       }
  474.    else if (slowmodem)
  475.       {
  476.       timer (1);                                 /* wait .1 sec for output      */
  477.       }
  478. }
  479.  
  480. void mdm_hangup ()
  481. {
  482.  
  483.    /*
  484.     * First, if a dial command is in progress, try to get the modem to abort
  485.     * it...
  486.     */
  487.  
  488.    CLEAR_OUTBOUND ();
  489.    CLEAR_INBOUND ();
  490.  
  491.    if (un_attended && fullscreen)
  492.       {
  493.       do_ready (msgtxt[M_READY_HANGUP]);
  494.       }
  495.    else
  496.       {
  497.       status_line (msgtxt[M_MODEM_HANGUP]);      /* Tell what we are doing */
  498.       }
  499.  
  500.    mdm_init (modem_init);                         /* re-initialize the modem   */
  501.    timer (5);                                     /* Wait another .5 sec       */
  502.  
  503.    set_xy ("");
  504.    CLEAR_INBOUND ();                             /* then flush input and exit */
  505. }
  506.  
  507. void mdm_init (str)
  508. char *str;
  509. {
  510.    CLEAR_OUTBOUND ();
  511.    CLEAR_INBOUND ();
  512.    if (init_setup != NULL)
  513.       {
  514.       (void) set_baud (max_baud.rate_value, 0);
  515.       mdm_cmd_string (init_setup, 1);
  516.       }
  517.    else
  518.       {
  519.       mdm_cmd_char (CR);                            /* output a CR, then         */
  520.       DTR_OFF ();                                    /* Drop DTR to hangup         */
  521.       timer (10);                                    /* Hold it down for 1 sec     */
  522.  
  523.       DTR_ON ();                                    /* Raise DTR,                 */
  524.       timer (5);                                    /* Then hold it up for .5
  525.                                                   * sec */
  526.       (void) set_baud (max_baud.rate_value, 0);
  527.  
  528.       mdm_cmd_char (' ');                           /* output a space            */
  529.       mdm_cmd_char (CR);                            /* then another CR             */
  530.       }
  531.    mdm_cmd_string (str, 0);                      /* then the modem init
  532.                                                   * string */
  533.    timer (5);                                     /* Hold DTR for .5 sec more  */
  534.    CLEAR_INBOUND ();                             /* then flush input and exit */
  535. }
  536.  
  537. void send_break (t)
  538. int t;
  539. {
  540.    long t1;
  541.  
  542.    t1 = timerset ((unsigned int) t);
  543.    do_break (1);
  544.    while (!timeup (t1))
  545.       time_release ();
  546.    do_break (0);
  547. }
  548.  
  549. void exit_DTR ()
  550. {
  551.    if (!leave_dtr_high)
  552.       DTR_OFF ();
  553. }
  554.  
  555. void MNP_Filter ()
  556. {
  557.    long t, t1;
  558.    int c;
  559.  
  560.    t1 = timerset (1000);   /* 10 second drop dead timer */
  561.    t = timerset (300);        /* at most a one second delay */
  562.    while (!timeup (t))
  563.       {
  564.       if (timeup (t1))
  565.          break;
  566.  
  567.       if ((c = PEEKBYTE ()) != 0xffff)
  568.          {
  569.          (void) TIMED_READ(0);
  570.  
  571.          /* If we get an MNP or v.42 character, eat it and wait for clear line */
  572.          if ((c != 0) && ((strchr (BadChars, c) != NULL) || (strchr (BadChars, c&0x7f) != NULL)))
  573.             {
  574.             t = timerset (300);
  575.             status_line (msgtxt[M_FILTER]);
  576.             }
  577.          }
  578.       }
  579. }
  580.  
  581.  
  582.