Merge branch 'master' of github.com:awakecoding/FreeRDP into shadow
This commit is contained in:
commit
c762a4d5a2
@ -53,6 +53,7 @@ typedef struct _SERIAL_DEVICE SERIAL_DEVICE;
|
||||
struct _SERIAL_DEVICE
|
||||
{
|
||||
DEVICE device;
|
||||
BOOL permissive;
|
||||
SERIAL_DRIVER_ID ServerSerialDriverId;
|
||||
HANDLE* hComm;
|
||||
|
||||
@ -182,11 +183,7 @@ static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp)
|
||||
|
||||
_comm_setServerSerialDriver(serial->hComm, serial->ServerSerialDriverId);
|
||||
|
||||
/* FIXME: Appeared to be useful to setup some devices. Guess
|
||||
* the device driver asked to setup some unsupported feature
|
||||
* that were not eventually used. TODO: collecting more
|
||||
* details, a command line argument? */
|
||||
/* _comm_set_permissive(serial->hComm, TRUE); */
|
||||
_comm_set_permissive(serial->hComm, serial->permissive);
|
||||
|
||||
/* NOTE: binary mode/raw mode required for the redirection. On
|
||||
* Linux, CommCreateFileA forces this setting.
|
||||
@ -817,6 +814,21 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
serial->ServerSerialDriverId = SerialDriverSerCx2Sys;
|
||||
}
|
||||
|
||||
|
||||
if (device->Permissive != NULL)
|
||||
{
|
||||
if (_stricmp(device->Permissive, "permissive") == 0)
|
||||
{
|
||||
serial->permissive = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_Print(serial->log, WLOG_DEBUG, "Unknown flag: %s", device->Permissive);
|
||||
assert(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WLog_Print(serial->log, WLOG_DEBUG, "Server's serial driver: %s (id: %d)", driver, serial->ServerSerialDriverId);
|
||||
/* TODO: implement auto detection of the server's serial driver */
|
||||
|
||||
|
@ -256,8 +256,8 @@ int freerdp_client_print_command_line_help(int argc, char** argv)
|
||||
|
||||
printf("Drive Redirection: /drive:home,/home/user\n");
|
||||
printf("Smartcard Redirection: /smartcard:<device>\n");
|
||||
printf("Printer Redirection: /printer:<device>,<driver>\n");
|
||||
printf("Serial Port Redirection: /serial:<device>\n");
|
||||
printf("Serial Port Redirection: /serial:<name>,<device>,[SerCx2|SerCx|Serial],[permissive]\n");
|
||||
printf("Serial Port Redirection: /serial:COM1,/dev/ttyS0\n");
|
||||
printf("Parallel Port Redirection: /parallel:<device>\n");
|
||||
printf("Printer Redirection: /printer:<device>,<driver>\n");
|
||||
printf("\n");
|
||||
@ -425,6 +425,9 @@ int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** p
|
||||
if (count > 3)
|
||||
serial->Driver = _strdup(params[3]);
|
||||
|
||||
if (count > 4)
|
||||
serial->Permissive = _strdup(params[4]);
|
||||
|
||||
freerdp_device_collection_add(settings, (RDPDR_DEVICE*) serial);
|
||||
|
||||
return 1;
|
||||
|
@ -471,7 +471,8 @@ struct _RDPDR_SERIAL
|
||||
UINT32 Type;
|
||||
char* Name;
|
||||
char* Path;
|
||||
char* Driver;
|
||||
char* Driver;
|
||||
char* Permissive;
|
||||
};
|
||||
typedef struct _RDPDR_SERIAL RDPDR_SERIAL;
|
||||
|
||||
|
@ -417,7 +417,7 @@ INLINE int gdi_is_mono_pixel_set(BYTE* data, int x, int y, int width)
|
||||
return (data[byte] & (0x80 >> shift)) != 0;
|
||||
}
|
||||
|
||||
gdiBitmap* gdi_glyph_new(rdpGdi* gdi, GLYPH_DATA* glyph)
|
||||
static gdiBitmap* gdi_glyph_new(rdpGdi* gdi, GLYPH_DATA* glyph)
|
||||
{
|
||||
BYTE* extra;
|
||||
gdiBitmap* gdi_bmp;
|
||||
@ -442,7 +442,7 @@ gdiBitmap* gdi_glyph_new(rdpGdi* gdi, GLYPH_DATA* glyph)
|
||||
return gdi_bmp;
|
||||
}
|
||||
|
||||
void gdi_glyph_free(gdiBitmap* gdi_bmp)
|
||||
static void gdi_glyph_free(gdiBitmap* gdi_bmp)
|
||||
{
|
||||
if (gdi_bmp)
|
||||
{
|
||||
@ -488,7 +488,7 @@ void gdi_bitmap_free_ex(gdiBitmap* bitmap)
|
||||
}
|
||||
}
|
||||
|
||||
void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
|
||||
static void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
|
||||
{
|
||||
int status;
|
||||
int nXDst;
|
||||
@ -591,7 +591,7 @@ void gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
|
||||
}
|
||||
}
|
||||
|
||||
void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
|
||||
static void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
|
||||
{
|
||||
int index;
|
||||
PALETTE_ENTRY* pe;
|
||||
@ -609,7 +609,7 @@ void gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
|
||||
}
|
||||
}
|
||||
|
||||
void gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
|
||||
static void gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
|
||||
{
|
||||
rdpGdi* gdi = context->gdi;
|
||||
|
||||
@ -624,7 +624,7 @@ void gdi_set_bounds(rdpContext* context, rdpBounds* bounds)
|
||||
}
|
||||
}
|
||||
|
||||
void gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
|
||||
static void gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
|
||||
{
|
||||
rdpGdi* gdi = context->gdi;
|
||||
|
||||
@ -632,7 +632,7 @@ void gdi_dstblt(rdpContext* context, DSTBLT_ORDER* dstblt)
|
||||
dstblt->nWidth, dstblt->nHeight, NULL, 0, 0, gdi_rop3_code(dstblt->bRop));
|
||||
}
|
||||
|
||||
void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
|
||||
static void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
|
||||
{
|
||||
BYTE* data;
|
||||
rdpBrush* brush;
|
||||
@ -712,7 +712,7 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt)
|
||||
gdi_SetTextColor(gdi->drawing->hdc, originalColor);
|
||||
}
|
||||
|
||||
void gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
|
||||
static void gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
|
||||
{
|
||||
rdpGdi* gdi = context->gdi;
|
||||
|
||||
@ -721,7 +721,7 @@ void gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
|
||||
scrblt->nXSrc, scrblt->nYSrc, gdi_rop3_code(scrblt->bRop));
|
||||
}
|
||||
|
||||
void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
|
||||
static void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
|
||||
{
|
||||
GDI_RECT rect;
|
||||
HGDI_BRUSH hBrush;
|
||||
@ -739,7 +739,7 @@ void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect)
|
||||
gdi_DeleteObject((HGDIOBJECT) hBrush);
|
||||
}
|
||||
|
||||
void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
|
||||
static void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_opaque_rect)
|
||||
{
|
||||
int i;
|
||||
GDI_RECT rect;
|
||||
@ -764,7 +764,7 @@ void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_o
|
||||
}
|
||||
}
|
||||
|
||||
void gdi_line_to(rdpContext* context, LINE_TO_ORDER* lineTo)
|
||||
static void gdi_line_to(rdpContext* context, LINE_TO_ORDER* lineTo)
|
||||
{
|
||||
UINT32 color;
|
||||
HGDI_PEN hPen;
|
||||
@ -781,7 +781,7 @@ void gdi_line_to(rdpContext* context, LINE_TO_ORDER* lineTo)
|
||||
gdi_DeleteObject((HGDIOBJECT) hPen);
|
||||
}
|
||||
|
||||
void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
|
||||
static void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
|
||||
{
|
||||
int i;
|
||||
INT32 x;
|
||||
@ -812,7 +812,7 @@ void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline)
|
||||
gdi_DeleteObject((HGDIOBJECT) hPen);
|
||||
}
|
||||
|
||||
void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
|
||||
static void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
|
||||
{
|
||||
gdiBitmap* bitmap;
|
||||
rdpGdi* gdi = context->gdi;
|
||||
@ -824,7 +824,7 @@ void gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt)
|
||||
memblt->nXSrc, memblt->nYSrc, gdi_rop3_code(memblt->bRop));
|
||||
}
|
||||
|
||||
void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
||||
static void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
||||
{
|
||||
BYTE* data;
|
||||
rdpBrush* brush;
|
||||
@ -889,29 +889,30 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt)
|
||||
gdi_SetTextColor(gdi->drawing->hdc, originalColor);
|
||||
}
|
||||
|
||||
void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
|
||||
static void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc)
|
||||
{
|
||||
WLog_ERR(TAG, "PolygonSC");
|
||||
WLog_VRB(TAG, "not implemented");
|
||||
}
|
||||
|
||||
void gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
|
||||
static void gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb)
|
||||
{
|
||||
WLog_ERR(TAG, "PolygonCB");
|
||||
WLog_VRB(TAG, "not implemented");
|
||||
}
|
||||
|
||||
void gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
|
||||
static void gdi_ellipse_sc(rdpContext* context, ELLIPSE_SC_ORDER* ellipse_sc)
|
||||
{
|
||||
WLog_ERR(TAG, "EllipseSC");
|
||||
WLog_VRB(TAG, "not implemented");
|
||||
}
|
||||
|
||||
void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
|
||||
static void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
|
||||
{
|
||||
WLog_ERR(TAG, "EllipseCB");
|
||||
WLog_VRB(TAG, "not implemented");
|
||||
}
|
||||
|
||||
void gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker)
|
||||
static void gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surfaceFrameMarker)
|
||||
@ -934,7 +935,7 @@ void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface
|
||||
}
|
||||
}
|
||||
|
||||
void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
|
||||
static void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* cmd)
|
||||
{
|
||||
int i, j;
|
||||
int tx, ty;
|
||||
|
@ -174,29 +174,6 @@
|
||||
#define BAUD_57600 ((DWORD)0x00040000)
|
||||
#define BAUD_USER ((DWORD)0x10000000)
|
||||
|
||||
/* Ntddser.h: http://msdn.microsoft.com/en-us/cc308432.aspx */
|
||||
#define SERIAL_BAUD_075 ((ULONG)0x00000001)
|
||||
#define SERIAL_BAUD_110 ((ULONG)0x00000002)
|
||||
#define SERIAL_BAUD_134_5 ((ULONG)0x00000004)
|
||||
#define SERIAL_BAUD_150 ((ULONG)0x00000008)
|
||||
#define SERIAL_BAUD_300 ((ULONG)0x00000010)
|
||||
#define SERIAL_BAUD_600 ((ULONG)0x00000020)
|
||||
#define SERIAL_BAUD_1200 ((ULONG)0x00000040)
|
||||
#define SERIAL_BAUD_1800 ((ULONG)0x00000080)
|
||||
#define SERIAL_BAUD_2400 ((ULONG)0x00000100)
|
||||
#define SERIAL_BAUD_4800 ((ULONG)0x00000200)
|
||||
#define SERIAL_BAUD_7200 ((ULONG)0x00000400)
|
||||
#define SERIAL_BAUD_9600 ((ULONG)0x00000800)
|
||||
#define SERIAL_BAUD_14400 ((ULONG)0x00001000)
|
||||
#define SERIAL_BAUD_19200 ((ULONG)0x00002000)
|
||||
#define SERIAL_BAUD_38400 ((ULONG)0x00004000)
|
||||
#define SERIAL_BAUD_56K ((ULONG)0x00008000)
|
||||
#define SERIAL_BAUD_128K ((ULONG)0x00010000)
|
||||
#define SERIAL_BAUD_115200 ((ULONG)0x00020000)
|
||||
#define SERIAL_BAUD_57600 ((ULONG)0x00040000)
|
||||
#define SERIAL_BAUD_USER ((ULONG)0x10000000)
|
||||
|
||||
|
||||
#define DATABITS_5 ((WORD)0x0001)
|
||||
#define DATABITS_6 ((WORD)0x0002)
|
||||
#define DATABITS_7 ((WORD)0x0004)
|
||||
|
@ -44,12 +44,17 @@ struct winpr_comm
|
||||
int fd_write_event; /* as of today, only used by _purge() */
|
||||
CRITICAL_SECTION WriteLock;
|
||||
|
||||
/* permissive mode on errors if TRUE (default is FALSE).
|
||||
/* permissive mode on errors. If TRUE (default is FALSE)
|
||||
* CommDeviceIoControl always return TRUE.
|
||||
*
|
||||
* Since not all features are supported, some devices and applications
|
||||
* can still be functional on such errors.
|
||||
* Not all features are supported yet and an error is then returned when
|
||||
* an application turns them on (e.g: i/o buffers > 4096). It appeared
|
||||
* though that devices and applications can be still functional on such
|
||||
* errors.
|
||||
*
|
||||
* TODO: command line switch or getting rid of it.
|
||||
* see also: comm_ioctl.c
|
||||
*
|
||||
* FIXME: getting rid of this flag once all features supported.
|
||||
*/
|
||||
BOOL permissive;
|
||||
|
||||
|
@ -163,10 +163,10 @@ SERIAL_DRIVER* SerCx2Sys_s()
|
||||
SERIAL_DRIVER* pSerialSys = SerialSys_s();
|
||||
SERIAL_DRIVER* pSerCxSys = SerCxSys_s();
|
||||
|
||||
_SerCx2Sys.set_baud_rate = pSerCxSys->set_baud_rate;
|
||||
_SerCx2Sys.get_baud_rate = pSerCxSys->get_baud_rate;
|
||||
_SerCx2Sys.set_baud_rate = pSerialSys->set_baud_rate;
|
||||
_SerCx2Sys.get_baud_rate = pSerialSys->get_baud_rate;
|
||||
|
||||
_SerCx2Sys.get_properties = pSerCxSys->get_properties;
|
||||
_SerCx2Sys.get_properties = pSerialSys->get_properties;
|
||||
|
||||
_SerCx2Sys.set_line_control = pSerCxSys->set_line_control;
|
||||
_SerCx2Sys.get_line_control = pSerCxSys->get_line_control;
|
||||
|
@ -30,207 +30,6 @@
|
||||
#include "comm_serial_sys.h"
|
||||
|
||||
|
||||
/* 0: B* (Linux termios)
|
||||
* 1: CBR_* or actual baud rate
|
||||
* 2: BAUD_* (similar to SERIAL_BAUD_*)
|
||||
*/
|
||||
static const speed_t _SERCX_SYS_BAUD_TABLE[][3] = {
|
||||
#ifdef B0
|
||||
{B0, 0, 0}, /* hang up */
|
||||
#endif
|
||||
#ifdef B50
|
||||
{B50, 50, 0},
|
||||
#endif
|
||||
#ifdef B75
|
||||
{B75, 75, BAUD_075},
|
||||
#endif
|
||||
#ifdef B110
|
||||
{B110, CBR_110, BAUD_110},
|
||||
#endif
|
||||
#ifdef B134
|
||||
{B134, 134, 0 /*BAUD_134_5*/},
|
||||
#endif
|
||||
#ifdef B150
|
||||
{B150, 150, BAUD_150},
|
||||
#endif
|
||||
#ifdef B200
|
||||
{B200, 200, 0},
|
||||
#endif
|
||||
#ifdef B300
|
||||
{B300, CBR_300, BAUD_300},
|
||||
#endif
|
||||
#ifdef B600
|
||||
{B600, CBR_600, BAUD_600},
|
||||
#endif
|
||||
#ifdef B1200
|
||||
{B1200, CBR_1200, BAUD_1200},
|
||||
#endif
|
||||
#ifdef B1800
|
||||
{B1800, 1800, BAUD_1800},
|
||||
#endif
|
||||
#ifdef B2400
|
||||
{B2400, CBR_2400, BAUD_2400},
|
||||
#endif
|
||||
#ifdef B4800
|
||||
{B4800, CBR_4800, BAUD_4800},
|
||||
#endif
|
||||
/* {, ,BAUD_7200} */
|
||||
#ifdef B9600
|
||||
{B9600, CBR_9600, BAUD_9600},
|
||||
#endif
|
||||
/* {, CBR_14400, BAUD_14400}, /\* unsupported on Linux *\/ */
|
||||
#ifdef B19200
|
||||
{B19200, CBR_19200, BAUD_19200},
|
||||
#endif
|
||||
#ifdef B38400
|
||||
{B38400, CBR_38400, BAUD_38400},
|
||||
#endif
|
||||
/* {, CBR_56000, BAUD_56K}, /\* unsupported on Linux *\/ */
|
||||
#ifdef B57600
|
||||
{B57600, CBR_57600, BAUD_57600},
|
||||
#endif
|
||||
#ifdef B115200
|
||||
{B115200, CBR_115200, BAUD_115200},
|
||||
#endif
|
||||
/* {, CBR_128000, BAUD_128K}, /\* unsupported on Linux *\/ */
|
||||
/* {, CBR_256000, BAUD_USER}, /\* unsupported on Linux *\/ */
|
||||
#ifdef B230400
|
||||
{B230400, 230400, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B460800
|
||||
{B460800, 460800, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B500000
|
||||
{B500000, 500000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B576000
|
||||
{B576000, 576000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B921600
|
||||
{B921600, 921600, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B1000000
|
||||
{B1000000, 1000000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B1152000
|
||||
{B1152000, 1152000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B1500000
|
||||
{B1500000, 1500000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B2000000
|
||||
{B2000000, 2000000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B2500000
|
||||
{B2500000, 2500000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B3000000
|
||||
{B3000000, 3000000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B3500000
|
||||
{B3500000, 3500000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B4000000
|
||||
{B4000000, 4000000, BAUD_USER}, /* __MAX_BAUD */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties)
|
||||
{
|
||||
int i;
|
||||
SERIAL_DRIVER* pSerialSys = SerialSys_s();
|
||||
|
||||
if (!pSerialSys->get_properties(pComm, pProperties))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* override some of the inherited properties from SerialSys ... */
|
||||
|
||||
pProperties->dwMaxBaud = BAUD_USER;
|
||||
|
||||
pProperties->dwSettableBaud = 0;
|
||||
for (i=0; _SERCX_SYS_BAUD_TABLE[i][0]<=__MAX_BAUD; i++)
|
||||
{
|
||||
pProperties->dwSettableBaud |= _SERCX_SYS_BAUD_TABLE[i][2];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static BOOL _set_baud_rate(WINPR_COMM *pComm, const SERIAL_BAUD_RATE *pBaudRate)
|
||||
{
|
||||
int i;
|
||||
speed_t newSpeed;
|
||||
struct termios futureState;
|
||||
|
||||
ZeroMemory(&futureState, sizeof(struct termios));
|
||||
if (tcgetattr(pComm->fd, &futureState) < 0) /* NB: preserves current settings not directly handled by the Communication Functions */
|
||||
{
|
||||
SetLastError(ERROR_IO_DEVICE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i=0; _SERCX_SYS_BAUD_TABLE[i][0]<=__MAX_BAUD; i++)
|
||||
{
|
||||
if (_SERCX_SYS_BAUD_TABLE[i][1] == pBaudRate->BaudRate)
|
||||
{
|
||||
newSpeed = _SERCX_SYS_BAUD_TABLE[i][0];
|
||||
if (cfsetspeed(&futureState, newSpeed) < 0)
|
||||
{
|
||||
CommLog_Print(WLOG_WARN, "failed to set speed 0x%x (%lu)", newSpeed, pBaudRate->BaudRate);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
assert(cfgetispeed(&futureState) == newSpeed);
|
||||
|
||||
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &futureState) < 0)
|
||||
{
|
||||
CommLog_Print(WLOG_WARN, "_comm_ioctl_tcsetattr failure: last-error: 0x%lX", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
CommLog_Print(WLOG_WARN, "could not find a matching speed for the baud rate %lu", pBaudRate->BaudRate);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static BOOL _get_baud_rate(WINPR_COMM *pComm, SERIAL_BAUD_RATE *pBaudRate)
|
||||
{
|
||||
int i;
|
||||
speed_t currentSpeed;
|
||||
struct termios currentState;
|
||||
|
||||
ZeroMemory(¤tState, sizeof(struct termios));
|
||||
if (tcgetattr(pComm->fd, ¤tState) < 0)
|
||||
{
|
||||
SetLastError(ERROR_IO_DEVICE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
currentSpeed = cfgetispeed(¤tState);
|
||||
|
||||
for (i=0; _SERCX_SYS_BAUD_TABLE[i][0]<=__MAX_BAUD; i++)
|
||||
{
|
||||
if (_SERCX_SYS_BAUD_TABLE[i][0] == currentSpeed)
|
||||
{
|
||||
pBaudRate->BaudRate = _SERCX_SYS_BAUD_TABLE[i][1];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
CommLog_Print(WLOG_WARN, "could not find a matching baud rate for the speed 0x%x", currentSpeed);
|
||||
SetLastError(ERROR_INVALID_DATA);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL _set_handflow(WINPR_COMM *pComm, const SERIAL_HANDFLOW *pHandflow)
|
||||
{
|
||||
SERIAL_HANDFLOW SerCxHandflow;
|
||||
@ -373,9 +172,9 @@ static SERIAL_DRIVER _SerCxSys =
|
||||
{
|
||||
.id = SerialDriverSerCxSys,
|
||||
.name = _T("SerCx.sys"),
|
||||
.set_baud_rate = _set_baud_rate,
|
||||
.get_baud_rate = _get_baud_rate,
|
||||
.get_properties = _get_properties,
|
||||
.set_baud_rate = NULL,
|
||||
.get_baud_rate = NULL,
|
||||
.get_properties = NULL,
|
||||
.set_serial_chars = NULL,
|
||||
.get_serial_chars = NULL,
|
||||
.set_line_control = NULL,
|
||||
@ -412,6 +211,11 @@ 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;
|
||||
|
@ -43,76 +43,114 @@
|
||||
#define N_TTY_BUF_SIZE 4096
|
||||
|
||||
|
||||
#define _BAUD_TABLE_END 0010020 /* __MAX_BAUD + 1 */
|
||||
|
||||
/*
|
||||
* Linux, Windows speeds
|
||||
*
|
||||
/* 0: B* (Linux termios)
|
||||
* 1: CBR_* or actual baud rate
|
||||
* 2: BAUD_* (identical to SERIAL_BAUD_*)
|
||||
*/
|
||||
static const speed_t _SERIAL_SYS_BAUD_TABLE[][2] = {
|
||||
static const speed_t _BAUD_TABLE[][3] = {
|
||||
#ifdef B0
|
||||
{B0, 0}, /* hang up */
|
||||
{B0, 0, 0}, /* hang up */
|
||||
#endif
|
||||
#ifdef B50
|
||||
{B50, 50, 0},
|
||||
#endif
|
||||
/* #ifdef B50 */
|
||||
/* {B50, }, /\* undefined by serial.sys *\/ */
|
||||
/* #endif */
|
||||
#ifdef B75
|
||||
{B75, SERIAL_BAUD_075},
|
||||
{B75, 75, BAUD_075},
|
||||
#endif
|
||||
#ifdef B110
|
||||
{B110, SERIAL_BAUD_110},
|
||||
{B110, CBR_110, BAUD_110},
|
||||
#endif
|
||||
#ifdef B134
|
||||
{B134, 134, 0 /*BAUD_134_5*/},
|
||||
#endif
|
||||
/* #ifdef B134 */
|
||||
/* {B134, SERIAL_BAUD_134_5}, /\* TODO: might be the same? *\/ */
|
||||
/* #endif */
|
||||
#ifdef B150
|
||||
{B150, SERIAL_BAUD_150},
|
||||
{B150, 150, BAUD_150},
|
||||
#endif
|
||||
#ifdef B200
|
||||
{B200, 200, 0},
|
||||
#endif
|
||||
/* #ifdef B200 */
|
||||
/* {B200, }, /\* undefined by serial.sys *\/ */
|
||||
/* #endif */
|
||||
#ifdef B300
|
||||
{B300, SERIAL_BAUD_300},
|
||||
{B300, CBR_300, BAUD_300},
|
||||
#endif
|
||||
#ifdef B600
|
||||
{B600, SERIAL_BAUD_600},
|
||||
{B600, CBR_600, BAUD_600},
|
||||
#endif
|
||||
#ifdef B1200
|
||||
{B1200, SERIAL_BAUD_1200},
|
||||
{B1200, CBR_1200, BAUD_1200},
|
||||
#endif
|
||||
#ifdef B1800
|
||||
{B1800, SERIAL_BAUD_1800},
|
||||
{B1800, 1800, BAUD_1800},
|
||||
#endif
|
||||
#ifdef B2400
|
||||
{B2400, SERIAL_BAUD_2400},
|
||||
{B2400, CBR_2400, BAUD_2400},
|
||||
#endif
|
||||
#ifdef B4800
|
||||
{B4800, SERIAL_BAUD_4800},
|
||||
{B4800, CBR_4800, BAUD_4800},
|
||||
#endif
|
||||
/* {, SERIAL_BAUD_7200} /\* undefined on Linux *\/ */
|
||||
/* {, ,BAUD_7200} */
|
||||
#ifdef B9600
|
||||
{B9600, SERIAL_BAUD_9600},
|
||||
{B9600, CBR_9600, BAUD_9600},
|
||||
#endif
|
||||
/* {, SERIAL_BAUD_14400} /\* undefined on Linux *\/ */
|
||||
/* {, CBR_14400, BAUD_14400}, /\* unsupported on Linux *\/ */
|
||||
#ifdef B19200
|
||||
{B19200, SERIAL_BAUD_19200},
|
||||
{B19200, CBR_19200, BAUD_19200},
|
||||
#endif
|
||||
#ifdef B38400
|
||||
{B38400, SERIAL_BAUD_38400},
|
||||
{B38400, CBR_38400, BAUD_38400},
|
||||
#endif
|
||||
/* {, SERIAL_BAUD_56K}, /\* undefined on Linux *\/ */
|
||||
/* {, CBR_56000, BAUD_56K}, /\* unsupported on Linux *\/ */
|
||||
#ifdef B57600
|
||||
{B57600, SERIAL_BAUD_57600},
|
||||
{B57600, CBR_57600, BAUD_57600},
|
||||
#endif
|
||||
/* {, SERIAL_BAUD_128K} /\* undefined on Linux *\/ */
|
||||
#ifdef B115200
|
||||
{B115200, SERIAL_BAUD_115200}, /* _SERIAL_MAX_BAUD */
|
||||
{B115200, CBR_115200, BAUD_115200},
|
||||
#endif
|
||||
|
||||
/* no greater speed defined by serial.sys */
|
||||
/* {, CBR_128000, BAUD_128K}, /\* unsupported on Linux *\/ */
|
||||
/* {, CBR_256000, BAUD_USER}, /\* unsupported on Linux *\/ */
|
||||
#ifdef B230400
|
||||
{B230400, 230400, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B460800
|
||||
{B460800, 460800, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B500000
|
||||
{B500000, 500000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B576000
|
||||
{B576000, 576000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B921600
|
||||
{B921600, 921600, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B1000000
|
||||
{B1000000, 1000000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B1152000
|
||||
{B1152000, 1152000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B1500000
|
||||
{B1500000, 1500000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B2000000
|
||||
{B2000000, 2000000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B2500000
|
||||
{B2500000, 2500000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B3000000
|
||||
{B3000000, 3000000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B3500000
|
||||
{B3500000, 3500000, BAUD_USER},
|
||||
#endif
|
||||
#ifdef B4000000
|
||||
{B4000000, 4000000, BAUD_USER}, /* __MAX_BAUD */
|
||||
#endif
|
||||
{_BAUD_TABLE_END, 0, 0}
|
||||
};
|
||||
|
||||
#define _SERIAL_MAX_BAUD B115200
|
||||
|
||||
|
||||
static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties)
|
||||
{
|
||||
@ -142,7 +180,8 @@ static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties)
|
||||
pProperties->dwMaxTxQueue = N_TTY_BUF_SIZE;
|
||||
pProperties->dwMaxRxQueue = N_TTY_BUF_SIZE;
|
||||
|
||||
pProperties->dwMaxBaud = SERIAL_BAUD_115200; /* _SERIAL_MAX_BAUD */
|
||||
/* FIXME: to be probe on the device? */
|
||||
pProperties->dwMaxBaud = BAUD_USER;
|
||||
|
||||
/* FIXME: what about PST_RS232? see also: serial_struct */
|
||||
pProperties->dwProvSubType = PST_UNSPECIFIED;
|
||||
@ -156,9 +195,9 @@ static BOOL _get_properties(WINPR_COMM *pComm, COMMPROP *pProperties)
|
||||
pProperties->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY | SP_PARITY_CHECK | /*SP_RLSD |*/ SP_STOPBITS;
|
||||
|
||||
pProperties->dwSettableBaud = 0;
|
||||
for (i=0; _SERIAL_SYS_BAUD_TABLE[i][0]<=_SERIAL_MAX_BAUD; i++)
|
||||
for (i=0; _BAUD_TABLE[i][0]<_BAUD_TABLE_END; i++)
|
||||
{
|
||||
pProperties->dwSettableBaud |= _SERIAL_SYS_BAUD_TABLE[i][1];
|
||||
pProperties->dwSettableBaud |= _BAUD_TABLE[i][2];
|
||||
}
|
||||
|
||||
pProperties->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 /*| DATABITS_16 | DATABITS_16X*/;
|
||||
@ -180,27 +219,29 @@ static BOOL _set_baud_rate(WINPR_COMM *pComm, const SERIAL_BAUD_RATE *pBaudRate)
|
||||
{
|
||||
int i;
|
||||
speed_t newSpeed;
|
||||
struct termios upcomingTermios;
|
||||
struct termios futureState;
|
||||
|
||||
ZeroMemory(&upcomingTermios, sizeof(struct termios));
|
||||
if (tcgetattr(pComm->fd, &upcomingTermios) < 0)
|
||||
ZeroMemory(&futureState, sizeof(struct termios));
|
||||
if (tcgetattr(pComm->fd, &futureState) < 0) /* NB: preserves current settings not directly handled by the Communication Functions */
|
||||
{
|
||||
SetLastError(ERROR_IO_DEVICE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i=0; _SERIAL_SYS_BAUD_TABLE[i][0]<=_SERIAL_MAX_BAUD; i++)
|
||||
for (i=0; _BAUD_TABLE[i][0]<_BAUD_TABLE_END; i++)
|
||||
{
|
||||
if (_SERIAL_SYS_BAUD_TABLE[i][1] == pBaudRate->BaudRate)
|
||||
if (_BAUD_TABLE[i][1] == pBaudRate->BaudRate)
|
||||
{
|
||||
newSpeed = _SERIAL_SYS_BAUD_TABLE[i][0];
|
||||
if (cfsetspeed(&upcomingTermios, newSpeed) < 0)
|
||||
newSpeed = _BAUD_TABLE[i][0];
|
||||
if (cfsetspeed(&futureState, newSpeed) < 0)
|
||||
{
|
||||
CommLog_Print(WLOG_WARN, "failed to set speed %u (%lu)", newSpeed, pBaudRate->BaudRate);
|
||||
CommLog_Print(WLOG_WARN, "failed to set speed 0x%x (%lu)", newSpeed, pBaudRate->BaudRate);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &upcomingTermios) < 0)
|
||||
assert(cfgetispeed(&futureState) == newSpeed);
|
||||
|
||||
if (_comm_ioctl_tcsetattr(pComm->fd, TCSANOW, &futureState) < 0)
|
||||
{
|
||||
CommLog_Print(WLOG_WARN, "_comm_ioctl_tcsetattr failure: last-error: 0x%lX", GetLastError());
|
||||
return FALSE;
|
||||
@ -231,11 +272,11 @@ static BOOL _get_baud_rate(WINPR_COMM *pComm, SERIAL_BAUD_RATE *pBaudRate)
|
||||
|
||||
currentSpeed = cfgetispeed(¤tState);
|
||||
|
||||
for (i=0; _SERIAL_SYS_BAUD_TABLE[i][0]<=_SERIAL_MAX_BAUD; i++)
|
||||
for (i=0; _BAUD_TABLE[i][0]<_BAUD_TABLE_END; i++)
|
||||
{
|
||||
if (_SERIAL_SYS_BAUD_TABLE[i][0] == currentSpeed)
|
||||
if (_BAUD_TABLE[i][0] == currentSpeed)
|
||||
{
|
||||
pBaudRate->BaudRate = _SERIAL_SYS_BAUD_TABLE[i][1];
|
||||
pBaudRate->BaudRate = _BAUD_TABLE[i][1];
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -245,6 +286,7 @@ static BOOL _get_baud_rate(WINPR_COMM *pComm, SERIAL_BAUD_RATE *pBaudRate)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NOTE: Only XonChar and XoffChar are plenty supported with the Linux
|
||||
* N_TTY line discipline.
|
||||
|
@ -132,76 +132,6 @@ static BOOL test_SerialSys(HANDLE hComm)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Test 1 */
|
||||
dcb.BaudRate = SERIAL_BAUD_115200;
|
||||
result = SetCommState(hComm, &dcb);
|
||||
if (!result)
|
||||
{
|
||||
fprintf(stderr, "SetCommState failure: 0x%08x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
init_empty_dcb(&dcb);
|
||||
result = GetCommState(hComm, &dcb);
|
||||
if (!result)
|
||||
{
|
||||
fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (dcb.BaudRate != SERIAL_BAUD_115200)
|
||||
{
|
||||
fprintf(stderr, "SetCommState failure: could not set BaudRate=%d (SERIAL_BAUD_115200)\n", SERIAL_BAUD_115200);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Test 2 using a defferent baud rate */
|
||||
|
||||
dcb.BaudRate = SERIAL_BAUD_57600;
|
||||
result = SetCommState(hComm, &dcb);
|
||||
if (!result)
|
||||
{
|
||||
fprintf(stderr, "SetCommState failure: 0x%x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
init_empty_dcb(&dcb);
|
||||
result = GetCommState(hComm, &dcb);
|
||||
if (!result)
|
||||
{
|
||||
fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (dcb.BaudRate != SERIAL_BAUD_57600)
|
||||
{
|
||||
fprintf(stderr, "SetCommState failure: could not set BaudRate=%d (SERIAL_BAUD_57600)\n", SERIAL_BAUD_57600);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Test 3 using an unsupported baud rate on Linux */
|
||||
dcb.BaudRate = SERIAL_BAUD_128K;
|
||||
result = SetCommState(hComm, &dcb);
|
||||
if (result)
|
||||
{
|
||||
fprintf(stderr, "SetCommState failure: unexpected support of BaudRate=%d (SERIAL_BAUD_128K)\n", SERIAL_BAUD_128K);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL test_SerCxSys(HANDLE hComm)
|
||||
{
|
||||
DCB dcb;
|
||||
BOOL result;
|
||||
|
||||
init_empty_dcb(&dcb);
|
||||
result = GetCommState(hComm, &dcb);
|
||||
if (!result)
|
||||
{
|
||||
fprintf(stderr, "GetCommState failure: 0x%x\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Test 1 */
|
||||
dcb.BaudRate = CBR_115200;
|
||||
result = SetCommState(hComm, &dcb);
|
||||
@ -259,11 +189,16 @@ static BOOL test_SerCxSys(HANDLE hComm)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL test_SerCxSys(HANDLE hComm)
|
||||
{
|
||||
/* as of today there is no difference */
|
||||
return test_SerialSys(hComm);
|
||||
}
|
||||
|
||||
static BOOL test_SerCx2Sys(HANDLE hComm)
|
||||
{
|
||||
/* as of today there is no difference */
|
||||
return test_SerCxSys(hComm);
|
||||
return test_SerialSys(hComm);
|
||||
}
|
||||
|
||||
static BOOL test_generic(HANDLE hComm)
|
||||
|
@ -306,7 +306,7 @@ BOOL LinkedList_Enumerator_MoveNext(wLinkedList* list)
|
||||
{
|
||||
if (list->initial)
|
||||
list->initial = 0;
|
||||
else
|
||||
else if (list->current)
|
||||
list->current = list->current->next;
|
||||
|
||||
if (!list->current)
|
||||
|
@ -109,6 +109,33 @@ int TestLinkedList(int argc, char* argv[])
|
||||
|
||||
LinkedList_Free(list);
|
||||
|
||||
/* Test enumerator robustness */
|
||||
|
||||
/* enumerator on an empty list */
|
||||
list = LinkedList_New();
|
||||
LinkedList_Enumerator_Reset(list);
|
||||
while (LinkedList_Enumerator_MoveNext(list))
|
||||
{
|
||||
number = (int) (size_t) LinkedList_Enumerator_Current(list);
|
||||
printf("\t%d\n", number);
|
||||
}
|
||||
printf("\n");
|
||||
LinkedList_Free(list);
|
||||
|
||||
/* Use an enumerator without reset */
|
||||
list = LinkedList_New();
|
||||
LinkedList_AddFirst(list, (void*) (size_t) 4);
|
||||
LinkedList_AddLast(list, (void*) (size_t) 5);
|
||||
LinkedList_AddLast(list, (void*) (size_t) 6);
|
||||
while (LinkedList_Enumerator_MoveNext(list))
|
||||
{
|
||||
number = (int) (size_t) LinkedList_Enumerator_Current(list);
|
||||
printf("\t%d\n", number);
|
||||
}
|
||||
printf("\n");
|
||||
LinkedList_Free(list);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user