home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d8xx / d832 / term.lha / Term / term-3.1-Source.lha / termSerial.c < prev    next >
C/C++ Source or Header  |  1993-02-18  |  33KB  |  1,735 lines

  1. /*
  2. **    termSerial.c
  3. **
  4. **    Serial driver support routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Local copy of serial driver name and unit number. */
  13.  
  14. STATIC UBYTE    SerialDevice[40];
  15. STATIC LONG    UnitNumber = -1;
  16.  
  17.     /* SetFlags(struct IOExtSer *SomeRequest):
  18.      *
  19.      *    Set the contents of a serial device request according
  20.      *    to the current configuration settings.
  21.      */
  22.  
  23. VOID __regargs
  24. SetFlags(struct IOExtSer *SomeRequest)
  25. {
  26.         /* Remember new baud rate. */
  27.  
  28.     DTERate = Config -> SerialConfig -> BaudRate;
  29.  
  30.     SomeRequest -> io_Baud        = Config -> SerialConfig -> BaudRate;
  31.     SomeRequest -> io_BrkTime    = Config -> SerialConfig -> BreakLength;
  32.     SomeRequest -> io_ReadLen    = Config -> SerialConfig -> BitsPerChar;
  33.     SomeRequest -> io_WriteLen    = Config -> SerialConfig -> BitsPerChar;
  34.     SomeRequest -> io_StopBits    = Config -> SerialConfig -> StopBits;
  35.  
  36.     SomeRequest -> io_ExtFlags    &= ~(SEXTF_MSPON|SEXTF_MARK);
  37.     SomeRequest -> io_SerFlags    &= ~(SERF_PARTY_ON|SERF_PARTY_ODD|SERF_7WIRE|SERF_RAD_BOOGIE);
  38.  
  39.     switch(Config -> SerialConfig -> Parity)
  40.     {
  41.         case PARITY_EVEN:
  42.  
  43.             SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  44.             break;
  45.  
  46.         case PARITY_ODD:
  47.  
  48.             SomeRequest -> io_SerFlags |= SERF_PARTY_ON|SERF_PARTY_ODD;
  49.             break;
  50.  
  51.         case PARITY_MARK:
  52.  
  53.             SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  54.             SomeRequest -> io_ExtFlags |= SEXTF_MSPON|SEXTF_MARK;
  55.             break;
  56.  
  57.         case PARITY_SPACE:
  58.  
  59.             SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  60.             SomeRequest -> io_ExtFlags |= SEXTF_MSPON;
  61.             break;
  62.     }
  63.  
  64.     if(Config -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE)
  65.         SomeRequest -> io_SerFlags |= SERF_7WIRE;
  66.  
  67.     if(Config -> SerialConfig -> HighSpeed)
  68.         SomeRequest -> io_SerFlags |= SERF_RAD_BOOGIE;
  69.  
  70.     if(Config -> SerialConfig -> Shared)
  71.         SomeRequest -> io_SerFlags |= SERF_SHARED;
  72.  
  73.     SomeRequest -> io_SerFlags |= SERF_XDISABLED;
  74. }
  75.  
  76.     /* GetFlags(struct Configuration *Config,struct IOExtSer *SomeRequest):
  77.      *
  78.      *    Update configuration with serial settings.
  79.      */
  80.  
  81. VOID __regargs
  82. GetFlags(struct Configuration *Config,struct IOExtSer *SomeRequest)
  83. {
  84.     Config -> SerialConfig -> BaudRate    = SomeRequest -> io_Baud;
  85.     Config -> SerialConfig -> BreakLength    = SomeRequest -> io_BrkTime;
  86.     Config -> SerialConfig -> BitsPerChar    = SomeRequest -> io_ReadLen;
  87.     Config -> SerialConfig -> BitsPerChar    = SomeRequest -> io_WriteLen;
  88.     Config -> SerialConfig -> StopBits    = SomeRequest -> io_StopBits;
  89.  
  90.     if(SomeRequest -> io_SerFlags & SERF_PARTY_ON)
  91.     {
  92.         if(SomeRequest -> io_SerFlags & SERF_PARTY_ODD)
  93.             Config -> SerialConfig -> Parity = PARITY_ODD;
  94.         else
  95.         {
  96.             if(SomeRequest -> io_ExtFlags & SEXTF_MSPON)
  97.             {
  98.                 if(SomeRequest -> io_ExtFlags & SEXTF_MARK)
  99.                     Config -> SerialConfig -> Parity = PARITY_MARK;
  100.                 else
  101.                     Config -> SerialConfig -> Parity = PARITY_SPACE;
  102.             }
  103.         }
  104.     }
  105.     else
  106.         Config -> SerialConfig -> Parity = PARITY_NONE;
  107.  
  108.     if(SomeRequest -> io_SerFlags & SERF_7WIRE)
  109.         Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_RTSCTS;
  110.     else
  111.         Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_NONE;
  112.  
  113.     if(SomeRequest -> io_SerFlags & SERF_RAD_BOOGIE)
  114.         Config -> SerialConfig -> HighSpeed = TRUE;
  115.     else
  116.         Config -> SerialConfig -> HighSpeed = FALSE;
  117.  
  118.     if(SomeRequest -> io_SerFlags & SERF_SHARED)
  119.         Config -> SerialConfig -> Shared = TRUE;
  120.     else
  121.         Config -> SerialConfig -> Shared = FALSE;
  122.  
  123.     SomeRequest -> io_SerFlags |= SERF_XDISABLED;
  124. }
  125.  
  126.     /* CallMenu(STRPTR Name,ULONG Code):
  127.      *
  128.      *    Call a menu function either through the name of the corresponding
  129.      *    menu item or a menu number.
  130.      */
  131.  
  132. STATIC VOID __inline
  133. CallMenu(STRPTR Name,ULONG Code)
  134. {
  135.     WORD MenuNum = -1,Item = 0,Sub = 0,i;
  136.  
  137.         /* Are we to look for a name? */
  138.  
  139.     if(Name)
  140.     {
  141.         WORD Len = strlen(Name);
  142.  
  143.             /* Scan the menu list... */
  144.  
  145.         for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
  146.         {
  147.             switch(TermMenu[i] . nm_Type)
  148.             {
  149.                 case NM_TITLE:
  150.  
  151.                     MenuNum++;
  152.                     Item = Sub = 0;
  153.                     break;
  154.  
  155.                 case NM_ITEM:
  156.  
  157.                     Sub = 0;
  158.                     break;
  159.             }
  160.  
  161.                 /* Did we get a valid name string? */
  162.  
  163.             if(TermMenu[i] . nm_Label != NM_BARLABEL)
  164.             {
  165.                     /* Does the name match our template? */
  166.  
  167.                 if(!Strnicmp(TermMenu[i] . nm_Label,Name,Len))
  168.                 {
  169.                     struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
  170.  
  171.                     if(MenuItem)
  172.                         HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
  173.  
  174.                     break;
  175.                 }
  176.             }
  177.  
  178.             switch(TermMenu[i] . nm_Type)
  179.             {
  180.                 case NM_ITEM:
  181.  
  182.                     Item++;
  183.                     break;
  184.  
  185.                 case NM_SUB:
  186.  
  187.                     Sub++;
  188.                     break;
  189.             }
  190.         }
  191.     }
  192.     else
  193.     {
  194.         WORD    TheMenu    =  Code % 100,
  195.             TheItem    = (Code / 100) % 100,
  196.             TheSub    =  Code / 10000;
  197.  
  198.             /* Scan the menu list... */
  199.  
  200.         for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
  201.         {
  202.             switch(TermMenu[i] . nm_Type)
  203.             {
  204.                 case NM_TITLE:
  205.  
  206.                     MenuNum++;
  207.                     Item = Sub = 0;
  208.                     break;
  209.  
  210.                 case NM_ITEM:
  211.  
  212.                     Sub = 0;
  213.                     break;
  214.             }
  215.  
  216.                 /* Is it the menu number we want? */
  217.  
  218.             if(TheMenu == MenuNum && TheItem == Item && TheSub == Sub)
  219.             {
  220.                 if(TermMenu[i] . nm_Label != NM_BARLABEL)
  221.                 {
  222.                     struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
  223.  
  224.                     if(MenuItem)
  225.                         HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
  226.                 }
  227.  
  228.                 break;
  229.             }
  230.  
  231.             switch(TermMenu[i] . nm_Type)
  232.             {
  233.                 case NM_ITEM:
  234.  
  235.                     Item++;
  236.                     break;
  237.  
  238.                 case NM_SUB:
  239.  
  240.                     Sub++;
  241.                     break;
  242.             }
  243.         }
  244.     }
  245. }
  246.  
  247.     /* TypeChars(STRPTR String,LONG Len):
  248.      *
  249.      *    Send single characters, just as if they had
  250.      *    been typed on the keyboard.
  251.      */
  252.  
  253. STATIC VOID __regargs
  254. TypeChars(register STRPTR String,register LONG Len,struct timeval *KeyRepeatDelay)
  255. {
  256.     if(KeyRepeatDelay)
  257.     {
  258.         while(Len--)
  259.         {
  260.             SerWrite(String++,1);
  261.  
  262.             if(Len)
  263.             {
  264.                 TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  265.                 TimeRequest -> tr_time            = *KeyRepeatDelay;
  266.  
  267.                 DoIO(TimeRequest);
  268.             }
  269.         }
  270.     }
  271.     else
  272.         SerWrite(String,Len);
  273. }
  274.  
  275.     /* SerialCommand(STRPTR String):
  276.      *
  277.      *    Send a command string to the serial line and
  278.      *    interprete the control sequences.
  279.      */
  280.  
  281. VOID __regargs
  282. SerialCommand(STRPTR String)
  283. {
  284.     LONG    Count = 0,i,Len = strlen(String);
  285.  
  286.     BYTE    GotControl    = FALSE,
  287.         GotEscape    = FALSE,
  288.         OldStatus;
  289.  
  290.     struct Preferences     Prefs;
  291.     struct timeval        *KeyRepeatDelay;
  292.  
  293.         /* Get current key repeat delay. */
  294.  
  295.     GetPrefs(&Prefs,offsetof(struct Preferences,KeyRptDelay));
  296.  
  297.         /* Any delay specified at all? */
  298.  
  299.     if(Prefs . KeyRptSpeed . tv_secs || Prefs . KeyRptSpeed . tv_micro)
  300.         KeyRepeatDelay = &Prefs . KeyRptSpeed;
  301.     else
  302.         KeyRepeatDelay = NULL;
  303.  
  304.         /* Scan the string. */
  305.  
  306.     for(i = 0 ; i < Len ; i++)
  307.     {
  308.             /* We are looking for plain characters
  309.              * and the control ('\') and escape
  310.              * ('^') characters.
  311.              */
  312.  
  313.         if(!GotControl && !GotEscape)
  314.         {
  315.                 /* Got a control character,
  316.                  * the next byte will probably be
  317.                  * a command sequence.
  318.                  */
  319.  
  320.             if(String[i] == '\\')
  321.             {
  322.                 GotControl = TRUE;
  323.                 continue;
  324.             }
  325.  
  326.                 /* Got an escape character,
  327.                  * the next byte will be some
  328.                  * kind of control character
  329.                  * (such as XON, XOF, bell, etc.).
  330.                  */
  331.  
  332.             if(String[i] == '^')
  333.             {
  334.                 GotEscape = TRUE;
  335.                 continue;
  336.             }
  337.  
  338.                 /* This tells us to wait another
  339.                  * second before continuing with
  340.                  * the scanning.
  341.                  */
  342.  
  343.             if(String[i] == '~')
  344.             {
  345.                 if(Count)
  346.                 {
  347.                     SerWrite(SharedBuffer,Count);
  348.  
  349.                     Count = 0;
  350.                 }
  351.  
  352.                 WaitTime(0,MILLION / 2);
  353.  
  354.                 HandleSerial();
  355.  
  356.                 continue;
  357.             }
  358.  
  359.                 /* Stuff the character into the
  360.                  * buffer.
  361.                  */
  362.  
  363.             SharedBuffer[Count++] = String[i];
  364.         }
  365.         else
  366.         {
  367.                 /* Convert the character to a control
  368.                  * style character (^C, etc.).
  369.                  */
  370.  
  371.             if(GotEscape)
  372.             {
  373.                 if(ToUpper(String[i]) >= 'A' && ToUpper(String[i]) <= '_')
  374.                     SharedBuffer[Count++] = ToUpper(String[i]) - '@';
  375.                 else
  376.                     SharedBuffer[Count++] = String[i];
  377.  
  378.                 GotEscape = FALSE;
  379.             }
  380.  
  381.                 /* The next character represents a command. */
  382.  
  383.             if(GotControl)
  384.             {
  385.                 switch(ToUpper(String[i]))
  386.                 {
  387.                         /* Translate code. */
  388.  
  389.                     case '*':
  390.  
  391.                         i++;
  392.  
  393.                         while(i < Len && String[i] == ' ')
  394.                             i++;
  395.  
  396.                         if(i < Len)
  397.                         {
  398.                             UBYTE DummyBuffer[5],j = 0,Char;
  399.  
  400.                             if(String[i] >= '0' && String[i] <= '9')
  401.                             {
  402.                                 while(j < 3 && i < Len)
  403.                                 {
  404.                                     Char = String[i++];
  405.  
  406.                                     if(Char >= '0' && Char <= '9')
  407.                                         DummyBuffer[j++] = Char;
  408.                                     else
  409.                                     {
  410.                                         i--;
  411.  
  412.                                         break;
  413.                                     }
  414.                                 }
  415.                             }
  416.                             else
  417.                             {
  418.                                 while(j < 4 && i < Len)
  419.                                 {
  420.                                     Char = ToLower(String[i++]);
  421.  
  422.                                     if((Char >= '0' && Char <= '9') || (Char >= 'a' && Char <= 'z'))
  423.                                         DummyBuffer[j++] = Char;
  424.                                     else
  425.                                     {
  426.                                         i--;
  427.  
  428.                                         break;
  429.                                     }
  430.                                 }
  431.                             }
  432.  
  433.                             DummyBuffer[j] = 0;
  434.  
  435.                             SharedBuffer[Count++] = NameToCode(DummyBuffer);
  436.                         }
  437.  
  438.                         i--;
  439.  
  440.                         break;
  441.  
  442.                         /* Execute an AmigaDOS command. */
  443.  
  444.                     case 'D':
  445.  
  446.                         if(!InRexx)
  447.                         {
  448.                             if(!WeAreBlocking)
  449.                             {
  450.                                 BlockWindows();
  451.  
  452.                                 SendAmigaDOSCommand(&String[i + 1]);
  453.  
  454.                                 ReleaseWindows();
  455.                             }
  456.                             else
  457.                                 SendAmigaDOSCommand(&String[i + 1]);
  458.                         }
  459.  
  460.                         return;
  461.  
  462.                         /* Execute an ARexx command. */
  463.  
  464.                     case 'A':
  465. #ifdef USE_AREXX
  466.                         if(!InRexx)
  467.                         {
  468.                             if(!WeAreBlocking)
  469.                             {
  470.                                 BlockWindows();
  471.  
  472.                                 SendARexxCommand(&String[i + 1]);
  473.  
  474.                                 ReleaseWindows();
  475.                             }
  476.                             else
  477.                                 SendARexxCommand(&String[i + 1]);
  478.                         }
  479.  
  480. #endif    /* USE_AREXX */
  481.  
  482.                         return;
  483.  
  484.                         /* Add the control character ('\'). */
  485.  
  486.                     case '\\':
  487.  
  488.                         SharedBuffer[Count++] = '\\';
  489.                         break;
  490.  
  491.                         /* This is a backspace. */
  492.  
  493.                     case 'B':
  494.  
  495.                         SharedBuffer[Count++] = '\b';
  496.                         break;
  497.  
  498.                         /* This is a form feed. */
  499.  
  500.                     case 'F':
  501.  
  502.                         SharedBuffer[Count++] = '\f';
  503.                         break;
  504.  
  505.                         /* This is a line feed. */
  506.  
  507.                     case 'N':
  508.  
  509.                         SharedBuffer[Count++] = '\n';
  510.                         break;
  511.  
  512.                         /* Send the current password. */
  513.  
  514.                     case 'P':
  515.  
  516.                         if(Password[0])
  517.                         {
  518.                             if(Count)
  519.                             {
  520.                                 SerWrite(SharedBuffer,Count);
  521.  
  522.                                 Count = 0;
  523.                             }
  524.  
  525.                             TypeChars(Password,strlen(Password),KeyRepeatDelay);
  526.                         }
  527.  
  528.                         break;
  529.  
  530.                         /* This is a carriage return. */
  531.  
  532.                     case 'R':
  533.  
  534.                         SharedBuffer[Count++] = '\r';
  535.                         break;
  536.  
  537.                         /* This is a tab. */
  538.  
  539.                     case 'T':
  540.  
  541.                         SharedBuffer[Count++] = '\t';
  542.                         break;
  543.  
  544.                         /* Send the current user name. */
  545.  
  546.                     case 'U':
  547.  
  548.                         if(UserName[0])
  549.                         {
  550.                             if(Count)
  551.                             {
  552.                                 SerWrite(SharedBuffer,Count);
  553.  
  554.                                 Count = 0;
  555.                             }
  556.  
  557.                             TypeChars(UserName,strlen(UserName),KeyRepeatDelay);
  558.                         }
  559.  
  560.                         break;
  561.  
  562.                         /* Send a break across the serial line. */
  563.  
  564.                     case 'X':
  565.  
  566.                         if(Count)
  567.                         {
  568.                             SerWrite(SharedBuffer,Count);
  569.  
  570.                             Count = 0;
  571.                         }
  572.  
  573.                         if(WriteRequest)
  574.                         {
  575.                             OldStatus = Status;
  576.  
  577.                             Status = STATUS_BREAKING;
  578.  
  579.                             WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
  580.  
  581.                             DoIO(WriteRequest);
  582.  
  583.                             Status = OldStatus;
  584.                         }
  585.  
  586.                         break;
  587.  
  588.                         /* Feed the contents of the
  589.                          * clipboard into the input
  590.                          * stream.
  591.                          */
  592.  
  593.                     case 'I':
  594.  
  595.                         if(Count)
  596.                             SerWrite(SharedBuffer,Count);
  597.  
  598.                         Count = LoadClip(SharedBuffer,256);
  599.  
  600.                         break;
  601.  
  602.                         /* Send a string to the clipboard. */
  603.  
  604.                     case 'G':
  605.  
  606.                         if(String[i + 1])
  607.                             SaveClip(&String[i + 1],strlen(&String[i + 1]));
  608.  
  609.                         return;
  610.  
  611.                         /* Produce the escape character. */
  612.  
  613.                     case 'E':
  614.  
  615.                         SharedBuffer[Count++] = ESC;
  616.                         break;
  617.  
  618.                         /* Call a menu item. */
  619.  
  620.                     case 'C':
  621.  
  622.                         i++;
  623.  
  624.                             /* Scan for a menu number or
  625.                              * a single quote...
  626.                              */
  627.  
  628.                         while(i < Len)
  629.                         {
  630.                             if(String[i] >= '0' && String[i] <= '9')
  631.                                 break;
  632.  
  633.                             if(String[i] == '\'')
  634.                                 break;
  635.  
  636.                             if(String[i] != ' ')
  637.                                 break;
  638.  
  639.                             i++;
  640.                         }
  641.  
  642.                         if(i < Len)
  643.                         {
  644.                             UBYTE DummyBuffer[256];
  645.  
  646.                                 /* Did we get a quote? */
  647.  
  648.                             if(String[i] == '\'')
  649.                             {
  650.                                 LONG Start = ++i;
  651.  
  652.                                 if(String[Start])
  653.                                 {
  654.                                     WORD Length;
  655.  
  656.                                     while(i < Len)
  657.                                     {
  658.                                         if(String[i] != '\'')
  659.                                             i++;
  660.                                         else
  661.                                             break;
  662.                                     }
  663.  
  664.                                     if(String[i] == '\'')
  665.                                         Length = i - Start;
  666.                                     else
  667.                                         Length = i - Start + 1;
  668.  
  669.                                     memcpy(DummyBuffer,&String[Start],Length);
  670.  
  671.                                     DummyBuffer[Length] = 0;
  672.  
  673.                                     CallMenu(DummyBuffer,0);
  674.                                 }
  675.                             }
  676.                             else
  677.                             {
  678.                                 if(String[i] >= '0' && String[i] <= '9')
  679.                                 {
  680.                                     LONG Start = i,Length;
  681.  
  682.                                     while(i < Len)
  683.                                     {
  684.                                         if(String[i] >= '0' && String[i] <= '9')
  685.                                             i++;
  686.                                         else
  687.                                             break;
  688.                                     }
  689.  
  690.                                     if(i == Start)
  691.                                         Length = 1;
  692.                                     else
  693.                                         Length = i - Start;
  694.  
  695.                                     memcpy(DummyBuffer,&String[Start],Length);
  696.  
  697.                                     DummyBuffer[Length] = 0;
  698.  
  699.                                     CallMenu(NULL,Atol(DummyBuffer));
  700.                                 }
  701.                             }
  702.                         }
  703.  
  704.                         break;
  705.  
  706.                         /* Stuff the character into the buffer. */
  707.  
  708.                     default:
  709.  
  710.                         SharedBuffer[Count++] = String[i];
  711.                         break;
  712.                 }
  713.  
  714.                 GotControl = FALSE;
  715.             }
  716.         }
  717.  
  718.             /* If the buffer is full, release it. */
  719.  
  720.         if(Count == 256)
  721.         {
  722.             SerWrite(SharedBuffer,Count);
  723.  
  724.             Count = 0;
  725.         }
  726.     }
  727.  
  728.     if(Count)
  729.         SerWrite(SharedBuffer,Count);
  730. }
  731.  
  732.     /* SerWrite(APTR Buffer,LONG Size):
  733.      *
  734.      *    Send a number of bytes across the serial line.
  735.      */
  736.  
  737. VOID __regargs
  738. SerWrite(APTR Buffer,LONG Size)
  739. {
  740.     if(Size < 0)
  741.         Size = strlen(Buffer);
  742.  
  743.     if(WriteRequest && Size)
  744.     {
  745.         STATIC UBYTE TranslateData[512];
  746.  
  747.             /* xpr wants to see the data before it is
  748.              * transferred.
  749.              */
  750.  
  751.         if(XProtocolBase && (TransferBits & XPRS_USERMON))
  752.         {
  753.             if(Size = XProtocolUserMon(XprIO,Buffer,Size,Size))
  754.             {
  755.                 if(SendTable)
  756.                 {
  757.                     struct TranslationHandle Handle;
  758.  
  759.                         /* Set up for buffer translation. */
  760.  
  761.                     TranslateSetup(&Handle,Buffer,Size,TranslateData,512,SendTable);
  762.  
  763.                         /* Full or half duplex? */
  764.  
  765.                     if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  766.                     {
  767.                             /* Process the data... */
  768.  
  769.                         while(Size = TranslateBuffer(&Handle))
  770.                         {
  771.                             WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  772.                             WriteRequest -> IOSer . io_Data        = TranslateData;
  773.                             WriteRequest -> IOSer . io_Length    = Size;
  774.  
  775.                                 /* ...and send it. */
  776.  
  777.                             DoIO(WriteRequest);
  778.  
  779.                             BytesOut += Size;
  780.                         }
  781.                     }
  782.                     else
  783.                     {
  784.                         if(Marking)
  785.                             DropMarker();
  786.  
  787.                         ClearCursor();
  788.  
  789.                         while(Size = TranslateBuffer(&Handle))
  790.                         {
  791.                             WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  792.                             WriteRequest -> IOSer . io_Data        = TranslateData;
  793.                             WriteRequest -> IOSer . io_Length    = Size;
  794.  
  795.                                 /* Process the data while it is transferred. */
  796.  
  797.                             BeginIO(WriteRequest);
  798.  
  799.                             ConProcess(Buffer,Size);
  800.  
  801.                             WaitIO(WriteRequest);
  802.  
  803.                             BytesOut += Size;
  804.                         }
  805.  
  806.                         DrawCursor();
  807.                     }
  808.                 }
  809.                 else
  810.                 {
  811.                     WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  812.                     WriteRequest -> IOSer . io_Data        = Buffer;
  813.                     WriteRequest -> IOSer . io_Length    = Size;
  814.  
  815.                         /* If full duplex is enabled, send the entire
  816.                          * buffer without processing.
  817.                          */
  818.  
  819.                     if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  820.                         DoIO(WriteRequest);
  821.                     else
  822.                     {
  823.                             /* Process the data while it is transferred. */
  824.  
  825.                         BeginIO(WriteRequest);
  826.  
  827.                         if(Marking)
  828.                             DropMarker();
  829.  
  830.                         ClearCursor();
  831.  
  832.                         ConProcess(Buffer,Size);
  833.  
  834.                         DrawCursor();
  835.  
  836.                         WaitIO(WriteRequest);
  837.                     }
  838.  
  839.                     BytesOut += Size;
  840.                 }
  841.             }
  842.         }
  843.         else
  844.         {
  845.             if(SendTable)
  846.             {
  847.                 struct TranslationHandle Handle;
  848.  
  849.                     /* Set up for buffer translation. */
  850.  
  851.                 TranslateSetup(&Handle,Buffer,Size,TranslateData,512,SendTable);
  852.  
  853.                     /* Full or half duplex? */
  854.  
  855.                 if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  856.                 {
  857.                         /* Process the data... */
  858.  
  859.                     while(Size = TranslateBuffer(&Handle))
  860.                     {
  861.                         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  862.                         WriteRequest -> IOSer . io_Data        = TranslateData;
  863.                         WriteRequest -> IOSer . io_Length    = Size;
  864.  
  865.                             /* ...and send it. */
  866.  
  867.                         DoIO(WriteRequest);
  868.  
  869.                         BytesOut += Size;
  870.                     }
  871.                 }
  872.                 else
  873.                 {
  874.                     if(Marking)
  875.                         DropMarker();
  876.  
  877.                     ClearCursor();
  878.  
  879.                     while(Size = TranslateBuffer(&Handle))
  880.                     {
  881.                         WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  882.                         WriteRequest -> IOSer . io_Data        = TranslateData;
  883.                         WriteRequest -> IOSer . io_Length    = Size;
  884.  
  885.                             /* Process the data while it is transferred. */
  886.  
  887.                         BeginIO(WriteRequest);
  888.  
  889.                         ConProcess(Buffer,Size);
  890.  
  891.                         WaitIO(WriteRequest);
  892.  
  893.                         BytesOut += Size;
  894.                     }
  895.  
  896.                     DrawCursor();
  897.                 }
  898.             }
  899.             else
  900.             {
  901.                 WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  902.                 WriteRequest -> IOSer . io_Data        = Buffer;
  903.                 WriteRequest -> IOSer . io_Length    = Size;
  904.  
  905.                     /* If full duplex is enabled, send the entire
  906.                      * buffer without processing.
  907.                      */
  908.  
  909.                 if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
  910.                     DoIO(WriteRequest);
  911.                 else
  912.                 {
  913.                         /* Process the data while it is transferred. */
  914.  
  915.                     BeginIO(WriteRequest);
  916.  
  917.                     if(Marking)
  918.                         DropMarker();
  919.  
  920.                     ClearCursor();
  921.  
  922.                     ConProcess(Buffer,Size);
  923.  
  924.                     DrawCursor();
  925.  
  926.                     WaitIO(WriteRequest);
  927.                 }
  928.  
  929.                 BytesOut += Size;
  930.             }
  931.         }
  932.     }
  933. }
  934.  
  935.     /* ClearSerial():
  936.      *
  937.      *    Terminate all read/write activity on the serial
  938.      *    line.
  939.      */
  940.  
  941. VOID
  942. ClearSerial()
  943. {
  944.     if(ReadRequest)
  945.     {
  946.         if(!CheckIO(ReadRequest))
  947.             AbortIO(ReadRequest);
  948.  
  949.         WaitIO(ReadRequest);
  950.     }
  951.  
  952.     if(WriteRequest)
  953.     {
  954.         WriteRequest -> IOSer . io_Command = CMD_CLEAR;
  955.  
  956.         DoIO(WriteRequest);
  957.     }
  958. }
  959.  
  960.     /* DropDTR():
  961.      *
  962.      *    Drop the data terminal ready signal (i.e. close, wait a bit
  963.      *    and then reopen the serial drive).
  964.      */
  965.  
  966. BYTE
  967. DropDTR()
  968. {
  969.         /* Finish all serial read activity. */
  970.  
  971.     ClearSerial();
  972.  
  973.         /* Do we have any channels to work with? */
  974.  
  975.     if(ReadRequest && WriteRequest)
  976.     {
  977.             /* Close the device. */
  978.  
  979.         CloseDevice(ReadRequest);
  980.  
  981.             /* Wait a bit. */
  982.  
  983.         WaitTime(1,0);
  984.  
  985.             /* Set up the original configuration data. */
  986.  
  987.         SetFlags(ReadRequest);
  988.  
  989.         ReadRequest -> io_RBufLen = Config -> SerialConfig -> SerialBufferSize;
  990.  
  991.             /* Reopen the driver. */
  992.  
  993.         if(!OpenDevice(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,ReadRequest,0))
  994.         {
  995.             struct MsgPort *WritePort = WriteRequest -> IOSer . io_Message . mn_ReplyPort;
  996.  
  997.                 /* Fill in the rest. */
  998.  
  999.             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  1000.  
  1001.             WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  1002.  
  1003.             WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  1004.  
  1005.             SetFlags(WriteRequest);
  1006.  
  1007.             DoIO(WriteRequest);
  1008.  
  1009.                 /* Restart read activity. */
  1010.  
  1011.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  1012.             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1013.             ReadRequest -> IOSer . io_Length    = 1;
  1014.  
  1015.             SetSignal(0,SIG_SERIAL);
  1016.  
  1017.             BeginIO(ReadRequest);
  1018.  
  1019.             return(TRUE);
  1020.         }
  1021.         else
  1022.             DeleteSerial();
  1023.     }
  1024.     else
  1025.     {
  1026.         DeleteSerial();
  1027.  
  1028.         return(TRUE);
  1029.     }
  1030.  
  1031.     return(FALSE);
  1032. }
  1033.  
  1034.     /* DeleteSerial():
  1035.      *
  1036.      *    Close the serial device and release all associated
  1037.      *    resources.
  1038.      */
  1039.  
  1040. VOID
  1041. DeleteSerial()
  1042. {
  1043.     BYTE Closed = FALSE;
  1044.  
  1045.     if(ReadRequest)
  1046.     {
  1047.         if(ReadRequest -> IOSer . io_Device)
  1048.         {
  1049.             if(!Config -> SerialConfig -> Shared)
  1050.             {
  1051.                 ReadRequest -> IOSer . io_Command = CMD_RESET;
  1052.  
  1053.                 DoIO(ReadRequest);
  1054.             }
  1055.  
  1056.             CloseDevice(ReadRequest);
  1057.  
  1058.             Closed = TRUE;
  1059.         }
  1060.  
  1061.         DeleteIORequest(ReadRequest);
  1062.  
  1063.         ReadRequest = NULL;
  1064.     }
  1065.  
  1066.     if(WriteRequest)
  1067.     {
  1068.         if(WriteRequest -> IOSer . io_Device && !Closed)
  1069.         {
  1070.             if(!Config -> SerialConfig -> Shared)
  1071.             {
  1072.                 ReadRequest -> IOSer . io_Command = CMD_RESET;
  1073.  
  1074.                 DoIO(ReadRequest);
  1075.             }
  1076.  
  1077.             CloseDevice(WriteRequest);
  1078.         }
  1079.  
  1080.         if(WriteRequest -> IOSer . io_Message . mn_ReplyPort)
  1081.             DeleteMsgPort(WriteRequest -> IOSer . io_Message . mn_ReplyPort);
  1082.  
  1083.         DeleteIORequest(WriteRequest);
  1084.  
  1085.         WriteRequest = NULL;
  1086.     }
  1087.  
  1088.     if(ReadPort)
  1089.     {
  1090.         DeleteMsgPort(ReadPort);
  1091.  
  1092.         ReadPort = NULL;
  1093.     }
  1094.  
  1095.     if(ReadBuffer)
  1096.     {
  1097.         FreeVec(ReadBuffer);
  1098.  
  1099.         ReadBuffer = NULL;
  1100.     }
  1101.  
  1102.     if(HostReadBuffer)
  1103.     {
  1104.         FreeVec(HostReadBuffer);
  1105.  
  1106.         HostReadBuffer = NULL;
  1107.     }
  1108.  
  1109.     if(StripBuffer)
  1110.     {
  1111.         FreeVec(StripBuffer);
  1112.  
  1113.         StripBuffer = NULL;
  1114.     }
  1115.  
  1116.     if(OwnDevUnitBase && SerialDevice[0] && UnitNumber != -1)
  1117.     {
  1118.         FreeDevUnit(SerialDevice,UnitNumber);
  1119.  
  1120.         SerialDevice[0] = 0;
  1121.  
  1122.         UnitNumber = -1;
  1123.     }
  1124. }
  1125.  
  1126.     /* GetSerialError(LONG Error,BYTE *Reset):
  1127.      *
  1128.      *    Return an error message for each possible serial device error.
  1129.      */
  1130.  
  1131. STRPTR
  1132. GetSerialError(LONG Error,BYTE *Reset)
  1133. {
  1134.     if(Reset)
  1135.         *Reset = FALSE;
  1136.  
  1137.     switch(Error)
  1138.     {
  1139.         case IOERR_BADLENGTH:
  1140.         case IOERR_BADADDRESS:
  1141.         case IOERR_SELFTEST:
  1142.         case IOERR_OPENFAIL:
  1143.  
  1144.             return(LocaleString(MSG_SERIAL_OPENFAILURE_TXT));
  1145.  
  1146.         case SerErr_DevBusy:
  1147.  
  1148.             return(LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT));
  1149.  
  1150.         case SerErr_BaudMismatch:
  1151.  
  1152.             if(Reset)
  1153.                 *Reset = TRUE;
  1154.  
  1155.             return(LocaleString(MSG_SERIAL_ERROR_BAUDMISMATCH_TXT));
  1156.  
  1157.         case SerErr_BufErr:
  1158.  
  1159.             if(Reset)
  1160.                 *Reset = TRUE;
  1161.  
  1162.             return(LocaleString(MSG_SERIAL_ERROR_BUFERR_TXT));
  1163.  
  1164.         case SerErr_InvParam:
  1165.  
  1166.             if(Reset)
  1167.                 *Reset = TRUE;
  1168.  
  1169.             return(LocaleString(MSG_SERIAL_ERROR_INVPARAM_TXT));
  1170.  
  1171.         case SerErr_LineErr:
  1172.  
  1173.             return(LocaleString(MSG_SERIAL_ERROR_LINEERR_TXT));
  1174.  
  1175.         case SerErr_ParityErr:
  1176.  
  1177.             if(Reset)
  1178.                 *Reset = TRUE;
  1179.  
  1180.             return(LocaleString(MSG_SERIAL_ERROR_PARITYERR_TXT));
  1181.  
  1182.         case SerErr_TimerErr:
  1183.  
  1184.             return(LocaleString(MSG_SERIAL_ERROR_TIMERERR_TXT));
  1185.  
  1186.         case SerErr_BufOverflow:
  1187.  
  1188.             if(Reset)
  1189.                 *Reset = TRUE;
  1190.  
  1191.             return(LocaleString(MSG_SERIAL_ERROR_BUFOVERFLOW_TXT));
  1192.  
  1193.         case SerErr_NoDSR:
  1194.  
  1195.             return(LocaleString(MSG_SERIAL_ERROR_NODSR_TXT));
  1196.  
  1197.     /*    case SerErr_UnitBusy:    */
  1198.         case IOERR_UNITBUSY:
  1199.         case 16:
  1200.  
  1201.             return(LocaleString(MSG_SERIAL_ERROR_UNIT_BUSY_TXT));
  1202.  
  1203.         default:
  1204.  
  1205.             return(NULL);
  1206.     }
  1207. }
  1208.  
  1209.     /* CreateSerial():
  1210.      *
  1211.      *    Create handles for the serial device and open it.
  1212.      */
  1213.  
  1214. STRPTR
  1215. CreateSerial()
  1216. {
  1217.     struct MsgPort *WritePort;
  1218.  
  1219.         /* If OwnDevUnit.library is available, try to lock
  1220.          * the serial driver.
  1221.          */
  1222.  
  1223. Start:    if(OwnDevUnitBase)
  1224.     {
  1225.         STRPTR Error;
  1226.  
  1227.             /* Attempt to lock the device unit... */
  1228.  
  1229.         if(Error = AttemptDevUnit(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,TermIDString,NULL))
  1230.         {
  1231.                 /* Check for error type if any. */
  1232.  
  1233.             if(!Strnicmp(Error,ODUERR_LEADCHAR,1))
  1234.                 SPrintf(SharedBuffer,LocaleString(MSG_SERIAL_ERROR_ACCESSING_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,&Error[1]);
  1235.             else
  1236.                 SPrintf(SharedBuffer,LocaleString(MSG_SERIAL_DEVICE_IN_USE_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,Error);
  1237.  
  1238.             SerialDevice[0] = 0;
  1239.  
  1240.             UnitNumber = -1;
  1241.  
  1242.             return(SharedBuffer);
  1243.         }
  1244.         else
  1245.         {
  1246.             strcpy(SerialDevice,Config -> SerialConfig -> SerialDevice);
  1247.  
  1248.             UnitNumber = Config -> SerialConfig -> UnitNumber;
  1249.         }
  1250.     }
  1251.  
  1252.     if(ReadBuffer = AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1253.     {
  1254.         if(StripBuffer = AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
  1255.         {
  1256.             if(XProtocolBase && (TransferBits & XPRS_HOSTNOWAIT))
  1257.                 HostReadBuffer = AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
  1258.             else
  1259.                 HostReadBuffer = NULL;
  1260.  
  1261.             if(ReadPort = (struct MsgPort *)CreateMsgPort())
  1262.             {
  1263.                 if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
  1264.                 {
  1265.                     LONG Error;
  1266.  
  1267.                     SetFlags(ReadRequest);
  1268.  
  1269.                     ReadRequest -> io_RBufLen = Config -> SerialConfig -> SerialBufferSize;
  1270.  
  1271.                     if(!(Error = OpenDevice(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,ReadRequest,0)))
  1272.                     {
  1273.                         if(WritePort = (struct MsgPort *)CreateMsgPort())
  1274.                         {
  1275.                             if(WriteRequest = (struct IOExtSer *)CreateIORequest(WritePort,sizeof(struct IOExtSer)))
  1276.                             {
  1277.                                 CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  1278.  
  1279.                                 WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  1280.  
  1281.                                 WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  1282.  
  1283.                                 SetFlags(WriteRequest);
  1284.  
  1285.                                 DoIO(WriteRequest);
  1286.  
  1287.                                 /* If RTS/CTS (7 wire handshaking) is
  1288.                                  * selected, have a look at the DSR
  1289.                                  * line to see whether the modem
  1290.                                  * connected is willing to support
  1291.                                  * this handshaking mode.
  1292.                                  */
  1293.  
  1294.                                 if(Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_RTSCTS_DSR)
  1295.                                 {
  1296. Retry:                                    WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1297.  
  1298.                                     DoIO(WriteRequest);
  1299.  
  1300.                                         /* If the line happens to
  1301.                                          * be high, there is no
  1302.                                          * DSR signal present.
  1303.                                          */
  1304.  
  1305.                                     if(WriteRequest -> io_Status & CIAF_COMDSR)
  1306.                                     {
  1307.                                         if(MyEasyRequest(Window,LocaleString(MSG_SERIAL_NO_DSR_SIGNAL_TXT),LocaleString(MSG_SERIAL_RETRY_CANCEL_TXT)))
  1308.                                             goto Retry;
  1309.                                         else
  1310.                                         {
  1311.                                             DeleteSerial();
  1312.  
  1313.                                             Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_NONE;
  1314.  
  1315.                                             SerialMessage = LocaleString(MSG_SERIAL_NO_DSR_SIGNAL_HANDSHAKING_DISABLED_TXT);
  1316.  
  1317.                                             goto Start;
  1318.                                         }
  1319.                                     }
  1320.                                 }
  1321.  
  1322.                                 ReadRequest -> IOSer . io_Command    = CMD_READ;
  1323.                                 ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1324.                                 ReadRequest -> IOSer . io_Length    = 1;
  1325.  
  1326.                                 SetSignal(0,SIG_SERIAL);
  1327.  
  1328.                                 BeginIO(ReadRequest);
  1329.  
  1330.                                 return(NULL);
  1331.                             }
  1332.                         }
  1333.                         else
  1334.                         {
  1335.                             SerialMessage = NULL;
  1336.  
  1337.                             DeleteSerial();
  1338.  
  1339.                             return(LocaleString(MSG_SERIAL_FAILED_TO_CREATE_WRITE_PORT_TXT));
  1340.                         }
  1341.                     }
  1342.                     else
  1343.                     {
  1344.                         STRPTR String;
  1345.  
  1346.                         ReadRequest -> IOSer . io_Device = NULL;
  1347.  
  1348.                         DeleteSerial();
  1349.  
  1350.                         SerialMessage = NULL;
  1351.  
  1352.                         if(!(String = GetSerialError(Error,NULL)))
  1353.                             String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
  1354.  
  1355.                         SPrintf(SharedBuffer,String,Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber);
  1356.  
  1357.                         return(SharedBuffer);
  1358.                     }
  1359.                 }
  1360.             }
  1361.             else
  1362.             {
  1363.                 SerialMessage = NULL;
  1364.  
  1365.                 DeleteSerial();
  1366.  
  1367.                 return(LocaleString(MSG_SERIAL_FAILED_TO_CREATE_READ_PORT_TXT));
  1368.             }
  1369.         }
  1370.     }
  1371.  
  1372.     SerialMessage = NULL;
  1373.  
  1374.     DeleteSerial();
  1375.  
  1376.     return(LocaleString(MSG_SERIAL_NOT_ENOUGH_MEMORY_TXT));
  1377. }
  1378.  
  1379.     /* ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig):
  1380.      *
  1381.      *    Reconfigure the serial driver according to the new
  1382.      *    serial settings.
  1383.      */
  1384.  
  1385. BYTE
  1386. ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig)
  1387. {
  1388.     BYTE    Success    = RECONFIGURE_NOCHANGE,
  1389.         IsNew;
  1390.  
  1391.         /* Are new settings to be installed or have they already
  1392.          * been copied to the correct locations?
  1393.          */
  1394.  
  1395.     if(SerialConfig)
  1396.     {
  1397.         if(memcmp(Config -> SerialConfig,SerialConfig,sizeof(struct SerialSettings)))
  1398.             IsNew = TRUE;
  1399.         else
  1400.             IsNew = FALSE;
  1401.     }
  1402.     else
  1403.     {
  1404.         if(memcmp(Config -> SerialConfig,PrivateConfig -> SerialConfig,sizeof(struct SerialSettings)))
  1405.             IsNew = TRUE;
  1406.         else
  1407.             IsNew = FALSE;
  1408.     }
  1409.  
  1410.         /* Any changes in the serial configuration area? */
  1411.  
  1412.     if(IsNew)
  1413.     {
  1414.         BYTE SameDevice = TRUE;
  1415.  
  1416.             /* Any new data to swap in? */
  1417.  
  1418.         if(SerialConfig)
  1419.         {
  1420.                 /* Store the previous settings. */
  1421.  
  1422.             SaveConfig(Config,PrivateConfig);
  1423.  
  1424.                 /* Install the new settings. */
  1425.  
  1426.             memcpy(Config -> SerialConfig,SerialConfig,sizeof(struct SerialSettings));
  1427.         }
  1428.  
  1429.             /* Any device name or unit number change? */
  1430.  
  1431.         if(strcmp(PrivateConfig -> SerialConfig -> SerialDevice,Config -> SerialConfig -> SerialDevice) || PrivateConfig -> SerialConfig -> UnitNumber != Config -> SerialConfig -> UnitNumber)
  1432.             SameDevice = FALSE;
  1433.         else
  1434.         {
  1435.                 /* Serial buffer size changed? */
  1436.  
  1437.             if(PrivateConfig -> SerialConfig -> SerialBufferSize != Config -> SerialConfig -> SerialBufferSize)
  1438.                 SameDevice = FALSE;
  1439.  
  1440.                 /* Handshaking mode changed to RTS/CTS protocol? */
  1441.  
  1442.             if((PrivateConfig -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE && Config -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE) || (PrivateConfig -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE && Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE))
  1443.                 SameDevice = FALSE;
  1444.         }
  1445.  
  1446.             /* Stop any IO activity. */
  1447.  
  1448.         if(ReadRequest)
  1449.             ClearSerial();
  1450.         else
  1451.             SameDevice = FALSE;
  1452.  
  1453.             /* No dramatic changes? Simply change the parameters. */
  1454.  
  1455.         if(SameDevice)
  1456.         {
  1457.             LONG Error;
  1458.  
  1459.                 /* Use new parameters... */
  1460.  
  1461.             SetFlags(WriteRequest);
  1462.             SetFlags(ReadRequest);
  1463.  
  1464.                 /* ...and set them. */
  1465.  
  1466.             WriteRequest -> IOSer . io_Command    = SDCMD_SETPARAMS;
  1467.             ReadRequest -> IOSer . io_Command    = SDCMD_SETPARAMS;
  1468.  
  1469.             if(!(Error = DoIO(WriteRequest)))
  1470.                 Error = DoIO(ReadRequest);
  1471.  
  1472.                 /* Trouble? */
  1473.  
  1474.             if(Error)
  1475.             {
  1476.                 STRPTR    String;
  1477.                 BYTE    Reset;
  1478.  
  1479.                     /* Query the error message. */
  1480.  
  1481.                 if(!(String = GetSerialError(Error,&Reset)))
  1482.                     String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
  1483.  
  1484.                     /* Build the device name/unit number string. */
  1485.  
  1486.                 SPrintf(SharedBuffer,String,Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber);
  1487.  
  1488.                     /* Display the error requester. */
  1489.  
  1490.                 BlockWindow(Window);
  1491.  
  1492.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SharedBuffer);
  1493.  
  1494.                 ReleaseWindow(Window);
  1495.  
  1496.                     /* Is a serial driver reset required? */
  1497.  
  1498.                 if(Reset)
  1499.                 {
  1500.                         /* Execute the reset command. */
  1501.  
  1502.                     WriteRequest -> IOSer . io_Command = CMD_RESET;
  1503.  
  1504.                     DoIO(WriteRequest);
  1505.  
  1506.                         /* Copy the serial driver settings
  1507.                          * to the global configuration.
  1508.                          */
  1509.  
  1510.                     GetFlags(Config,WriteRequest);
  1511.  
  1512.                         /* Also set the read request driver
  1513.                          * flags.
  1514.                          */
  1515.  
  1516.                     SetFlags(ReadRequest);
  1517.  
  1518.                     ReadRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  1519.  
  1520.                     DoIO(ReadRequest);
  1521.                 }
  1522.             }
  1523.  
  1524.                 /* Restart read request. */
  1525.  
  1526.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  1527.             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1528.             ReadRequest -> IOSer . io_Length    = 1;
  1529.  
  1530.             SetSignal(0,SIG_SERIAL);
  1531.  
  1532.             BeginIO(ReadRequest);
  1533.         }
  1534.         else
  1535.         {
  1536.             STRPTR Error;
  1537.  
  1538.                 /* Shut down the serial driver. */
  1539.  
  1540.             DeleteSerial();
  1541.  
  1542.                 /* Reinitialize the serial driver. */
  1543.  
  1544.             if(!(Error = CreateSerial()))
  1545.             {
  1546.                     /* Free the work buffer. */
  1547.  
  1548.                 if(StripBuffer)
  1549.                     FreeVec(StripBuffer);
  1550.  
  1551.                     /* Try to allocate a new serial data work buffer. */
  1552.  
  1553.                 if(!(StripBuffer = (STRPTR)AllocVec(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY)))
  1554.                     Error = LocaleString(MSG_GLOBAL_NO_AUX_BUFFERS_TXT);
  1555.             }
  1556.  
  1557.                 /* Trouble? */
  1558.  
  1559.             if(Error)
  1560.             {
  1561.                     /* Display the error requester. */
  1562.  
  1563.                 BlockWindow(Window);
  1564.  
  1565.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
  1566.  
  1567.                     /* Clean up the mess :-( */
  1568.  
  1569.                 DeleteSerial();
  1570.  
  1571.                 ReleaseWindow(Window);
  1572.  
  1573.                 Success = RECONFIGURE_FAILURE;
  1574.             }
  1575.             else
  1576.             {
  1577.                     /* Are we to display an error message? */
  1578.  
  1579.                 if(SerialMessage)
  1580.                 {
  1581.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  1582.  
  1583.                     SerialMessage = NULL;
  1584.                 }
  1585.             }
  1586.         }
  1587.     }
  1588.  
  1589.     return(Success);
  1590. }
  1591.  
  1592.     /* ReopenSerial():
  1593.      *
  1594.      *    Reopen the serial driver.
  1595.      */
  1596.  
  1597. VOID
  1598. ReopenSerial()
  1599. {
  1600.     BYTE    SerialClosed = TRUE;
  1601.     STRPTR    Error;
  1602.  
  1603.     do
  1604.     {
  1605.         if(Error = CreateSerial())
  1606.         {
  1607.             DeleteSerial();
  1608.  
  1609.             switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_RETRY_IGNORE_QUIT_TXT),Error))
  1610.             {
  1611.                 case 2:    SerialClosed = FALSE;
  1612.                     break;
  1613.  
  1614.                 case 0:    MainTerminated = TRUE;
  1615.                     break;
  1616.             }
  1617.         }
  1618.         else
  1619.         {
  1620.             SerialClosed = FALSE;
  1621.  
  1622.             if(SerialMessage)
  1623.             {
  1624.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  1625.  
  1626.                 SerialMessage = NULL;
  1627.             }
  1628.         }
  1629.     }
  1630.     while(SerialClosed);
  1631. }
  1632.  
  1633.     /* HandleSerial():
  1634.      *
  1635.      *    Handle the data coming in from the serial line.
  1636.      */
  1637.  
  1638. BYTE
  1639. HandleSerial()
  1640. {
  1641.     BYTE MoreData = FALSE;
  1642.  
  1643.     if(ReadPort && !ReleaseSerial && Status != STATUS_HOLDING)
  1644.     {
  1645.         if(HostReadBuffer)
  1646.         {
  1647.             LONG Length = XProtocolHostMon(XprIO,HostReadBuffer,0,Config -> SerialConfig -> SerialBufferSize);
  1648.  
  1649.             if(Length)
  1650.             {
  1651.                 if(Marking)
  1652.                     DropMarker();
  1653.  
  1654.                 ClearCursor();
  1655.  
  1656.                 ConProcess(HostReadBuffer,Length);
  1657.  
  1658.                 if(Status == STATUS_HOLDING)
  1659.                 {
  1660.                     DrawCursor();
  1661.  
  1662.                     return(FALSE);
  1663.                 }
  1664.             }
  1665.  
  1666.             MoreData = TRUE;
  1667.         }
  1668.  
  1669.             /* Any news? */
  1670.  
  1671.         if(CheckIO(ReadRequest))
  1672.         {
  1673.             MoreData = TRUE;
  1674.  
  1675.             if(!WaitIO(ReadRequest))
  1676.             {
  1677.                 if(Marking)
  1678.                     DropMarker();
  1679.  
  1680.                 ClearCursor();
  1681.  
  1682.                 BytesIn++;
  1683.  
  1684.                 (* ConTransfer)(ReadBuffer,1);
  1685.  
  1686.                 if(Status != STATUS_HOLDING)
  1687.                 {
  1688.                     ULONG Length;
  1689.  
  1690.                         /* Check how many bytes are still in
  1691.                          * the serial buffer.
  1692.                          */
  1693.  
  1694.                     WriteRequest -> IOSer . io_Command = SDCMD_QUERY;
  1695.  
  1696.                     DoIO(WriteRequest);
  1697.  
  1698.                     if(Length = WriteRequest -> IOSer . io_Actual)
  1699.                     {
  1700.                         ULONG Max = Config -> SerialConfig -> SerialBufferSize;
  1701.  
  1702.                         if(Length > Max)
  1703.                             Length = Max;
  1704.  
  1705.                         ReadRequest -> IOSer . io_Command    = CMD_READ;
  1706.                         ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1707.                         ReadRequest -> IOSer . io_Length    = Length;
  1708.  
  1709.                         if(!DoIO(ReadRequest))
  1710.                         {
  1711.                             BytesIn += Length;
  1712.  
  1713.                             (* ConTransfer)(ReadBuffer,Length);
  1714.                         }
  1715.                     }
  1716.                 }
  1717.  
  1718.                 DrawCursor();
  1719.             }
  1720.  
  1721.                 /* Ask for another byte. */
  1722.  
  1723.             ReadRequest -> IOSer . io_Command    = CMD_READ;
  1724.             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  1725.             ReadRequest -> IOSer . io_Length     = 1;
  1726.  
  1727.             SetSignal(0,SIG_SERIAL);
  1728.  
  1729.             BeginIO(ReadRequest);
  1730.         }
  1731.     }
  1732.  
  1733.     return(MoreData);
  1734. }
  1735.