home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 550b.lha / Term_v1.8a / Source.LZH / Serial.c < prev    next >
C/C++ Source or Header  |  1991-07-11  |  10KB  |  527 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
  4.  *
  5.  *    Name .....: Serial.c
  6.  *    Created ..: Monday 21-Jan-91 20:12
  7.  *    Revision .: 0
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    21-Jan-91       Olsen           Created this file!
  12.  *
  13.  * $Revision Header ********************************************************/
  14.  
  15. #include "TermGlobal.h"
  16.  
  17.     /* XOn():
  18.      *
  19.      *    Perform XON (stop data flow).
  20.      */
  21.  
  22. VOID
  23. XOn()
  24. {
  25.     if(Config . Handshaking == HANDSHAKING_XONXOFF)
  26.         Status = STATUS_HOLDING;
  27. }
  28.  
  29.     /* SerialCommand(UBYTE *String):
  30.      *
  31.      *    Send a command string to the serial line and
  32.      *    interprete the control sequences.
  33.      */
  34.  
  35. VOID
  36. SerialCommand(UBYTE *String)
  37. {
  38.     LONG    Count = 0,i;
  39.     BYTE    GotControl = FALSE,GotEscape = FALSE;
  40.     BYTE    OldStatus,BlockSet;
  41.  
  42.         /* Scan the string. */
  43.  
  44.     for(i = 0 ; i < strlen(String) ; i++)
  45.     {
  46.             /* We are looking for plain characters
  47.              * and the control ('\') and escape
  48.              * ('^') characters.
  49.              */
  50.  
  51.         if(!GotControl && !GotEscape)
  52.         {
  53.                 /* Got a control character,
  54.                  * the next byte will probably be
  55.                  * a command sequence.
  56.                  */
  57.  
  58.             if(String[i] == '\\')
  59.             {
  60.                 GotControl = TRUE;
  61.                 continue;
  62.             }
  63.  
  64.                 /* Got an escape character,
  65.                  * the next byte will be some
  66.                  * kind of control character
  67.                  * (such as XON, XOF, bell, etc.).
  68.                  */
  69.  
  70.             if(String[i] == '^')
  71.             {
  72.                 GotEscape = TRUE;
  73.                 continue;
  74.             }
  75.  
  76.                 /* This tells us to wait another
  77.                  * second before continuing with
  78.                  * the scanning.
  79.                  */
  80.  
  81.             if(String[i] == '~')
  82.             {
  83.                 if(Count)
  84.                 {
  85.                     SerWrite(SharedBuffer,Count);
  86.  
  87.                     Count = 0;
  88.                 }
  89.  
  90.                 WaitTime(0,MILLION / 2);
  91.                 HandleSerial();
  92.  
  93.                 continue;
  94.             }
  95.  
  96.                 /* Stuff the character into the
  97.                  * buffer.
  98.                  */
  99.  
  100.             SharedBuffer[Count++] = String[i];
  101.         }
  102.         else
  103.         {
  104.                 /* Convert the character to a control
  105.                  * style character (^C, etc.).
  106.                  */
  107.  
  108.             if(GotEscape)
  109.             {
  110.                 if(ToUpper(String[i]) >= 'A' && ToUpper(String[i]) <= 91)
  111.                     SharedBuffer[Count++] = ToUpper(String[i]) - '@';
  112.                 else
  113.                     SharedBuffer[Count++] = String[i];
  114.  
  115.                 GotEscape = FALSE;
  116.             }
  117.  
  118.                 /* The next character represents a command. */
  119.  
  120.             if(GotControl)
  121.             {
  122.                 switch(ToUpper(String[i]))
  123.                 {
  124.                         /* Execute an AmigaDOS command. */
  125.  
  126.                     case 'D':    if(!WeAreBlocking)
  127.                             {
  128.                                 BlockSet = TRUE;
  129.  
  130.                                 BlockWindows();
  131.                             }
  132.                             else
  133.                                 BlockSet = FALSE;
  134.  
  135.                             SendAmigaDOSCommand(&String[i + 1]);
  136.  
  137.                             if(BlockSet)
  138.                                 ReleaseWindows();
  139.  
  140.                             return;
  141.  
  142.                         /* Execute an ARexx command. */
  143.  
  144.                     case 'A':    if(!WeAreBlocking)
  145.                             {
  146.                                 BlockSet = TRUE;
  147.  
  148.                                 BlockWindows();
  149.                             }
  150.                             else
  151.                                 BlockSet = FALSE;
  152.  
  153.                             SendARexxCommand(&String[i + 1]);
  154.  
  155.                             if(BlockSet)
  156.                                 ReleaseWindows();
  157.  
  158.                             return;
  159.  
  160.                         /* Add the control character ('\'). */
  161.  
  162.                     case '\\':    SharedBuffer[Count++] = '\\';
  163.                             break;
  164.  
  165.                         /* This is a backspace. */
  166.  
  167.                     case 'B':    SharedBuffer[Count++] = '\b';
  168.                             break;
  169.  
  170.                         /* This is a form feed. */
  171.  
  172.                     case 'F':    SharedBuffer[Count++] = '\f';
  173.                             break;
  174.  
  175.                         /* This is a line feed. */
  176.  
  177.                     case 'N':    SharedBuffer[Count++] = '\n';
  178.                             break;
  179.  
  180.                         /* Send the current password. */
  181.  
  182.                     case 'P':    if(Password[0])
  183.                             {
  184.                                 if(Count)
  185.                                 {
  186.                                     SerWrite(SharedBuffer,Count);
  187.  
  188.                                     Count = 0;
  189.                                 }
  190.  
  191.                                 SerWrite(Password,strlen(Password));
  192.                             }
  193.  
  194.                             break;
  195.  
  196.                         /* This is a carriage return. */
  197.  
  198.                     case 'R':    SharedBuffer[Count++] = '\r';
  199.                             break;
  200.  
  201.                         /* This is a tab. */
  202.  
  203.                     case 'T':    SharedBuffer[Count++] = '\t';
  204.                             break;
  205.  
  206.                         /* Send a break across the serial line. */
  207.  
  208.                     case 'X':    if(Count)
  209.                             {
  210.                                 SerWrite(SharedBuffer,Count);
  211.  
  212.                                 Count = 0;
  213.                             }
  214.  
  215.                             if(WriteRequest)
  216.                             {
  217.                                 OldStatus = Status;
  218.  
  219.                                 Status = STATUS_BREAKING;
  220.  
  221.                                 WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
  222.                                 DoIO(WriteRequest);
  223.  
  224.                                 Status = OldStatus;
  225.                             }
  226.  
  227.                             break;
  228.  
  229.                         /* Feed the contents of the
  230.                          * clipboard into the input
  231.                          * stream.
  232.                          */
  233.  
  234.                     case 'I':    if(Count)
  235.                                 SerWrite(SharedBuffer,Count);
  236.  
  237.                             Count = LoadClip(SharedBuffer,256);
  238.  
  239.                             break;
  240.  
  241.                         /* Send a string to the clipboard. */
  242.  
  243.                     case 'G':    if(String[i + 1])
  244.                                 SaveClip(&String[i + 1],strlen(&String[i + 1]));
  245.  
  246.                             return;
  247.  
  248.                         /* Produce the escape character. */
  249.  
  250.                     case 'E':    SharedBuffer[Count++] = ESC;
  251.                             break;
  252.  
  253.                         /* Stuff the character into the buffer. */
  254.  
  255.                     default:    SharedBuffer[Count++] = String[i];
  256.                             break;
  257.                 }
  258.  
  259.                 GotControl = FALSE;
  260.             }
  261.         }
  262.  
  263.             /* If the buffer is full, release it. */
  264.  
  265.         if(Count == 256)
  266.         {
  267.             SerWrite(SharedBuffer,Count);
  268.  
  269.             Count = 0;
  270.         }
  271.     }
  272.  
  273.     if(Count)
  274.         SerWrite(SharedBuffer,Count);
  275. }
  276.  
  277.     /* SerWrite(APTR Buffer,LONG Size):
  278.      *
  279.      *    Send a number of bytes across the serial line.
  280.      */
  281.  
  282. VOID
  283. SerWrite(APTR Buffer,LONG Size)
  284. {
  285.     if(WriteRequest && Size)
  286.     {
  287.             /* xpr wants to see the data before it is
  288.              * transferred.
  289.              */
  290.  
  291.         if(TransferBits & XPRS_USERMON)
  292.             if(!(Size = XProtocolUserMon(XprIO,Buffer,Size,Size)))
  293.                 return;
  294.  
  295.             /* If full duplex is enabled, send the entire
  296.              * buffer.
  297.              */
  298.  
  299.         if(Config . Duplex == DUPLEX_FULL)
  300.         {
  301.             WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  302.             WriteRequest -> IOSer . io_Data        = Buffer;
  303.             WriteRequest -> IOSer . io_Length    = Size;
  304.  
  305.             DoIO(WriteRequest);
  306.         }
  307.         else
  308.         {
  309.             UBYTE *ByteBuffer = Buffer;
  310.  
  311.                 /* Half duplex is enabled, send only
  312.                  * a single character at a time.
  313.                  */
  314.  
  315.             WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  316.             WriteRequest -> IOSer . io_Length    = 1;
  317.  
  318.             while(Size--)
  319.             {
  320.                 WriteRequest -> IOSer . io_Data = ByteBuffer;
  321.                 DoIO(WriteRequest);
  322.  
  323.                 ConProcess(ByteBuffer,1);
  324.  
  325.                 ByteBuffer++;
  326.             }
  327.         }
  328.     }
  329. }
  330.  
  331.     /* SetFlags(struct IOExtSer *SomeRequest):
  332.      *
  333.      *    Set the contents of a serial device request according
  334.      *    to the current configuration settings.
  335.      */
  336.  
  337. VOID
  338. SetFlags(struct IOExtSer *SomeRequest)
  339. {
  340.     SomeRequest -> io_Baud        = Config . BaudRate;
  341.     SomeRequest -> io_BrkTime    = Config . BreakLength;
  342.     SomeRequest -> io_ReadLen    = Config . BitsPerChar;
  343.     SomeRequest -> io_WriteLen    = Config . BitsPerChar;
  344.     SomeRequest -> io_StopBits    = Config . StopBits;
  345.  
  346.     SomeRequest -> io_ExtFlags    &= ~(SEXTF_MSPON|SEXTF_MARK);
  347.     SomeRequest -> io_SerFlags    &= ~(SERF_PARTY_ON|SERF_PARTY_ODD|SERF_7WIRE|SERF_RAD_BOOGIE);
  348.  
  349.     switch(Config . Parity)
  350.     {
  351.         case PARITY_EVEN:    SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  352.                     break;
  353.  
  354.         case PARITY_ODD:    SomeRequest -> io_SerFlags |= SERF_PARTY_ON|SERF_PARTY_ODD;
  355.                     break;
  356.  
  357.         case PARITY_MARK:    SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  358.                     SomeRequest -> io_ExtFlags |= SEXTF_MSPON|SEXTF_MARK;
  359.                     break;
  360.  
  361.         case PARITY_SPACE:    SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  362.                     SomeRequest -> io_ExtFlags |= SEXTF_MSPON;
  363.                     break;
  364.  
  365.         default:        break;
  366.     }
  367.  
  368.     if(Config . Handshaking == HANDSHAKING_RTSCTS)
  369.         SomeRequest -> io_SerFlags |= SERF_7WIRE;
  370.  
  371.     if(Config . HighSpeed)
  372.         SomeRequest -> io_SerFlags |= SERF_RAD_BOOGIE;
  373.  
  374.     SomeRequest -> io_SerFlags |= SERF_XDISABLED;
  375. }
  376.  
  377.     /* SetParameters():
  378.      *
  379.      *    Set the parameters for both serial requests and the
  380.      *    serial line.
  381.      */
  382.  
  383. VOID
  384. SetParameters()
  385. {
  386.     if(WriteRequest)
  387.     {
  388.         WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  389.  
  390.         SetFlags(WriteRequest);
  391.         SetFlags(ReadRequest);
  392.  
  393.         DoIO(WriteRequest);
  394.     }
  395. }
  396.  
  397.     /* FlushSerial():
  398.      *
  399.      *    Terminate all read/write activity on the serial
  400.      *    line.
  401.      */
  402.  
  403. VOID
  404. FlushSerial()
  405. {
  406.     if(ReadPort)
  407.     {
  408.         if(!CheckIO(ReadRequest))
  409.             AbortIO(ReadRequest);
  410.  
  411.         WaitIO(ReadRequest);
  412.  
  413.         GetMsg(ReadRequest -> IOSer . io_Message . mn_ReplyPort);
  414.  
  415.         WriteRequest -> IOSer . io_Command = CMD_CLEAR;
  416.         DoIO(WriteRequest);
  417.     }
  418. }
  419.  
  420.     /* DeleteSerial():
  421.      *
  422.      *    Close the serial device and release all associated
  423.      *    resources.
  424.      */
  425.  
  426. VOID
  427. DeleteSerial()
  428. {
  429.     BYTE Closed = FALSE;
  430.  
  431.     if(ReadBuffer)
  432.     {
  433.         FreeMem(ReadBuffer,1024);
  434.  
  435.         ReadBuffer = NULL;
  436.     }
  437.  
  438.     if(ReadRequest)
  439.     {
  440.         if(ReadRequest -> IOSer . io_Device)
  441.         {
  442.             ReadRequest -> IOSer . io_Command = CMD_RESET;
  443.             DoIO(ReadRequest);
  444.  
  445.             CloseDevice(ReadRequest);
  446.  
  447.             Closed = TRUE;
  448.         }
  449.  
  450.         if(ReadRequest -> IOSer . io_Message . mn_ReplyPort)
  451.             DeleteMsgPort(ReadRequest -> IOSer . io_Message . mn_ReplyPort);
  452.  
  453.         DeleteIORequest(ReadRequest);
  454.  
  455.         ReadRequest = NULL;
  456.     }
  457.  
  458.     if(WriteRequest)
  459.     {
  460.         if(WriteRequest -> IOSer . io_Device && !Closed)
  461.         {
  462.             WriteRequest -> IOSer . io_Command = CMD_RESET;
  463.             DoIO(WriteRequest);
  464.  
  465.             CloseDevice(WriteRequest);
  466.         }
  467.  
  468.         if(WriteRequest -> IOSer . io_Message . mn_ReplyPort)
  469.             DeleteMsgPort(WriteRequest -> IOSer . io_Message . mn_ReplyPort);
  470.  
  471.         DeleteIORequest(WriteRequest);
  472.  
  473.         WriteRequest = NULL;
  474.     }
  475.  
  476.     ReadPort = NULL;
  477. }
  478.  
  479.     /* CreateSerial():
  480.      *
  481.      *    Create handles for the serial device and open it.
  482.      */
  483.  
  484. BYTE
  485. CreateSerial()
  486. {
  487.     struct MsgPort    *WritePort;
  488.  
  489.     if(ReadBuffer = AllocMem(1024,MEMF_PUBLIC))
  490.     {
  491.         if(ReadPort = (struct MsgPort *)CreateMsgPort())
  492.         {
  493.             if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
  494.             {
  495.                 SetFlags(ReadRequest);
  496.  
  497.                 ReadRequest -> io_RBufLen = 8000;
  498.  
  499.                 if(!OpenDevice(Config . SerialDevice,Config . UnitNumber,ReadRequest,0))
  500.                 {
  501.                     if(WritePort = (struct MsgPort *)CreateMsgPort())
  502.                     {
  503.                         if(WriteRequest = (struct IOExtSer *)CreateIORequest(WritePort,sizeof(struct IOExtSer)))
  504.                         {
  505.                             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  506.  
  507.                             WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  508.  
  509.                             SetParameters();
  510.  
  511.                             ReadRequest -> IOSer . io_Command    = CMD_READ;
  512.                             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  513.                             ReadRequest -> IOSer . io_Length    = 1;
  514.  
  515.                             SendIO(ReadRequest);
  516.  
  517.                             return(TRUE);
  518.                         }
  519.                     }
  520.                 }
  521.             }
  522.         }
  523.     }
  524.  
  525.     return(FALSE);
  526. }
  527.