serialport 1.0.3 → 1.0.4

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.3"
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 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,637 +1,627 @@
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
- VALUE RB_SERIAL_EXPORT sp_create_impl(class, _port)
54
- VALUE class, _port;
55
- {
56
- #ifdef RUBY_1_9
57
- rb_io_t *fp;
58
- #else
59
- OpenFile *fp;
60
- #endif
61
- int fd;
62
- HANDLE fh;
63
- int num_port;
64
- char *str_port;
65
- char port[260]; /* Windows XP MAX_PATH. See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx */
66
-
67
- DCB dcb;
68
-
69
- NEWOBJ(sp, struct RFile);
70
- rb_secure(4);
71
- OBJSETUP(sp, class, T_FILE);
72
- MakeOpenFile((VALUE) sp, fp);
73
-
74
- switch(TYPE(_port))
75
- {
76
- case T_FIXNUM:
77
- num_port = FIX2INT(_port);
78
- if (num_port < 0)
79
- {
80
- rb_raise(rb_eArgError, "illegal port number");
81
- }
82
- sprintf(port, "\\\\.\\COM%d", num_port + 1); /* '0' is actually COM1, etc. */
83
- break;
84
-
85
- case T_STRING:
86
- Check_SafeStr(_port);
87
- #ifdef RUBY_1_9
88
- str_port = RSTRING_PTR(_port);
89
- #else
90
- str_port = RSTRING(_port)->ptr;
91
- #endif
92
- if (str_port[0] != '\\') /* Check for Win32 Device Namespace prefix "\\.\" */
93
- {
94
- sprintf(port, "\\\\.\\%s", str_port);
95
- }
96
- else
97
- {
98
- sprintf(port, "%s", str_port);
99
- }
100
- break;
101
-
102
- default:
103
- rb_raise(rb_eTypeError, "wrong argument type");
104
- break;
105
- }
106
-
107
- fd = open(port, O_BINARY | O_RDWR);
108
- if (fd == -1)
109
- {
110
- rb_sys_fail(port);
111
- }
112
-
113
- fh = (HANDLE) _get_osfhandle(fd);
114
- if (SetupComm(fh, 1024, 1024) == 0)
115
- {
116
- close(fd);
117
- rb_raise(rb_eArgError, "not a serial port");
118
- }
119
-
120
- dcb.DCBlength = sizeof(dcb);
121
- if (GetCommState(fh, &dcb) == 0)
122
- {
123
- close(fd);
124
- rb_sys_fail(sGetCommState);
125
- }
126
- dcb.fBinary = TRUE;
127
- dcb.fParity = FALSE;
128
- dcb.fOutxDsrFlow = FALSE;
129
- dcb.fDtrControl = DTR_CONTROL_ENABLE;
130
- dcb.fDsrSensitivity = FALSE;
131
- dcb.fTXContinueOnXoff = FALSE;
132
- dcb.fErrorChar = FALSE;
133
- dcb.fNull = FALSE;
134
- dcb.fAbortOnError = FALSE;
135
- dcb.XonChar = 17;
136
- dcb.XoffChar = 19;
137
- if (SetCommState(fh, &dcb) == 0)
138
- {
139
- close(fd);
140
- rb_sys_fail(sSetCommState);
141
- }
142
-
143
- errno = 0;
144
- fp->mode = FMODE_READWRITE | FMODE_BINMODE | FMODE_SYNC;
145
- #ifdef RUBY_1_9
146
- fp->fd = fd;
147
- #else
148
- fp->f = fdopen(fd, "rb+");
149
- #endif
150
- return (VALUE) sp;
151
- }
152
-
153
- VALUE RB_SERIAL_EXPORT sp_set_modem_params_impl(argc, argv, self)
154
- int argc;
155
- VALUE *argv, self;
156
- {
157
- HANDLE fh;
158
- DCB dcb;
159
- VALUE _data_rate, _data_bits, _parity, _stop_bits;
160
- int use_hash = 0;
161
- int data_rate, data_bits, parity;
162
-
163
- if (argc == 0)
164
- {
165
- return self;
166
- }
167
- if (argc == 1 && T_HASH == TYPE(argv[0]))
168
- {
169
- use_hash = 1;
170
- _data_rate = rb_hash_aref(argv[0], sBaud);
171
- _data_bits = rb_hash_aref(argv[0], sDataBits);
172
- _stop_bits = rb_hash_aref(argv[0], sStopBits);
173
- _parity = rb_hash_aref(argv[0], sParity);
174
- }
175
-
176
- fh = get_handle_helper(self);
177
- dcb.DCBlength = sizeof(dcb);
178
- if (GetCommState(fh, &dcb) == 0)
179
- {
180
- rb_sys_fail(sGetCommState);
181
- }
182
-
183
- if (!use_hash)
184
- {
185
- _data_rate = argv[0];
186
- }
187
-
188
- if (NIL_P(_data_rate))
189
- {
190
- goto SkipDataRate;
191
- }
192
-
193
- Check_Type(_data_rate, T_FIXNUM);
194
-
195
- data_rate = FIX2INT(_data_rate);
196
- switch (data_rate)
197
- {
198
- case 110:
199
- case 300:
200
- case 600:
201
- case 1200:
202
- case 2400:
203
- case 4800:
204
- case 9600:
205
- case 14400:
206
- case 19200:
207
- case 38400:
208
- case 56000:
209
- case 57600:
210
- case 115200:
211
- case 128000:
212
- case 256000:
213
- dcb.BaudRate = data_rate;
214
- break;
215
-
216
- default:
217
- rb_raise(rb_eArgError, "unknown baud rate");
218
- break;
219
- }
220
-
221
- SkipDataRate:
222
-
223
- if (!use_hash)
224
- {
225
- _data_bits = (argc >= 2 ? argv[1] : INT2FIX(8));
226
- }
227
-
228
- if (NIL_P(_data_bits))
229
- {
230
- goto SkipDataBits;
231
- }
232
-
233
- Check_Type(_data_bits, T_FIXNUM);
234
-
235
- data_bits = FIX2INT(_data_bits);
236
- if (4 <= data_bits && data_bits <= 8)
237
- {
238
- dcb.ByteSize = data_bits;
239
- }
240
- else
241
- {
242
- rb_raise(rb_eArgError, "unknown character size");
243
- }
244
-
245
- SkipDataBits:
246
-
247
- if (!use_hash)
248
- {
249
- _stop_bits = (argc >= 3 ? argv[2] : INT2FIX(1));
250
- }
251
-
252
- if (NIL_P(_stop_bits))
253
- {
254
- goto SkipStopBits;
255
- }
256
-
257
- Check_Type(_stop_bits, T_FIXNUM);
258
-
259
- switch (FIX2INT(_stop_bits))
260
- {
261
- case 1:
262
- dcb.StopBits = ONESTOPBIT;
263
- break;
264
- case 2:
265
- dcb.StopBits = TWOSTOPBITS;
266
- break;
267
- default:
268
- rb_raise(rb_eArgError, "unknown number of stop bits");
269
- break;
270
- }
271
-
272
- SkipStopBits:
273
-
274
- if (!use_hash)
275
- {
276
- _parity = (argc >= 4 ? argv[3] : (dcb.ByteSize == 8 ?
277
- INT2FIX(NOPARITY) : INT2FIX(EVENPARITY)));
278
- }
279
-
280
- if (NIL_P(_parity))
281
- {
282
- goto SkipParity;
283
- }
284
-
285
- Check_Type(_parity, T_FIXNUM);
286
-
287
- parity = FIX2INT(_parity);
288
- switch (parity)
289
- {
290
- case EVENPARITY:
291
- case ODDPARITY:
292
- case MARKPARITY:
293
- case SPACEPARITY:
294
- case NOPARITY:
295
- dcb.Parity = parity;
296
- break;
297
-
298
- default:
299
- rb_raise(rb_eArgError, "unknown parity");
300
- break;
301
- }
302
-
303
- SkipParity:
304
-
305
- if (SetCommState(fh, &dcb) == 0)
306
- {
307
- rb_sys_fail(sSetCommState);
308
- }
309
-
310
- return argv[0];
311
- }
312
-
313
- void RB_SERIAL_EXPORT get_modem_params_impl(self, mp)
314
- VALUE self;
315
- struct modem_params *mp;
316
- {
317
- HANDLE fh;
318
- DCB dcb;
319
-
320
- fh = get_handle_helper(self);
321
- dcb.DCBlength = sizeof(dcb);
322
- if (GetCommState(fh, &dcb) == 0)
323
- {
324
- rb_sys_fail(sGetCommState);
325
- }
326
-
327
- mp->data_rate = dcb.BaudRate;
328
- mp->data_bits = dcb.ByteSize;
329
- mp->stop_bits = (dcb.StopBits == ONESTOPBIT ? 1 : 2);
330
- mp->parity = dcb.Parity;
331
- }
332
-
333
- VALUE RB_SERIAL_EXPORT sp_set_flow_control_impl(self, val)
334
- VALUE self, val;
335
- {
336
- HANDLE fh;
337
- int flowc;
338
- DCB dcb;
339
-
340
- Check_Type(val, T_FIXNUM);
341
-
342
- fh = get_handle_helper(self);
343
- dcb.DCBlength = sizeof(dcb);
344
- if (GetCommState(fh, &dcb) == 0)
345
- {
346
- rb_sys_fail(sGetCommState);
347
- }
348
-
349
- flowc = FIX2INT(val);
350
- if (flowc & HARD)
351
- {
352
- dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
353
- dcb.fOutxCtsFlow = TRUE;
354
- }
355
- else
356
- {
357
- dcb.fRtsControl = RTS_CONTROL_ENABLE;
358
- dcb.fOutxCtsFlow = FALSE;
359
- }
360
-
361
- if (flowc & SOFT)
362
- {
363
- dcb.fOutX = dcb.fInX = TRUE;
364
- }
365
- else
366
- {
367
- dcb.fOutX = dcb.fInX = FALSE;
368
- }
369
-
370
- if (SetCommState(fh, &dcb) == 0)
371
- {
372
- rb_sys_fail(sSetCommState);
373
- }
374
-
375
- return val;
376
- }
377
-
378
- VALUE RB_SERIAL_EXPORT sp_get_flow_control_impl(self)
379
- VALUE self;
380
- {
381
- HANDLE fh;
382
- int ret;
383
- DCB dcb;
384
-
385
- fh = get_handle_helper(self);
386
- dcb.DCBlength = sizeof(dcb);
387
- if (GetCommState(fh, &dcb) == 0)
388
- {
389
- rb_sys_fail(sGetCommState);
390
- }
391
-
392
- ret = 0;
393
- if (dcb.fOutxCtsFlow)
394
- {
395
- ret += HARD;
396
- }
397
-
398
- if (dcb.fOutX)
399
- {
400
- ret += SOFT;
401
- }
402
-
403
- return INT2FIX(ret);
404
- }
405
-
406
- VALUE RB_SERIAL_EXPORT sp_set_read_timeout_impl(self, val)
407
- VALUE self, val;
408
- {
409
- int timeout;
410
- HANDLE fh;
411
- COMMTIMEOUTS ctout;
412
-
413
- Check_Type(val, T_FIXNUM);
414
- timeout = FIX2INT(val);
415
-
416
- fh = get_handle_helper(self);
417
- if (GetCommTimeouts(fh, &ctout) == 0)
418
- {
419
- rb_sys_fail(sGetCommTimeouts);
420
- }
421
-
422
- if (timeout < 0)
423
- {
424
- ctout.ReadIntervalTimeout = MAXDWORD;
425
- ctout.ReadTotalTimeoutMultiplier = 0;
426
- ctout.ReadTotalTimeoutConstant = 0;
427
- }
428
- else if (timeout == 0)
429
- {
430
- ctout.ReadIntervalTimeout = MAXDWORD;
431
- ctout.ReadTotalTimeoutMultiplier = MAXDWORD;
432
- ctout.ReadTotalTimeoutConstant = MAXDWORD - 1;
433
- }
434
- else
435
- {
436
- ctout.ReadIntervalTimeout = timeout;
437
- ctout.ReadTotalTimeoutMultiplier = 0;
438
- ctout.ReadTotalTimeoutConstant = timeout;
439
- }
440
-
441
- if (SetCommTimeouts(fh, &ctout) == 0)
442
- {
443
- rb_sys_fail(sSetCommTimeouts);
444
- }
445
-
446
- return val;
447
- }
448
-
449
- VALUE RB_SERIAL_EXPORT sp_get_read_timeout_impl(self)
450
- VALUE self;
451
- {
452
- HANDLE fh;
453
- COMMTIMEOUTS ctout;
454
-
455
- fh = get_handle_helper(self);
456
- if (GetCommTimeouts(fh, &ctout) == 0)
457
- {
458
- rb_sys_fail(sGetCommTimeouts);
459
- }
460
-
461
- switch (ctout.ReadTotalTimeoutConstant)
462
- {
463
- case 0:
464
- return INT2FIX(-1);
465
- case MAXDWORD:
466
- return INT2FIX(0);
467
- }
468
-
469
- return INT2FIX(ctout.ReadTotalTimeoutConstant);
470
- }
471
-
472
- VALUE RB_SERIAL_EXPORT sp_set_write_timeout_impl(self, val)
473
- VALUE self, val;
474
- {
475
- int timeout;
476
- HANDLE fh;
477
- COMMTIMEOUTS ctout;
478
-
479
- Check_Type(val, T_FIXNUM);
480
- timeout = FIX2INT(val);
481
-
482
- fh = get_handle_helper(self);
483
- if (GetCommTimeouts(fh, &ctout) == 0)
484
- {
485
- rb_sys_fail(sGetCommTimeouts);
486
- }
487
-
488
- if (timeout <= 0)
489
- {
490
- ctout.WriteTotalTimeoutMultiplier = 0;
491
- ctout.WriteTotalTimeoutConstant = 0;
492
- }
493
- else
494
- {
495
- ctout.WriteTotalTimeoutMultiplier = timeout;
496
- ctout.WriteTotalTimeoutConstant = 0;
497
- }
498
-
499
- if (SetCommTimeouts(fh, &ctout) == 0)
500
- {
501
- rb_sys_fail(sSetCommTimeouts);
502
- }
503
-
504
- return val;
505
- }
506
-
507
- VALUE RB_SERIAL_EXPORT sp_get_write_timeout_impl(self)
508
- VALUE self;
509
- {
510
- HANDLE fh;
511
- COMMTIMEOUTS ctout;
512
-
513
- fh = get_handle_helper(self);
514
- if (GetCommTimeouts(fh, &ctout) == 0)
515
- {
516
- rb_sys_fail(sGetCommTimeouts);
517
- }
518
-
519
- return INT2FIX(ctout.WriteTotalTimeoutMultiplier);
520
- }
521
-
522
- static void delay_ms(time)
523
- int time;
524
- {
525
- HANDLE ev;
526
-
527
- ev = CreateEvent(NULL, FALSE, FALSE, NULL);
528
- if (!ev)
529
- {
530
- rb_sys_fail("CreateEvent");
531
- }
532
-
533
- if (WaitForSingleObject(ev, time) == WAIT_FAILED)
534
- {
535
- rb_sys_fail("WaitForSingleObject");
536
- }
537
-
538
- CloseHandle(ev);
539
- }
540
-
541
- VALUE RB_SERIAL_EXPORT sp_break_impl(self, time)
542
- VALUE self, time;
543
- {
544
- HANDLE fh;
545
-
546
- Check_Type(time, T_FIXNUM);
547
-
548
- fh = get_handle_helper(self);
549
- if (SetCommBreak(fh) == 0)
550
- {
551
- rb_sys_fail("SetCommBreak");
552
- }
553
-
554
- delay_ms(FIX2INT(time) * 100);
555
- ClearCommBreak(fh);
556
-
557
- return Qnil;
558
- }
559
-
560
- void RB_SERIAL_EXPORT get_line_signals_helper_impl(obj, ls)
561
- VALUE obj;
562
- struct line_signals *ls;
563
- {
564
- HANDLE fh;
565
- unsigned long status; /* DWORD */
566
-
567
- fh = get_handle_helper(obj);
568
- if (GetCommModemStatus(fh, &status) == 0)
569
- {
570
- rb_sys_fail("GetCommModemStatus");
571
- }
572
-
573
- ls->cts = (status & MS_CTS_ON ? 1 : 0);
574
- ls->dsr = (status & MS_DSR_ON ? 1 : 0);
575
- ls->dcd = (status & MS_RLSD_ON ? 1 : 0);
576
- ls->ri = (status & MS_RING_ON ? 1 : 0);
577
- }
578
-
579
- static VALUE set_signal(obj, val, sigoff, sigon)
580
- VALUE obj,val;
581
- int sigoff, sigon;
582
- {
583
- HANDLE fh;
584
- int set, sig;
585
-
586
- Check_Type(val, T_FIXNUM);
587
- fh = get_handle_helper(obj);
588
-
589
- set = FIX2INT(val);
590
- if (set == 0)
591
- {
592
- sig = sigoff;
593
- }
594
- else if (set == 1)
595
- {
596
- sig = sigon;
597
- }
598
- else
599
- {
600
- rb_raise(rb_eArgError, "invalid value");
601
- }
602
-
603
- if (EscapeCommFunction(fh, sig) == 0)
604
- {
605
- rb_sys_fail("EscapeCommFunction");
606
- }
607
-
608
- return val;
609
- }
610
-
611
- VALUE RB_SERIAL_EXPORT sp_set_rts_impl(self, val)
612
- VALUE self, val;
613
- {
614
- return set_signal(self, val, CLRRTS, SETRTS);
615
- }
616
-
617
- VALUE RB_SERIAL_EXPORT sp_set_dtr_impl(self, val)
618
- VALUE self, val;
619
- {
620
- return set_signal(self, val, CLRDTR, SETDTR);
621
- }
622
-
623
- VALUE RB_SERIAL_EXPORT sp_get_rts_impl(self)
624
- VALUE self;
625
- {
626
- rb_notimplement();
627
- return self;
628
- }
629
-
630
- VALUE RB_SERIAL_EXPORT sp_get_dtr_impl(self)
631
- VALUE self;
632
- {
633
- rb_notimplement();
634
- return self;
635
- }
636
-
637
- #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 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) */