| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /**
- * WinPR: Windows Portable Runtime
- * Serial Communication API
- *
- * Copyright 2011 O.S. Systems Software Ltda.
- * Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
- * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
- * Copyright 2014 Hewlett-Packard Development Company, L.P.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #if defined __linux__ && !defined ANDROID
- #include <assert.h>
- #include <termios.h>
- #include <winpr/wlog.h>
- #include "comm_serial_sys.h"
- static BOOL _set_handflow(WINPR_COMM* pComm, const SERIAL_HANDFLOW* pHandflow)
- {
- SERIAL_HANDFLOW SerCxHandflow;
- BOOL result = TRUE;
- SERIAL_DRIVER* pSerialSys = SerialSys_s();
- memcpy(&SerCxHandflow, pHandflow, sizeof(SERIAL_HANDFLOW));
- /* filter out unsupported bits by SerCx.sys
- *
- * http://msdn.microsoft.com/en-us/library/windows/hardware/jj680685%28v=vs.85%29.aspx
- */
- SerCxHandflow.ControlHandShake =
- pHandflow->ControlHandShake &
- (SERIAL_DTR_CONTROL | SERIAL_DTR_HANDSHAKE | SERIAL_CTS_HANDSHAKE | SERIAL_DSR_HANDSHAKE);
- SerCxHandflow.FlowReplace =
- pHandflow->FlowReplace & (SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE);
- if (SerCxHandflow.ControlHandShake != pHandflow->ControlHandShake)
- {
- if (pHandflow->ControlHandShake & SERIAL_DCD_HANDSHAKE)
- {
- CommLog_Print(WLOG_WARN,
- "SERIAL_DCD_HANDSHAKE not supposed to be implemented by SerCx.sys");
- }
- if (pHandflow->ControlHandShake & SERIAL_DSR_SENSITIVITY)
- {
- CommLog_Print(WLOG_WARN,
- "SERIAL_DSR_SENSITIVITY not supposed to be implemented by SerCx.sys");
- }
- if (pHandflow->ControlHandShake & SERIAL_ERROR_ABORT)
- {
- CommLog_Print(WLOG_WARN,
- "SERIAL_ERROR_ABORT not supposed to be implemented by SerCx.sys");
- }
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- result = FALSE;
- }
- if (SerCxHandflow.FlowReplace != pHandflow->FlowReplace)
- {
- if (pHandflow->ControlHandShake & SERIAL_AUTO_TRANSMIT)
- {
- CommLog_Print(WLOG_WARN,
- "SERIAL_AUTO_TRANSMIT not supposed to be implemented by SerCx.sys");
- }
- if (pHandflow->ControlHandShake & SERIAL_AUTO_RECEIVE)
- {
- CommLog_Print(WLOG_WARN,
- "SERIAL_AUTO_RECEIVE not supposed to be implemented by SerCx.sys");
- }
- if (pHandflow->ControlHandShake & SERIAL_ERROR_CHAR)
- {
- CommLog_Print(WLOG_WARN,
- "SERIAL_ERROR_CHAR not supposed to be implemented by SerCx.sys");
- }
- if (pHandflow->ControlHandShake & SERIAL_NULL_STRIPPING)
- {
- CommLog_Print(WLOG_WARN,
- "SERIAL_NULL_STRIPPING not supposed to be implemented by SerCx.sys");
- }
- if (pHandflow->ControlHandShake & SERIAL_BREAK_CHAR)
- {
- CommLog_Print(WLOG_WARN,
- "SERIAL_BREAK_CHAR not supposed to be implemented by SerCx.sys");
- }
- if (pHandflow->ControlHandShake & SERIAL_XOFF_CONTINUE)
- {
- CommLog_Print(WLOG_WARN,
- "SERIAL_XOFF_CONTINUE not supposed to be implemented by SerCx.sys");
- }
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- result = FALSE;
- }
- if (!pSerialSys->set_handflow(pComm, &SerCxHandflow))
- return FALSE;
- return result;
- }
- static BOOL _get_handflow(WINPR_COMM* pComm, SERIAL_HANDFLOW* pHandflow)
- {
- BOOL result;
- SERIAL_DRIVER* pSerialSys = SerialSys_s();
- result = pSerialSys->get_handflow(pComm, pHandflow);
- /* filter out unsupported bits by SerCx.sys
- *
- * http://msdn.microsoft.com/en-us/library/windows/hardware/jj680685%28v=vs.85%29.aspx
- */
- pHandflow->ControlHandShake =
- pHandflow->ControlHandShake &
- (SERIAL_DTR_CONTROL | SERIAL_DTR_HANDSHAKE | SERIAL_CTS_HANDSHAKE | SERIAL_DSR_HANDSHAKE);
- pHandflow->FlowReplace = pHandflow->FlowReplace & (SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE);
- return result;
- }
- /* http://msdn.microsoft.com/en-us/library/windows/hardware/hh439605%28v=vs.85%29.aspx */
- static const ULONG _SERCX_SYS_SUPPORTED_EV_MASK = SERIAL_EV_RXCHAR |
- /* SERIAL_EV_RXFLAG | */
- SERIAL_EV_TXEMPTY | SERIAL_EV_CTS |
- SERIAL_EV_DSR | SERIAL_EV_RLSD | SERIAL_EV_BREAK |
- SERIAL_EV_ERR | SERIAL_EV_RING /* |
- SERIAL_EV_PERR |
- SERIAL_EV_RX80FULL |
- SERIAL_EV_EVENT1 |
- SERIAL_EV_EVENT2*/
- ;
- static BOOL _set_wait_mask(WINPR_COMM* pComm, const ULONG* pWaitMask)
- {
- ULONG possibleMask;
- SERIAL_DRIVER* pSerialSys = SerialSys_s();
- possibleMask = *pWaitMask & _SERCX_SYS_SUPPORTED_EV_MASK;
- if (possibleMask != *pWaitMask)
- {
- CommLog_Print(WLOG_WARN,
- "Not all wait events supported (SerCx.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;
- return FALSE;
- }
- /* NB: All events that are supported by SerCx.sys are supported by Serial.sys*/
- return pSerialSys->set_wait_mask(pComm, pWaitMask);
- }
- /* specific functions only */
- static SERIAL_DRIVER _SerCxSys = {
- .id = SerialDriverSerCxSys,
- .name = _T("SerCx.sys"),
- .set_baud_rate = NULL,
- .get_baud_rate = NULL,
- .get_properties = NULL,
- .set_serial_chars = NULL,
- .get_serial_chars = NULL,
- .set_line_control = NULL,
- .get_line_control = NULL,
- .set_handflow = _set_handflow,
- .get_handflow = _get_handflow,
- .set_timeouts = NULL,
- .get_timeouts = NULL,
- .set_dtr = NULL,
- .clear_dtr = NULL,
- .set_rts = NULL,
- .clear_rts = NULL,
- .get_modemstatus = NULL,
- .set_wait_mask = _set_wait_mask,
- .get_wait_mask = NULL,
- .wait_on_mask = NULL,
- .set_queue_size = NULL,
- .purge = NULL,
- .get_commstatus = NULL,
- .set_break_on = NULL,
- .set_break_off = NULL,
- .set_xoff = NULL,
- .set_xon = NULL,
- .get_dtrrts = NULL,
- .config_size = NULL, /* not supported by SerCx.sys */
- .immediate_char = NULL,
- .reset_device = NULL, /* not supported by SerCx.sys */
- };
- SERIAL_DRIVER* SerCxSys_s()
- {
- /* _SerCxSys completed with inherited functions from SerialSys */
- SERIAL_DRIVER* pSerialSys = SerialSys_s();
- _SerCxSys.set_baud_rate = pSerialSys->set_baud_rate;
- _SerCxSys.get_baud_rate = pSerialSys->get_baud_rate;
- _SerCxSys.get_properties = pSerialSys->get_properties;
- _SerCxSys.set_serial_chars = pSerialSys->set_serial_chars;
- _SerCxSys.get_serial_chars = pSerialSys->get_serial_chars;
- _SerCxSys.set_line_control = pSerialSys->set_line_control;
- _SerCxSys.get_line_control = pSerialSys->get_line_control;
- _SerCxSys.set_timeouts = pSerialSys->set_timeouts;
- _SerCxSys.get_timeouts = pSerialSys->get_timeouts;
- _SerCxSys.set_dtr = pSerialSys->set_dtr;
- _SerCxSys.clear_dtr = pSerialSys->clear_dtr;
- _SerCxSys.set_rts = pSerialSys->set_rts;
- _SerCxSys.clear_rts = pSerialSys->clear_rts;
- _SerCxSys.get_modemstatus = pSerialSys->get_modemstatus;
- _SerCxSys.set_wait_mask = pSerialSys->set_wait_mask;
- _SerCxSys.get_wait_mask = pSerialSys->get_wait_mask;
- _SerCxSys.wait_on_mask = pSerialSys->wait_on_mask;
- _SerCxSys.set_queue_size = pSerialSys->set_queue_size;
- _SerCxSys.purge = pSerialSys->purge;
- _SerCxSys.get_commstatus = pSerialSys->get_commstatus;
- _SerCxSys.set_break_on = pSerialSys->set_break_on;
- _SerCxSys.set_break_off = pSerialSys->set_break_off;
- _SerCxSys.set_xoff = pSerialSys->set_xoff;
- _SerCxSys.set_xon = pSerialSys->set_xon;
- _SerCxSys.get_dtrrts = pSerialSys->get_dtrrts;
- _SerCxSys.immediate_char = pSerialSys->immediate_char;
- return &_SerCxSys;
- }
- #endif /* __linux__ */
|