ruby-serialport 0.7.0

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