mirror of https://github.com/FreeRDP/FreeRDP
serial redirection: implement event char
The signotec signature device requires the eventChar support to work properly in serial redirection mode. This implementation is basic but does the job for this device. Sponsored by: Rangee GmbH (http://www.rangee.de)
This commit is contained in:
parent
ff8f7e9474
commit
de7d7e43c9
|
@ -425,10 +425,8 @@ BOOL GetCommState(HANDLE hFile, LPDCB lpDCB)
|
|||
lpLocalDcb->fDtrControl = DTR_CONTROL_DISABLE;
|
||||
}
|
||||
|
||||
lpLocalDcb->fDsrSensitivity = (handflow.ControlHandShake &
|
||||
SERIAL_DSR_SENSITIVITY) != 0;
|
||||
lpLocalDcb->fTXContinueOnXoff = (handflow.FlowReplace & SERIAL_XOFF_CONTINUE) !=
|
||||
0;
|
||||
lpLocalDcb->fDsrSensitivity = (handflow.ControlHandShake & SERIAL_DSR_SENSITIVITY) != 0;
|
||||
lpLocalDcb->fTXContinueOnXoff = (handflow.FlowReplace & SERIAL_XOFF_CONTINUE) != 0;
|
||||
lpLocalDcb->fOutX = (handflow.FlowReplace & SERIAL_AUTO_TRANSMIT) != 0;
|
||||
lpLocalDcb->fInX = (handflow.FlowReplace & SERIAL_AUTO_RECEIVE) != 0;
|
||||
lpLocalDcb->fErrorChar = (handflow.FlowReplace & SERIAL_ERROR_CHAR) != 0;
|
||||
|
|
|
@ -69,6 +69,7 @@ struct winpr_comm
|
|||
ULONG WaitEventMask;
|
||||
ULONG PendingEvents;
|
||||
|
||||
char eventChar;
|
||||
/* NB: CloseHandle() has to free resources */
|
||||
};
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
|||
*
|
||||
* ReadIntervalTimeout | ReadTotalTimeoutMultiplier | ReadTotalTimeoutConstant | VMIN | VTIME | TMAX |
|
||||
* 0 | 0 | 0 | N | 0 | INDEF | Blocks for N bytes available.
|
||||
* 0< Ti <MAXULONG | 0 | 0 | N | Ti | INDEF | Blocks on first byte, then use Ti between bytes.
|
||||
* 0< Ti <MAXULONG | 0 | 0 | N | Ti | INDEF | Blocks on first byte, then use Ti between bytes.
|
||||
* MAXULONG | 0 | 0 | 0 | 0 | 0 | Returns immediately with bytes available (don't block)
|
||||
* MAXULONG | MAXULONG | 0< Tc <MAXULONG | N | 0 | Tc | Blocks on first byte during Tc or returns immediately whith bytes available
|
||||
* MAXULONG | m | MAXULONG | | Invalid
|
||||
|
@ -349,6 +349,14 @@ BOOL CommReadFile(HANDLE hDevice, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
|||
}
|
||||
|
||||
*lpNumberOfBytesRead = nbRead;
|
||||
|
||||
EnterCriticalSection(&pComm->EventsLock);
|
||||
if (pComm->PendingEvents & SERIAL_EV_FREERDP_WAITING)
|
||||
{
|
||||
if (pComm->eventChar != '\0' && memchr(lpBuffer, pComm->eventChar, nbRead))
|
||||
pComm->PendingEvents |= SERIAL_EV_RXCHAR;
|
||||
}
|
||||
LeaveCriticalSection(&pComm->EventsLock);
|
||||
goto return_true;
|
||||
}
|
||||
|
||||
|
@ -546,13 +554,15 @@ BOOL CommWriteFile(HANDLE hDevice, LPCVOID lpBuffer,
|
|||
* printer. Its driver was expecting the modem line status
|
||||
* SERIAL_MSR_DSR true after the sending which was never
|
||||
* happenning otherwise. A purge was also done before each
|
||||
* Write operation. The serial port was oppened with:
|
||||
* Write operation. The serial port was opened with:
|
||||
* DesiredAccess=0x0012019F. The printer worked fine with
|
||||
* mstsc. */
|
||||
tcdrain(pComm->fd_write);
|
||||
|
||||
return_true:
|
||||
LeaveCriticalSection(&pComm->WriteLock);
|
||||
return TRUE;
|
||||
|
||||
return_false:
|
||||
LeaveCriticalSection(&pComm->WriteLock);
|
||||
return FALSE;
|
||||
|
|
|
@ -316,7 +316,7 @@ static BOOL _set_serial_chars(WINPR_COMM *pComm, const SERIAL_CHARS *pSerialChar
|
|||
|
||||
if (pSerialChars->XonChar == pSerialChars->XoffChar)
|
||||
{
|
||||
/* http://msdn.microsoft.com/en-us/library/windows/hardware/ff546688%28v=vs.85%29.aspx */
|
||||
/* https://msdn.microsoft.com/en-us/library/windows/hardware/ff546688?v=vs.85.aspx */
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -360,12 +360,9 @@ static BOOL _set_serial_chars(WINPR_COMM *pComm, const SERIAL_CHARS *pSerialChar
|
|||
result = FALSE; /* but keep on */
|
||||
}
|
||||
|
||||
/* FIXME: could be implemented during read/write I/O. What about ISIG? */
|
||||
if (pSerialChars->EventChar != '\0')
|
||||
{
|
||||
CommLog_Print(WLOG_WARN, "EventChar 0x%02"PRIX8" ('%c') cannot be set\n", pSerialChars->EventChar, (char) pSerialChars->EventChar);
|
||||
SetLastError(ERROR_NOT_SUPPORTED);
|
||||
result = FALSE; /* but keep on */
|
||||
pComm->eventChar = pSerialChars->EventChar;
|
||||
}
|
||||
|
||||
upcomingTermios.c_cc[VSTART] = pSerialChars->XonChar;
|
||||
|
@ -1076,7 +1073,8 @@ static BOOL _set_wait_mask(WINPR_COMM *pComm, const ULONG *pWaitMask)
|
|||
|
||||
if (possibleMask != *pWaitMask)
|
||||
{
|
||||
CommLog_Print(WLOG_WARN, "Not all wait events supported (Serial.sys), requested events= 0x%08"PRIX32", possible events= 0x%08"PRIX32"", *pWaitMask, possibleMask);
|
||||
CommLog_Print(WLOG_WARN, "Not all wait events supported (Serial.sys), requested events= 0x%08"PRIX32", possible events= 0x%08"PRIX32"",
|
||||
*pWaitMask, possibleMask);
|
||||
|
||||
/* FIXME: shall we really set the possibleMask and return FALSE? */
|
||||
pComm->WaitEventMask = possibleMask;
|
||||
|
@ -1310,7 +1308,7 @@ static BOOL _get_commstatus(WINPR_COMM *pComm, SERIAL_STATUS *pCommstatus)
|
|||
|
||||
if (currentCounters.rx != pComm->counters.rx)
|
||||
{
|
||||
pComm->PendingEvents |= SERIAL_EV_RXCHAR;
|
||||
pComm->PendingEvents |= SERIAL_EV_RXFLAG;
|
||||
}
|
||||
|
||||
if ((currentCounters.tx != pComm->counters.tx) && /* at least a transmission occurred AND ...*/
|
||||
|
@ -1458,7 +1456,7 @@ static BOOL _wait_on_mask(WINPR_COMM *pComm, ULONG *pOutputMask)
|
|||
*
|
||||
* NOTE: previously used a semaphore but used
|
||||
* sem_timedwait() anyway. Finally preferred a simpler
|
||||
* solution with Sleep() whithout the burden of the
|
||||
* solution with Sleep() without the burden of the
|
||||
* semaphore initialization and destroying.
|
||||
*/
|
||||
|
||||
|
|
Loading…
Reference in New Issue