/src/FreeRDP/winpr/libwinpr/comm/comm_sercx2_sys.c
Line | Count | Source (jump to first uncovered line) |
1 | | /** |
2 | | * WinPR: Windows Portable Runtime |
3 | | * Serial Communication API |
4 | | * |
5 | | * Copyright 2011 O.S. Systems Software Ltda. |
6 | | * Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br> |
7 | | * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com> |
8 | | * Copyright 2014 Hewlett-Packard Development Company, L.P. |
9 | | * |
10 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
11 | | * you may not use this file except in compliance with the License. |
12 | | * You may obtain a copy of the License at |
13 | | * |
14 | | * http://www.apache.org/licenses/LICENSE-2.0 |
15 | | * |
16 | | * Unless required by applicable law or agreed to in writing, software |
17 | | * distributed under the License is distributed on an "AS IS" BASIS, |
18 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
19 | | * See the License for the specific language governing permissions and |
20 | | * limitations under the License. |
21 | | */ |
22 | | |
23 | | #if defined __linux__ && !defined ANDROID |
24 | | |
25 | | #include <winpr/wlog.h> |
26 | | |
27 | | #include "comm_serial_sys.h" |
28 | | #include "comm_sercx_sys.h" |
29 | | |
30 | | #include "comm_sercx2_sys.h" |
31 | | |
32 | | /* http://msdn.microsoft.com/en-us/library/dn265347%28v=vs.85%29.aspx |
33 | | * |
34 | | * SerCx2 does not support special characters. SerCx2 always completes |
35 | | * an IOCTL_SERIAL_SET_CHARS request with a STATUS_SUCCESS status |
36 | | * code, but does not set any special characters or perform any other |
37 | | * operation in response to this request. For an |
38 | | * IOCTL_SERIAL_GET_CHARS request, SerCx2 sets all the character |
39 | | * values in the SERIAL_CHARS structure to null, and completes the |
40 | | * request with a STATUS_SUCCESS status code. |
41 | | */ |
42 | | |
43 | | static BOOL _set_serial_chars(WINPR_COMM* pComm, const SERIAL_CHARS* pSerialChars) |
44 | 0 | { |
45 | 0 | return TRUE; |
46 | 0 | } |
47 | | |
48 | | static BOOL _get_serial_chars(WINPR_COMM* pComm, SERIAL_CHARS* pSerialChars) |
49 | 0 | { |
50 | 0 | WINPR_ASSERT(pSerialChars); |
51 | 0 | ZeroMemory(pSerialChars, sizeof(SERIAL_CHARS)); |
52 | 0 | return TRUE; |
53 | 0 | } |
54 | | |
55 | | /* http://msdn.microsoft.com/en-us/library/windows/hardware/hh439605%28v=vs.85%29.aspx */ |
56 | | /* FIXME: only using the Serial.sys' events, complete the support of the remaining events */ |
57 | | static const ULONG _SERCX2_SYS_SUPPORTED_EV_MASK = |
58 | | SERIAL_EV_RXCHAR | SERIAL_EV_RXFLAG | SERIAL_EV_TXEMPTY | SERIAL_EV_CTS | SERIAL_EV_DSR | |
59 | | SERIAL_EV_RLSD | SERIAL_EV_BREAK | SERIAL_EV_ERR | SERIAL_EV_RING | |
60 | | /* SERIAL_EV_PERR | */ |
61 | | SERIAL_EV_RX80FULL /*| |
62 | | SERIAL_EV_EVENT1 | |
63 | | SERIAL_EV_EVENT2*/ |
64 | | ; |
65 | | |
66 | | /* use Serial.sys for basis (not SerCx.sys) */ |
67 | | static BOOL _set_wait_mask(WINPR_COMM* pComm, const ULONG* pWaitMask) |
68 | 0 | { |
69 | 0 | ULONG possibleMask = 0; |
70 | 0 | SERIAL_DRIVER* pSerialSys = SerialSys_s(); |
71 | |
|
72 | 0 | possibleMask = *pWaitMask & _SERCX2_SYS_SUPPORTED_EV_MASK; |
73 | |
|
74 | 0 | if (possibleMask != *pWaitMask) |
75 | 0 | { |
76 | 0 | CommLog_Print(WLOG_WARN, |
77 | 0 | "Not all wait events supported (SerCx2.sys), requested events= 0x%08" PRIX32 |
78 | 0 | ", possible events= 0x%08" PRIX32 "", |
79 | 0 | *pWaitMask, possibleMask); |
80 | | |
81 | | /* FIXME: shall we really set the possibleMask and return FALSE? */ |
82 | 0 | pComm->WaitEventMask = possibleMask; |
83 | 0 | return FALSE; |
84 | 0 | } |
85 | | |
86 | | /* NB: All events that are supported by SerCx.sys are supported by Serial.sys*/ |
87 | 0 | return pSerialSys->set_wait_mask(pComm, pWaitMask); |
88 | 0 | } |
89 | | |
90 | | static BOOL _purge(WINPR_COMM* pComm, const ULONG* pPurgeMask) |
91 | 0 | { |
92 | 0 | SERIAL_DRIVER* pSerialSys = SerialSys_s(); |
93 | | |
94 | | /* http://msdn.microsoft.com/en-us/library/windows/hardware/ff546655%28v=vs.85%29.aspx */ |
95 | |
|
96 | 0 | if ((*pPurgeMask & SERIAL_PURGE_RXCLEAR) && !(*pPurgeMask & SERIAL_PURGE_RXABORT)) |
97 | 0 | { |
98 | 0 | CommLog_Print(WLOG_WARN, |
99 | 0 | "Expecting SERIAL_PURGE_RXABORT since SERIAL_PURGE_RXCLEAR is set"); |
100 | 0 | SetLastError(ERROR_INVALID_DEVICE_OBJECT_PARAMETER); |
101 | 0 | return FALSE; |
102 | 0 | } |
103 | | |
104 | 0 | if ((*pPurgeMask & SERIAL_PURGE_TXCLEAR) && !(*pPurgeMask & SERIAL_PURGE_TXABORT)) |
105 | 0 | { |
106 | 0 | CommLog_Print(WLOG_WARN, |
107 | 0 | "Expecting SERIAL_PURGE_TXABORT since SERIAL_PURGE_TXCLEAR is set"); |
108 | 0 | SetLastError(ERROR_INVALID_DEVICE_OBJECT_PARAMETER); |
109 | 0 | return FALSE; |
110 | 0 | } |
111 | | |
112 | 0 | return pSerialSys->purge(pComm, pPurgeMask); |
113 | 0 | } |
114 | | |
115 | | /* specific functions only */ |
116 | | static SERIAL_DRIVER _SerCx2Sys = { |
117 | | .id = SerialDriverSerCx2Sys, |
118 | | .name = _T("SerCx2.sys"), |
119 | | .set_baud_rate = NULL, |
120 | | .get_baud_rate = NULL, |
121 | | .get_properties = NULL, |
122 | | .set_serial_chars = _set_serial_chars, |
123 | | .get_serial_chars = _get_serial_chars, |
124 | | .set_line_control = NULL, |
125 | | .get_line_control = NULL, |
126 | | .set_handflow = NULL, |
127 | | .get_handflow = NULL, |
128 | | .set_timeouts = NULL, |
129 | | .get_timeouts = NULL, |
130 | | .set_dtr = NULL, |
131 | | .clear_dtr = NULL, |
132 | | .set_rts = NULL, |
133 | | .clear_rts = NULL, |
134 | | .get_modemstatus = NULL, |
135 | | .set_wait_mask = _set_wait_mask, |
136 | | .get_wait_mask = NULL, |
137 | | .wait_on_mask = NULL, |
138 | | .set_queue_size = NULL, |
139 | | .purge = _purge, |
140 | | .get_commstatus = NULL, |
141 | | .set_break_on = NULL, |
142 | | .set_break_off = NULL, |
143 | | .set_xoff = NULL, /* not supported by SerCx2.sys */ |
144 | | .set_xon = NULL, /* not supported by SerCx2.sys */ |
145 | | .get_dtrrts = NULL, |
146 | | .config_size = NULL, /* not supported by SerCx2.sys */ |
147 | | .immediate_char = NULL, /* not supported by SerCx2.sys */ |
148 | | .reset_device = NULL, /* not supported by SerCx2.sys */ |
149 | | }; |
150 | | |
151 | | SERIAL_DRIVER* SerCx2Sys_s(void) |
152 | 0 | { |
153 | | /* _SerCx2Sys completed with inherited functions from SerialSys or SerCxSys */ |
154 | 0 | SERIAL_DRIVER* pSerialSys = SerialSys_s(); |
155 | 0 | SERIAL_DRIVER* pSerCxSys = SerCxSys_s(); |
156 | 0 | if (!pSerialSys || !pSerCxSys) |
157 | 0 | return NULL; |
158 | | |
159 | 0 | _SerCx2Sys.set_baud_rate = pSerialSys->set_baud_rate; |
160 | 0 | _SerCx2Sys.get_baud_rate = pSerialSys->get_baud_rate; |
161 | |
|
162 | 0 | _SerCx2Sys.get_properties = pSerialSys->get_properties; |
163 | |
|
164 | 0 | _SerCx2Sys.set_line_control = pSerCxSys->set_line_control; |
165 | 0 | _SerCx2Sys.get_line_control = pSerCxSys->get_line_control; |
166 | | |
167 | | /* Only SERIAL_CTS_HANDSHAKE, SERIAL_RTS_CONTROL and SERIAL_RTS_HANDSHAKE flags are really |
168 | | * required by SerCx2.sys http://msdn.microsoft.com/en-us/library/jj680685%28v=vs.85%29.aspx |
169 | | */ |
170 | 0 | _SerCx2Sys.set_handflow = pSerialSys->set_handflow; |
171 | 0 | _SerCx2Sys.get_handflow = pSerialSys->get_handflow; |
172 | |
|
173 | 0 | _SerCx2Sys.set_timeouts = pSerialSys->set_timeouts; |
174 | 0 | _SerCx2Sys.get_timeouts = pSerialSys->get_timeouts; |
175 | |
|
176 | 0 | _SerCx2Sys.set_dtr = pSerialSys->set_dtr; |
177 | 0 | _SerCx2Sys.clear_dtr = pSerialSys->clear_dtr; |
178 | |
|
179 | 0 | _SerCx2Sys.set_rts = pSerialSys->set_rts; |
180 | 0 | _SerCx2Sys.clear_rts = pSerialSys->clear_rts; |
181 | |
|
182 | 0 | _SerCx2Sys.get_modemstatus = pSerialSys->get_modemstatus; |
183 | |
|
184 | 0 | _SerCx2Sys.set_wait_mask = pSerialSys->set_wait_mask; |
185 | 0 | _SerCx2Sys.get_wait_mask = pSerialSys->get_wait_mask; |
186 | 0 | _SerCx2Sys.wait_on_mask = pSerialSys->wait_on_mask; |
187 | |
|
188 | 0 | _SerCx2Sys.set_queue_size = pSerialSys->set_queue_size; |
189 | |
|
190 | 0 | _SerCx2Sys.get_commstatus = pSerialSys->get_commstatus; |
191 | |
|
192 | 0 | _SerCx2Sys.set_break_on = pSerialSys->set_break_on; |
193 | 0 | _SerCx2Sys.set_break_off = pSerialSys->set_break_off; |
194 | |
|
195 | 0 | _SerCx2Sys.get_dtrrts = pSerialSys->get_dtrrts; |
196 | |
|
197 | 0 | return &_SerCx2Sys; |
198 | 0 | } |
199 | | |
200 | | #endif /* __linux__ */ |