hybridgroup-serialport 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,530 @@
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
+ * 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
+ #include "serialport.h"
22
+
23
+ VALUE cSerialPort; /* serial port class */
24
+
25
+ VALUE sBaud, sDataBits, sStopBits, sParity; /* strings */
26
+ VALUE sRts, sDtr, sCts, sDsr, sDcd, sRi;
27
+
28
+ /*
29
+ * :nodoc: This method is private and will be called by SerialPort#new or SerialPort#open.
30
+ */
31
+ static VALUE sp_create(class, _port)
32
+ VALUE class, _port;
33
+ {
34
+ return sp_create_impl(class, _port);
35
+ }
36
+
37
+ /*
38
+ * Configure the serial port. You can pass a hash or multiple values
39
+ * as separate arguments. Invalid or unsupported values will raise
40
+ * an ArgumentError.
41
+ *
42
+ * When using a hash the following keys are recognized:
43
+ * ["baud"] Integer from 50 to 256000, depends on platform
44
+ * ["data_bits"] Integer from 5 to 8 (4 is allowed on Windows too)
45
+ * ["stop_bits"] An integer, only allowed values are 1 or 2 (1.5 is not supported)
46
+ * ["parity"] One of the constants NONE, EVEN or ODD (Windows allows also MARK and SPACE)
47
+ *
48
+ * When using separate arguments, they are interpreted as:
49
+ * (baud, data_bits = 8, stop_bits = 1, parity = (previous_databits==8 ? NONE : EVEN))
50
+ *
51
+ * Nota: A baudrate of nil will keep the old value. The default parity depends on the
52
+ * number of databits configured before this function call.
53
+ */
54
+ static VALUE sp_set_modem_params(argc, argv, self)
55
+ int argc;
56
+ VALUE *argv, self;
57
+ {
58
+ return sp_set_modem_params_impl(argc, argv, self);
59
+ }
60
+
61
+ /*
62
+ * Send a break for the given time.
63
+ *
64
+ * <tt>time</tt> is an integer of tenths-of-a-second for the break.
65
+ *
66
+ * Note: Under Posix, this value is very approximate.
67
+ */
68
+ static VALUE sp_break(self, time)
69
+ VALUE self, time;
70
+ {
71
+ return sp_break_impl(self, time);
72
+ }
73
+
74
+ /*
75
+ * Get the state (0 or 1) of the DTR line (not available on Windows)
76
+ */
77
+ static VALUE sp_get_dtr(self)
78
+ VALUE self;
79
+ {
80
+ return sp_get_dtr_impl(self);
81
+ }
82
+
83
+ /*
84
+ * Get the flow control. The result is either NONE, HARD, SOFT or (HARD | SOFT)
85
+ */
86
+ static VALUE sp_get_flow_control(self)
87
+ VALUE self;
88
+ {
89
+ return sp_get_flow_control_impl(self);
90
+ }
91
+
92
+ /*
93
+ * Get the timeout value (in milliseconds) for reading.
94
+ * See SerialPort#set_read_timeout for details.
95
+ */
96
+ static VALUE sp_get_read_timeout(self)
97
+ VALUE self;
98
+ {
99
+ return sp_get_read_timeout_impl(self);
100
+ }
101
+
102
+ /*
103
+ * Get the state (0 or 1) of the RTS line (not available on Windows)
104
+ */
105
+ static VALUE sp_get_rts(self)
106
+ VALUE self;
107
+ {
108
+ return sp_get_rts_impl(self);
109
+ }
110
+
111
+ /*
112
+ * Get the write timeout (in milliseconds)
113
+ *
114
+ * Note: Under Posix, write timeouts are not implemented.
115
+ */
116
+ static VALUE sp_get_write_timeout(self)
117
+ VALUE self;
118
+ {
119
+ return sp_get_write_timeout_impl(self);
120
+ }
121
+
122
+ /*
123
+ * Set the state (0 or 1) of the DTR line
124
+ */
125
+ static VALUE sp_set_dtr(self, val)
126
+ VALUE self, val;
127
+ {
128
+ return sp_set_dtr_impl(self, val);
129
+ }
130
+
131
+ /*
132
+ * Set the flow control to either NONE, HARD, SOFT or (HARD | SOFT)
133
+ *
134
+ * Note: SerialPort::HARD mode is not supported on all platforms.
135
+ * SerialPort::HARD uses RTS/CTS handshaking; DSR/DTR is not
136
+ * supported.
137
+ */
138
+ static VALUE sp_set_flow_control(self, val)
139
+ VALUE self, val;
140
+ {
141
+ return sp_set_flow_control_impl(self, val);
142
+ }
143
+
144
+ /*
145
+ * Set the timeout value (in milliseconds) for reading.
146
+ * A negative read timeout will return all the available data without
147
+ * waiting, a zero read timeout will not return until at least one
148
+ * byte is available, and a positive read timeout returns when the
149
+ * requested number of bytes is available or the interval between the
150
+ * arrival of two bytes exceeds the timeout value.
151
+ *
152
+ * Note: Read timeouts don't mix well with multi-threading.
153
+ */
154
+ static VALUE sp_set_read_timeout(self, val)
155
+ VALUE self, val;
156
+ {
157
+ return sp_set_read_timeout_impl(self, val);
158
+ }
159
+
160
+ /*
161
+ * Set the state (0 or 1) of the RTS line
162
+ */
163
+ static VALUE sp_set_rts(self, val)
164
+ VALUE self, val;
165
+ {
166
+ return sp_set_rts_impl(self, val);
167
+ }
168
+
169
+ /*
170
+ * Set a write timeout (in milliseconds)
171
+ *
172
+ * Note: Under Posix, write timeouts are not implemented.
173
+ */
174
+ static VALUE sp_set_write_timeout(self, val)
175
+ VALUE self, val;
176
+ {
177
+ return sp_set_write_timeout_impl(self, val);
178
+ }
179
+
180
+ /*
181
+ */
182
+ static void get_modem_params(self, mp)
183
+ VALUE self;
184
+ struct modem_params *mp;
185
+ {
186
+ get_modem_params_impl(self, mp);
187
+ }
188
+
189
+ /*
190
+ * Set the baud rate, see SerialPort#set_modem_params for details.
191
+ */
192
+ static VALUE sp_set_data_rate(self, data_rate)
193
+ VALUE self, data_rate;
194
+ {
195
+ VALUE argv[4];
196
+
197
+ argv[0] = data_rate;
198
+ argv[1] = argv[2] = argv[3] = Qnil;
199
+ sp_set_modem_params(4, argv, self);
200
+
201
+ return data_rate;
202
+ }
203
+
204
+ /*
205
+ * Set the data bits, see SerialPort#set_modem_params for details.
206
+ */
207
+ static VALUE sp_set_data_bits(self, data_bits)
208
+ VALUE self, data_bits;
209
+ {
210
+ VALUE argv[4];
211
+
212
+ argv[1] = data_bits;
213
+ argv[0] = argv[2] = argv[3] = Qnil;
214
+ sp_set_modem_params(4, argv, self);
215
+
216
+ return data_bits;
217
+ }
218
+
219
+ /*
220
+ * Set the stop bits, see SerialPort#set_modem_params for details.
221
+ */
222
+ static VALUE sp_set_stop_bits(self, stop_bits)
223
+ VALUE self, stop_bits;
224
+ {
225
+ VALUE argv[4];
226
+
227
+ argv[2] = stop_bits;
228
+ argv[0] = argv[1] = argv[3] = Qnil;
229
+ sp_set_modem_params(4, argv, self);
230
+
231
+ return stop_bits;
232
+ }
233
+
234
+ /*
235
+ * Set the parity, see SerialPort#set_modem_params for details.
236
+ */
237
+ static VALUE sp_set_parity(self, parity)
238
+ VALUE self, parity;
239
+ {
240
+ VALUE argv[4];
241
+
242
+ argv[3] = parity;
243
+ argv[0] = argv[1] = argv[2] = Qnil;
244
+ sp_set_modem_params(4, argv, self);
245
+
246
+ return parity;
247
+ }
248
+
249
+ /*
250
+ * Get the current baud rate, see SerialPort#get_modem_params for details.
251
+ */
252
+ static VALUE sp_get_data_rate(self)
253
+ VALUE self;
254
+ {
255
+ struct modem_params mp;
256
+
257
+ get_modem_params(self, &mp);
258
+
259
+ return INT2FIX(mp.data_rate);
260
+ }
261
+
262
+ /*
263
+ * Get the current data bits, see SerialPort#get_modem_params for details.
264
+ */
265
+ static VALUE sp_get_data_bits(self)
266
+ VALUE self;
267
+ {
268
+ struct modem_params mp;
269
+
270
+ get_modem_params(self, &mp);
271
+
272
+ return INT2FIX(mp.data_bits);
273
+ }
274
+
275
+ /*
276
+ * Get the current stop bits, see SerialPort#get_modem_params for details.
277
+ */
278
+ static VALUE sp_get_stop_bits(self)
279
+ VALUE self;
280
+ {
281
+ struct modem_params mp;
282
+
283
+ get_modem_params(self, &mp);
284
+
285
+ return INT2FIX(mp.stop_bits);
286
+ }
287
+
288
+ /*
289
+ * Get the current parity, see SerialPort#get_modem_params for details.
290
+ */
291
+ static VALUE sp_get_parity(self)
292
+ VALUE self;
293
+ {
294
+ struct modem_params mp;
295
+
296
+ get_modem_params(self, &mp);
297
+
298
+ return INT2FIX(mp.parity);
299
+ }
300
+
301
+ /*
302
+ * Get the configure of the serial port.
303
+ *
304
+ * Returned is a hash with the following keys:
305
+ * ["baud"] Integer with the baud rate
306
+ * ["data_bits"] Integer from 5 to 8 (4 is possible on Windows too)
307
+ * ["stop_bits"] Integer, 1 or 2 (1.5 is not supported)
308
+ * ["parity"] One of the constants NONE, EVEN or ODD (on Windows may also MARK or SPACE)
309
+ */
310
+ static VALUE sp_get_modem_params(self)
311
+ VALUE self;
312
+ {
313
+ struct modem_params mp;
314
+ VALUE hash;
315
+
316
+ get_modem_params(self, &mp);
317
+
318
+ hash = rb_hash_new();
319
+
320
+ rb_hash_aset(hash, sBaud, INT2FIX(mp.data_rate));
321
+ rb_hash_aset(hash, sDataBits, INT2FIX(mp.data_bits));
322
+ rb_hash_aset(hash, sStopBits, INT2FIX(mp.stop_bits));
323
+ rb_hash_aset(hash, sParity, INT2FIX(mp.parity));
324
+
325
+ return hash;
326
+ }
327
+
328
+ void get_line_signals_helper(obj, ls)
329
+ VALUE obj;
330
+ struct line_signals *ls;
331
+ {
332
+ get_line_signals_helper_impl(obj, ls);
333
+ }
334
+
335
+ /*
336
+ * Get the state (0 or 1) of the CTS line
337
+ */
338
+ static VALUE sp_get_cts(self)
339
+ VALUE self;
340
+ {
341
+ struct line_signals ls;
342
+
343
+ get_line_signals_helper(self, &ls);
344
+
345
+ return INT2FIX(ls.cts);
346
+ }
347
+
348
+ /*
349
+ * Get the state (0 or 1) of the DSR line
350
+ */
351
+ static VALUE sp_get_dsr(self)
352
+ VALUE self;
353
+ {
354
+ struct line_signals ls;
355
+
356
+ get_line_signals_helper(self, &ls);
357
+
358
+ return INT2FIX(ls.dsr);
359
+ }
360
+
361
+ /*
362
+ * Get the state (0 or 1) of the DCD line
363
+ */
364
+ static VALUE sp_get_dcd(self)
365
+ VALUE self;
366
+ {
367
+ struct line_signals ls;
368
+
369
+ get_line_signals_helper(self, &ls);
370
+
371
+ return INT2FIX(ls.dcd);
372
+ }
373
+
374
+ /*
375
+ * Get the state (0 or 1) of the RI line
376
+ */
377
+ static VALUE sp_get_ri(self)
378
+ VALUE self;
379
+ {
380
+ struct line_signals ls;
381
+
382
+ get_line_signals_helper(self, &ls);
383
+
384
+ return INT2FIX(ls.ri);
385
+ }
386
+
387
+ /*
388
+ * Return a hash with the state of each line status bit. Keys are
389
+ * "rts", "dtr", "cts", "dsr", "dcd", and "ri".
390
+ *
391
+ * Note: Under Windows, the rts and dtr values are not included.
392
+ */
393
+ static VALUE sp_signals(self)
394
+ VALUE self;
395
+ {
396
+ struct line_signals ls;
397
+ VALUE hash;
398
+
399
+ get_line_signals_helper(self, &ls);
400
+
401
+ hash = rb_hash_new();
402
+
403
+ #if !(defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW))
404
+ rb_hash_aset(hash, sRts, INT2FIX(ls.rts));
405
+ rb_hash_aset(hash, sDtr, INT2FIX(ls.dtr));
406
+ #endif
407
+ rb_hash_aset(hash, sCts, INT2FIX(ls.cts));
408
+ rb_hash_aset(hash, sDsr, INT2FIX(ls.dsr));
409
+ rb_hash_aset(hash, sDcd, INT2FIX(ls.dcd));
410
+ rb_hash_aset(hash, sRi, INT2FIX(ls.ri));
411
+
412
+ return hash;
413
+ }
414
+
415
+ static VALUE sp_write(self, str)
416
+ VALUE self, str;
417
+ {
418
+ return sp_write_impl(self, str);
419
+ }
420
+
421
+ static VALUE sp_read(argc, argv, self)
422
+ int argc;
423
+ VALUE *argv, self;
424
+ {
425
+ return sp_read_impl(argc, argv, self);
426
+ }
427
+
428
+ static void sp_close(self)
429
+ VALUE self;
430
+ {
431
+ sp_close_impl(self);
432
+ }
433
+
434
+ static void sp_set_initial_offset(self, offset)
435
+ VALUE self, offset;
436
+ {
437
+ sp_set_initial_offset_impl(self, offset);
438
+ }
439
+
440
+ /*
441
+ * This class is used for communication over a serial port.
442
+ * In addition to the methods here, you can use everything
443
+ * Ruby's IO-class provides (read, write, getc, readlines, ...)
444
+ */
445
+ void Init_serialport()
446
+ {
447
+ sBaud = rb_str_new2("baud");
448
+ sDataBits = rb_str_new2("data_bits");
449
+ sStopBits = rb_str_new2("stop_bits");
450
+ sParity = rb_str_new2("parity");
451
+ sRts = rb_str_new2("rts");
452
+ sDtr = rb_str_new2("dtr");
453
+ sCts = rb_str_new2("cts");
454
+ sDsr = rb_str_new2("dsr");
455
+ sDcd = rb_str_new2("dcd");
456
+ sRi = rb_str_new2("ri");
457
+
458
+ rb_gc_register_address(&sBaud);
459
+ rb_gc_register_address(&sDataBits);
460
+ rb_gc_register_address(&sStopBits);
461
+ rb_gc_register_address(&sParity);
462
+ rb_gc_register_address(&sRts);
463
+ rb_gc_register_address(&sDtr);
464
+ rb_gc_register_address(&sCts);
465
+ rb_gc_register_address(&sDsr);
466
+ rb_gc_register_address(&sDcd);
467
+ rb_gc_register_address(&sRi);
468
+
469
+ #if (defined(WIN32) || defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW))
470
+ cSerialPort = rb_define_class("SerialPort", rb_cObject);
471
+ rb_define_method(cSerialPort, "write", sp_write, 1);
472
+ rb_define_method(cSerialPort, "read", sp_read, -1);
473
+ rb_define_method(cSerialPort, "close", sp_close, 0);
474
+ rb_define_class_variable(cSerialPort,"@@fh",NULL);
475
+ rb_define_class_variable(cSerialPort,"@@byte_offset",0);
476
+ rb_define_class_variable(cSerialPort,"@@initial_offset",0);
477
+ rb_define_method(cSerialPort, "initial_byte_offset=", sp_set_initial_offset, 1);
478
+ #else
479
+ cSerialPort = rb_define_class("SerialPort", rb_cIO);
480
+ #endif
481
+
482
+ rb_define_singleton_method(cSerialPort, "create", sp_create, 1);
483
+
484
+ rb_define_method(cSerialPort, "get_modem_params", sp_get_modem_params, 0);
485
+ rb_define_method(cSerialPort, "set_modem_params", sp_set_modem_params, -1);
486
+ rb_define_method(cSerialPort, "modem_params", sp_get_modem_params, 0);
487
+ rb_define_method(cSerialPort, "modem_params=", sp_set_modem_params, -1);
488
+ rb_define_method(cSerialPort, "baud", sp_get_data_rate, 0);
489
+ rb_define_method(cSerialPort, "baud=", sp_set_data_rate, 1);
490
+ rb_define_method(cSerialPort, "data_bits", sp_get_data_bits, 0);
491
+ rb_define_method(cSerialPort, "data_bits=", sp_set_data_bits, 1);
492
+ rb_define_method(cSerialPort, "stop_bits", sp_get_stop_bits, 0);
493
+ rb_define_method(cSerialPort, "stop_bits=", sp_set_stop_bits, 1);
494
+ rb_define_method(cSerialPort, "parity", sp_get_parity, 0);
495
+ rb_define_method(cSerialPort, "parity=", sp_set_parity, 1);
496
+
497
+ rb_define_method(cSerialPort, "flow_control=", sp_set_flow_control, 1);
498
+ rb_define_method(cSerialPort, "flow_control", sp_get_flow_control, 0);
499
+
500
+ rb_define_method(cSerialPort, "read_timeout", sp_get_read_timeout, 0);
501
+ rb_define_method(cSerialPort, "read_timeout=", sp_set_read_timeout, 1);
502
+ rb_define_method(cSerialPort, "write_timeout", sp_get_write_timeout, 0);
503
+ rb_define_method(cSerialPort, "write_timeout=", sp_set_write_timeout, 1);
504
+
505
+ rb_define_method(cSerialPort, "break", sp_break, 1);
506
+
507
+ rb_define_method(cSerialPort, "signals", sp_signals, 0);
508
+ rb_define_method(cSerialPort, "get_signals", sp_signals, 0);
509
+ rb_define_method(cSerialPort, "rts", sp_get_rts, 0);
510
+ rb_define_method(cSerialPort, "rts=", sp_set_rts, 1);
511
+ rb_define_method(cSerialPort, "dtr", sp_get_dtr, 0);
512
+ rb_define_method(cSerialPort, "dtr=", sp_set_dtr, 1);
513
+ rb_define_method(cSerialPort, "cts", sp_get_cts, 0);
514
+ rb_define_method(cSerialPort, "dsr", sp_get_dsr, 0);
515
+ rb_define_method(cSerialPort, "dcd", sp_get_dcd, 0);
516
+ rb_define_method(cSerialPort, "ri", sp_get_ri, 0);
517
+
518
+ rb_define_const(cSerialPort, "NONE", INT2FIX(NONE));
519
+ rb_define_const(cSerialPort, "HARD", INT2FIX(HARD));
520
+ rb_define_const(cSerialPort, "SOFT", INT2FIX(SOFT));
521
+
522
+ rb_define_const(cSerialPort, "SPACE", INT2FIX(SPACE));
523
+ rb_define_const(cSerialPort, "MARK", INT2FIX(MARK));
524
+ rb_define_const(cSerialPort, "EVEN", INT2FIX(EVEN));
525
+ rb_define_const(cSerialPort, "ODD", INT2FIX(ODD));
526
+
527
+ /* the package's version as a string "X.Y.Z", beeing major, minor and patch level */
528
+ rb_define_const(cSerialPort, "VERSION", rb_str_new2(RUBY_SERIAL_PORT_VERSION));
529
+
530
+ }