home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / xyz.lzh / ftserial.c < prev    next >
Text File  |  1995-08-18  |  9KB  |  329 lines

  1. /*
  2.    Printed form of this source is Copyright (C) 1995 Coriolis
  3.    Group, Inc.  All rights reserved.  Individual users may
  4.    make printed copies for their own personal use.
  5.  
  6.    All other forms are Copyright (C) 1995 Tim Kientzle. All
  7.    rights reserved.
  8.  
  9. Redistribution in source or binary form is permitted only under
  10. the following conditions:
  11. 1. If you own a copy of `The Working Programmer's Guide To Serial
  12.    Protocols,' then you may redistribute this code as part of
  13.    a complete application program under the conditions
  14.    described in that book.  (See pages xiv, xv.)  In any case,
  15.    you must abide by terms 4-7 below.
  16. 2. Otherwise, if you have received this code as a part of an
  17.    application program, it may only be redistributed with the
  18.    complete source of that program, under whatever conditions
  19.    apply to redistribution of that program as a whole.
  20. 3. If you have received this source code by some other means,
  21.    you may not redistribute it without explicit written
  22.    permission from Tim Kientzle.
  23. 4. All advertising materials mentioning features or use of this
  24.    software must prominently display the following acknowledgement:
  25.       This product is partially based on source code appearing in
  26.       `The Working Programmer's Guide to Serial Protocols,'
  27.       Copyright (C) 1995 Coriolis Group, Inc. and Tim Kientzle.
  28. 5. All programs using this source code must display the above
  29.    acknowledgement prominently in the program documentation
  30.    and user interface.
  31. 6. Neither the name of the Tim Kientzle nor the Coriolis Group, Inc.,
  32.    may be used to endorse or promote products derived from this
  33.    software without specific prior written permission.
  34. 7. Any redistribution in source form must retain the above copyright
  35.    notice, this list of conditions, and the disclaimer below.
  36.  
  37. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  38. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  39. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  40. IN NO EVENT SHALL TIM KIENTZLE OR THE CORIOLIS GROUP BE LIABLE FOR
  41. ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  42. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  43. GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  44. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  45. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  46. OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  47. IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48.  
  49. */
  50.  
  51. #include "ftserial.h"
  52. #include <stdio.h>
  53. #ifdef _UCC
  54. #include <stdlib.h>
  55. #else
  56. int     fprintf ();
  57. #endif
  58.  
  59. #include <stddef.h>
  60. void   *malloc (size_t);
  61. void    free (void *);
  62.  
  63. /* System-specific headers for OS9 */
  64. #include <sgstat.h>
  65. /*#include <setsys.h>*/
  66. #include <time.h>
  67. #include <modes.h>
  68. #define TRUE (1)
  69. int     _gs_opt (int path, struct sgbuf *buffer);
  70. int     _ss_opt (int path, struct sgbuf *buffer);
  71. int     memset (char *s, int val, unsigned size);
  72. int     _gs_rdy (int path);
  73. int     _ss_rel (int path);
  74. int     _ss_ssig (int path, short sigcode);
  75. int     intercept (int (*inter) ());
  76. int     tsleep (unsigned);
  77. int     close (int path);
  78. int     open (const char *name, short mode);
  79. int     read (int path, char *buff, unsigned count);
  80. int     write (int path, const char *buffer, unsigned count);
  81. typedef struct PORT_PARAMS PORT_PARAMS;
  82. struct PORT_PARAMS {
  83.    PORT_PARAMS *pNext;
  84.    struct sgbuf inParams;
  85.    struct sgbuf outParams;
  86. };
  87. typedef struct {
  88.    PORT_PARAMS *stack;
  89.    int     inPath;
  90.    int     outPath;
  91. } SERIAL_PORT_PRIVATE;
  92. static void 
  93. DisableTTYOptions (struct sgbuf *pBuf)
  94. {
  95.    pBuf->sg_case = 0;
  96.    pBuf->sg_backsp = 0;
  97.    pBuf->sg_delete = 0;
  98.    pBuf->sg_echo = 0;
  99.    pBuf->sg_alf = 0;
  100.    pBuf->sg_nulls = 0;
  101.    pBuf->sg_pause = 0;
  102.    pBuf->sg_page = 0;
  103.    pBuf->sg_bspch = 0;
  104.    pBuf->sg_dlnch = 0;
  105.    pBuf->sg_eorch = 0;
  106.    pBuf->sg_eofch = 0;
  107.    pBuf->sg_rlnch = 0;
  108.    pBuf->sg_dulnch = 0;
  109.    pBuf->sg_psch = 0;
  110.    pBuf->sg_kbich = 0;
  111.    pBuf->sg_kbach = 0;
  112.    pBuf->sg_bsech = 0;
  113.    pBuf->sg_bellch = 0;
  114.    pBuf->sg_tabcr = 0;
  115.    pBuf->sg_tabsiz = 0;
  116. }
  117. static void 
  118. CleanPort (SERIAL_PORT_PRIVATE *port)
  119. {
  120.    struct sgbuf buff;
  121.  
  122.    _gs_opt (port->inPath, &buff);
  123.    DisableTTYOptions (&buff);
  124.    _ss_opt (port->inPath, &buff);
  125.    _gs_opt (port->outPath, &buff);
  126.    DisableTTYOptions (&buff);
  127.    _ss_opt (port->outPath, &buff);
  128. }
  129.  
  130. int     SerialOpen
  131.         (SERIAL_PORT *pPort, const char *name) {
  132.    SERIAL_PORT_PRIVATE *port;
  133.  
  134.    port = malloc (sizeof (*port));
  135.    if (port == NULL)
  136.       return serialFatal;
  137.    port->stack = NULL;
  138.    if ((name == NULL) || (name[0] == 0)) {
  139.       port->inPath = 0;
  140.       port->outPath = 1;
  141.       SerialSaveState (port);
  142.    } else {
  143.       port->inPath = port->outPath = open (name, 3);
  144.       if (port->inPath == -1) {
  145.          free (port);
  146.          return serialFatal;
  147.       }
  148.    }
  149.    CleanPort (port);
  150.    *pPort = port;
  151.    return serialOK;
  152. }
  153. int     SerialClose
  154.         (SERIAL_PORT portPublic) {
  155.    SERIAL_PORT_PRIVATE *port = portPublic;
  156.  
  157.    while (port->stack)
  158.       SerialRestoreState (portPublic);
  159.    if (port->inPath > 2)
  160.       close (port->inPath);
  161.    if (port->outPath > 2)
  162.       close (port->outPath);
  163.    free (port);
  164.    return serialOK;
  165. }
  166. int     SerialSaveState
  167.         (SERIAL_PORT portPublic) {
  168.    SERIAL_PORT_PRIVATE *port = portPublic;
  169.    PORT_PARAMS *pParams;
  170.  
  171.    pParams = malloc (sizeof (*pParams));
  172.    if (pParams == NULL)
  173.       return serialFatal;
  174.    _gs_opt (port->inPath, &(pParams->inParams));
  175.    _gs_opt (port->outPath, &(pParams->outParams));
  176.    pParams->pNext = port->stack;
  177.    port->stack = pParams;
  178.    return serialOK;
  179. }
  180. int     SerialRestoreState
  181.         (SERIAL_PORT portPublic) {
  182.    SERIAL_PORT_PRIVATE *port = portPublic;
  183.    PORT_PARAMS *pParams;
  184.  
  185.    pParams = port->stack;
  186.    if (pParams == NULL)
  187.       return serialOK;
  188.    port->stack = pParams->pNext;
  189.    _ss_opt (port->inPath, &(pParams->inParams));
  190.    _ss_opt (port->outPath, &(pParams->outParams));
  191.    free (pParams);
  192.    return serialOK;
  193. }
  194. int     SerialSetWord
  195.         (SERIAL_PORT portPublic, int wordLength) {
  196.    SERIAL_PORT_PRIVATE *port = portPublic;
  197.    struct sgbuf buff;
  198.  
  199.    _gs_opt (port->inPath, &buff);
  200.    switch (wordLength) {
  201.    case 8:
  202.       buff.sg_baud &= 0x1f;
  203.       break;
  204.    default:
  205.       return serialFatal;
  206.    }
  207.    _ss_opt (port->inPath, &buff);
  208.    _gs_opt (port->outPath, &buff);
  209.    switch (wordLength) {
  210.    case 8:
  211.       buff.sg_baud &= 0x1f;
  212.       break;
  213.    default:
  214.       return serialFatal;
  215.    }
  216.    _ss_opt (port->outPath, &buff);
  217.    return serialOK;
  218. }
  219. int     SerialSetParity
  220.         (SERIAL_PORT portPublic, int parity) {
  221.    SERIAL_PORT_PRIVATE *port = portPublic;
  222.    struct sgbuf buff;
  223.  
  224.    _gs_opt (port->inPath, &buff);
  225.    switch (parity) {
  226.    case parityNone:
  227.       buff.sg_parity = 0;
  228.       break;
  229.    default:
  230.       return serialFatal;
  231.    }
  232.    _ss_opt (port->inPath, &buff);
  233.    _gs_opt (port->outPath, &buff);
  234.    switch (parity) {
  235.    case parityNone:
  236.       buff.sg_parity = 0;
  237.       break;
  238.    default:
  239.       return serialFatal;
  240.    }
  241.    _ss_opt (port->outPath, &buff);
  242.    return serialOK;
  243. }
  244. int     SerialMakeTransparent
  245.         (SERIAL_PORT portPublic) {
  246.    SERIAL_PORT_PRIVATE *port = portPublic;
  247.    struct sgbuf buff;
  248.  
  249.    _gs_opt (port->inPath, &buff);
  250.    memset (&(buff.sg_backsp), 0,
  251.            ((int) &(((struct sgbuf *) 0)->sg_parity)) - ((int) &(((struct sgbuf *) 0)->sg_backsp)));
  252.    buff.sg_xon = buff.sg_xoff = 0;
  253.    _ss_opt (port->inPath, &buff);
  254.    _gs_opt (port->outPath, &buff);
  255.    memset (&(buff.sg_backsp), 0,
  256.            ((int) &(((struct sgbuf *) 0)->sg_parity)) - ((int) &(((struct sgbuf *) 0)->sg_backsp)));
  257.    buff.sg_xon = buff.sg_xoff = 0;
  258.    _ss_opt (port->outPath, &buff);
  259.    return serialOK;
  260. }
  261. static int sigabort = 0;
  262. static int 
  263. trap (int sig)
  264. {
  265.    if (sig != 101)
  266.       sigabort = TRUE;
  267.    return 0;
  268. }
  269. int     SerialReadWithTimeout
  270.         (SERIAL_PORT portPublic, int timeout,
  271.          void *pBuffer, unsigned long *pLength) {
  272.    SERIAL_PORT_PRIVATE *port = portPublic;
  273.    int     n = *pLength;
  274.    int     readsize;
  275.    char   *p = pBuffer;
  276.  
  277.    intercept (trap);
  278.    while (n > 0) {
  279.       if ((readsize = _gs_rdy (port->inPath)) < 0) {
  280.          int     ticks = CLK_TCK * timeout;
  281.          int     interval = CLK_TCK / 8;
  282.  
  283.          _ss_ssig (port->inPath, 101);
  284.          while (((readsize = _gs_rdy (port->inPath)) < 0) && !sigabort && (ticks > 0)) {
  285.             tsleep (interval);
  286.             ticks -= interval;
  287.          }
  288.          if (sigabort) {
  289.             *pLength -= n;
  290.             return serialUserCancel;
  291.          }
  292.          if (readsize < 0) {
  293.             *pLength -= n;
  294.             return serialTimeout;
  295.          }
  296.          _ss_rel (port->inPath);
  297.       }
  298.       if (readsize > n)
  299.          readsize = n;
  300.       read (port->inPath, p, readsize);
  301.       n -= readsize;
  302.       p += readsize;
  303.    }
  304.    *pLength -= n;
  305.    return serialOK;
  306. }
  307. int     SerialSend
  308.         (SERIAL_PORT portPublic, const void *pBuffer, unsigned long length) {
  309.    SERIAL_PORT_PRIVATE *port = portPublic;
  310.  
  311.    intercept (trap);
  312.    write (port->outPath, pBuffer, length);
  313.    return serialOK;
  314. }
  315. int     SerialWaitForSentBytes
  316.         (SERIAL_PORT portPublic) {
  317.    return serialOK;
  318. }
  319. int     SerialSendBreak
  320.         (SERIAL_PORT portPublic) {
  321. /* System-specific code to send a break signal. */
  322.    return serialOK;
  323. }
  324. int     SerialPause
  325.         (SERIAL_PORT portPublic, int seconds) {
  326. /* System-specific code to pause without losing serial data. */
  327.    return serialOK;
  328. }
  329.