serialport 1.0.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,99 +1,99 @@
1
- /* Ruby/SerialPort
2
- * Guillaume Pierronnet <moumar@netcourrier.com>
3
- * Alan Stern <stern@rowland.harvard.edu>
4
- * Daniel E. Shipton <dshipton@redshiptechnologies.com>
5
- * Tobin Richard <tobin.richard@gmail.com>
6
- * Ryan C. Payne <rpayne-oss@bullittsystems.com>
7
- *
8
- * This code is hereby licensed for public consumption under either the
9
- * GNU GPL v2 or greater.
10
- *
11
- * You should have received a copy of the GNU General Public License
12
- * along with this program; if not, write to the Free Software
13
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14
- *
15
- * For documentation on serial programming, see the excellent:
16
- * "Serial Programming Guide for POSIX Operating Systems"
17
- * written Michael R. Sweet.
18
- * http://www.easysw.com/~mike/serial/
19
- */
20
-
21
- #ifndef _RUBY_SERIAL_PORT_H_
22
- #define _RUBY_SERIAL_PORT_H_
23
-
24
- #define RUBY_SERIAL_PORT_VERSION "1.0.4"
25
-
26
- #include <ruby.h> /* ruby inclusion */
27
- #ifdef RUBY_1_9 /* ruby io inclusion */
28
- #include <ruby/io.h>
29
- #else
30
- #include <rubyio.h>
31
- #endif
32
-
33
- struct modem_params
34
- {
35
- int data_rate;
36
- int data_bits;
37
- int stop_bits;
38
- int parity;
39
- };
40
-
41
- struct line_signals
42
- {
43
- int rts;
44
- int dtr;
45
- int cts;
46
- int dsr;
47
- int dcd;
48
- int ri;
49
- };
50
-
51
- #define NONE 0
52
- #define HARD 1
53
- #define SOFT 2
54
-
55
- #if defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW)
56
- #define SPACE SPACEPARITY
57
- #define MARK MARKPARITY
58
- #define EVEN EVENPARITY
59
- #define ODD ODDPARITY
60
-
61
- #ifndef RB_SERIAL_EXPORT
62
- #ifndef RUBY_1_9
63
- #define RB_SERIAL_EXPORT __declspec(dllexport)
64
- #else
65
- #define RB_SERIAL_EXPORT
66
- #endif
67
- #endif
68
-
69
- #else
70
- #define SPACE 0
71
- #define MARK 0
72
- #define EVEN 1
73
- #define ODD 2
74
-
75
- #define RB_SERIAL_EXPORT
76
- #endif
77
-
78
- extern VALUE sBaud, sDataBits, sStopBits, sParity; /* strings */
79
- extern VALUE sRts, sDtr, sCts, sDsr, sDcd, sRi;
80
-
81
- /* Implementation specific functions. */
82
- VALUE RB_SERIAL_EXPORT sp_create_impl(VALUE class, VALUE _port);
83
- VALUE RB_SERIAL_EXPORT sp_set_modem_params_impl(int argc, VALUE *argv, VALUE self);
84
- void RB_SERIAL_EXPORT get_modem_params_impl(VALUE self, struct modem_params *mp);
85
- VALUE RB_SERIAL_EXPORT sp_set_flow_control_impl(VALUE self, VALUE val);
86
- VALUE RB_SERIAL_EXPORT sp_get_flow_control_impl(VALUE self);
87
- VALUE RB_SERIAL_EXPORT sp_set_read_timeout_impl(VALUE self, VALUE val);
88
- VALUE RB_SERIAL_EXPORT sp_get_read_timeout_impl(VALUE self);
89
- VALUE RB_SERIAL_EXPORT sp_set_write_timeout_impl(VALUE self, VALUE val);
90
- VALUE RB_SERIAL_EXPORT sp_get_write_timeout_impl(VALUE self);
91
- VALUE RB_SERIAL_EXPORT sp_break_impl(VALUE self, VALUE time);
92
- void RB_SERIAL_EXPORT get_line_signals_helper_impl(VALUE obj, struct line_signals *ls);
93
- VALUE RB_SERIAL_EXPORT set_signal_impl(VALUE obj, VALUE val, int sig);
94
- VALUE RB_SERIAL_EXPORT sp_set_rts_impl(VALUE self, VALUE val);
95
- VALUE RB_SERIAL_EXPORT sp_set_dtr_impl(VALUE self, VALUE val);
96
- VALUE RB_SERIAL_EXPORT sp_get_rts_impl(VALUE self);
97
- VALUE RB_SERIAL_EXPORT sp_get_dtr_impl(VALUE self);
98
-
99
- #endif
1
+ /* Ruby/SerialPort
2
+ * Guillaume Pierronnet <moumar@netcourrier.com>
3
+ * Alan Stern <stern@rowland.harvard.edu>
4
+ * Daniel E. Shipton <dshipton@redshiptechnologies.com>
5
+ * Tobin Richard <tobin.richard@gmail.com>
6
+ * Ryan C. Payne <rpayne-oss@bullittsystems.com>
7
+ *
8
+ * This code is hereby licensed for public consumption under either the
9
+ * GNU GPL v2 or greater.
10
+ *
11
+ * You should have received a copy of the GNU General Public License
12
+ * along with this program; if not, write to the Free Software
13
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14
+ *
15
+ * For documentation on serial programming, see the excellent:
16
+ * "Serial Programming Guide for POSIX Operating Systems"
17
+ * written Michael R. Sweet.
18
+ * http://www.easysw.com/~mike/serial/
19
+ */
20
+
21
+ #ifndef _RUBY_SERIAL_PORT_H_
22
+ #define _RUBY_SERIAL_PORT_H_
23
+
24
+ #define RUBY_SERIAL_PORT_VERSION "1.0.4"
25
+
26
+ #include <ruby.h> /* ruby inclusion */
27
+ #ifdef HAVE_RUBY_IO_H /* ruby io inclusion */
28
+ #include <ruby/io.h>
29
+ #else
30
+ #include <rubyio.h>
31
+ #endif
32
+
33
+ struct modem_params
34
+ {
35
+ int data_rate;
36
+ int data_bits;
37
+ int stop_bits;
38
+ int parity;
39
+ };
40
+
41
+ struct line_signals
42
+ {
43
+ int rts;
44
+ int dtr;
45
+ int cts;
46
+ int dsr;
47
+ int dcd;
48
+ int ri;
49
+ };
50
+
51
+ #define NONE 0
52
+ #define HARD 1
53
+ #define SOFT 2
54
+
55
+ #if defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW)
56
+ #define SPACE SPACEPARITY
57
+ #define MARK MARKPARITY
58
+ #define EVEN EVENPARITY
59
+ #define ODD ODDPARITY
60
+
61
+ #ifndef RB_SERIAL_EXPORT
62
+ #ifndef HAVE_RUBY_IO_H
63
+ #define RB_SERIAL_EXPORT __declspec(dllexport)
64
+ #else
65
+ #define RB_SERIAL_EXPORT
66
+ #endif
67
+ #endif
68
+
69
+ #else
70
+ #define SPACE 0
71
+ #define MARK 0
72
+ #define EVEN 1
73
+ #define ODD 2
74
+
75
+ #define RB_SERIAL_EXPORT
76
+ #endif
77
+
78
+ extern VALUE sBaud, sDataBits, sStopBits, sParity; /* strings */
79
+ extern VALUE sRts, sDtr, sCts, sDsr, sDcd, sRi;
80
+
81
+ /* Implementation specific functions. */
82
+ VALUE RB_SERIAL_EXPORT sp_create_impl(VALUE class, VALUE _port);
83
+ VALUE RB_SERIAL_EXPORT sp_set_modem_params_impl(int argc, VALUE *argv, VALUE self);
84
+ void RB_SERIAL_EXPORT get_modem_params_impl(VALUE self, struct modem_params *mp);
85
+ VALUE RB_SERIAL_EXPORT sp_set_flow_control_impl(VALUE self, VALUE val);
86
+ VALUE RB_SERIAL_EXPORT sp_get_flow_control_impl(VALUE self);
87
+ VALUE RB_SERIAL_EXPORT sp_set_read_timeout_impl(VALUE self, VALUE val);
88
+ VALUE RB_SERIAL_EXPORT sp_get_read_timeout_impl(VALUE self);
89
+ VALUE RB_SERIAL_EXPORT sp_set_write_timeout_impl(VALUE self, VALUE val);
90
+ VALUE RB_SERIAL_EXPORT sp_get_write_timeout_impl(VALUE self);
91
+ VALUE RB_SERIAL_EXPORT sp_break_impl(VALUE self, VALUE time);
92
+ void RB_SERIAL_EXPORT get_line_signals_helper_impl(VALUE obj, struct line_signals *ls);
93
+ VALUE RB_SERIAL_EXPORT set_signal_impl(VALUE obj, VALUE val, int sig);
94
+ VALUE RB_SERIAL_EXPORT sp_set_rts_impl(VALUE self, VALUE val);
95
+ VALUE RB_SERIAL_EXPORT sp_set_dtr_impl(VALUE self, VALUE val);
96
+ VALUE RB_SERIAL_EXPORT sp_get_rts_impl(VALUE self);
97
+ VALUE RB_SERIAL_EXPORT sp_get_dtr_impl(VALUE self);
98
+
99
+ #endif
@@ -1,627 +1,623 @@
1
- /* Ruby/SerialPort
2
- * Guillaume Pierronnet <moumar@netcourrier.com>
3
- * Alan Stern <stern@rowland.harvard.edu>
4
- * Daniel E. Shipton <dshipton@redshiptechnologies.com>
5
- * Hector G. Parra <hector@hectorparra.com>
6
- *
7
- * This code is hereby licensed for public consumption under either the
8
- * GNU GPL v2 or greater.
9
- *
10
- * You should have received a copy of the GNU General Public License
11
- * along with this program; if not, write to the Free Software
12
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
13
- *
14
- * For documentation on serial programming, see the excellent:
15
- * "Serial Programming Guide for POSIX Operating Systems"
16
- * written Michael R. Sweet.
17
- * http://www.easysw.com/~mike/serial/
18
- */
19
-
20
- #include "serialport.h"
21
-
22
- #if defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW)
23
-
24
- #include <stdio.h> /* Standard input/output definitions */
25
- #include <io.h> /* Low-level I/O definitions */
26
- #include <fcntl.h> /* File control definitions */
27
- #include <windows.h> /* Windows standard function definitions */
28
-
29
-
30
- static char sGetCommState[] = "GetCommState";
31
- static char sSetCommState[] = "SetCommState";
32
- static char sGetCommTimeouts[] = "GetCommTimeouts";
33
- static char sSetCommTimeouts[] = "SetCommTimeouts";
34
-
35
-
36
- static HANDLE get_handle_helper(obj)
37
- VALUE obj;
38
- {
39
- #ifdef RUBY_1_9
40
- rb_io_t *fptr;
41
- #else
42
- OpenFile *fptr;
43
- #endif
44
-
45
- GetOpenFile(obj, fptr);
46
- #ifdef RUBY_1_9
47
- return (HANDLE) _get_osfhandle(fptr->fd);
48
- #else
49
- return (HANDLE) _get_osfhandle(fileno(fptr->f));
50
- #endif
51
- }
52
-
53
- /* hack to work around the fact that Ruby doesn't use GetLastError? */
54
- static void _rb_win32_fail(const char *function_call) {
55
- rb_raise(
56
- rb_eRuntimeError,
57
- "%s failed: GetLastError returns %d",
58
- function_call, GetLastError( )
59
- );
60
- }
61
-
62
- VALUE RB_SERIAL_EXPORT sp_create_impl(class, _port)
63
- VALUE class, _port;
64
- {
65
- #ifdef RUBY_1_9
66
- rb_io_t *fp;
67
- #else
68
- OpenFile *fp;
69
- #endif
70
- int fd;
71
- HANDLE fh;
72
- int num_port;
73
- char *str_port;
74
- char port[260]; /* Windows XP MAX_PATH. See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx */
75
-
76
- DCB dcb;
77
-
78
- NEWOBJ(sp, struct RFile);
79
- rb_secure(4);
80
- OBJSETUP(sp, class, T_FILE);
81
- MakeOpenFile((VALUE) sp, fp);
82
-
83
- switch(TYPE(_port))
84
- {
85
- case T_FIXNUM:
86
- num_port = FIX2INT(_port);
87
- if (num_port < 0)
88
- {
89
- rb_raise(rb_eArgError, "illegal port number");
90
- }
91
- snprintf(port, sizeof(port) - 1, "\\\\.\\COM%d", num_port + 1); /* '0' is actually COM1, etc. */
92
- port[sizeof(port) - 1] = 0;
93
-
94
- break;
95
-
96
- case T_STRING:
97
- Check_SafeStr(_port);
98
- #ifdef RUBY_1_9
99
- str_port = RSTRING_PTR(_port);
100
- #else
101
- str_port = RSTRING(_port)->ptr;
102
- #endif
103
- if (str_port[0] != '\\') /* Check for Win32 Device Namespace prefix "\\.\" */
104
- {
105
- snprintf(port, sizeof(port) - 1, "\\\\.\\%s", str_port);
106
- port[sizeof(port) - 1] = 0;
107
- }
108
- else
109
- {
110
- snprintf(port, sizeof(port) - 1, "%s", str_port);
111
- port[sizeof(port) - 1] = 0;
112
- }
113
- break;
114
-
115
- default:
116
- rb_raise(rb_eTypeError, "wrong argument type");
117
- break;
118
- }
119
-
120
- fd = open(port, O_BINARY | O_RDWR);
121
- if (fd == -1)
122
- {
123
- rb_sys_fail(port);
124
- }
125
-
126
- fh = (HANDLE) _get_osfhandle(fd);
127
- if (SetupComm(fh, 1024, 1024) == 0)
128
- {
129
- close(fd);
130
- rb_raise(rb_eArgError, "not a serial port");
131
- }
132
-
133
- dcb.DCBlength = sizeof(dcb);
134
- if (GetCommState(fh, &dcb) == 0)
135
- {
136
- close(fd);
137
- _rb_win32_fail(sGetCommState);
138
- }
139
- dcb.fBinary = TRUE;
140
- dcb.fParity = FALSE;
141
- dcb.fOutxDsrFlow = FALSE;
142
- dcb.fDtrControl = DTR_CONTROL_ENABLE;
143
- dcb.fDsrSensitivity = FALSE;
144
- dcb.fTXContinueOnXoff = FALSE;
145
- dcb.fErrorChar = FALSE;
146
- dcb.fNull = FALSE;
147
- dcb.fAbortOnError = FALSE;
148
- dcb.XonChar = 17;
149
- dcb.XoffChar = 19;
150
- if (SetCommState(fh, &dcb) == 0)
151
- {
152
- close(fd);
153
- _rb_win32_fail(sSetCommState);
154
- }
155
-
156
- errno = 0;
157
- fp->mode = FMODE_READWRITE | FMODE_BINMODE | FMODE_SYNC;
158
- #ifdef RUBY_1_9
159
- fp->fd = fd;
160
- #else
161
- fp->f = fdopen(fd, "rb+");
162
- #endif
163
- return (VALUE) sp;
164
- }
165
-
166
- VALUE RB_SERIAL_EXPORT sp_set_modem_params_impl(argc, argv, self)
167
- int argc;
168
- VALUE *argv, self;
169
- {
170
- HANDLE fh;
171
- DCB dcb;
172
- VALUE _data_rate, _data_bits, _parity, _stop_bits;
173
- int use_hash = 0;
174
- int data_rate, data_bits, parity;
175
-
176
- if (argc == 0)
177
- {
178
- return self;
179
- }
180
- if (argc == 1 && T_HASH == TYPE(argv[0]))
181
- {
182
- use_hash = 1;
183
- _data_rate = rb_hash_aref(argv[0], sBaud);
184
- _data_bits = rb_hash_aref(argv[0], sDataBits);
185
- _stop_bits = rb_hash_aref(argv[0], sStopBits);
186
- _parity = rb_hash_aref(argv[0], sParity);
187
- }
188
-
189
- fh = get_handle_helper(self);
190
- dcb.DCBlength = sizeof(dcb);
191
- if (GetCommState(fh, &dcb) == 0)
192
- {
193
- _rb_win32_fail(sGetCommState);
194
- }
195
-
196
- if (!use_hash)
197
- {
198
- _data_rate = argv[0];
199
- }
200
-
201
- if (NIL_P(_data_rate))
202
- {
203
- goto SkipDataRate;
204
- }
205
-
206
- Check_Type(_data_rate, T_FIXNUM);
207
-
208
- data_rate = FIX2INT(_data_rate);
209
- dcb.BaudRate = data_rate;
210
-
211
- SkipDataRate:
212
-
213
- if (!use_hash)
214
- {
215
- _data_bits = (argc >= 2 ? argv[1] : INT2FIX(8));
216
- }
217
-
218
- if (NIL_P(_data_bits))
219
- {
220
- goto SkipDataBits;
221
- }
222
-
223
- Check_Type(_data_bits, T_FIXNUM);
224
-
225
- data_bits = FIX2INT(_data_bits);
226
- if (4 <= data_bits && data_bits <= 8)
227
- {
228
- dcb.ByteSize = data_bits;
229
- }
230
- else
231
- {
232
- rb_raise(rb_eArgError, "unknown character size");
233
- }
234
-
235
- SkipDataBits:
236
-
237
- if (!use_hash)
238
- {
239
- _stop_bits = (argc >= 3 ? argv[2] : INT2FIX(1));
240
- }
241
-
242
- if (NIL_P(_stop_bits))
243
- {
244
- goto SkipStopBits;
245
- }
246
-
247
- Check_Type(_stop_bits, T_FIXNUM);
248
-
249
- switch (FIX2INT(_stop_bits))
250
- {
251
- case 1:
252
- dcb.StopBits = ONESTOPBIT;
253
- break;
254
- case 2:
255
- dcb.StopBits = TWOSTOPBITS;
256
- break;
257
- default:
258
- rb_raise(rb_eArgError, "unknown number of stop bits");
259
- break;
260
- }
261
-
262
- SkipStopBits:
263
-
264
- if (!use_hash)
265
- {
266
- _parity = (argc >= 4 ? argv[3] : (dcb.ByteSize == 8 ?
267
- INT2FIX(NOPARITY) : INT2FIX(EVENPARITY)));
268
- }
269
-
270
- if (NIL_P(_parity))
271
- {
272
- goto SkipParity;
273
- }
274
-
275
- Check_Type(_parity, T_FIXNUM);
276
-
277
- parity = FIX2INT(_parity);
278
- switch (parity)
279
- {
280
- case EVENPARITY:
281
- case ODDPARITY:
282
- case MARKPARITY:
283
- case SPACEPARITY:
284
- case NOPARITY:
285
- dcb.Parity = parity;
286
- break;
287
-
288
- default:
289
- rb_raise(rb_eArgError, "unknown parity");
290
- break;
291
- }
292
-
293
- SkipParity:
294
-
295
- if (SetCommState(fh, &dcb) == 0)
296
- {
297
- _rb_win32_fail(sSetCommState);
298
- }
299
-
300
- return argv[0];
301
- }
302
-
303
- void RB_SERIAL_EXPORT get_modem_params_impl(self, mp)
304
- VALUE self;
305
- struct modem_params *mp;
306
- {
307
- HANDLE fh;
308
- DCB dcb;
309
-
310
- fh = get_handle_helper(self);
311
- dcb.DCBlength = sizeof(dcb);
312
- if (GetCommState(fh, &dcb) == 0)
313
- {
314
- _rb_win32_fail(sGetCommState);
315
- }
316
-
317
- mp->data_rate = dcb.BaudRate;
318
- mp->data_bits = dcb.ByteSize;
319
- mp->stop_bits = (dcb.StopBits == ONESTOPBIT ? 1 : 2);
320
- mp->parity = dcb.Parity;
321
- }
322
-
323
- VALUE RB_SERIAL_EXPORT sp_set_flow_control_impl(self, val)
324
- VALUE self, val;
325
- {
326
- HANDLE fh;
327
- int flowc;
328
- DCB dcb;
329
-
330
- Check_Type(val, T_FIXNUM);
331
-
332
- fh = get_handle_helper(self);
333
- dcb.DCBlength = sizeof(dcb);
334
- if (GetCommState(fh, &dcb) == 0)
335
- {
336
- _rb_win32_fail(sGetCommState);
337
- }
338
-
339
- flowc = FIX2INT(val);
340
- if (flowc & HARD)
341
- {
342
- dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
343
- dcb.fOutxCtsFlow = TRUE;
344
- }
345
- else
346
- {
347
- dcb.fRtsControl = RTS_CONTROL_ENABLE;
348
- dcb.fOutxCtsFlow = FALSE;
349
- }
350
-
351
- if (flowc & SOFT)
352
- {
353
- dcb.fOutX = dcb.fInX = TRUE;
354
- }
355
- else
356
- {
357
- dcb.fOutX = dcb.fInX = FALSE;
358
- }
359
-
360
- if (SetCommState(fh, &dcb) == 0)
361
- {
362
- _rb_win32_fail(sSetCommState);
363
- }
364
-
365
- return val;
366
- }
367
-
368
- VALUE RB_SERIAL_EXPORT sp_get_flow_control_impl(self)
369
- VALUE self;
370
- {
371
- HANDLE fh;
372
- int ret;
373
- DCB dcb;
374
-
375
- fh = get_handle_helper(self);
376
- dcb.DCBlength = sizeof(dcb);
377
- if (GetCommState(fh, &dcb) == 0)
378
- {
379
- _rb_win32_fail(sGetCommState);
380
- }
381
-
382
- ret = 0;
383
- if (dcb.fOutxCtsFlow)
384
- {
385
- ret += HARD;
386
- }
387
-
388
- if (dcb.fOutX)
389
- {
390
- ret += SOFT;
391
- }
392
-
393
- return INT2FIX(ret);
394
- }
395
-
396
- VALUE RB_SERIAL_EXPORT sp_set_read_timeout_impl(self, val)
397
- VALUE self, val;
398
- {
399
- int timeout;
400
- HANDLE fh;
401
- COMMTIMEOUTS ctout;
402
-
403
- Check_Type(val, T_FIXNUM);
404
- timeout = FIX2INT(val);
405
-
406
- fh = get_handle_helper(self);
407
- if (GetCommTimeouts(fh, &ctout) == 0)
408
- {
409
- _rb_win32_fail(sGetCommTimeouts);
410
- }
411
-
412
- if (timeout < 0)
413
- {
414
- ctout.ReadIntervalTimeout = MAXDWORD;
415
- ctout.ReadTotalTimeoutMultiplier = 0;
416
- ctout.ReadTotalTimeoutConstant = 0;
417
- }
418
- else if (timeout == 0)
419
- {
420
- ctout.ReadIntervalTimeout = MAXDWORD;
421
- ctout.ReadTotalTimeoutMultiplier = MAXDWORD;
422
- ctout.ReadTotalTimeoutConstant = MAXDWORD - 1;
423
- }
424
- else
425
- {
426
- ctout.ReadIntervalTimeout = timeout;
427
- ctout.ReadTotalTimeoutMultiplier = 0;
428
- ctout.ReadTotalTimeoutConstant = timeout;
429
- }
430
-
431
- if (SetCommTimeouts(fh, &ctout) == 0)
432
- {
433
- _rb_win32_fail(sSetCommTimeouts);
434
- }
435
-
436
- return val;
437
- }
438
-
439
- VALUE RB_SERIAL_EXPORT sp_get_read_timeout_impl(self)
440
- VALUE self;
441
- {
442
- HANDLE fh;
443
- COMMTIMEOUTS ctout;
444
-
445
- fh = get_handle_helper(self);
446
- if (GetCommTimeouts(fh, &ctout) == 0)
447
- {
448
- _rb_win32_fail(sGetCommTimeouts);
449
- }
450
-
451
- switch (ctout.ReadTotalTimeoutConstant)
452
- {
453
- case 0:
454
- return INT2FIX(-1);
455
- case MAXDWORD:
456
- return INT2FIX(0);
457
- }
458
-
459
- return INT2FIX(ctout.ReadTotalTimeoutConstant);
460
- }
461
-
462
- VALUE RB_SERIAL_EXPORT sp_set_write_timeout_impl(self, val)
463
- VALUE self, val;
464
- {
465
- int timeout;
466
- HANDLE fh;
467
- COMMTIMEOUTS ctout;
468
-
469
- Check_Type(val, T_FIXNUM);
470
- timeout = FIX2INT(val);
471
-
472
- fh = get_handle_helper(self);
473
- if (GetCommTimeouts(fh, &ctout) == 0)
474
- {
475
- _rb_win32_fail(sGetCommTimeouts);
476
- }
477
-
478
- if (timeout <= 0)
479
- {
480
- ctout.WriteTotalTimeoutMultiplier = 0;
481
- ctout.WriteTotalTimeoutConstant = 0;
482
- }
483
- else
484
- {
485
- ctout.WriteTotalTimeoutMultiplier = timeout;
486
- ctout.WriteTotalTimeoutConstant = 0;
487
- }
488
-
489
- if (SetCommTimeouts(fh, &ctout) == 0)
490
- {
491
- _rb_win32_fail(sSetCommTimeouts);
492
- }
493
-
494
- return val;
495
- }
496
-
497
- VALUE RB_SERIAL_EXPORT sp_get_write_timeout_impl(self)
498
- VALUE self;
499
- {
500
- HANDLE fh;
501
- COMMTIMEOUTS ctout;
502
-
503
- fh = get_handle_helper(self);
504
- if (GetCommTimeouts(fh, &ctout) == 0)
505
- {
506
- _rb_win32_fail(sGetCommTimeouts);
507
- }
508
-
509
- return INT2FIX(ctout.WriteTotalTimeoutMultiplier);
510
- }
511
-
512
- static void delay_ms(time)
513
- int time;
514
- {
515
- HANDLE ev;
516
-
517
- ev = CreateEvent(NULL, FALSE, FALSE, NULL);
518
- if (!ev)
519
- {
520
- _rb_win32_fail("CreateEvent");
521
- }
522
-
523
- if (WaitForSingleObject(ev, time) == WAIT_FAILED)
524
- {
525
- _rb_win32_fail("WaitForSingleObject");
526
- }
527
-
528
- CloseHandle(ev);
529
- }
530
-
531
- VALUE RB_SERIAL_EXPORT sp_break_impl(self, time)
532
- VALUE self, time;
533
- {
534
- HANDLE fh;
535
-
536
- Check_Type(time, T_FIXNUM);
537
-
538
- fh = get_handle_helper(self);
539
- if (SetCommBreak(fh) == 0)
540
- {
541
- _rb_win32_fail("SetCommBreak");
542
- }
543
-
544
- delay_ms(FIX2INT(time) * 100);
545
- ClearCommBreak(fh);
546
-
547
- return Qnil;
548
- }
549
-
550
- void RB_SERIAL_EXPORT get_line_signals_helper_impl(obj, ls)
551
- VALUE obj;
552
- struct line_signals *ls;
553
- {
554
- HANDLE fh;
555
- unsigned long status; /* DWORD */
556
-
557
- fh = get_handle_helper(obj);
558
- if (GetCommModemStatus(fh, &status) == 0)
559
- {
560
- _rb_win32_fail("GetCommModemStatus");
561
- }
562
-
563
- ls->cts = (status & MS_CTS_ON ? 1 : 0);
564
- ls->dsr = (status & MS_DSR_ON ? 1 : 0);
565
- ls->dcd = (status & MS_RLSD_ON ? 1 : 0);
566
- ls->ri = (status & MS_RING_ON ? 1 : 0);
567
- }
568
-
569
- static VALUE set_signal(obj, val, sigoff, sigon)
570
- VALUE obj,val;
571
- int sigoff, sigon;
572
- {
573
- HANDLE fh;
574
- int set, sig;
575
-
576
- Check_Type(val, T_FIXNUM);
577
- fh = get_handle_helper(obj);
578
-
579
- set = FIX2INT(val);
580
- if (set == 0)
581
- {
582
- sig = sigoff;
583
- }
584
- else if (set == 1)
585
- {
586
- sig = sigon;
587
- }
588
- else
589
- {
590
- rb_raise(rb_eArgError, "invalid value");
591
- }
592
-
593
- if (EscapeCommFunction(fh, sig) == 0)
594
- {
595
- _rb_win32_fail("EscapeCommFunction");
596
- }
597
-
598
- return val;
599
- }
600
-
601
- VALUE RB_SERIAL_EXPORT sp_set_rts_impl(self, val)
602
- VALUE self, val;
603
- {
604
- return set_signal(self, val, CLRRTS, SETRTS);
605
- }
606
-
607
- VALUE RB_SERIAL_EXPORT sp_set_dtr_impl(self, val)
608
- VALUE self, val;
609
- {
610
- return set_signal(self, val, CLRDTR, SETDTR);
611
- }
612
-
613
- VALUE RB_SERIAL_EXPORT sp_get_rts_impl(self)
614
- VALUE self;
615
- {
616
- rb_notimplement();
617
- return self;
618
- }
619
-
620
- VALUE RB_SERIAL_EXPORT sp_get_dtr_impl(self)
621
- VALUE self;
622
- {
623
- rb_notimplement();
624
- return self;
625
- }
626
-
627
- #endif /* defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW) */
1
+ /* Ruby/SerialPort
2
+ * Guillaume Pierronnet <moumar@netcourrier.com>
3
+ * Alan Stern <stern@rowland.harvard.edu>
4
+ * Daniel E. Shipton <dshipton@redshiptechnologies.com>
5
+ * Hector G. Parra <hector@hectorparra.com>
6
+ *
7
+ * This code is hereby licensed for public consumption under either the
8
+ * GNU GPL v2 or greater.
9
+ *
10
+ * You should have received a copy of the GNU General Public License
11
+ * along with this program; if not, write to the Free Software
12
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
13
+ *
14
+ * For documentation on serial programming, see the excellent:
15
+ * "Serial Programming Guide for POSIX Operating Systems"
16
+ * written Michael R. Sweet.
17
+ * http://www.easysw.com/~mike/serial/
18
+ */
19
+
20
+ #include "serialport.h"
21
+
22
+ #if defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW)
23
+
24
+ #include <stdio.h> /* Standard input/output definitions */
25
+ #include <io.h> /* Low-level I/O definitions */
26
+ #include <fcntl.h> /* File control definitions */
27
+ #include <windows.h> /* Windows standard function definitions */
28
+
29
+
30
+ static char sGetCommState[] = "GetCommState";
31
+ static char sSetCommState[] = "SetCommState";
32
+ static char sGetCommTimeouts[] = "GetCommTimeouts";
33
+ static char sSetCommTimeouts[] = "SetCommTimeouts";
34
+
35
+
36
+ static HANDLE get_handle_helper(obj)
37
+ VALUE obj;
38
+ {
39
+ #ifdef HAVE_RUBY_IO_H
40
+ rb_io_t *fptr;
41
+ #else
42
+ OpenFile *fptr;
43
+ #endif
44
+
45
+ GetOpenFile(obj, fptr);
46
+ #ifdef HAVE_RUBY_IO_H
47
+ return (HANDLE) _get_osfhandle(fptr->fd);
48
+ #else
49
+ return (HANDLE) _get_osfhandle(fileno(fptr->f));
50
+ #endif
51
+ }
52
+
53
+ /* hack to work around the fact that Ruby doesn't use GetLastError? */
54
+ static void _rb_win32_fail(const char *function_call) {
55
+ rb_raise(
56
+ rb_eRuntimeError,
57
+ "%s failed: GetLastError returns %d",
58
+ function_call, GetLastError( )
59
+ );
60
+ }
61
+
62
+ VALUE RB_SERIAL_EXPORT sp_create_impl(class, _port)
63
+ VALUE class, _port;
64
+ {
65
+ #ifdef HAVE_RUBY_IO_H
66
+ rb_io_t *fp;
67
+ #else
68
+ OpenFile *fp;
69
+ #endif
70
+ int fd;
71
+ HANDLE fh;
72
+ int num_port;
73
+ char *str_port;
74
+ char port[260]; /* Windows XP MAX_PATH. See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx */
75
+
76
+ DCB dcb;
77
+
78
+ NEWOBJ(sp, struct RFile);
79
+ rb_secure(4);
80
+ OBJSETUP(sp, class, T_FILE);
81
+ MakeOpenFile((VALUE) sp, fp);
82
+
83
+ switch(TYPE(_port))
84
+ {
85
+ case T_FIXNUM:
86
+ num_port = FIX2INT(_port);
87
+ if (num_port < 0)
88
+ {
89
+ rb_raise(rb_eArgError, "illegal port number");
90
+ }
91
+ snprintf(port, sizeof(port) - 1, "\\\\.\\COM%d", num_port + 1); /* '0' is actually COM1, etc. */
92
+ port[sizeof(port) - 1] = 0;
93
+
94
+ break;
95
+
96
+ case T_STRING:
97
+ Check_SafeStr(_port);
98
+ str_port = RSTRING_PTR(_port);
99
+ if (str_port[0] != '\\') /* Check for Win32 Device Namespace prefix "\\.\" */
100
+ {
101
+ snprintf(port, sizeof(port) - 1, "\\\\.\\%s", str_port);
102
+ port[sizeof(port) - 1] = 0;
103
+ }
104
+ else
105
+ {
106
+ snprintf(port, sizeof(port) - 1, "%s", str_port);
107
+ port[sizeof(port) - 1] = 0;
108
+ }
109
+ break;
110
+
111
+ default:
112
+ rb_raise(rb_eTypeError, "wrong argument type");
113
+ break;
114
+ }
115
+
116
+ fd = open(port, O_BINARY | O_RDWR);
117
+ if (fd == -1)
118
+ {
119
+ rb_sys_fail(port);
120
+ }
121
+
122
+ fh = (HANDLE) _get_osfhandle(fd);
123
+ if (SetupComm(fh, 1024, 1024) == 0)
124
+ {
125
+ close(fd);
126
+ rb_raise(rb_eArgError, "not a serial port");
127
+ }
128
+
129
+ dcb.DCBlength = sizeof(dcb);
130
+ if (GetCommState(fh, &dcb) == 0)
131
+ {
132
+ close(fd);
133
+ _rb_win32_fail(sGetCommState);
134
+ }
135
+ dcb.fBinary = TRUE;
136
+ dcb.fParity = FALSE;
137
+ dcb.fOutxDsrFlow = FALSE;
138
+ dcb.fDtrControl = DTR_CONTROL_ENABLE;
139
+ dcb.fDsrSensitivity = FALSE;
140
+ dcb.fTXContinueOnXoff = FALSE;
141
+ dcb.fErrorChar = FALSE;
142
+ dcb.fNull = FALSE;
143
+ dcb.fAbortOnError = FALSE;
144
+ dcb.XonChar = 17;
145
+ dcb.XoffChar = 19;
146
+ if (SetCommState(fh, &dcb) == 0)
147
+ {
148
+ close(fd);
149
+ _rb_win32_fail(sSetCommState);
150
+ }
151
+
152
+ errno = 0;
153
+ fp->mode = FMODE_READWRITE | FMODE_BINMODE | FMODE_SYNC;
154
+ #ifdef HAVE_RUBY_IO_H
155
+ fp->fd = fd;
156
+ #else
157
+ fp->f = fdopen(fd, "rb+");
158
+ #endif
159
+ return (VALUE) sp;
160
+ }
161
+
162
+ VALUE RB_SERIAL_EXPORT sp_set_modem_params_impl(argc, argv, self)
163
+ int argc;
164
+ VALUE *argv, self;
165
+ {
166
+ HANDLE fh;
167
+ DCB dcb;
168
+ VALUE _data_rate, _data_bits, _parity, _stop_bits;
169
+ int use_hash = 0;
170
+ int data_rate, data_bits, parity;
171
+
172
+ if (argc == 0)
173
+ {
174
+ return self;
175
+ }
176
+ if (argc == 1 && T_HASH == TYPE(argv[0]))
177
+ {
178
+ use_hash = 1;
179
+ _data_rate = rb_hash_aref(argv[0], sBaud);
180
+ _data_bits = rb_hash_aref(argv[0], sDataBits);
181
+ _stop_bits = rb_hash_aref(argv[0], sStopBits);
182
+ _parity = rb_hash_aref(argv[0], sParity);
183
+ }
184
+
185
+ fh = get_handle_helper(self);
186
+ dcb.DCBlength = sizeof(dcb);
187
+ if (GetCommState(fh, &dcb) == 0)
188
+ {
189
+ _rb_win32_fail(sGetCommState);
190
+ }
191
+
192
+ if (!use_hash)
193
+ {
194
+ _data_rate = argv[0];
195
+ }
196
+
197
+ if (NIL_P(_data_rate))
198
+ {
199
+ goto SkipDataRate;
200
+ }
201
+
202
+ Check_Type(_data_rate, T_FIXNUM);
203
+
204
+ data_rate = FIX2INT(_data_rate);
205
+ dcb.BaudRate = data_rate;
206
+
207
+ SkipDataRate:
208
+
209
+ if (!use_hash)
210
+ {
211
+ _data_bits = (argc >= 2 ? argv[1] : INT2FIX(8));
212
+ }
213
+
214
+ if (NIL_P(_data_bits))
215
+ {
216
+ goto SkipDataBits;
217
+ }
218
+
219
+ Check_Type(_data_bits, T_FIXNUM);
220
+
221
+ data_bits = FIX2INT(_data_bits);
222
+ if (4 <= data_bits && data_bits <= 8)
223
+ {
224
+ dcb.ByteSize = data_bits;
225
+ }
226
+ else
227
+ {
228
+ rb_raise(rb_eArgError, "unknown character size");
229
+ }
230
+
231
+ SkipDataBits:
232
+
233
+ if (!use_hash)
234
+ {
235
+ _stop_bits = (argc >= 3 ? argv[2] : INT2FIX(1));
236
+ }
237
+
238
+ if (NIL_P(_stop_bits))
239
+ {
240
+ goto SkipStopBits;
241
+ }
242
+
243
+ Check_Type(_stop_bits, T_FIXNUM);
244
+
245
+ switch (FIX2INT(_stop_bits))
246
+ {
247
+ case 1:
248
+ dcb.StopBits = ONESTOPBIT;
249
+ break;
250
+ case 2:
251
+ dcb.StopBits = TWOSTOPBITS;
252
+ break;
253
+ default:
254
+ rb_raise(rb_eArgError, "unknown number of stop bits");
255
+ break;
256
+ }
257
+
258
+ SkipStopBits:
259
+
260
+ if (!use_hash)
261
+ {
262
+ _parity = (argc >= 4 ? argv[3] : (dcb.ByteSize == 8 ?
263
+ INT2FIX(NOPARITY) : INT2FIX(EVENPARITY)));
264
+ }
265
+
266
+ if (NIL_P(_parity))
267
+ {
268
+ goto SkipParity;
269
+ }
270
+
271
+ Check_Type(_parity, T_FIXNUM);
272
+
273
+ parity = FIX2INT(_parity);
274
+ switch (parity)
275
+ {
276
+ case EVENPARITY:
277
+ case ODDPARITY:
278
+ case MARKPARITY:
279
+ case SPACEPARITY:
280
+ case NOPARITY:
281
+ dcb.Parity = parity;
282
+ break;
283
+
284
+ default:
285
+ rb_raise(rb_eArgError, "unknown parity");
286
+ break;
287
+ }
288
+
289
+ SkipParity:
290
+
291
+ if (SetCommState(fh, &dcb) == 0)
292
+ {
293
+ _rb_win32_fail(sSetCommState);
294
+ }
295
+
296
+ return argv[0];
297
+ }
298
+
299
+ void RB_SERIAL_EXPORT get_modem_params_impl(self, mp)
300
+ VALUE self;
301
+ struct modem_params *mp;
302
+ {
303
+ HANDLE fh;
304
+ DCB dcb;
305
+
306
+ fh = get_handle_helper(self);
307
+ dcb.DCBlength = sizeof(dcb);
308
+ if (GetCommState(fh, &dcb) == 0)
309
+ {
310
+ _rb_win32_fail(sGetCommState);
311
+ }
312
+
313
+ mp->data_rate = dcb.BaudRate;
314
+ mp->data_bits = dcb.ByteSize;
315
+ mp->stop_bits = (dcb.StopBits == ONESTOPBIT ? 1 : 2);
316
+ mp->parity = dcb.Parity;
317
+ }
318
+
319
+ VALUE RB_SERIAL_EXPORT sp_set_flow_control_impl(self, val)
320
+ VALUE self, val;
321
+ {
322
+ HANDLE fh;
323
+ int flowc;
324
+ DCB dcb;
325
+
326
+ Check_Type(val, T_FIXNUM);
327
+
328
+ fh = get_handle_helper(self);
329
+ dcb.DCBlength = sizeof(dcb);
330
+ if (GetCommState(fh, &dcb) == 0)
331
+ {
332
+ _rb_win32_fail(sGetCommState);
333
+ }
334
+
335
+ flowc = FIX2INT(val);
336
+ if (flowc & HARD)
337
+ {
338
+ dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
339
+ dcb.fOutxCtsFlow = TRUE;
340
+ }
341
+ else
342
+ {
343
+ dcb.fRtsControl = RTS_CONTROL_ENABLE;
344
+ dcb.fOutxCtsFlow = FALSE;
345
+ }
346
+
347
+ if (flowc & SOFT)
348
+ {
349
+ dcb.fOutX = dcb.fInX = TRUE;
350
+ }
351
+ else
352
+ {
353
+ dcb.fOutX = dcb.fInX = FALSE;
354
+ }
355
+
356
+ if (SetCommState(fh, &dcb) == 0)
357
+ {
358
+ _rb_win32_fail(sSetCommState);
359
+ }
360
+
361
+ return val;
362
+ }
363
+
364
+ VALUE RB_SERIAL_EXPORT sp_get_flow_control_impl(self)
365
+ VALUE self;
366
+ {
367
+ HANDLE fh;
368
+ int ret;
369
+ DCB dcb;
370
+
371
+ fh = get_handle_helper(self);
372
+ dcb.DCBlength = sizeof(dcb);
373
+ if (GetCommState(fh, &dcb) == 0)
374
+ {
375
+ _rb_win32_fail(sGetCommState);
376
+ }
377
+
378
+ ret = 0;
379
+ if (dcb.fOutxCtsFlow)
380
+ {
381
+ ret += HARD;
382
+ }
383
+
384
+ if (dcb.fOutX)
385
+ {
386
+ ret += SOFT;
387
+ }
388
+
389
+ return INT2FIX(ret);
390
+ }
391
+
392
+ VALUE RB_SERIAL_EXPORT sp_set_read_timeout_impl(self, val)
393
+ VALUE self, val;
394
+ {
395
+ int timeout;
396
+ HANDLE fh;
397
+ COMMTIMEOUTS ctout;
398
+
399
+ Check_Type(val, T_FIXNUM);
400
+ timeout = FIX2INT(val);
401
+
402
+ fh = get_handle_helper(self);
403
+ if (GetCommTimeouts(fh, &ctout) == 0)
404
+ {
405
+ _rb_win32_fail(sGetCommTimeouts);
406
+ }
407
+
408
+ if (timeout < 0)
409
+ {
410
+ ctout.ReadIntervalTimeout = MAXDWORD;
411
+ ctout.ReadTotalTimeoutMultiplier = 0;
412
+ ctout.ReadTotalTimeoutConstant = 0;
413
+ }
414
+ else if (timeout == 0)
415
+ {
416
+ ctout.ReadIntervalTimeout = MAXDWORD;
417
+ ctout.ReadTotalTimeoutMultiplier = MAXDWORD;
418
+ ctout.ReadTotalTimeoutConstant = MAXDWORD - 1;
419
+ }
420
+ else
421
+ {
422
+ ctout.ReadIntervalTimeout = timeout;
423
+ ctout.ReadTotalTimeoutMultiplier = 0;
424
+ ctout.ReadTotalTimeoutConstant = timeout;
425
+ }
426
+
427
+ if (SetCommTimeouts(fh, &ctout) == 0)
428
+ {
429
+ _rb_win32_fail(sSetCommTimeouts);
430
+ }
431
+
432
+ return val;
433
+ }
434
+
435
+ VALUE RB_SERIAL_EXPORT sp_get_read_timeout_impl(self)
436
+ VALUE self;
437
+ {
438
+ HANDLE fh;
439
+ COMMTIMEOUTS ctout;
440
+
441
+ fh = get_handle_helper(self);
442
+ if (GetCommTimeouts(fh, &ctout) == 0)
443
+ {
444
+ _rb_win32_fail(sGetCommTimeouts);
445
+ }
446
+
447
+ switch (ctout.ReadTotalTimeoutConstant)
448
+ {
449
+ case 0:
450
+ return INT2FIX(-1);
451
+ case MAXDWORD:
452
+ return INT2FIX(0);
453
+ }
454
+
455
+ return INT2FIX(ctout.ReadTotalTimeoutConstant);
456
+ }
457
+
458
+ VALUE RB_SERIAL_EXPORT sp_set_write_timeout_impl(self, val)
459
+ VALUE self, val;
460
+ {
461
+ int timeout;
462
+ HANDLE fh;
463
+ COMMTIMEOUTS ctout;
464
+
465
+ Check_Type(val, T_FIXNUM);
466
+ timeout = FIX2INT(val);
467
+
468
+ fh = get_handle_helper(self);
469
+ if (GetCommTimeouts(fh, &ctout) == 0)
470
+ {
471
+ _rb_win32_fail(sGetCommTimeouts);
472
+ }
473
+
474
+ if (timeout <= 0)
475
+ {
476
+ ctout.WriteTotalTimeoutMultiplier = 0;
477
+ ctout.WriteTotalTimeoutConstant = 0;
478
+ }
479
+ else
480
+ {
481
+ ctout.WriteTotalTimeoutMultiplier = timeout;
482
+ ctout.WriteTotalTimeoutConstant = 0;
483
+ }
484
+
485
+ if (SetCommTimeouts(fh, &ctout) == 0)
486
+ {
487
+ _rb_win32_fail(sSetCommTimeouts);
488
+ }
489
+
490
+ return val;
491
+ }
492
+
493
+ VALUE RB_SERIAL_EXPORT sp_get_write_timeout_impl(self)
494
+ VALUE self;
495
+ {
496
+ HANDLE fh;
497
+ COMMTIMEOUTS ctout;
498
+
499
+ fh = get_handle_helper(self);
500
+ if (GetCommTimeouts(fh, &ctout) == 0)
501
+ {
502
+ _rb_win32_fail(sGetCommTimeouts);
503
+ }
504
+
505
+ return INT2FIX(ctout.WriteTotalTimeoutMultiplier);
506
+ }
507
+
508
+ static void delay_ms(time)
509
+ int time;
510
+ {
511
+ HANDLE ev;
512
+
513
+ ev = CreateEvent(NULL, FALSE, FALSE, NULL);
514
+ if (!ev)
515
+ {
516
+ _rb_win32_fail("CreateEvent");
517
+ }
518
+
519
+ if (WaitForSingleObject(ev, time) == WAIT_FAILED)
520
+ {
521
+ _rb_win32_fail("WaitForSingleObject");
522
+ }
523
+
524
+ CloseHandle(ev);
525
+ }
526
+
527
+ VALUE RB_SERIAL_EXPORT sp_break_impl(self, time)
528
+ VALUE self, time;
529
+ {
530
+ HANDLE fh;
531
+
532
+ Check_Type(time, T_FIXNUM);
533
+
534
+ fh = get_handle_helper(self);
535
+ if (SetCommBreak(fh) == 0)
536
+ {
537
+ _rb_win32_fail("SetCommBreak");
538
+ }
539
+
540
+ delay_ms(FIX2INT(time) * 100);
541
+ ClearCommBreak(fh);
542
+
543
+ return Qnil;
544
+ }
545
+
546
+ void RB_SERIAL_EXPORT get_line_signals_helper_impl(obj, ls)
547
+ VALUE obj;
548
+ struct line_signals *ls;
549
+ {
550
+ HANDLE fh;
551
+ unsigned long status; /* DWORD */
552
+
553
+ fh = get_handle_helper(obj);
554
+ if (GetCommModemStatus(fh, &status) == 0)
555
+ {
556
+ _rb_win32_fail("GetCommModemStatus");
557
+ }
558
+
559
+ ls->cts = (status & MS_CTS_ON ? 1 : 0);
560
+ ls->dsr = (status & MS_DSR_ON ? 1 : 0);
561
+ ls->dcd = (status & MS_RLSD_ON ? 1 : 0);
562
+ ls->ri = (status & MS_RING_ON ? 1 : 0);
563
+ }
564
+
565
+ static VALUE set_signal(obj, val, sigoff, sigon)
566
+ VALUE obj,val;
567
+ int sigoff, sigon;
568
+ {
569
+ HANDLE fh;
570
+ int set, sig;
571
+
572
+ Check_Type(val, T_FIXNUM);
573
+ fh = get_handle_helper(obj);
574
+
575
+ set = FIX2INT(val);
576
+ if (set == 0)
577
+ {
578
+ sig = sigoff;
579
+ }
580
+ else if (set == 1)
581
+ {
582
+ sig = sigon;
583
+ }
584
+ else
585
+ {
586
+ rb_raise(rb_eArgError, "invalid value");
587
+ }
588
+
589
+ if (EscapeCommFunction(fh, sig) == 0)
590
+ {
591
+ _rb_win32_fail("EscapeCommFunction");
592
+ }
593
+
594
+ return val;
595
+ }
596
+
597
+ VALUE RB_SERIAL_EXPORT sp_set_rts_impl(self, val)
598
+ VALUE self, val;
599
+ {
600
+ return set_signal(self, val, CLRRTS, SETRTS);
601
+ }
602
+
603
+ VALUE RB_SERIAL_EXPORT sp_set_dtr_impl(self, val)
604
+ VALUE self, val;
605
+ {
606
+ return set_signal(self, val, CLRDTR, SETDTR);
607
+ }
608
+
609
+ VALUE RB_SERIAL_EXPORT sp_get_rts_impl(self)
610
+ VALUE self;
611
+ {
612
+ rb_notimplement();
613
+ return self;
614
+ }
615
+
616
+ VALUE RB_SERIAL_EXPORT sp_get_dtr_impl(self)
617
+ VALUE self;
618
+ {
619
+ rb_notimplement();
620
+ return self;
621
+ }
622
+
623
+ #endif /* defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW) */