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,613 @@
1
+ /* Ruby/SerialPort
2
+ * Guillaume Pierronnet <moumar@netcourrier.com>
3
+ * Alan Stern <stern@rowland.harvard.edu>
4
+ * Daniel E. Shipton <dshipton@redshiptechnologies.com>
5
+ * Jonas Bähr <jonas.baehr@fs.ei.tum.de>
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
+
16
+ #include "serialport.h"
17
+
18
+ VALUE cSerialPort; /* serial port class */
19
+
20
+ VALUE sBaud, sDataBits, sStopBits, sParity; /* strings */
21
+ VALUE sRts, sDtr, sCts, sDsr, sDcd, sRi;
22
+
23
+ /*
24
+ * @api private
25
+ *
26
+ * @see SerialPort#new
27
+ * @see SerialPort#open
28
+ */
29
+ static VALUE sp_create(class, _port)
30
+ VALUE class, _port;
31
+ {
32
+ return sp_create_impl(class, _port);
33
+ }
34
+
35
+ /*
36
+ * Configure the serial port. You can pass a hash or multiple values
37
+ * as separate arguments. Invalid or unsupported values will raise
38
+ * an ArgumentError.
39
+ *
40
+ * When using a hash the following keys are recognized:
41
+ * ["baud"] Integer from 50 to 256000, depending on platform
42
+ * ["data_bits"] Integer from 5 to 8 (4 is allowed on Windows too)
43
+ * ["stop_bits"] Integer, only allowed values are 1 or 2 (1.5 is not supported)
44
+ * ["parity"] One of the constants NONE, EVEN or ODD (Windows allows also MARK and SPACE)
45
+ *
46
+ * When using separate arguments, they are interpreted as:
47
+ * (baud, data_bits = 8, stop_bits = 1, parity = (previous_databits == 8 ? NONE : EVEN))
48
+ * A baudrate of nil will keep the old value.
49
+ * The default parity depends on the number of databits configured before this function call.
50
+ *
51
+ * @overload set_modem_params(baud, data_bits, stop_bits, parity)
52
+ * @param baud [Integer] the baud rate
53
+ * @param data_bits [Integer] the number of data bits
54
+ * @param stop_bits [Integer] the number of stop bits
55
+ * @param parity [Integer] the type of parity checking
56
+ * @overload set_modem_params(hash)
57
+ * @param opts [Hash] the options to configure port
58
+ *
59
+ * @return [Hash] the original paramters
60
+ * @raise [ArgumentError] if values are invalide or unsupported
61
+ */
62
+ static VALUE sp_set_modem_params(argc, argv, self)
63
+ int argc;
64
+ VALUE *argv, self;
65
+ {
66
+ return sp_set_modem_params_impl(argc, argv, self);
67
+ }
68
+
69
+ /*
70
+ * Send a break for the given time
71
+ *
72
+ * @param time [Integer] break time in tenths-of-a-second
73
+ * @return [nil]
74
+ * @note (POSIX) this value is very approximate
75
+ */
76
+ static VALUE sp_break(self, time)
77
+ VALUE self, time;
78
+ {
79
+ return sp_break_impl(self, time);
80
+ }
81
+
82
+ /*
83
+ * Get the state of the DTR line
84
+ *
85
+ * @note (Windows) DTR is not available
86
+ * @return [Integer] the state of DTR line, 0 or 1
87
+ */
88
+ static VALUE sp_get_dtr(self)
89
+ VALUE self;
90
+ {
91
+ return sp_get_dtr_impl(self);
92
+ }
93
+
94
+ /*
95
+ * Get the flow control flag
96
+ *
97
+ * @return [Integer] the flow control flag
98
+ * @see SerialPort#set_flow_control
99
+ */
100
+ static VALUE sp_get_flow_control(self)
101
+ VALUE self;
102
+ {
103
+ return sp_get_flow_control_impl(self);
104
+ }
105
+
106
+ /*
107
+ * Get the read timeout value
108
+ *
109
+ * @return [Integer] the read timeout, in milliseconds
110
+ * @see SerialPort#set_read_timeout
111
+ */
112
+ static VALUE sp_get_read_timeout(self)
113
+ VALUE self;
114
+ {
115
+ return sp_get_read_timeout_impl(self);
116
+ }
117
+
118
+ /*
119
+ * Get the state of the RTS line
120
+ *
121
+ * @return [Integer] the state of RTS line, 0 or 1
122
+ * @note (Windows) RTS is not available
123
+ */
124
+ static VALUE sp_get_rts(self)
125
+ VALUE self;
126
+ {
127
+ return sp_get_rts_impl(self);
128
+ }
129
+
130
+ /*
131
+ * Get the write timeout
132
+ *
133
+ * @return [Integer] the write timeout, in milliseconds
134
+ * @note (POSIX) write timeouts are not implemented
135
+ */
136
+ static VALUE sp_get_write_timeout(self)
137
+ VALUE self;
138
+ {
139
+ return sp_get_write_timeout_impl(self);
140
+ }
141
+
142
+ /*
143
+ * Set the state of the DTR line
144
+ *
145
+ * @param val [Integer] the desired state of the DTR line, 0 or 1
146
+ * @return [Integer] the original +val+ parameter
147
+ */
148
+ static VALUE sp_set_dtr(self, val)
149
+ VALUE self, val;
150
+ {
151
+ return sp_set_dtr_impl(self, val);
152
+ }
153
+
154
+ /*
155
+ * Set the flow control
156
+ *
157
+ * @param val [Integer] the flow control flag,
158
+ * +NONE+, +HARD+, +SOFT+, or (+HARD+ | +SOFT+)
159
+ * @return [Integer] the original +val+ parameter
160
+ * @note SerialPort::HARD mode is not supported on all platforms.
161
+ * @note SerialPort::HARD uses RTS/CTS handshaking.
162
+ * DSR/DTR is not supported.
163
+ */
164
+ static VALUE sp_set_flow_control(self, val)
165
+ VALUE self, val;
166
+ {
167
+ return sp_set_flow_control_impl(self, val);
168
+ }
169
+
170
+ /*
171
+ * Set the timeout value (in milliseconds) for reading.
172
+ * A negative read timeout will return all the available data without
173
+ * waiting, a zero read timeout will not return until at least one
174
+ * byte is available, and a positive read timeout returns when the
175
+ * requested number of bytes is available or the interval between the
176
+ * arrival of two bytes exceeds the timeout value.
177
+ *
178
+ * @param timeout [Integer] the read timeout in milliseconds
179
+ * @return [Integer] the original +timeout+ parameter
180
+ * @note Read timeouts don't mix well with multi-threading
181
+ */
182
+ static VALUE sp_set_read_timeout(self, val)
183
+ VALUE self, val;
184
+ {
185
+ return sp_set_read_timeout_impl(self, val);
186
+ }
187
+
188
+ /*
189
+ * Set the state of the RTS line
190
+ *
191
+ * @param val [Integer] the state of RTS line, 0 or 1
192
+ * @return [Integer] the original +val+ parameter
193
+ */
194
+ static VALUE sp_set_rts(self, val)
195
+ VALUE self, val;
196
+ {
197
+ return sp_set_rts_impl(self, val);
198
+ }
199
+
200
+ /*
201
+ * Set a write timeout
202
+ *
203
+ * @param val [Integer] the write timeout in milliseconds
204
+ * @return [Integer] the original +val+ parameter
205
+ * @note (POSIX) write timeouts are not implemented
206
+ */
207
+ static VALUE sp_set_write_timeout(self, val)
208
+ VALUE self, val;
209
+ {
210
+ return sp_set_write_timeout_impl(self, val);
211
+ }
212
+
213
+ /*
214
+ * @private helper
215
+ */
216
+ static void get_modem_params(self, mp)
217
+ VALUE self;
218
+ struct modem_params *mp;
219
+ {
220
+ get_modem_params_impl(self, mp);
221
+ }
222
+
223
+ /*
224
+ * Set the baud rate
225
+ *
226
+ * @param data_rate [Integer] the baud rate
227
+ * @return [Integer] the original +data_rate+ parameter
228
+ * @see SerialPort#set_modem_params
229
+ */
230
+ static VALUE sp_set_data_rate(self, data_rate)
231
+ VALUE self, data_rate;
232
+ {
233
+ VALUE argv[4];
234
+
235
+ argv[0] = data_rate;
236
+ argv[1] = argv[2] = argv[3] = Qnil;
237
+ sp_set_modem_params(4, argv, self);
238
+
239
+ return data_rate;
240
+ }
241
+
242
+ /*
243
+ * Set the data bits
244
+ *
245
+ * @param data_bits [Integer] the number of data bits
246
+ * @return [Integer] the original +data_bits+ parameter
247
+ * @see SerialPort#set_modem_params
248
+ */
249
+ static VALUE sp_set_data_bits(self, data_bits)
250
+ VALUE self, data_bits;
251
+ {
252
+ VALUE argv[4];
253
+
254
+ argv[1] = data_bits;
255
+ argv[0] = argv[2] = argv[3] = Qnil;
256
+ sp_set_modem_params(4, argv, self);
257
+
258
+ return data_bits;
259
+ }
260
+
261
+ /*
262
+ * Set the stop bits
263
+ *
264
+ * @param stop_bits [Integer] the number of stop bits
265
+ * @return [Integer] the original +stop_bits+ parameter
266
+ * @see SerialPort#set_modem_params
267
+ */
268
+ static VALUE sp_set_stop_bits(self, stop_bits)
269
+ VALUE self, stop_bits;
270
+ {
271
+ VALUE argv[4];
272
+
273
+ argv[2] = stop_bits;
274
+ argv[0] = argv[1] = argv[3] = Qnil;
275
+ sp_set_modem_params(4, argv, self);
276
+
277
+ return stop_bits;
278
+ }
279
+
280
+ /*
281
+ * Set the parity
282
+ *
283
+ * @param parity [Integer] the parity type
284
+ * @return [Integer] the original +parity+ parameter
285
+ * @see SerialPort#set_modem_params
286
+ */
287
+ static VALUE sp_set_parity(self, parity)
288
+ VALUE self, parity;
289
+ {
290
+ VALUE argv[4];
291
+
292
+ argv[3] = parity;
293
+ argv[0] = argv[1] = argv[2] = Qnil;
294
+ sp_set_modem_params(4, argv, self);
295
+
296
+ return parity;
297
+ }
298
+
299
+ /*
300
+ * Get the current baud rate
301
+ *
302
+ * @return [Integer] the current baud rate
303
+ * @see SerialPort#set_modem_params
304
+ */
305
+ static VALUE sp_get_data_rate(self)
306
+ VALUE self;
307
+ {
308
+ struct modem_params mp;
309
+
310
+ get_modem_params(self, &mp);
311
+
312
+ return INT2FIX(mp.data_rate);
313
+ }
314
+
315
+ /*
316
+ * Get the current data bits
317
+ *
318
+ * @return [Integer] the current number of data bits
319
+ * @see SerialPort#set_modem_params
320
+ */
321
+ static VALUE sp_get_data_bits(self)
322
+ VALUE self;
323
+ {
324
+ struct modem_params mp;
325
+
326
+ get_modem_params(self, &mp);
327
+
328
+ return INT2FIX(mp.data_bits);
329
+ }
330
+
331
+ /*
332
+ * Get the current stop bits
333
+ *
334
+ * @return [Integer] the current number of stop bits
335
+ * @see SerialPort#set_modem_params for details
336
+ */
337
+ static VALUE sp_get_stop_bits(self)
338
+ VALUE self;
339
+ {
340
+ struct modem_params mp;
341
+
342
+ get_modem_params(self, &mp);
343
+
344
+ return INT2FIX(mp.stop_bits);
345
+ }
346
+
347
+ /*
348
+ * Get the current parity
349
+ *
350
+ * @return [Integer] the current parity
351
+ * @see SerialPort#set_modem_params
352
+ */
353
+ static VALUE sp_get_parity(self)
354
+ VALUE self;
355
+ {
356
+ struct modem_params mp;
357
+
358
+ get_modem_params(self, &mp);
359
+
360
+ return INT2FIX(mp.parity);
361
+ }
362
+
363
+ /*
364
+ * Get the configure of the serial port
365
+ *
366
+ * @return [Hash] the serial port configuration
367
+ * @see SerialPort#set_modem_params
368
+ */
369
+ static VALUE sp_get_modem_params(self)
370
+ VALUE self;
371
+ {
372
+ struct modem_params mp;
373
+ VALUE hash;
374
+
375
+ get_modem_params(self, &mp);
376
+
377
+ hash = rb_hash_new();
378
+
379
+ rb_hash_aset(hash, sBaud, INT2FIX(mp.data_rate));
380
+ rb_hash_aset(hash, sDataBits, INT2FIX(mp.data_bits));
381
+ rb_hash_aset(hash, sStopBits, INT2FIX(mp.stop_bits));
382
+ rb_hash_aset(hash, sParity, INT2FIX(mp.parity));
383
+
384
+ return hash;
385
+ }
386
+
387
+ /*
388
+ * @api private
389
+ */
390
+ void get_line_signals_helper(obj, ls)
391
+ VALUE obj;
392
+ struct line_signals *ls;
393
+ {
394
+ get_line_signals_helper_impl(obj, ls);
395
+ }
396
+
397
+ /*
398
+ * Get the state of the CTS line
399
+ *
400
+ * @return [Integer] the state of the CTS line, 0 or 1
401
+ * @see SerialPort#get_signals
402
+ */
403
+ static VALUE sp_get_cts(self)
404
+ VALUE self;
405
+ {
406
+ struct line_signals ls;
407
+
408
+ get_line_signals_helper(self, &ls);
409
+
410
+ return INT2FIX(ls.cts);
411
+ }
412
+
413
+ /*
414
+ * Get the state of the DSR line
415
+ *
416
+ * @return [Integer] the state of the DSR line, 0 or 1
417
+ * @see SerialPort#get_signals
418
+ */
419
+ static VALUE sp_get_dsr(self)
420
+ VALUE self;
421
+ {
422
+ struct line_signals ls;
423
+
424
+ get_line_signals_helper(self, &ls);
425
+
426
+ return INT2FIX(ls.dsr);
427
+ }
428
+
429
+ /*
430
+ * Get the state of the DCD line
431
+ *
432
+ * @return [Integer] the state of the DCD line, 0 or 1
433
+ * @see SerialPort#get_signals
434
+ */
435
+ static VALUE sp_get_dcd(self)
436
+ VALUE self;
437
+ {
438
+ struct line_signals ls;
439
+
440
+ get_line_signals_helper(self, &ls);
441
+
442
+ return INT2FIX(ls.dcd);
443
+ }
444
+
445
+ /*
446
+ * Get the state of the RI line
447
+ *
448
+ * @return [Integer] the state of the RI line, 0 or 1
449
+ * @see SerialPort#get_signals
450
+ */
451
+ static VALUE sp_get_ri(self)
452
+ VALUE self;
453
+ {
454
+ struct line_signals ls;
455
+
456
+ get_line_signals_helper(self, &ls);
457
+
458
+ return INT2FIX(ls.ri);
459
+ }
460
+
461
+ /*
462
+ * Return a hash with the state of each line status bit.
463
+ * Keys:
464
+ * "rts", "dtr", "cts", "dsr", "dcd", and "ri".
465
+ *
466
+ * @return [Hash] the state line info
467
+ * @note (Windows) the rts and dtr values are not included
468
+ * @note This method is implemented as both SerialPort#signals and SerialPort#get_signals
469
+ */
470
+ static VALUE sp_signals(self)
471
+ VALUE self;
472
+ {
473
+ struct line_signals ls;
474
+ VALUE hash;
475
+
476
+ get_line_signals_helper(self, &ls);
477
+
478
+ hash = rb_hash_new();
479
+
480
+ #if !(defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW))
481
+ rb_hash_aset(hash, sRts, INT2FIX(ls.rts));
482
+ rb_hash_aset(hash, sDtr, INT2FIX(ls.dtr));
483
+ #endif
484
+ rb_hash_aset(hash, sCts, INT2FIX(ls.cts));
485
+ rb_hash_aset(hash, sDsr, INT2FIX(ls.dsr));
486
+ rb_hash_aset(hash, sDcd, INT2FIX(ls.dcd));
487
+ rb_hash_aset(hash, sRi, INT2FIX(ls.ri));
488
+
489
+ return hash;
490
+ }
491
+
492
+ /**
493
+ * Flush data received but not read.
494
+ *
495
+ * @return [Boolean] true on success or false if an error occurs.
496
+ */
497
+ static VALUE sp_flush_input_data(self)
498
+ VALUE self;
499
+ {
500
+ return sp_flush_input_data_impl(self);
501
+ }
502
+
503
+ /**
504
+ * Flush data written but not transmitted.
505
+ *
506
+ * @return [Boolean] true on success or false if an error occurs.
507
+ */
508
+ static VALUE sp_flush_output_data(self)
509
+ VALUE self;
510
+ {
511
+ return sp_flush_output_data_impl(self);
512
+ }
513
+
514
+
515
+ void Init_serialport()
516
+ {
517
+ sBaud = rb_str_new2("baud");
518
+ sDataBits = rb_str_new2("data_bits");
519
+ sStopBits = rb_str_new2("stop_bits");
520
+ sParity = rb_str_new2("parity");
521
+ sRts = rb_str_new2("rts");
522
+ sDtr = rb_str_new2("dtr");
523
+ sCts = rb_str_new2("cts");
524
+ sDsr = rb_str_new2("dsr");
525
+ sDcd = rb_str_new2("dcd");
526
+ sRi = rb_str_new2("ri");
527
+
528
+ rb_gc_register_address(&sBaud);
529
+ rb_gc_register_address(&sDataBits);
530
+ rb_gc_register_address(&sStopBits);
531
+ rb_gc_register_address(&sParity);
532
+ rb_gc_register_address(&sRts);
533
+ rb_gc_register_address(&sDtr);
534
+ rb_gc_register_address(&sCts);
535
+ rb_gc_register_address(&sDsr);
536
+ rb_gc_register_address(&sDcd);
537
+ rb_gc_register_address(&sRi);
538
+
539
+ cSerialPort = rb_define_class("SerialPort", rb_cIO);
540
+ rb_define_singleton_method(cSerialPort, "create", sp_create, 1);
541
+
542
+ rb_define_method(cSerialPort, "get_modem_params", sp_get_modem_params, 0);
543
+ rb_define_method(cSerialPort, "set_modem_params", sp_set_modem_params, -1);
544
+ rb_define_method(cSerialPort, "modem_params", sp_get_modem_params, 0);
545
+ rb_define_method(cSerialPort, "modem_params=", sp_set_modem_params, -1);
546
+ rb_define_method(cSerialPort, "baud", sp_get_data_rate, 0);
547
+ rb_define_method(cSerialPort, "baud=", sp_set_data_rate, 1);
548
+ rb_define_method(cSerialPort, "data_bits", sp_get_data_bits, 0);
549
+ rb_define_method(cSerialPort, "data_bits=", sp_set_data_bits, 1);
550
+ rb_define_method(cSerialPort, "stop_bits", sp_get_stop_bits, 0);
551
+ rb_define_method(cSerialPort, "stop_bits=", sp_set_stop_bits, 1);
552
+ rb_define_method(cSerialPort, "parity", sp_get_parity, 0);
553
+ rb_define_method(cSerialPort, "parity=", sp_set_parity, 1);
554
+
555
+ rb_define_method(cSerialPort, "flow_control=", sp_set_flow_control, 1);
556
+ rb_define_method(cSerialPort, "flow_control", sp_get_flow_control, 0);
557
+
558
+ rb_define_method(cSerialPort, "read_timeout", sp_get_read_timeout, 0);
559
+ rb_define_method(cSerialPort, "read_timeout=", sp_set_read_timeout, 1);
560
+ rb_define_method(cSerialPort, "write_timeout", sp_get_write_timeout, 0);
561
+ rb_define_method(cSerialPort, "write_timeout=", sp_set_write_timeout, 1);
562
+
563
+ rb_define_method(cSerialPort, "break", sp_break, 1);
564
+
565
+ rb_define_method(cSerialPort, "signals", sp_signals, 0);
566
+ rb_define_method(cSerialPort, "get_signals", sp_signals, 0);
567
+ rb_define_method(cSerialPort, "rts", sp_get_rts, 0);
568
+ rb_define_method(cSerialPort, "rts=", sp_set_rts, 1);
569
+ rb_define_method(cSerialPort, "dtr", sp_get_dtr, 0);
570
+ rb_define_method(cSerialPort, "dtr=", sp_set_dtr, 1);
571
+ rb_define_method(cSerialPort, "cts", sp_get_cts, 0);
572
+ rb_define_method(cSerialPort, "dsr", sp_get_dsr, 0);
573
+ rb_define_method(cSerialPort, "dcd", sp_get_dcd, 0);
574
+ rb_define_method(cSerialPort, "ri", sp_get_ri, 0);
575
+
576
+ rb_define_method(cSerialPort, "flush_input", sp_flush_input_data, 0);
577
+ rb_define_method(cSerialPort, "flush_output", sp_flush_output_data, 0);
578
+
579
+ /*
580
+ * 0
581
+ */
582
+ rb_define_const(cSerialPort, "NONE", INT2FIX(NONE));
583
+
584
+ /*
585
+ * 1
586
+ */
587
+ rb_define_const(cSerialPort, "HARD", INT2FIX(HARD));
588
+
589
+ /*
590
+ * 2
591
+ */
592
+ rb_define_const(cSerialPort, "SOFT", INT2FIX(SOFT));
593
+
594
+ /*
595
+ * 0
596
+ */
597
+ rb_define_const(cSerialPort, "SPACE", INT2FIX(SPACE));
598
+
599
+ /*
600
+ * 1
601
+ */
602
+ rb_define_const(cSerialPort, "MARK", INT2FIX(MARK));
603
+
604
+ /*
605
+ * 2
606
+ */
607
+ rb_define_const(cSerialPort, "EVEN", INT2FIX(EVEN));
608
+
609
+ /*
610
+ * 3
611
+ */
612
+ rb_define_const(cSerialPort, "ODD", INT2FIX(ODD));
613
+ }