aarontc-serialport 1.4.0

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