rs_232 2.3.2.pre → 3.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2013, Ingenico Inc.
2
+ * Copyright (c) 2013, Roman Lishtaba.
3
3
  *
4
4
  * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
5
5
  * provided that the above copyright notice and this permission notice appear in all copies.
@@ -12,9 +12,16 @@
12
12
  *
13
13
  **/
14
14
 
15
- #ifndef rs_232_port_h____FILEEXTENSION___
16
- #define rs_232_port_h____FILEEXTENSION___
15
+ /*
16
+ * @author Roman Lishtaba
17
+ */
18
+
19
+ #pragma once
17
20
 
21
+ #ifdef __cplusplus
22
+ extern "C" {
23
+ #endif
24
+
18
25
  # include <ruby.h>
19
26
  # include <stdio.h>
20
27
  # include <string.h>
@@ -23,31 +30,33 @@
23
30
  # include <errno.h>
24
31
  # include <termios.h>
25
32
  # include <sys/ioctl.h>
26
- # include "structs.h"
27
-
28
-
29
- void setBaudRate(VALUE, VALUE);
30
-
31
- VALUE getBaudRate(VALUE);
32
-
33
- void setParity(VALUE, VALUE);
34
-
35
- VALUE getParity(VALUE);
36
-
37
- void setDataBits(VALUE, VALUE);
38
-
39
- VALUE getDataBits(VALUE);
40
-
41
- void setStopBits(VALUE, VALUE);
42
-
43
- VALUE getStopBits(VALUE);
44
-
45
- void setFlowControl(VALUE, VALUE);
46
-
47
- VALUE getFlowControl(VALUE);
48
-
49
- void setTimeout(VALUE, VALUE);
50
-
51
- void setSettings(VALUE);
52
-
33
+ # include "Structs.h"
34
+
35
+
36
+ void setBaudRate(VALUE, VALUE);
37
+
38
+ VALUE getBaudRate(VALUE);
39
+
40
+ void setParity(VALUE, VALUE);
41
+
42
+ VALUE getParity(VALUE);
43
+
44
+ void setDataBits(VALUE, VALUE);
45
+
46
+ VALUE getDataBits(VALUE);
47
+
48
+ void setStopBits(VALUE, VALUE);
49
+
50
+ VALUE getStopBits(VALUE);
51
+
52
+ void setFlowControl(VALUE, VALUE);
53
+
54
+ VALUE getFlowControl(VALUE);
55
+
56
+ void setTimeout(VALUE, VALUE);
57
+
58
+ void setSettings(VALUE);
59
+
60
+ #ifdef __cplusplus
61
+ }
53
62
  #endif
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2013, Ingenico Inc.
2
+ * Copyright (c) 2013, Roman Lishtaba.
3
3
  *
4
4
  * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
5
5
  * provided that the above copyright notice and this permission notice appear in all copies.
@@ -12,7 +12,11 @@
12
12
  *
13
13
  **/
14
14
 
15
- #include "port.h"
15
+ /*
16
+ * @author Roman Lishtaba
17
+ */
18
+
19
+ #include "Port.h"
16
20
 
17
21
 
18
22
  VALUE setDtrIO(VALUE self, VALUE rb_int)
@@ -20,49 +24,44 @@ VALUE setDtrIO(VALUE self, VALUE rb_int)
20
24
  {
21
25
  Check_Type(rb_int, T_FIXNUM);
22
26
  }
23
-
24
27
  int boolean = FIX2INT(rb_int);
25
-
26
28
  PortDescriptor *port = NULL;
27
-
28
29
  Data_Get_Struct(self, PortDescriptor, port);
29
-
30
+
30
31
  return INT2FIX( EscapeCommFunction(port->fd, boolean == 1 ? SETDTR : CLRDTR) );
31
32
  }
32
33
 
33
34
 
34
35
  VALUE setRtsIO(VALUE self, VALUE rb_int)
35
36
  {
36
- {
37
- Check_Type(rb_int, T_FIXNUM);
38
- }
39
-
37
+ Check_Type(rb_int, T_FIXNUM);
38
+
40
39
  int boolean = FIX2INT(rb_int);
41
-
40
+
42
41
  PortDescriptor *port = NULL;
43
-
42
+
44
43
  Data_Get_Struct(self, PortDescriptor, port);
45
-
44
+
46
45
  return INT2FIX( EscapeCommFunction(port->fd, boolean == 1 ? SETRTS : CLRRTS) );
47
46
  }
48
47
 
49
48
 
50
49
  VALUE lineStatusIO(VALUE self)
51
50
  {
52
-
51
+
53
52
  PortDescriptor *port = NULL;
54
-
53
+
55
54
  Data_Get_Struct(self, PortDescriptor, port);
56
-
55
+
57
56
  unsigned long Status = 0, Temp = 0;
58
-
57
+
59
58
  GetCommModemStatus(port->fd, &Temp);
60
-
59
+
61
60
  if (Temp & MS_CTS_ON) Status |= LS_CTS;
62
61
  if (Temp & MS_DSR_ON) Status |= LS_DSR;
63
62
  if (Temp & MS_RING_ON) Status |= LS_RI;
64
63
  if (Temp & MS_RLSD_ON) Status |= LS_DCD;
65
-
64
+
66
65
  return LONG2FIX(Status);
67
66
  }
68
67
 
@@ -76,28 +75,28 @@ static void platformInitIO(PortDescriptor *port)
76
75
 
77
76
  void updateSettings(PortDescriptor *port)
78
77
  {
79
-
80
- if (port->status != 0)
81
- rb_raise(rb_eException, "Can not set due to comport is not open, status: %d\n", port->status);
82
-
83
-
78
+
79
+ if (PORT_OPEN != port->status)
80
+ rb_raise(rb_eRuntimeError, "Can not set due to comport is not open, status: %d\n", port->status);
81
+
82
+
84
83
  if (port->toBeUpdated & T_BaudRate)
85
84
  port->commConfig.dcb.BaudRate = port->settings.BaudRate;
86
-
87
-
85
+
86
+
88
87
  if (port->toBeUpdated & T_Parity)
89
88
  {
90
89
  port->commConfig.dcb.Parity = (BYTE) port->settings.Parity;
91
90
  port->commConfig.dcb.fParity = (port->settings.Parity == PAR_NONE) ? 0 : 1;
92
91
  }
93
-
94
-
92
+
93
+
95
94
  if (port->toBeUpdated & T_DataBits)
96
95
  {
97
96
  port->commConfig.dcb.ByteSize = (BYTE) port->settings.DataBits;
98
97
  }
99
-
100
-
98
+
99
+
101
100
  if (port->toBeUpdated & T_StopBits)
102
101
  {
103
102
  switch (port->settings.StopBits)
@@ -110,7 +109,7 @@ void updateSettings(PortDescriptor *port)
110
109
  break;
111
110
  }
112
111
  }
113
-
112
+
114
113
  if (port->toBeUpdated & T_Flow)
115
114
  {
116
115
  switch (port->settings.FlowControl)
@@ -135,11 +134,11 @@ void updateSettings(PortDescriptor *port)
135
134
  break;
136
135
  }
137
136
  }
138
-
137
+
139
138
  if (port->toBeUpdated & T_TimeOut)
140
139
  {
141
140
  int millisec = port->settings.Timeout_Millisec;
142
-
141
+
143
142
  if (millisec == -1)
144
143
  {
145
144
  port->commTimeouts.ReadIntervalTimeout = MAXDWORD;
@@ -153,14 +152,14 @@ void updateSettings(PortDescriptor *port)
153
152
  port->commTimeouts.WriteTotalTimeoutMultiplier = millisec;
154
153
  port->commTimeouts.WriteTotalTimeoutConstant = 0;
155
154
  }
156
-
157
-
155
+
156
+
158
157
  if (port->toBeUpdated & T_SettingsDone)
159
158
  SetCommConfig(port->fd, &port->commConfig, sizeof(COMMCONFIG));
160
-
159
+
161
160
  if ((port->toBeUpdated & T_TimeOut))
162
161
  SetCommTimeouts(port->fd, &port->commTimeouts);
163
-
162
+
164
163
  port->toBeUpdated = 0;
165
164
  }
166
165
 
@@ -168,25 +167,25 @@ void updateSettings(PortDescriptor *port)
168
167
  static int queryStatusIO(VALUE self)
169
168
  {
170
169
  PortDescriptor *port = NULL;
171
-
170
+
172
171
  Data_Get_Struct(self, PortDescriptor, port);
173
-
172
+
174
173
  return port->status;
175
174
  }
176
175
 
177
176
 
178
- VALUE isClosedIO(VALUE self)
177
+ VALUE isOpenIO(VALUE self)
179
178
  {
180
- return queryStatusIO(self) != 0 ? Qtrue : Qfalse;
179
+ return queryStatusIO(self) != PORT_OPEN ? Qtrue : Qfalse;
181
180
  }
182
181
 
183
182
 
184
183
  VALUE flushIO(VALUE self)
185
184
  {
186
185
  PortDescriptor *port = NULL;
187
-
186
+
188
187
  Data_Get_Struct(self, PortDescriptor, port);
189
-
188
+
190
189
  return (INT2FIX(FlushFileBuffers(port->fd)));
191
190
  }
192
191
 
@@ -194,9 +193,9 @@ VALUE flushIO(VALUE self)
194
193
  VALUE bytesAvailableIO(VALUE self)
195
194
  {
196
195
  PortDescriptor *port = NULL;
197
-
196
+
198
197
  Data_Get_Struct(self, PortDescriptor, port);
199
-
198
+
200
199
  DWORD Errors;
201
200
  COMSTAT Status;
202
201
  if (ClearCommError(port->fd, &Errors, &Status))
@@ -209,150 +208,148 @@ VALUE bytesAvailableIO(VALUE self)
209
208
 
210
209
  VALUE openIO(VALUE self)
211
210
  {
212
-
211
+
213
212
  PortDescriptor *port = NULL;
214
-
215
213
  Data_Get_Struct(self, PortDescriptor, port);
216
-
217
- if (port->status == 0)
218
- return INT2FIX(port->status);
219
-
214
+ if (port->status == PORT_OPEN)
215
+ return self;
216
+
220
217
  DWORD conf_length = sizeof(COMMCONFIG);
221
218
  port->commConfig.dwSize = conf_length;
222
219
  DWORD threading = 0;
223
-
220
+
224
221
  port->fd = CreateFileA(port->settings.ComPort,
225
- GENERIC_READ | GENERIC_WRITE,
226
- 0,
227
- NULL,
228
- OPEN_EXISTING,
229
- threading,
230
- NULL);
231
-
222
+ GENERIC_READ | GENERIC_WRITE,
223
+ 0,
224
+ NULL,
225
+ OPEN_EXISTING,
226
+ threading,
227
+ NULL);
228
+
232
229
  if (port->fd == INVALID_HANDLE_VALUE)
233
230
  {
234
-
235
- port->status = 1;
236
- rb_raise(rb_eException, "Unable to open comport: %s\n", port->settings.ComPort);
237
-
231
+
232
+ port->status = PORT_CLOSED;
233
+ rb_raise(rb_eRuntimeError, "Unable to open comport: `%s`", port->settings.ComPort);
234
+
238
235
  } else
239
236
  {
240
-
241
- port->status = 0;
237
+
238
+ port->status = PORT_OPEN;
242
239
  rb_iv_set(self, "@open", INT2FIX(port->status));
243
-
240
+
244
241
  GetCommConfig(port->fd, &port->commConfig, &conf_length);
245
242
  GetCommState(port->fd, &(port->commConfig.dcb));
246
-
243
+
247
244
  port->commConfig.dcb.fBinary = 1;
248
245
  port->commConfig.dcb.fInX = 0;
249
246
  port->commConfig.dcb.fOutX = 0;
250
247
  port->commConfig.dcb.fAbortOnError = 0;
251
248
  port->commConfig.dcb.fNull = 0;
252
-
249
+
253
250
  port->commConfig.dcb.fDtrControl = 1;
254
-
251
+
255
252
  port->toBeUpdated = T_ALL;
256
-
253
+
257
254
  setSettings(self);
258
-
255
+
259
256
  }
260
-
261
- return INT2FIX(port->status);
257
+
258
+ return self;
262
259
  }
263
260
 
264
261
 
265
262
  VALUE writeIO(VALUE self, VALUE message)
266
263
  {
267
-
264
+
268
265
  int recv;
269
266
  int len;
270
267
  PortDescriptor *port = NULL;
271
-
268
+
272
269
  Data_Get_Struct(self, PortDescriptor, port);
273
-
270
+
274
271
  Check_Type(message, T_STRING);
275
-
272
+
276
273
  len = RSTRING_LEN(message);
277
274
  char cStr[len];
278
275
  strcpy(cStr, RSTRING_PTR(message));
279
-
276
+
280
277
  if (!WriteFile(port->fd, cStr, len, (LPDWORD)((void *) &recv), NULL))
281
278
  {
282
279
  rb_raise(rb_eIOError, "IO: writing of the %d bytes has been failed", len);
283
280
  }
284
-
281
+
285
282
  return (INT2FIX(recv));
286
-
283
+
287
284
  }
288
285
 
289
286
 
290
287
  VALUE readIO(VALUE self, VALUE rb_int)
291
288
  {
292
-
289
+
293
290
  {
294
291
  Check_Type(rb_int, T_FIXNUM);
295
292
  }
296
-
293
+
297
294
  PortDescriptor *port = NULL;
298
-
295
+
299
296
  Data_Get_Struct(self, PortDescriptor, port);
300
-
297
+
301
298
  int n;
302
299
  int len = FIX2INT(rb_int);
303
300
  char buf[len];
304
-
301
+
305
302
  ReadFile(port->fd, &buf, len, (LPDWORD)((void *) &n), NULL);
306
-
303
+
307
304
  if (n > 0)
308
- return rb_str_new(buf, n);
309
-
305
+ return rb_str_new(buf, n);
306
+
310
307
  return Qnil;
311
308
  }
312
309
 
313
310
 
314
311
  VALUE closeIO(VALUE self)
315
312
  {
316
-
313
+
317
314
  PortDescriptor *port = NULL;
318
-
315
+
319
316
  Data_Get_Struct(self, PortDescriptor, port);
320
-
317
+
321
318
  flushIO(self);
322
319
  port->status = CloseHandle(port->fd);
323
320
  port->fd = INVALID_HANDLE_VALUE;
324
-
321
+
325
322
  rb_iv_set(self, "@open", INT2FIX(port->status));
326
-
323
+
327
324
  return INT2FIX(port->status);
328
-
325
+
329
326
  }
330
327
 
331
328
 
332
329
  VALUE initializeStruct(VALUE self, VALUE portName)
333
330
  {
334
-
331
+
335
332
  {
336
333
  Check_Type(portName, T_STRING);
337
334
  }
338
-
335
+
339
336
  PortDescriptor *port = NULL;
340
-
337
+
341
338
  Data_Get_Struct(self, PortDescriptor, port);
342
-
339
+
343
340
  port->settings.BaudRate = BAUD115200;
344
341
  port->settings.Parity = PAR_NONE;
345
342
  port->settings.FlowControl = FLOW_OFF;
346
343
  port->settings.DataBits = DATA_8;
347
344
  port->settings.StopBits = STOP_1;
348
345
  port->settings.Timeout_Millisec = 0;
349
-
346
+
350
347
  snprintf(port->settings.ComPort, sizeof(port->settings.ComPort) - 1, WIN_PATTERN, RSTRING_PTR(portName));
351
-
348
+
352
349
  platformInitIO(port);
353
-
350
+
354
351
  rb_iv_set(self, "@port", portName);
355
-
352
+
356
353
  return self;
357
354
  }
358
355
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2013, Ingenico Inc.
2
+ * Copyright (c) 2013, Roman Lishtaba.
3
3
  *
4
4
  * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
5
5
  * provided that the above copyright notice and this permission notice appear in all copies.
@@ -12,9 +12,16 @@
12
12
  *
13
13
  **/
14
14
 
15
- #ifndef rs_232_port_h____FILEEXTENSION___
16
- #define rs_232_port_h____FILEEXTENSION___
15
+ /*
16
+ * @author Roman Lishtaba
17
+ */
18
+
19
+ #pragma once
17
20
 
21
+ #ifdef __cplusplus
22
+ extern "C" {
23
+ #endif
24
+
18
25
  # include <ruby.h>
19
26
  # include <ruby/io.h>
20
27
  # include <windows.h>
@@ -22,32 +29,34 @@
22
29
  # include <io.h>
23
30
  # include <stdio.h>
24
31
  # include <string.h>
25
- # include "structs.h"
26
-
32
+ # include "Structs.h"
33
+
27
34
  #define WIN_PATTERN "\\\\.\\%s"
28
-
29
- void setBaudRate(VALUE, VALUE);
30
-
31
- VALUE getBaudRate(VALUE);
32
-
33
- void setParity(VALUE, VALUE);
34
-
35
- VALUE getParity(VALUE);
36
-
37
- void setDataBits(VALUE, VALUE);
38
-
39
- VALUE getDataBits(VALUE);
40
-
41
- void setStopBits(VALUE, VALUE);
42
-
43
- VALUE getStopBits(VALUE);
44
-
45
- void setFlowControl(VALUE, VALUE);
46
-
47
- VALUE getFlowControl(VALUE);
48
-
49
- void setTimeout(VALUE, VALUE);
50
-
51
- void setSettings(VALUE);
52
-
35
+
36
+ void setBaudRate(VALUE, VALUE);
37
+
38
+ VALUE getBaudRate(VALUE);
39
+
40
+ void setParity(VALUE, VALUE);
41
+
42
+ VALUE getParity(VALUE);
43
+
44
+ void setDataBits(VALUE, VALUE);
45
+
46
+ VALUE getDataBits(VALUE);
47
+
48
+ void setStopBits(VALUE, VALUE);
49
+
50
+ VALUE getStopBits(VALUE);
51
+
52
+ void setFlowControl(VALUE, VALUE);
53
+
54
+ VALUE getFlowControl(VALUE);
55
+
56
+ void setTimeout(VALUE, VALUE);
57
+
58
+ void setSettings(VALUE);
59
+
60
+ #ifdef __cplusplus
61
+ }
53
62
  #endif
@@ -1,3 +1,3 @@
1
1
  module Rs232
2
- VERSION = '2.3.2.pre'
2
+ VERSION = '3.0.0.pre2'.freeze
3
3
  end
data/lib/rs_232.rb CHANGED
@@ -1,6 +1,98 @@
1
1
  require 'rs_232/version'
2
- require 'rs_232.so'
2
+ require 'rs_232_native.so'
3
+ require 'forwardable'
3
4
 
4
5
  module Rs232
5
- # see 'examples' folder in order to use existent or decorate your own adapter.
6
+ # public accessible factory method
7
+ #
8
+ # @example
9
+ #
10
+ # > port = Rs232.new('/dev/tty.ACM0', baud_rate: 9600)
11
+ # #=> <#Rs232::Impl @port='/dev/tty.ACM0'>
12
+ # > port.open?
13
+ # #=> false
14
+ # > port.connect
15
+ # #=> <#Rs232::Impl @port='/dev/tty.ACM0'>
16
+ # port.pending_bytes
17
+ # #=> 15
18
+ # port.read(15)
19
+ # #=> 'Hello, World!!!'
20
+ #
21
+ def new_serial_port(port, opts = {}, &block)
22
+ Impl.new(port, opts, &block)
23
+ end
24
+
25
+ # the following class represents ruby public interface
26
+ # to native Rs232 implementation
27
+ #
28
+ # There no public instantiation, can be instantiate through
29
+ # the factory method @see Rs232.new
30
+ #
31
+ class Impl
32
+ include Rs232::Constants
33
+
34
+ STD_OPTS = {
35
+ baud_rate: BAUD_115200,
36
+ parity: PAR_NONE,
37
+ data_bits: DATA_BITS_8,
38
+ stop_bits: STOP_BITS_1,
39
+ flow_control: FLOW_OFF,
40
+ timeout: 10
41
+ }.freeze
42
+
43
+ extend Forwardable
44
+
45
+ def_delegators :@impl,
46
+ :read,
47
+ :write,
48
+ :flush,
49
+ :close,
50
+ :open?,
51
+ :set_rts,
52
+ :set_dtr
53
+
54
+ def initialize(name, opts = {})
55
+ @impl = Rs232::Native.new(name)
56
+ @opts = STD_OPTS.merge(opts).freeze
57
+ freeze
58
+ yield self if block_given?
59
+ end
60
+
61
+ # @raise RuntimeError in case of open error
62
+ def connect
63
+ return self if open?
64
+ @impl.open.tap do |io|
65
+ io.baud_rate = @opts[:baud_rate]
66
+ io.parity = @opts[:parity]
67
+ io.data_bits = @opts[:data_bits]
68
+ io.stop_bits = @opts[:stop_bits]
69
+ io.flow_control = @opts[:flow_control]
70
+ io.timeout = @opts[:timeout]
71
+ end
72
+ self
73
+ end
74
+
75
+ def settings
76
+ {}.tap do |o|
77
+ o[:baud_rate] = @impl.baud_rate
78
+ o[:parity] = @impl.parity
79
+ o[:data_bits] = @impl.data_bits
80
+ o[:stop_bits] = @impl.stop_bits
81
+ o[:flow_control] = @impl.flow_control
82
+ o[:timeout] = @impl.timeout
83
+ o[:line_status] = @impl.line_status
84
+ end.freeze
85
+ end
86
+
87
+ def open?
88
+ @impl.open?
89
+ end
90
+
91
+ def close
92
+ return !open unless open?
93
+ 0 == @impl.close
94
+ end
95
+ end
96
+
97
+ private_constant :Impl
6
98
  end