Blame winpr/libwinpr/comm/comm_sercx2_sys.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 * Serial Communication API
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2011 O.S. Systems Software Ltda.
Packit 1fb8d4
 * Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
Packit 1fb8d4
 * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 * Copyright 2014 Hewlett-Packard Development Company, L.P.
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#if defined __linux__ && !defined ANDROID
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/wlog.h>
Packit 1fb8d4
Packit 1fb8d4
#include "comm_serial_sys.h"
Packit 1fb8d4
#include "comm_sercx_sys.h"
Packit 1fb8d4
Packit 1fb8d4
#include "comm_sercx2_sys.h"
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
/* http://msdn.microsoft.com/en-us/library/dn265347%28v=vs.85%29.aspx
Packit 1fb8d4
 *
Packit 1fb8d4
 * SerCx2 does not support special characters. SerCx2 always completes
Packit 1fb8d4
 * an IOCTL_SERIAL_SET_CHARS request with a STATUS_SUCCESS status
Packit 1fb8d4
 * code, but does not set any special characters or perform any other
Packit 1fb8d4
 * operation in response to this request. For an
Packit 1fb8d4
 * IOCTL_SERIAL_GET_CHARS request, SerCx2 sets all the character
Packit 1fb8d4
 * values in the SERIAL_CHARS structure to null, and completes the
Packit 1fb8d4
 * request with a STATUS_SUCCESS status code.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
static BOOL _set_serial_chars(WINPR_COMM* pComm, const SERIAL_CHARS* pSerialChars)
Packit 1fb8d4
{
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
static BOOL _get_serial_chars(WINPR_COMM* pComm, SERIAL_CHARS* pSerialChars)
Packit 1fb8d4
{
Packit 1fb8d4
	ZeroMemory(pSerialChars, sizeof(SERIAL_CHARS));
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
/* http://msdn.microsoft.com/en-us/library/windows/hardware/hh439605%28v=vs.85%29.aspx */
Packit 1fb8d4
/* FIXME: only using the Serial.sys' events, complete the support of the remaining events */
Packit 1fb8d4
static const ULONG _SERCX2_SYS_SUPPORTED_EV_MASK =
Packit 1fb8d4
	SERIAL_EV_RXCHAR   |
Packit 1fb8d4
	SERIAL_EV_RXFLAG   |
Packit 1fb8d4
	SERIAL_EV_TXEMPTY  |
Packit 1fb8d4
	SERIAL_EV_CTS      |
Packit 1fb8d4
	SERIAL_EV_DSR      |
Packit 1fb8d4
	SERIAL_EV_RLSD     |
Packit 1fb8d4
	SERIAL_EV_BREAK    |
Packit 1fb8d4
	SERIAL_EV_ERR      |
Packit 1fb8d4
	SERIAL_EV_RING     |
Packit 1fb8d4
	/* SERIAL_EV_PERR     | */
Packit 1fb8d4
	SERIAL_EV_RX80FULL /*|
Packit 1fb8d4
	SERIAL_EV_EVENT1   |
Packit 1fb8d4
	SERIAL_EV_EVENT2*/;
Packit 1fb8d4
Packit 1fb8d4
/* use Serial.sys for basis (not SerCx.sys) */
Packit 1fb8d4
static BOOL _set_wait_mask(WINPR_COMM *pComm, const ULONG *pWaitMask)
Packit 1fb8d4
{
Packit 1fb8d4
	ULONG possibleMask;
Packit 1fb8d4
	SERIAL_DRIVER* pSerialSys = SerialSys_s();
Packit 1fb8d4
Packit 1fb8d4
	possibleMask = *pWaitMask & _SERCX2_SYS_SUPPORTED_EV_MASK;
Packit 1fb8d4
Packit 1fb8d4
	if (possibleMask != *pWaitMask)
Packit 1fb8d4
	{
Packit 1fb8d4
		CommLog_Print(WLOG_WARN, "Not all wait events supported (SerCx2.sys), requested events= 0x%08"PRIX32", possible events= 0x%08"PRIX32"", *pWaitMask, possibleMask);
Packit 1fb8d4
Packit 1fb8d4
		/* FIXME: shall we really set the possibleMask and return FALSE? */
Packit 1fb8d4
		pComm->WaitEventMask = possibleMask;
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	/* NB: All events that are supported by SerCx.sys are supported by Serial.sys*/
Packit 1fb8d4
	return pSerialSys->set_wait_mask(pComm, pWaitMask);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
static BOOL _purge(WINPR_COMM *pComm, const ULONG *pPurgeMask)
Packit 1fb8d4
{
Packit 1fb8d4
	SERIAL_DRIVER* pSerialSys = SerialSys_s();
Packit 1fb8d4
Packit 1fb8d4
	/* http://msdn.microsoft.com/en-us/library/windows/hardware/ff546655%28v=vs.85%29.aspx */
Packit 1fb8d4
Packit 1fb8d4
	if ((*pPurgeMask & SERIAL_PURGE_RXCLEAR) && !(*pPurgeMask & SERIAL_PURGE_RXABORT))
Packit 1fb8d4
	{
Packit 1fb8d4
		CommLog_Print(WLOG_WARN, "Expecting SERIAL_PURGE_RXABORT since SERIAL_PURGE_RXCLEAR is set");
Packit 1fb8d4
		SetLastError(ERROR_INVALID_DEVICE_OBJECT_PARAMETER);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
	if ((*pPurgeMask & SERIAL_PURGE_TXCLEAR) && !(*pPurgeMask & SERIAL_PURGE_TXABORT))
Packit 1fb8d4
	{
Packit 1fb8d4
		CommLog_Print(WLOG_WARN, "Expecting SERIAL_PURGE_TXABORT since SERIAL_PURGE_TXCLEAR is set");
Packit 1fb8d4
		SetLastError(ERROR_INVALID_DEVICE_OBJECT_PARAMETER);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
	return pSerialSys->purge(pComm, pPurgeMask);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
/* specific functions only */
Packit 1fb8d4
static SERIAL_DRIVER _SerCx2Sys =
Packit 1fb8d4
{
Packit 1fb8d4
	.id		  = SerialDriverSerCx2Sys,
Packit 1fb8d4
	.name		  = _T("SerCx2.sys"),
Packit 1fb8d4
	.set_baud_rate	  = NULL,
Packit 1fb8d4
	.get_baud_rate    = NULL,
Packit 1fb8d4
	.get_properties   = NULL,
Packit 1fb8d4
	.set_serial_chars = _set_serial_chars,
Packit 1fb8d4
	.get_serial_chars = _get_serial_chars,
Packit 1fb8d4
	.set_line_control = NULL,
Packit 1fb8d4
	.get_line_control = NULL,
Packit 1fb8d4
	.set_handflow     = NULL,
Packit 1fb8d4
	.get_handflow     = NULL,
Packit 1fb8d4
	.set_timeouts     = NULL,
Packit 1fb8d4
	.get_timeouts     = NULL,
Packit 1fb8d4
	.set_dtr          = NULL,
Packit 1fb8d4
	.clear_dtr        = NULL,
Packit 1fb8d4
	.set_rts          = NULL,
Packit 1fb8d4
	.clear_rts        = NULL,
Packit 1fb8d4
	.get_modemstatus  = NULL,
Packit 1fb8d4
	.set_wait_mask    = _set_wait_mask,
Packit 1fb8d4
	.get_wait_mask    = NULL,
Packit 1fb8d4
	.wait_on_mask     = NULL,
Packit 1fb8d4
	.set_queue_size   = NULL,
Packit 1fb8d4
	.purge            = _purge,
Packit 1fb8d4
	.get_commstatus   = NULL,
Packit 1fb8d4
	.set_break_on     = NULL,
Packit 1fb8d4
	.set_break_off    = NULL,
Packit 1fb8d4
	.set_xoff         = NULL, /* not supported by SerCx2.sys */
Packit 1fb8d4
	.set_xon          = NULL, /* not supported by SerCx2.sys */
Packit 1fb8d4
	.get_dtrrts       = NULL,
Packit 1fb8d4
	.config_size      = NULL, /* not supported by SerCx2.sys */
Packit 1fb8d4
	.immediate_char   = NULL, /* not supported by SerCx2.sys */
Packit 1fb8d4
	.reset_device     = NULL, /* not supported by SerCx2.sys */
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
Packit 1fb8d4
SERIAL_DRIVER* SerCx2Sys_s()
Packit 1fb8d4
{
Packit 1fb8d4
	/* _SerCx2Sys completed with inherited functions from SerialSys or SerCxSys */
Packit 1fb8d4
	SERIAL_DRIVER* pSerialSys = SerialSys_s();
Packit 1fb8d4
	SERIAL_DRIVER* pSerCxSys = SerCxSys_s();
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.set_baud_rate    = pSerialSys->set_baud_rate;
Packit 1fb8d4
	_SerCx2Sys.get_baud_rate    = pSerialSys->get_baud_rate;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.get_properties   = pSerialSys->get_properties;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.set_line_control = pSerCxSys->set_line_control;
Packit 1fb8d4
	_SerCx2Sys.get_line_control = pSerCxSys->get_line_control;
Packit 1fb8d4
Packit 1fb8d4
	/* Only SERIAL_CTS_HANDSHAKE, SERIAL_RTS_CONTROL and SERIAL_RTS_HANDSHAKE flags are really required by SerCx2.sys
Packit 1fb8d4
	 * http://msdn.microsoft.com/en-us/library/jj680685%28v=vs.85%29.aspx
Packit 1fb8d4
	 */
Packit 1fb8d4
	_SerCx2Sys.set_handflow = pSerialSys->set_handflow;
Packit 1fb8d4
	_SerCx2Sys.get_handflow = pSerialSys->get_handflow;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.set_timeouts = pSerialSys->set_timeouts;
Packit 1fb8d4
	_SerCx2Sys.get_timeouts = pSerialSys->get_timeouts;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.set_dtr   = pSerialSys->set_dtr;
Packit 1fb8d4
	_SerCx2Sys.clear_dtr = pSerialSys->clear_dtr;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.set_rts   = pSerialSys->set_rts;
Packit 1fb8d4
	_SerCx2Sys.clear_rts = pSerialSys->clear_rts;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.get_modemstatus = pSerialSys->get_modemstatus;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.set_wait_mask = pSerialSys->set_wait_mask;
Packit 1fb8d4
	_SerCx2Sys.get_wait_mask = pSerialSys->get_wait_mask;
Packit 1fb8d4
	_SerCx2Sys.wait_on_mask  = pSerialSys->wait_on_mask;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.set_queue_size = pSerialSys->set_queue_size;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.get_commstatus = pSerialSys->get_commstatus;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.set_break_on  = pSerialSys->set_break_on;
Packit 1fb8d4
	_SerCx2Sys.set_break_off = pSerialSys->set_break_off;
Packit 1fb8d4
Packit 1fb8d4
	_SerCx2Sys.get_dtrrts = pSerialSys->get_dtrrts;
Packit 1fb8d4
Packit 1fb8d4
	return &_SerCx2Sys;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif /* __linux__ */