1
0
Fork 0

Fix handling of escape characters in softmodem

When running BBS DOSBox's softmodem does not correctly handle
escape characters properly nor does it properly transition
to command mode:

Characters are swallowed instead of passed-through, this causes
issue when transmitting strings with the plus character.
Additional characters before and after the escape sequence don't
reset the counters causing switch to command mode even if not
intended. For example, connect to a remote and type a+++ it
switches to command mode, it should not. The attached proposed
patch fixes the escape handling:

Transmission pause is checked before and after the escape
sequence, so <pause>+++<pause> is the correct
sequence.</pause></pause> Extra characters cause the counters to
be reset so no unwanted switch is triggered. Use register S12 to
set the pause timer in 1/50th of seconds, default is 50 = 1 sec.
Plus characters are passed to the remote. With this fix I'm able
to run a BBS software and do file transfers with XModem and ZModem
without problems.

Imported-from: https://sourceforge.net/p/dosbox/patches/287/
This commit is contained in:
Marco Maccaferri 2020-02-09 19:41:55 -08:00 committed by krcroft
parent 950bb436e7
commit 4aee47a770
No known key found for this signature in database
GPG key ID: 4AD3678F4A2C291C
2 changed files with 23 additions and 21 deletions

View file

@ -258,6 +258,7 @@ void CSerialModem::Reset(){
reg[MREG_CR_CHAR] = '\r';
reg[MREG_LF_CHAR] = '\n';
reg[MREG_BACKSPACE_CHAR] = '\b';
reg[MREG_GUARD_TIME] = 50;
cmdpause = 0;
echo = true;
@ -688,14 +689,26 @@ void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) {
}
void CSerialModem::Timer2(void) {
bool sendbyte = true;
Bitu usesize;
Bit8u txval;
Bitu txbuffersize =0;
// Check for eventual break command
if (!commandmode) cmdpause++;
if (!commandmode) {
cmdpause++;
if (cmdpause > (20 * reg[MREG_GUARD_TIME])) {
if (plusinc == 0) {
plusinc = 1;
}
else if (plusinc == 4) {
LOG_MSG("Modem: Entering command mode(escape sequence)");
commandmode = true;
SendRes(ResOK);
plusinc = 0;
}
}
}
// Handle incoming data from serial port, read as much as available
CSerial::setCTS(true); // buffer will get 'emptier', new data can be received
while (tqueue->inuse()) {
@ -716,29 +729,18 @@ void CSerialModem::Timer2(void) {
}
}
else {// + character
// 1000 ticks have passed, can check for pause command
if (cmdpause > 1000) {
if (txval == reg[MREG_ESCAPE_CHAR]) // +
{
plusinc++;
if (plusinc >= 3) {
LOG_MSG("Modem: Entering command mode(escape sequence)");
commandmode = true;
SendRes(ResOK);
plusinc = 0;
}
sendbyte=false;
} else {
plusinc=0;
}
// If not a special pause command, should go for bigger blocks to send
if (plusinc >= 1 && plusinc <= 3 && txval == reg[MREG_ESCAPE_CHAR]) // +
plusinc++;
else {
plusinc = 0;
}
cmdpause = 0;
tmpbuf[txbuffersize] = txval;
txbuffersize++;
}
} // while loop
if (clientsocket && sendbyte && txbuffersize) {
if (clientsocket && txbuffersize) {
// down here it saves a lot of network traffic
if (!clientsocket->SendArray(tmpbuf,txbuffersize)) {
SendRes(ResNOCARRIER);
@ -759,7 +761,6 @@ void CSerialModem::Timer2(void) {
TelnetEmulation(tmpbuf, usesize);
else
rqueue->adds(tmpbuf,usesize);
cmdpause = 0;
}
}
// Check for incoming calls

View file

@ -165,6 +165,7 @@ private:
#define MREG_CR_CHAR 3
#define MREG_LF_CHAR 4
#define MREG_BACKSPACE_CHAR 5
#define MREG_GUARD_TIME 12
class CSerialModem : public CSerial {