/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 | | #include <winpr/assert.h> |
24 | | #include <winpr/wlog.h> |
25 | | |
26 | | #include "comm_serial_sys.h" |
27 | | #include "comm_sercx_sys.h" |
28 | | |
29 | | #include "comm_sercx2_sys.h" |
30 | | |
31 | | /* http://msdn.microsoft.com/en-us/library/dn265347%28v=vs.85%29.aspx |
32 | | * |
33 | | * SerCx2 does not support special characters. SerCx2 always completes |
34 | | * an IOCTL_SERIAL_SET_CHARS request with a STATUS_SUCCESS status |
35 | | * code, but does not set any special characters or perform any other |
36 | | * operation in response to this request. For an |
37 | | * IOCTL_SERIAL_GET_CHARS request, SerCx2 sets all the character |
38 | | * values in the SERIAL_CHARS structure to null, and completes the |
39 | | * request with a STATUS_SUCCESS status code. |
40 | | */ |
41 | | |
42 | | static BOOL set_serial_chars(WINPR_ATTR_UNUSED WINPR_COMM* pComm, |
43 | | WINPR_ATTR_UNUSED const SERIAL_CHARS* pSerialChars) |
44 | 0 | { |
45 | 0 | WINPR_ASSERT(pComm); |
46 | 0 | WINPR_ASSERT(pSerialChars); |
47 | | |
48 | 0 | return TRUE; |
49 | 0 | } |
50 | | |
51 | | static BOOL get_serial_chars(WINPR_ATTR_UNUSED WINPR_COMM* pComm, SERIAL_CHARS* pSerialChars) |
52 | 0 | { |
53 | 0 | WINPR_ASSERT(pComm); |
54 | 0 | WINPR_ASSERT(pSerialChars); |
55 | | |
56 | 0 | ZeroMemory(pSerialChars, sizeof(SERIAL_CHARS)); |
57 | 0 | return TRUE; |
58 | 0 | } |
59 | | |
60 | | /* http://msdn.microsoft.com/en-us/library/windows/hardware/hh439605%28v=vs.85%29.aspx */ |
61 | | /* FIXME: only using the Serial.sys' events, complete the support of the remaining events */ |
62 | | static const ULONG SERCX2_SYS_SUPPORTED_EV_MASK = |
63 | | SERIAL_EV_RXCHAR | SERIAL_EV_RXFLAG | SERIAL_EV_TXEMPTY | SERIAL_EV_CTS | SERIAL_EV_DSR | |
64 | | SERIAL_EV_RLSD | SERIAL_EV_BREAK | SERIAL_EV_ERR | SERIAL_EV_RING | |
65 | | /* SERIAL_EV_PERR | */ |
66 | | SERIAL_EV_RX80FULL /*| |
67 | | SERIAL_EV_EVENT1 | |
68 | | SERIAL_EV_EVENT2*/ |
69 | | ; |
70 | | |
71 | | /* use Serial.sys for basis (not SerCx.sys) */ |
72 | | static BOOL set_wait_mask(WINPR_COMM* pComm, const ULONG* pWaitMask) |
73 | 0 | { |
74 | 0 | const SERIAL_DRIVER* pSerialSys = SerialSys_s(); |
75 | |
|
76 | 0 | WINPR_ASSERT(pComm); |
77 | 0 | WINPR_ASSERT(pWaitMask); |
78 | 0 | WINPR_ASSERT(pSerialSys); |
79 | | |
80 | 0 | const ULONG possibleMask = *pWaitMask & SERCX2_SYS_SUPPORTED_EV_MASK; |
81 | |
|
82 | 0 | if (possibleMask != *pWaitMask) |
83 | 0 | { |
84 | 0 | CommLog_Print(WLOG_WARN, |
85 | 0 | "Not all wait events supported (SerCx2.sys), requested events= 0x%08" PRIX32 |
86 | 0 | ", possible events= 0x%08" PRIX32 "", |
87 | 0 | *pWaitMask, possibleMask); |
88 | | |
89 | | /* FIXME: shall we really set the possibleMask and return FALSE? */ |
90 | 0 | pComm->WaitEventMask = possibleMask; |
91 | 0 | return FALSE; |
92 | 0 | } |
93 | | |
94 | | /* NB: All events that are supported by SerCx.sys are supported by Serial.sys*/ |
95 | 0 | return pSerialSys->set_wait_mask(pComm, pWaitMask); |
96 | 0 | } |
97 | | |
98 | | static BOOL purge(WINPR_COMM* pComm, const ULONG* pPurgeMask) |
99 | 0 | { |
100 | 0 | const SERIAL_DRIVER* pSerialSys = SerialSys_s(); |
101 | |
|
102 | 0 | WINPR_ASSERT(pComm); |
103 | 0 | WINPR_ASSERT(pPurgeMask); |
104 | 0 | WINPR_ASSERT(pSerialSys); |
105 | | |
106 | | /* http://msdn.microsoft.com/en-us/library/windows/hardware/ff546655%28v=vs.85%29.aspx */ |
107 | | |
108 | 0 | if ((*pPurgeMask & SERIAL_PURGE_RXCLEAR) && !(*pPurgeMask & SERIAL_PURGE_RXABORT)) |
109 | 0 | { |
110 | 0 | CommLog_Print(WLOG_WARN, |
111 | 0 | "Expecting SERIAL_PURGE_RXABORT since SERIAL_PURGE_RXCLEAR is set"); |
112 | 0 | SetLastError(ERROR_INVALID_DEVICE_OBJECT_PARAMETER); |
113 | 0 | return FALSE; |
114 | 0 | } |
115 | | |
116 | 0 | if ((*pPurgeMask & SERIAL_PURGE_TXCLEAR) && !(*pPurgeMask & SERIAL_PURGE_TXABORT)) |
117 | 0 | { |
118 | 0 | CommLog_Print(WLOG_WARN, |
119 | 0 | "Expecting SERIAL_PURGE_TXABORT since SERIAL_PURGE_TXCLEAR is set"); |
120 | 0 | SetLastError(ERROR_INVALID_DEVICE_OBJECT_PARAMETER); |
121 | 0 | return FALSE; |
122 | 0 | } |
123 | | |
124 | 0 | return pSerialSys->purge(pComm, pPurgeMask); |
125 | 0 | } |
126 | | |
127 | | /* specific functions only */ |
128 | | static SERIAL_DRIVER SerCx2Sys = { |
129 | | .id = SerialDriverSerCx2Sys, |
130 | | .name = _T("SerCx2.sys"), |
131 | | .set_baud_rate = NULL, |
132 | | .get_baud_rate = NULL, |
133 | | .get_properties = NULL, |
134 | | .set_serial_chars = set_serial_chars, |
135 | | .get_serial_chars = get_serial_chars, |
136 | | .set_line_control = NULL, |
137 | | .get_line_control = NULL, |
138 | | .set_handflow = NULL, |
139 | | .get_handflow = NULL, |
140 | | .set_timeouts = NULL, |
141 | | .get_timeouts = NULL, |
142 | | .set_dtr = NULL, |
143 | | .clear_dtr = NULL, |
144 | | .set_rts = NULL, |
145 | | .clear_rts = NULL, |
146 | | .get_modemstatus = NULL, |
147 | | .set_wait_mask = set_wait_mask, |
148 | | .get_wait_mask = NULL, |
149 | | .wait_on_mask = NULL, |
150 | | .set_queue_size = NULL, |
151 | | .purge = purge, |
152 | | .get_commstatus = NULL, |
153 | | .set_break_on = NULL, |
154 | | .set_break_off = NULL, |
155 | | .set_xoff = NULL, /* not supported by SerCx2.sys */ |
156 | | .set_xon = NULL, /* not supported by SerCx2.sys */ |
157 | | .get_dtrrts = NULL, |
158 | | .config_size = NULL, /* not supported by SerCx2.sys */ |
159 | | .immediate_char = NULL, /* not supported by SerCx2.sys */ |
160 | | .reset_device = NULL, /* not supported by SerCx2.sys */ |
161 | | }; |
162 | | |
163 | | const SERIAL_DRIVER* SerCx2Sys_s(void) |
164 | 0 | { |
165 | | /* SerCx2Sys completed with inherited functions from SerialSys or SerCxSys */ |
166 | 0 | const SERIAL_DRIVER* pSerialSys = SerialSys_s(); |
167 | 0 | const SERIAL_DRIVER* pSerCxSys = SerCxSys_s(); |
168 | 0 | if (!pSerialSys || !pSerCxSys) |
169 | 0 | return NULL; |
170 | | |
171 | 0 | SerCx2Sys.set_baud_rate = pSerialSys->set_baud_rate; |
172 | 0 | SerCx2Sys.get_baud_rate = pSerialSys->get_baud_rate; |
173 | |
|
174 | 0 | SerCx2Sys.get_properties = pSerialSys->get_properties; |
175 | |
|
176 | 0 | SerCx2Sys.set_line_control = pSerCxSys->set_line_control; |
177 | 0 | SerCx2Sys.get_line_control = pSerCxSys->get_line_control; |
178 | | |
179 | | /* Only SERIAL_CTS_HANDSHAKE, SERIAL_RTS_CONTROL and SERIAL_RTS_HANDSHAKE flags are really |
180 | | * required by SerCx2.sys http://msdn.microsoft.com/en-us/library/jj680685%28v=vs.85%29.aspx |
181 | | */ |
182 | 0 | SerCx2Sys.set_handflow = pSerialSys->set_handflow; |
183 | 0 | SerCx2Sys.get_handflow = pSerialSys->get_handflow; |
184 | |
|
185 | 0 | SerCx2Sys.set_timeouts = pSerialSys->set_timeouts; |
186 | 0 | SerCx2Sys.get_timeouts = pSerialSys->get_timeouts; |
187 | |
|
188 | 0 | SerCx2Sys.set_dtr = pSerialSys->set_dtr; |
189 | 0 | SerCx2Sys.clear_dtr = pSerialSys->clear_dtr; |
190 | |
|
191 | 0 | SerCx2Sys.set_rts = pSerialSys->set_rts; |
192 | 0 | SerCx2Sys.clear_rts = pSerialSys->clear_rts; |
193 | |
|
194 | 0 | SerCx2Sys.get_modemstatus = pSerialSys->get_modemstatus; |
195 | |
|
196 | 0 | SerCx2Sys.set_wait_mask = pSerialSys->set_wait_mask; |
197 | 0 | SerCx2Sys.get_wait_mask = pSerialSys->get_wait_mask; |
198 | 0 | SerCx2Sys.wait_on_mask = pSerialSys->wait_on_mask; |
199 | |
|
200 | 0 | SerCx2Sys.set_queue_size = pSerialSys->set_queue_size; |
201 | |
|
202 | 0 | SerCx2Sys.get_commstatus = pSerialSys->get_commstatus; |
203 | |
|
204 | 0 | SerCx2Sys.set_break_on = pSerialSys->set_break_on; |
205 | 0 | SerCx2Sys.set_break_off = pSerialSys->set_break_off; |
206 | |
|
207 | 0 | SerCx2Sys.get_dtrrts = pSerialSys->get_dtrrts; |
208 | |
|
209 | 0 | return &SerCx2Sys; |
210 | 0 | } |