home *** CD-ROM | disk | FTP | other *** search
- /*
- ** termSerial.c
- **
- ** Serial driver support routines
- **
- ** Copyright © 1990-1995 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- **
- ** :ts=4
- */
-
- #include "termGlobal.h"
-
- /* Local copy of serial driver name and unit number. */
-
- STATIC UBYTE __far SerialDevice[40];
- STATIC LONG UnitNumber = -1;
-
- STATIC BOOLEAN SerialLocked;
-
- /* SetFlags():
- *
- * Set the contents of a serial device request according
- * to the current configuration settings.
- */
-
- STATIC BYTE __regargs
- SetFlags(VOID)
- {
- return(SetBothSerialAttributes(
- SERA_Baud, Config -> SerialConfig -> BaudRate,
- SERA_BreakTime, Config -> SerialConfig -> BreakLength,
- SERA_BitsPerChar, Config -> SerialConfig -> BitsPerChar,
- SERA_StopBits, Config -> SerialConfig -> StopBits,
- SERA_BufferSize, Config -> SerialConfig -> SerialBufferSize,
- SERA_Parity, Config -> SerialConfig -> Parity,
- SERA_Handshaking, UseRTS_CTS ? Config -> SerialConfig -> HandshakingProtocol : HANDSHAKING_NONE,
- SERA_HighSpeed, Config -> SerialConfig -> HighSpeed,
- SERA_Shared, Config -> SerialConfig -> Shared,
- TAG_DONE));
- }
-
- /* SendBreak():
- *
- * Transmit a break signal.
- */
-
- VOID
- SendBreak()
- {
- BYTE OldStatus = Status;
-
- Status = STATUS_BREAKING;
-
- DoSerialCmd(SDCMD_BREAK);
-
- Status = OldStatus;
- }
-
- /* HangUp():
- *
- * Hang up the line.
- */
-
- VOID
- HangUp()
- {
- BYTE OldStatus = Status;
-
- StopSerialWrite();
-
- Status = STATUS_HANGUP;
-
- /* Are we to drop the DTR line
- * before sending the hangup
- * string?
- */
-
- if(Config -> ModemConfig -> DropDTR && WriteRequest)
- {
- /* Let's be nice and try to transmit the
- * `drop the line' command before
- * trying to close and reopen the driver.
- */
-
- WriteRequest -> IOSer . io_Command = SIOCMD_SETCTRLLINES;
- WriteRequest -> IOSer . io_Offset = SIOB_DTRF;
- WriteRequest -> IOSer . io_Length = 0;
-
- /* Transmit the command. */
-
- if(!DoIO(WriteRequest))
- {
- /* Wait a bit... */
-
- WaitTime(1,0);
-
- /* Raise the line again. */
-
- WriteRequest -> IOSer . io_Command = SIOCMD_SETCTRLLINES;
- WriteRequest -> IOSer . io_Offset = SIOB_DTRF;
- WriteRequest -> IOSer . io_Length = SIOB_DTRF;
-
- DoIO(WriteRequest);
- }
- else
- {
- /* Do it the standard way: close and reopen
- * the serial driver (the serial.device is
- * supposed to drop the DTR line when closed).
- */
-
- if(!DropDTR())
- {
- if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_REOPEN_UNIT_TXT),LocaleString(MSG_TERMMAIN_IGNORE_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
- MainTerminated = TRUE;
- }
- }
- }
-
- /* Transmit the hangup command. */
-
- if(Config -> ModemConfig -> ModemHangup[0])
- SerialCommand(Config -> ModemConfig -> ModemHangup);
-
- /* Reset to old status. */
-
- Status = OldStatus;
- }
-
- /* DropDTR():
- *
- * Drop the data terminal ready signal (i.e. close, wait a bit
- * and then reopen the serial drive).
- */
-
- BYTE
- DropDTR()
- {
- /* Finish all serial read activity. */
-
- ClearSerial();
-
- /* Do we have any channels to work with? */
-
- if(ReadRequest && WriteRequest)
- {
- /* Close the device. */
-
- CloseDevice(ReadRequest);
-
- /* Wait a bit. */
-
- WaitTime(1,0);
-
- /* Reopen the driver. */
-
- if(!OpenDevice(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,ReadRequest,0))
- {
- struct MsgPort *WritePort = WriteRequest -> IOSer . io_Message . mn_ReplyPort;
-
- ResetSerialRead();
- ResetSerialWrite();
-
- /* Fill in the rest. */
-
- CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
-
- WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
-
- SetFlags();
-
- DoSerialCmd(SDCMD_SETPARAMS);
-
- /* Restart read activity. */
-
- RestartSerial();
-
- return(TRUE);
- }
- else
- DeleteSerial();
- }
- else
- {
- DeleteSerial();
-
- return(TRUE);
- }
-
- return(FALSE);
- }
-
- /* CopyWriteFlags():
- *
- * Update configuration with serial settings.
- */
-
- VOID
- CopyWriteFlags()
- {
- ULONG Baud,
- BreakTime,
- BitsPerChar,
- StopBits,
- BufferSize,
- Parity,
- Handshaking,
- HighSpeed,
- Shared;
-
- GetSerialWriteAttributes(
- SERA_Baud, &Baud,
- SERA_BreakTime, &BreakTime,
- SERA_BitsPerChar, &BitsPerChar,
- SERA_StopBits, &StopBits,
- SERA_BufferSize, &BufferSize,
- SERA_Parity, &Parity,
- SERA_Handshaking, &Handshaking,
- SERA_HighSpeed, &HighSpeed,
- SERA_Shared, &Shared,
- TAG_DONE);
-
- Config -> SerialConfig -> BaudRate = Baud;
- Config -> SerialConfig -> BreakLength = BreakTime;
- Config -> SerialConfig -> BitsPerChar = BitsPerChar;
- Config -> SerialConfig -> StopBits = StopBits;
- Config -> SerialConfig -> SerialBufferSize = BufferSize;
- Config -> SerialConfig -> Parity = Parity;
- Config -> SerialConfig -> HandshakingProtocol = Handshaking;
- Config -> SerialConfig -> HighSpeed = HighSpeed;
- Config -> SerialConfig -> Shared = Shared;
- }
-
- /* CallMenu(STRPTR Name,ULONG Code):
- *
- * Call a menu function either through the name of the corresponding
- * menu item or a menu number.
- */
-
- STATIC VOID __inline
- CallMenu(STRPTR Name,ULONG Code)
- {
- WORD MenuNum = -1,Item = 0,Sub = 0,i;
-
- /* Are we to look for a name? */
-
- if(Name)
- {
- WORD Len = strlen(Name);
-
- /* Scan the menu list... */
-
- for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
- {
- switch(TermMenu[i] . nm_Type)
- {
- case NM_TITLE:
-
- MenuNum++;
- Item = Sub = 0;
- break;
-
- case NM_ITEM:
-
- Sub = 0;
- break;
- }
-
- /* Did we get a valid name string? */
-
- if(TermMenu[i] . nm_Label != NM_BARLABEL)
- {
- /* Does the name match our template? */
-
- if(!Strnicmp(TermMenu[i] . nm_Label,Name,Len))
- {
- struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
-
- if(MenuItem && (MenuItem -> Flags & ITEMENABLED))
- HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
-
- break;
- }
- }
-
- switch(TermMenu[i] . nm_Type)
- {
- case NM_ITEM:
-
- Item++;
- break;
-
- case NM_SUB:
-
- Sub++;
- break;
- }
- }
- }
- else
- {
- WORD TheMenu = Code % 100,
- TheItem = (Code / 100) % 100,
- TheSub = Code / 10000;
-
- /* Scan the menu list... */
-
- for(i = 0 ; TermMenu[i] . nm_Type != NM_END ; i++)
- {
- switch(TermMenu[i] . nm_Type)
- {
- case NM_TITLE:
-
- MenuNum++;
- Item = Sub = 0;
- break;
-
- case NM_ITEM:
-
- Sub = 0;
- break;
- }
-
- /* Is it the menu number we want? */
-
- if(TheMenu == MenuNum && TheItem == Item && TheSub == Sub)
- {
- if(TermMenu[i] . nm_Label != NM_BARLABEL)
- {
- struct MenuItem *MenuItem = ItemAddress(Menu,FULLMENUNUM(MenuNum,Item,Sub));
-
- if(MenuItem && (MenuItem -> Flags & ITEMENABLED))
- HandleMenuCode((ULONG)TermMenu[i] . nm_UserData,NULL);
- }
-
- break;
- }
-
- switch(TermMenu[i] . nm_Type)
- {
- case NM_ITEM:
-
- Item++;
- break;
-
- case NM_SUB:
-
- Sub++;
- break;
- }
- }
- }
- }
-
- /* SerialCommand(STRPTR String):
- *
- * Send a command string to the serial line and
- * interprete the control sequences.
- */
-
- VOID __regargs
- SerialCommand(STRPTR String)
- {
- BYTE (* SendLineLocal)(register STRPTR,register LONG);
-
- LONG Count = 0,i,Len = strlen(String);
-
- BYTE GotControl = FALSE,
- GotEscape = FALSE;
-
- SendLineLocal = SendLine;
-
- /* Scan the string. */
-
- for(i = 0 ; i < Len ; i++)
- {
- /* We are looking for plain characters
- * and the control ('\') and escape
- * ('^') characters.
- */
-
- if(!GotControl && !GotEscape)
- {
- /* Got a control character,
- * the next byte will probably be
- * a command sequence.
- */
-
- if(String[i] == '\\')
- {
- GotControl = TRUE;
- continue;
- }
-
- /* Got an escape character,
- * the next byte will be some
- * kind of control character
- * (such as XON, XOF, bell, etc.).
- */
-
- if(String[i] == '^')
- {
- GotEscape = TRUE;
- continue;
- }
-
- /* This tells us to wait another
- * second before continuing with
- * the scanning.
- */
-
- if(String[i] == '~')
- {
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- WaitTime(0,MILLION / 2);
-
- HandleSerial();
-
- continue;
- }
-
- /* Stuff the character into the
- * buffer.
- */
-
- SharedBuffer[Count++] = String[i];
- }
- else
- {
- /* Convert the character to a control
- * style character (^C, etc.).
- */
-
- if(GotEscape)
- {
- if(ToUpper(String[i]) >= 'A' && ToUpper(String[i]) <= '_')
- SharedBuffer[Count++] = ToUpper(String[i]) - '@';
- else
- SharedBuffer[Count++] = String[i];
-
- GotEscape = FALSE;
- }
-
- /* The next character represents a command. */
-
- if(GotControl)
- {
- switch(ToUpper(String[i]))
- {
- /* Fall back to default send mode. */
-
- case '0':
-
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- SendLineLocal = SendLine;
- break;
-
- /* Select `direct' send mode. */
-
- case '1':
-
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- SendLineLocal = SendLineSimple;
- break;
-
- /* Select `echo' send mode. */
-
- case '2':
-
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- if(Config -> ClipConfig -> SendTimeout)
- SendLineLocal = SendLineEcho;
- else
- SendLineLocal = SendLineSimple;
-
- break;
-
- /* Select `any echo' send mode. */
-
- case '3':
-
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- if(Config -> ClipConfig -> SendTimeout)
- SendLineLocal = SendLineAnyEcho;
- else
- SendLineLocal = SendLineSimple;
-
- break;
-
- /* Select `prompt' send mode. */
-
- case '4':
-
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- if(Config -> ClipConfig -> SendTimeout)
- SendLineLocal = SendLinePrompt;
- else
- SendLineLocal = SendLineSimple;
-
- break;
-
- /* Select `delay' send mode. */
-
- case '5':
-
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- if(Config -> ClipConfig -> LineDelay || Config -> ClipConfig -> CharDelay)
- SendLineLocal = SendLineDelay;
- else
- SendLineLocal = SendLineSimple;
-
- break;
-
- /* Select `keyboard' send mode. */
-
- case '6':
-
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- SendLineLocal = SendLineKeyDelay;
- break;
-
- /* Translate code. */
-
- case '*':
-
- i++;
-
- while(i < Len && String[i] == ' ')
- i++;
-
- if(i < Len)
- {
- UBYTE DummyBuffer[5],j = 0,Char;
-
- if(String[i] >= '0' && String[i] <= '9')
- {
- while(j < 3 && i < Len)
- {
- Char = String[i++];
-
- if(Char >= '0' && Char <= '9')
- DummyBuffer[j++] = Char;
- else
- {
- i--;
-
- break;
- }
- }
- }
- else
- {
- while(j < 4 && i < Len)
- {
- Char = ToLower(String[i++]);
-
- if((Char >= '0' && Char <= '9') || (Char >= 'a' && Char <= 'z'))
- DummyBuffer[j++] = Char;
- else
- {
- i--;
-
- break;
- }
- }
- }
-
- DummyBuffer[j] = 0;
-
- SharedBuffer[Count++] = NameToCode(DummyBuffer);
- }
-
- i--;
-
- break;
-
- /* Execute an AmigaDOS command. */
-
- case 'D':
-
- if(!InRexx)
- {
- if(!WeAreBlocking)
- {
- BlockWindows();
-
- SendAmigaDOSCommand(&String[i + 1]);
-
- ReleaseWindows();
- }
- else
- SendAmigaDOSCommand(&String[i + 1]);
- }
-
- return;
-
- /* Execute an ARexx command. */
-
- case 'A':
-
- if(!InRexx)
- {
- if(!WeAreBlocking)
- {
- BlockWindows();
-
- SendARexxCommand(&String[i + 1],TRUE);
-
- ReleaseWindows();
- }
- else
- SendARexxCommand(&String[i + 1],TRUE);
- }
-
- return;
-
- /* Add the control character ('\'). */
-
- case '\\':
-
- SharedBuffer[Count++] = '\\';
- break;
-
- /* This is a backspace. */
-
- case 'B':
-
- SharedBuffer[Count++] = '\b';
- break;
-
- /* This is a form feed. */
-
- case 'F':
-
- SharedBuffer[Count++] = '\f';
- break;
-
- /* This is a line feed. */
-
- case 'N':
-
- SharedBuffer[Count++] = '\n';
- break;
-
- /* Send the current password. */
-
- case 'P':
-
- if(Password[0])
- {
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- (*SendLineLocal)(Password,strlen(Password));
- }
-
- break;
-
- /* This is a carriage return. */
-
- case 'R':
-
- SharedBuffer[Count++] = '\r';
- break;
-
- /* This is a tab. */
-
- case 'T':
-
- SharedBuffer[Count++] = '\t';
- break;
-
- /* Send the current user name. */
-
- case 'U':
-
- if(UserName[0])
- {
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- (*SendLineLocal)(UserName,strlen(UserName));
- }
-
- break;
-
- /* Send a break across the serial line. */
-
- case 'X':
-
- if(Count)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
-
- SendBreak();
-
- break;
-
- /* Feed the contents of the
- * clipboard into the input
- * stream.
- */
-
- case 'I':
-
- if(Count)
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = LoadClip(SharedBuffer,256);
-
- break;
-
- /* Send a string to the clipboard. */
-
- case 'G':
-
- if(String[i + 1])
- SaveClip(&String[i + 1],strlen(&String[i + 1]));
-
- return;
-
- /* Send a string to the clipboard. */
-
- case 'H':
-
- if(String[i + 1])
- AddClip(&String[i + 1],strlen(&String[i + 1]));
-
- return;
-
- /* Produce the escape character. */
-
- case 'E':
-
- SharedBuffer[Count++] = ESC;
- break;
-
- /* Call a menu item. */
-
- case 'C':
-
- i++;
-
- /* Scan for a menu number or
- * a single quote...
- */
-
- while(i < Len)
- {
- if(String[i] >= '0' && String[i] <= '9')
- break;
-
- if(String[i] == '\'')
- break;
-
- if(String[i] != ' ')
- break;
-
- i++;
- }
-
- if(i < Len)
- {
- UBYTE DummyBuffer[256];
-
- /* Did we get a quote? */
-
- if(String[i] == '\'')
- {
- LONG Start = ++i;
-
- if(String[Start])
- {
- WORD Length;
-
- while(i < Len)
- {
- if(String[i] != '\'')
- i++;
- else
- break;
- }
-
- if(String[i] == '\'')
- Length = i - Start;
- else
- Length = i - Start + 1;
-
- memcpy(DummyBuffer,&String[Start],Length);
-
- DummyBuffer[Length] = 0;
-
- CallMenu(DummyBuffer,0);
- }
- }
- else
- {
- if(String[i] >= '0' && String[i] <= '9')
- {
- LONG Start = i,Length;
-
- while(i < Len)
- {
- if(String[i] >= '0' && String[i] <= '9')
- i++;
- else
- break;
- }
-
- if(i == Start)
- Length = 1;
- else
- Length = i - Start;
-
- memcpy(DummyBuffer,&String[Start],Length);
-
- DummyBuffer[Length] = 0;
-
- CallMenu(NULL,Atol(DummyBuffer));
- }
- }
- }
-
- break;
-
- /* Insert the current dialing mode suffix. */
-
- case 'W':
-
- if(Config -> ModemConfig -> DialMode == DIALMODE_PULSE)
- SharedBuffer[Count++] = 'P';
- else
- SharedBuffer[Count++] = 'T';
-
- break;
-
- /* Stuff the character into the buffer. */
-
- default:
-
- SharedBuffer[Count++] = String[i];
- break;
- }
-
- GotControl = FALSE;
- }
- }
-
- /* If the buffer is full, release it. */
-
- if(Count == 256)
- {
- (*SendLineLocal)(SharedBuffer,Count);
-
- Count = 0;
- }
- }
-
- if(Count)
- (*SendLineLocal)(SharedBuffer,Count);
- }
-
- /* SerWriteVerbatim(APTR Buffer,LONG Size,BOOLEAN Echo):
- *
- * The `no fancy features' version of SerWrite().
- */
-
- VOID __regargs
- SerWriteVerbatim(APTR Buffer,LONG Size,BOOLEAN Echo)
- {
- if(XProtocolBase && (TransferBits & XPRS_USERMON))
- Size = XProtocolUserMon(XprIO,Buffer,Size,Size);
-
- if(Size > 0)
- {
- if(Echo)
- {
- if(Marking)
- DropMarker();
-
- StartSerialWrite(Buffer,Size);
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
- }
- else
- DoSerialWrite(Buffer,Size);
-
- BytesOut += Size;
- }
- }
-
- /* SerWrite(APTR Buffer,LONG Size):
- *
- * Send a number of bytes across the serial line.
- */
-
- VOID __regargs
- SerWrite(APTR Buffer,LONG Size)
- {
- if(Size < 0)
- Size = strlen(Buffer);
-
- if(Size)
- {
- if(RememberInput)
- {
- RememberInputText(Buffer,Size);
-
- if(((UBYTE *)Buffer)[Size - 1] == '\r' && RecordingLine)
- {
- RememberSpill();
-
- RecordingLine = FALSE;
-
- RememberOutput = TRUE;
- RememberInput = FALSE;
-
- CheckItem(MEN_RECORD_LINE,FALSE);
- }
- }
- else
- {
- if(RememberOutput)
- {
- RememberInputText(Buffer,Size);
-
- RememberSpill();
- }
- }
-
- if(WriteRequest)
- {
- STATIC UBYTE __far TranslateData[512];
-
- /* xpr wants to see the data before it is
- * transferred.
- */
-
- if(XProtocolBase && (TransferBits & XPRS_USERMON))
- {
- if(Size = XProtocolUserMon(XprIO,Buffer,Size,Size))
- {
- if(SendTable)
- {
- struct TranslationHandle Handle;
-
- /* Set up for buffer translation. */
-
- TranslateSetup(&Handle,Buffer,Size,TranslateData,512,SendTable);
-
- /* Full or half duplex? */
-
- if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
- {
- if(SerWriteBypass)
- {
- /* Process the data... */
-
- while(Size = TranslateBuffer(&Handle))
- {
- if((*SerWriteBypass)(TranslateData,Size))
- {
- /* ...and send it. */
-
- DoSerialWrite(TranslateData,Size);
- }
-
- BytesOut += Size;
- }
- }
- else
- {
- /* Process the data... */
-
- while(Size = TranslateBuffer(&Handle))
- {
- /* ...and send it. */
-
- DoSerialWrite(TranslateData,Size);
-
- BytesOut += Size;
- }
- }
- }
- else
- {
- if(Marking)
- DropMarker();
-
- if(SerWriteBypass)
- {
- while(Size = TranslateBuffer(&Handle))
- {
- if((*SerWriteBypass)(TranslateData,Size))
- {
- /* Process the data while it is transferred. */
-
- StartSerialWrite(TranslateData,Size);
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
- }
-
- BytesOut += Size;
- }
- }
- else
- {
- while(Size = TranslateBuffer(&Handle))
- {
- /* Process the data while it is transferred. */
-
- StartSerialWrite(TranslateData,Size);
-
- ConProcess(TranslateData,Size);
-
- WaitSerialWrite();
-
- BytesOut += Size;
- }
- }
- }
- }
- else
- {
- if(SerWriteBypass)
- {
- if((*SerWriteBypass)(Buffer,Size))
- {
- /* If full duplex is enabled, send the entire
- * buffer without processing.
- */
-
- if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
- DoSerialWrite(Buffer,Size);
- else
- {
- /* Process the data while it is transferred. */
-
- StartSerialWrite(Buffer,Size);
-
- if(Marking)
- DropMarker();
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
- }
- }
- else
- {
- if(Config -> SerialConfig -> Duplex != DUPLEX_FULL)
- {
- if(Marking)
- DropMarker();
-
- ConProcess(Buffer,Size);
- }
- }
- }
- else
- {
- /* If full duplex is enabled, send the entire
- * buffer without processing.
- */
-
- if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
- DoSerialWrite(Buffer,Size);
- else
- {
- /* Process the data while it is transferred. */
-
- StartSerialWrite(Buffer,Size);
-
- if(Marking)
- DropMarker();
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
- }
- }
-
- BytesOut += Size;
- }
- }
- }
- else
- {
- if(SendTable)
- {
- struct TranslationHandle Handle;
-
- /* Set up for buffer translation. */
-
- TranslateSetup(&Handle,Buffer,Size,TranslateData,512,SendTable);
-
- /* Full or half duplex? */
-
- if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
- {
- if(SerWriteBypass)
- {
- /* Process the data... */
-
- while(Size = TranslateBuffer(&Handle))
- {
- if((*SerWriteBypass)(TranslateData,Size))
- {
- /* ...and send it. */
-
- DoSerialWrite(TranslateData,Size);
- }
-
- BytesOut += Size;
- }
- }
- else
- {
- /* Process the data... */
-
- while(Size = TranslateBuffer(&Handle))
- {
- /* ...and send it. */
-
- DoSerialWrite(TranslateData,Size);
-
- BytesOut += Size;
- }
- }
- }
- else
- {
- if(Marking)
- DropMarker();
-
- if(SerWriteBypass)
- {
- while(Size = TranslateBuffer(&Handle))
- {
- if((*SerWriteBypass)(TranslateData,Size))
- {
- /* Process the data while it is transferred. */
-
- StartSerialWrite(TranslateData,Size);
-
- ConProcess(TranslateData,Size);
-
- WaitSerialWrite();
- }
-
- BytesOut += Size;
- }
- }
- else
- {
- while(Size = TranslateBuffer(&Handle))
- {
- /* Process the data while it is transferred. */
-
- StartSerialWrite(TranslateData,Size);
-
- ConProcess(TranslateData,Size);
-
- WaitSerialWrite();
-
- BytesOut += Size;
- }
- }
- }
- }
- else
- {
- if(SerWriteBypass)
- {
- if((*SerWriteBypass)(Buffer,Size))
- {
- /* If full duplex is enabled, send the entire
- * buffer without processing.
- */
-
- if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
- DoSerialWrite(Buffer,Size);
- else
- {
- /* Process the data while it is transferred. */
-
- StartSerialWrite(Buffer,Size);
-
- if(Marking)
- DropMarker();
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
- }
- }
- }
- else
- {
- /* If full duplex is enabled, send the entire
- * buffer without processing.
- */
-
- if(Config -> SerialConfig -> Duplex == DUPLEX_FULL)
- DoSerialWrite(Buffer,Size);
- else
- {
- /* Process the data while it is transferred. */
-
- StartSerialWrite(Buffer,Size);
-
- if(Marking)
- DropMarker();
-
- ConProcess(Buffer,Size);
-
- WaitSerialWrite();
- }
- }
-
- BytesOut += Size;
- }
- }
- }
- }
- }
-
- /* RestartSerial():
- *
- * Restart read/write activity on the serial line.
- */
-
- VOID
- RestartSerial()
- {
- StartSerialRead(ReadBuffer,1);
- }
-
- /* ClearSerial():
- *
- * Terminate all read/write activity on the serial line.
- */
-
- VOID
- ClearSerial()
- {
- StopSerialRead();
-
- DoSerialCmd(CMD_CLEAR);
- }
-
- /* DeleteSerial():
- *
- * Close the serial device and release all associated
- * resources.
- */
-
- VOID
- DeleteSerial()
- {
- BYTE Closed = FALSE;
-
- if(ReadRequest)
- {
- if(ReadRequest -> IOSer . io_Device)
- {
- struct Device *Device;
- UBYTE Name[MAX_FILENAME_LENGTH];
-
- StopSerialRead();
-
- if(!Config -> SerialConfig -> Shared)
- {
- ReadRequest -> IOSer . io_Command = CMD_RESET;
-
- DoIO(ReadRequest);
- }
-
- strcpy(Name,ReadRequest -> IOSer . io_Device -> dd_Library . lib_Node . ln_Name);
-
- CloseDevice(ReadRequest);
-
- Forbid();
-
- if(Device = (struct Device *)FindName(&SysBase -> DeviceList,Name))
- RemDevice(Device);
-
- Permit();
-
- Closed = TRUE;
- }
-
- DeleteIORequest(ReadRequest);
-
- ReadRequest = NULL;
- }
-
- if(WriteRequest)
- {
- if(WriteRequest -> IOSer . io_Device && !Closed)
- {
- struct Device *Device;
- UBYTE Name[MAX_FILENAME_LENGTH];
-
- StopSerialWrite();
-
- strcpy(Name,WriteRequest -> IOSer . io_Device -> dd_Library . lib_Node . ln_Name);
-
- CloseDevice(WriteRequest);
-
- Forbid();
-
- if(Device = (struct Device *)FindName(&SysBase -> DeviceList,Name))
- RemDevice(Device);
-
- Permit();
- }
-
- if(WriteRequest -> IOSer . io_Message . mn_ReplyPort)
- DeleteMsgPort(WriteRequest -> IOSer . io_Message . mn_ReplyPort);
-
- DeleteIORequest(WriteRequest);
-
- WriteRequest = NULL;
- }
-
- if(ReadPort)
- {
- DeleteMsgPort(ReadPort);
-
- ReadPort = NULL;
- }
-
- if(ReadBuffer)
- {
- FreeVecPooled(ReadBuffer);
-
- ReadBuffer = NULL;
- }
-
- if(HostReadBuffer)
- {
- FreeVecPooled(HostReadBuffer);
-
- HostReadBuffer = NULL;
- }
-
- if(StripBuffer)
- {
- FreeVecPooled(StripBuffer);
-
- StripBuffer = NULL;
- }
-
- if(OwnDevUnitBase && SerialDevice[0] && UnitNumber != -1 && SerialLocked)
- {
- FreeDevUnit(SerialDevice,UnitNumber);
-
- SerialDevice[0] = 0;
-
- UnitNumber = -1;
- }
-
- if(OwnDevBit != -1)
- {
- FreeSignal(OwnDevBit);
-
- OwnDevBit = -1;
- }
-
- SerialLocked = FALSE;
-
- ResetSerialRead();
- ResetSerialWrite();
- }
-
- /* GetSerialError(LONG Error,BYTE *Reset):
- *
- * Return an error message for each possible serial device error.
- */
-
- STRPTR __regargs
- GetSerialError(LONG Error,BYTE *Reset)
- {
- if(Reset)
- *Reset = FALSE;
-
- switch(Error)
- {
- case IOERR_BADLENGTH:
- case IOERR_BADADDRESS:
- case IOERR_SELFTEST:
- case IOERR_OPENFAIL:
-
- return(LocaleString(MSG_SERIAL_OPENFAILURE_TXT));
-
- case SerErr_DevBusy:
-
- return(LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT));
-
- case SerErr_BaudMismatch:
-
- if(Reset)
- *Reset = TRUE;
-
- return(LocaleString(MSG_SERIAL_ERROR_BAUDMISMATCH_TXT));
-
- case SerErr_BufErr:
-
- if(Reset)
- *Reset = TRUE;
-
- return(LocaleString(MSG_SERIAL_ERROR_BUFERR_TXT));
-
- case SerErr_InvParam:
-
- if(Reset)
- *Reset = TRUE;
-
- return(LocaleString(MSG_SERIAL_ERROR_INVPARAM_TXT));
-
- case SerErr_LineErr:
-
- return(LocaleString(MSG_SERIAL_ERROR_LINEERR_TXT));
-
- case SerErr_ParityErr:
-
- if(Reset)
- *Reset = TRUE;
-
- return(LocaleString(MSG_SERIAL_ERROR_PARITYERR_TXT));
-
- case SerErr_TimerErr:
-
- return(LocaleString(MSG_SERIAL_ERROR_TIMERERR_TXT));
-
- case SerErr_BufOverflow:
-
- if(Reset)
- *Reset = TRUE;
-
- return(LocaleString(MSG_SERIAL_ERROR_BUFOVERFLOW_TXT));
-
- case SerErr_NoDSR:
-
- return(LocaleString(MSG_SERIAL_ERROR_NODSR_TXT));
-
- /* case SerErr_UnitBusy: */
- case IOERR_UNITBUSY:
- case 16:
-
- return(LocaleString(MSG_SERIAL_ERROR_UNIT_BUSY_TXT));
-
- default:
-
- return(NULL);
- }
- }
-
- /* CreateSerial():
- *
- * Create handles for the serial device and open it.
- */
-
- STRPTR
- CreateSerial()
- {
- struct MsgPort *WritePort;
-
- /* If OwnDevUnit.library is available, try to lock
- * the serial driver.
- */
-
- if(OwnDevUnitBase && Config -> SerialConfig -> UseOwnDevUnit && !(Config -> SerialConfig -> Shared && Config -> SerialConfig -> NoODUIfShared))
- {
- STRPTR Error;
-
- /* Allocate a signal for OwnDevUnit, in case we might need it. */
-
- if(OwnDevBit == -1)
- {
- OwnDevBit = AllocSignal(-1);
-
- /* Attempt to lock the device unit... */
-
- Error = AttemptDevUnit(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,TermIDString,OwnDevBit == -1 ? NULL : OwnDevBit);
- }
- else
- Error = NULL;
-
- if(Error)
- {
- /* Check for error type if any. */
-
- if(!Strnicmp(Error,ODUERR_LEADCHAR,1))
- SPrintf(SharedBuffer,LocaleString(MSG_SERIAL_ERROR_ACCESSING_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,&Error[1]);
- else
- SPrintf(SharedBuffer,LocaleString(MSG_SERIAL_DEVICE_IN_USE_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,Error);
-
- SerialDevice[0] = 0;
-
- UnitNumber = -1;
-
- SerialLocked = FALSE;
-
- return(SharedBuffer);
- }
- else
- {
- strcpy(SerialDevice,Config -> SerialConfig -> SerialDevice);
-
- UnitNumber = Config -> SerialConfig -> UnitNumber;
-
- SerialLocked = TRUE;
- }
- }
- else
- SerialLocked = FALSE;
-
- Update_CR_LF_Translation();
-
- if(ReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
- {
- if(StripBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
- {
- if(XProtocolBase && (TransferBits & XPRS_HOSTNOWAIT))
- HostReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY);
- else
- HostReadBuffer = NULL;
-
- if(ReadPort = (struct MsgPort *)CreateMsgPort())
- {
- if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
- {
- if(WritePort = (struct MsgPort *)CreateMsgPort())
- {
- if(WriteRequest = (struct IOExtSer *)CreateIORequest(WritePort,sizeof(struct IOExtSer)))
- {
- BYTE HandshakingProtocol = Config -> SerialConfig -> HandshakingProtocol;
- LONG Error;
-
- /* In order to avoid trouble, the device driver is to be opened in
- * plain mode, i.e. no RTS/CTS handshaking will be enabled.
- */
-
- if(Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_RTSCTS_DSR)
- HandshakingProtocol = HANDSHAKING_RTSCTS;
-
- UseRTS_CTS = TRUE;
-
- Reset: SetSerialReadAttributes(
- SERA_Baud, Config -> SerialConfig -> BaudRate,
- SERA_BreakTime, Config -> SerialConfig -> BreakLength,
- SERA_BitsPerChar, Config -> SerialConfig -> BitsPerChar,
- SERA_StopBits, Config -> SerialConfig -> StopBits,
- SERA_BufferSize, Config -> SerialConfig -> SerialBufferSize,
- SERA_Parity, Config -> SerialConfig -> Parity,
- SERA_Handshaking, HandshakingProtocol,
- SERA_HighSpeed, Config -> SerialConfig -> HighSpeed,
- SERA_Shared, Config -> SerialConfig -> Shared,
- TAG_DONE);
-
- if(!(Error = OpenDevice(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,ReadRequest,0)))
- {
- SetSerialReadAttributes(SERA_Handshaking,HandshakingProtocol,TAG_DONE);
-
- CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
-
- WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
-
- if(Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_RTSCTS_DSR && HandshakingProtocol == HANDSHAKING_RTSCTS)
- {
- /* Now check if the DSR signal is enabled. */
-
- if(GetSerialStatus() & CIAF_COMDSR)
- {
- /* If this is the first time the driver gets initialized,
- * skip the notification message and just drop the RTS/CTS
- * handshaking bit.
- */
-
- if(FirstInvocation)
- UseRTS_CTS = FALSE;
- else
- {
- do
- {
- if(!MyEasyRequest(Window,LocaleString(MSG_SERIAL_NO_DSR_SIGNAL_TXT),LocaleString(MSG_SERIAL_RETRY_CANCEL_TXT)))
- {
- UseRTS_CTS = FALSE;
- break;
- }
- }
- while(GetSerialStatus() & CIAF_COMDSR);
- }
- }
-
- if(!UseRTS_CTS)
- {
- CloseDevice(ReadRequest);
-
- ReadRequest -> IOSer . io_Device = NULL;
-
- HandshakingProtocol = HANDSHAKING_NONE;
-
- goto Reset;
- }
- }
-
- ResetSerialRead();
- ResetSerialWrite();
-
- SetFlags();
-
- RestartSerial();
-
- return(NULL);
- }
- else
- {
- STRPTR String;
-
- ReadRequest -> IOSer . io_Device = NULL;
-
- DeleteSerial();
-
- SerialMessage = NULL;
-
- if(!(String = GetSerialError(Error,NULL)))
- String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
-
- SPrintf(SharedBuffer,String,Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber);
-
- return(SharedBuffer);
- }
- }
- }
- else
- {
- SerialMessage = NULL;
-
- DeleteSerial();
-
- return(LocaleString(MSG_SERIAL_FAILED_TO_CREATE_WRITE_PORT_TXT));
- }
- }
- }
- else
- {
- SerialMessage = NULL;
-
- DeleteSerial();
-
- return(LocaleString(MSG_SERIAL_FAILED_TO_CREATE_READ_PORT_TXT));
- }
- }
- }
-
- SerialMessage = NULL;
-
- DeleteSerial();
-
- return(LocaleString(MSG_SERIAL_NOT_ENOUGH_MEMORY_TXT));
- }
-
- /* ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig):
- *
- * Reconfigure the serial driver according to the new
- * serial settings.
- */
-
- BYTE __regargs
- ReconfigureSerial(struct Window *Window,struct SerialSettings *SerialConfig)
- {
- BYTE Success = RECONFIGURE_NOCHANGE,
- IsNew;
-
- /* Are new settings to be installed or have they already
- * been copied to the correct locations?
- */
-
- if(SerialConfig)
- {
- if(memcmp(Config -> SerialConfig,SerialConfig,sizeof(struct SerialSettings)))
- IsNew = TRUE;
- else
- IsNew = FALSE;
- }
- else
- {
- if(memcmp(Config -> SerialConfig,PrivateConfig -> SerialConfig,sizeof(struct SerialSettings)))
- IsNew = TRUE;
- else
- IsNew = FALSE;
- }
-
- /* Any changes in the serial configuration area? */
-
- if(IsNew)
- {
- BYTE SameDevice = TRUE;
-
- /* Any new data to swap in? */
-
- if(SerialConfig)
- {
- /* Store the previous settings. */
-
- SaveConfig(Config,PrivateConfig);
-
- /* Install the new settings. */
-
- memcpy(Config -> SerialConfig,SerialConfig,sizeof(struct SerialSettings));
- }
-
- /* Any device name or unit number change? */
-
- if(strcmp(PrivateConfig -> SerialConfig -> SerialDevice,Config -> SerialConfig -> SerialDevice) || PrivateConfig -> SerialConfig -> UnitNumber != Config -> SerialConfig -> UnitNumber || PrivateConfig -> SerialConfig -> UseOwnDevUnit != Config -> SerialConfig -> UseOwnDevUnit)
- SameDevice = FALSE;
- else
- {
- /* Handshaking mode changed to RTS/CTS protocol? */
-
- if((PrivateConfig -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE && Config -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE) || (PrivateConfig -> SerialConfig -> HandshakingProtocol != HANDSHAKING_NONE && Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE))
- SameDevice = FALSE;
- else
- {
- // Did the ODU options change?
-
- if(PrivateConfig -> SerialConfig -> NoODUIfShared != Config -> SerialConfig -> NoODUIfShared && Config -> SerialConfig -> Shared)
- SameDevice = FALSE;
- }
- }
-
- /* Stop any IO activity. */
-
- if(ReadRequest)
- ClearSerial();
- else
- SameDevice = FALSE;
-
- /* No dramatic changes? Simply change the parameters. */
-
- if(SameDevice)
- {
- LONG Error;
-
- if(PrivateConfig -> SerialConfig -> SerialBufferSize != Config -> SerialConfig -> SerialBufferSize)
- {
- STRPTR NewReadBuffer;
-
- if(NewReadBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
- {
- STRPTR NewStripBuffer;
-
- if(NewStripBuffer = AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY))
- {
- FreeVecPooled(ReadBuffer);
- FreeVecPooled(StripBuffer);
-
- ReadBuffer = NewReadBuffer;
- StripBuffer = NewStripBuffer;
- }
- else
- {
- FreeVecPooled(NewReadBuffer);
-
- Config -> SerialConfig -> SerialBufferSize = PrivateConfig -> SerialConfig -> SerialBufferSize;
- }
- }
- else
- Config -> SerialConfig -> SerialBufferSize = PrivateConfig -> SerialConfig -> SerialBufferSize;
- }
-
- Update_CR_LF_Translation();
-
- /* Use new parameters... */
-
- Error = SetFlags();
-
- /* Trouble? */
-
- if(Error)
- {
- STRPTR String;
- BYTE Reset;
-
- /* Query the error message. */
-
- if(!(String = GetSerialError(Error,&Reset)))
- String = LocaleString(MSG_SERIAL_ERROR_DEVBUSY_TXT);
-
- /* Build the device name/unit number string. */
-
- SPrintf(SharedBuffer,String,Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber);
-
- /* Display the error requester. */
-
- LT_LockWindow(Window);
-
- MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SharedBuffer);
-
- LT_UnlockWindow(Window);
-
- /* Is a serial driver reset required? */
-
- if(Reset)
- {
- /* Execute the reset command. */
-
- DoSerialCmd(CMD_RESET);
-
- /* Copy the serial driver settings
- * to the global configuration.
- */
-
- CopyWriteFlags();
-
- /* Also set the read request driver
- * flags.
- */
-
- SetFlags();
- }
- }
-
- /* Restart read request. */
-
- RestartSerial();
- }
- else
- {
- STRPTR Error;
-
- /* Shut down the serial driver. */
-
- DeleteSerial();
-
- /* Reinitialize the serial driver. */
-
- if(!(Error = CreateSerial()))
- {
- /* Free the work buffer. */
-
- if(StripBuffer)
- FreeVecPooled(StripBuffer);
-
- /* Try to allocate a new serial data work buffer. */
-
- if(!(StripBuffer = (STRPTR)AllocVecPooled(Config -> SerialConfig -> SerialBufferSize,MEMF_ANY)))
- Error = LocaleString(MSG_GLOBAL_NO_AUX_BUFFERS_TXT);
- }
-
- /* Trouble? */
-
- if(Error)
- {
- /* Display the error requester. */
-
- LT_LockWindow(Window);
-
- MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Error);
-
- /* Clean up the mess :-( */
-
- DeleteSerial();
-
- LT_UnlockWindow(Window);
-
- Success = RECONFIGURE_FAILURE;
- }
- else
- {
- /* Are we to display an error message? */
-
- if(SerialMessage)
- {
- MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
-
- SerialMessage = NULL;
- }
- }
- }
- }
-
- return(Success);
- }
-
- /* ReopenSerial():
- *
- * Reopen the serial driver.
- */
-
- VOID
- ReopenSerial()
- {
- BYTE SerialClosed = TRUE;
- STRPTR Error;
-
- do
- {
- if(Error = CreateSerial())
- {
- DeleteSerial();
-
- switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_RETRY_IGNORE_QUIT_TXT),Error))
- {
- case 2: SerialClosed = FALSE;
- break;
-
- case 0: MainTerminated = TRUE;
- break;
- }
- }
- else
- {
- SerialClosed = FALSE;
-
- if(SerialMessage)
- {
- MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
-
- SerialMessage = NULL;
- }
- }
- }
- while(SerialClosed);
- }
-
- /* HandleSerial():
- *
- * Handle the data coming in from the serial line.
- */
-
- BYTE
- HandleSerial()
- {
- BYTE MoreData = FALSE;
-
- if(ReadPort && !ReleaseSerial && Status != STATUS_HOLDING)
- {
- if(HostReadBuffer)
- {
- LONG Length = XProtocolHostMon(XprIO,HostReadBuffer,0,SerialBufferSize);
-
- if(Translate_CR_LF)
- Length = (* Translate_CR_LF)(HostReadBuffer,Length);
-
- if(Length)
- {
- if(Marking)
- DropMarker();
-
- ConProcess(HostReadBuffer,Length);
-
- if(Status == STATUS_HOLDING)
- return(FALSE);
- }
-
- MoreData = TRUE;
- }
-
- if(DataHold)
- {
- register STRPTR Data = DataHold;
- register LONG Size = DataSize;
-
- DataHold = NULL;
-
- if(Marking)
- DropMarker();
-
- (* ConTransfer)(Data,Size);
-
- MoreData = TRUE;
-
- RestartSerial();
-
- return(MoreData);
- }
-
- /* Any news? */
-
- if(CheckSerialRead())
- {
- MoreData = TRUE;
-
- if(!WaitSerialRead())
- {
- if(Marking)
- DropMarker();
-
- BytesIn++;
-
- if(Translate_CR_LF)
- {
- register LONG Size = (* Translate_CR_LF)(ReadBuffer,1);
-
- if(Size)
- (* ConTransfer)(ReadBuffer,Size);
- }
- else
- (* ConTransfer)(ReadBuffer,1);
-
- if(Status != STATUS_HOLDING && !DataHold)
- {
- ULONG Length;
-
- /* Check how many bytes are still in
- * the serial buffer.
- */
-
- if(Length = GetSerialWaiting())
- {
- ULONG Max = SerialBufferSize;
-
- if(Max > Config -> SerialConfig -> Quantum)
- Max = Config -> SerialConfig -> Quantum;
-
- if(Length > Max)
- Length = Max;
-
- if(!DoSerialRead(ReadBuffer,Length))
- {
- BytesIn += Length;
-
- if(Translate_CR_LF)
- {
- if(Length = (* Translate_CR_LF)(ReadBuffer,Length))
- (* ConTransfer)(ReadBuffer,Length);
- }
- else
- (* ConTransfer)(ReadBuffer,Length);
- }
- }
- }
- }
-
- if(DataHold)
- ClrSignal(SIG_SERIAL);
- else
- RestartSerial();
- }
- }
-
- return(MoreData);
- }
-