rs_232 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,429 @@
1
+ /*
2
+ * Copyright (c) 2013, Ingenico Inc.
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
5
+ * provided that the above copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
8
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
9
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
10
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
11
+ * PERFORMANCE OF THIS SOFTWARE.
12
+ *
13
+ **/
14
+
15
+ #include "port.h"
16
+
17
+ VALUE setDtrIO(VALUE self, VALUE rb_int)
18
+ {
19
+ {
20
+ Check_Type(rb_int, T_FIXNUM);
21
+ }
22
+
23
+ int boolean = FIX2INT(rb_int);
24
+
25
+ PortDescriptor *port = NULL;
26
+
27
+ Data_Get_Struct(self, PortDescriptor, port);
28
+
29
+ int status;
30
+ ioctl(port->fd, TIOCMGET, &status);
31
+ if (boolean == 1)
32
+ status |= TIOCM_DTR;
33
+ else
34
+ status &= ~TIOCM_DTR;
35
+ ioctl(port->fd, TIOCMSET, &status);
36
+
37
+ return INT2FIX(status);
38
+
39
+ }
40
+
41
+
42
+ VALUE setRtsIO(VALUE self, VALUE rb_int)
43
+ {
44
+ {
45
+ Check_Type(rb_int, T_FIXNUM);
46
+ }
47
+
48
+ int boolean = FIX2INT(rb_int);
49
+
50
+ PortDescriptor *port = NULL;
51
+
52
+ Data_Get_Struct(self, PortDescriptor, port);
53
+
54
+ int status;
55
+ ioctl(port->fd, TIOCMGET, &status);
56
+ if (boolean == 1)
57
+ status |= TIOCM_RTS;
58
+ else
59
+ status &=
60
+ ~TIOCM_RTS;
61
+ ioctl(port->fd, TIOCMSET, &status);
62
+
63
+ return INT2FIX(status);
64
+ }
65
+
66
+
67
+ VALUE lineStatusIO(VALUE self)
68
+ {
69
+
70
+ PortDescriptor *port = NULL;
71
+
72
+ Data_Get_Struct(self, PortDescriptor, port);
73
+
74
+ unsigned long Status = 0, Temp = 0;
75
+ ioctl(port->fd, TIOCMGET, &Temp);
76
+ if (Temp & TIOCM_CTS) Status |= LS_CTS;
77
+ if (Temp & TIOCM_DSR) Status |= LS_DSR;
78
+ if (Temp & TIOCM_RI ) Status |= LS_RI;
79
+ if (Temp & TIOCM_CD ) Status |= LS_DCD;
80
+ if (Temp & TIOCM_DTR) Status |= LS_DTR;
81
+ if (Temp & TIOCM_RTS) Status |= LS_RTS;
82
+ if (Temp & TIOCM_ST ) Status |= LS_ST;
83
+ if (Temp & TIOCM_SR ) Status |= LS_SR;
84
+
85
+ return LONG2FIX(Status);
86
+ }
87
+
88
+
89
+ static void platformInitIO(PortDescriptor *port)
90
+ {
91
+ port->fd = -1;
92
+ port->status = 1;
93
+ }
94
+
95
+
96
+ static void setPosixBaudRate(PortDescriptor *port)
97
+ {
98
+ #ifdef CBAUD
99
+ port->posixConfig.c_cflag &= (~CBAUD);
100
+ port->posixConfig.c_cflag |= port->settings.BaudRate;
101
+ #else
102
+ cfsetispeed(&port->posixConfig, port->settings.BaudRate);
103
+ cfsetospeed(&port->posixConfig, port->settings.BaudRate);
104
+ #endif
105
+ }
106
+
107
+
108
+ void updateSettings(PortDescriptor *port)
109
+ {
110
+
111
+ if (port->status != 0)
112
+ rb_raise(rb_eException, "Can not set due to comport is not open, status: %d\n", port->status);
113
+
114
+ /*
115
+ * BaudRate clause ************************************************
116
+ */
117
+ if (port->toBeUpdated & T_BaudRate)
118
+ setPosixBaudRate(port);
119
+
120
+ /*
121
+ * Parity clause ************************************************
122
+ */
123
+ if (port->toBeUpdated & T_Parity)
124
+ {
125
+ switch (port->settings.Parity)
126
+ {
127
+ case PAR_NONE:
128
+ port->posixConfig.c_cflag &= (~PARENB);
129
+ break;
130
+ case PAR_EVEN:
131
+ port->posixConfig.c_cflag &= (~PARODD);
132
+ port->posixConfig.c_cflag |= PARENB;
133
+ break;
134
+ case PAR_ODD:
135
+ port->posixConfig.c_cflag |= (PARENB| PARODD);
136
+ break;
137
+ }
138
+ }
139
+
140
+ /*
141
+ * Data Bits clause ************************************************
142
+ */
143
+
144
+ if (port->toBeUpdated & T_DataBits)
145
+ {
146
+ port->posixConfig.c_cflag &= (~CSIZE);
147
+ switch (port->settings.DataBits)
148
+ {
149
+ case DATA_5:
150
+ port->posixConfig.c_cflag |= CS5;
151
+ break;
152
+ case DATA_6:
153
+ port->posixConfig.c_cflag |= CS6;
154
+ break;
155
+ case DATA_7:
156
+ port->posixConfig.c_cflag |= CS7;
157
+ break;
158
+ case DATA_8:
159
+ port->posixConfig.c_cflag |= CS8;
160
+ break;
161
+ }
162
+ }
163
+
164
+ /*
165
+ * StopBits clause ************************************************
166
+ */
167
+
168
+ if (port->toBeUpdated & T_StopBits)
169
+ {
170
+ switch (port->settings.StopBits)
171
+ {
172
+ case STOP_1:
173
+ port->posixConfig.c_cflag &= (~CSTOPB);
174
+ break;
175
+ case STOP_2:
176
+ port->posixConfig.c_cflag |= CSTOPB;
177
+ break;
178
+ }
179
+ }
180
+
181
+ /*
182
+ * FlowControl clause ************************************************
183
+ */
184
+
185
+ if (port->toBeUpdated & T_Flow)
186
+ {
187
+ switch (port->settings.FlowControl)
188
+ {
189
+ case FLOW_OFF:
190
+ port->posixConfig.c_cflag &= (~CRTSCTS);
191
+ port->posixConfig.c_iflag &= (~(IXON| IXOFF| IXANY));
192
+ break;
193
+ case FLOW_XONXOFF:
194
+ /*software (XON/XOFF) flow control*/
195
+ port->posixConfig.c_cflag &= (~CRTSCTS);
196
+ port->posixConfig.c_iflag |= (IXON| IXOFF| IXANY);
197
+ break;
198
+ case FLOW_HARDWARE:
199
+ port->posixConfig.c_cflag |= CRTSCTS;
200
+ port->posixConfig.c_iflag &= (~(IXON| IXOFF| IXANY));
201
+ break;
202
+ }
203
+ }
204
+
205
+
206
+ /*
207
+ * In case of update flush IO
208
+ */
209
+
210
+ if (port->toBeUpdated & T_SettingsDone)
211
+ {
212
+ tcsetattr(port->fd, TCSAFLUSH, &port->posixConfig);
213
+ }
214
+
215
+ /*
216
+ * Timeout clause ************************************************
217
+ */
218
+
219
+ if (port->toBeUpdated & T_TimeOut)
220
+ {
221
+ int timeout = port->settings.Timeout_Millisec;
222
+
223
+ if (timeout == -1)
224
+ {
225
+ fcntl(port->fd, F_SETFL, O_NDELAY); /* O_NDELAY should release if no any data here */
226
+ }
227
+ else
228
+ {
229
+ fcntl(port->fd, F_SETFL, O_SYNC); /* O_SYNC should enable blocking function */
230
+ }
231
+ tcgetattr(port->fd, &port->posixConfig);
232
+ port->posixConfig.c_cc[VTIME] = (timeout / 100);
233
+
234
+ tcsetattr(port->fd, TCSAFLUSH, &port->posixConfig);
235
+ }
236
+
237
+ port->toBeUpdated = 0;
238
+
239
+ }
240
+
241
+
242
+ int queryStatusIO(VALUE self)
243
+ {
244
+ PortDescriptor *port = NULL;
245
+
246
+ Data_Get_Struct(self, PortDescriptor, port);
247
+
248
+ return port->status;
249
+ }
250
+
251
+
252
+ VALUE isClosedIO(VALUE self)
253
+ {
254
+ return queryStatusIO(self) == 1 ? Qtrue : Qfalse;
255
+ }
256
+
257
+
258
+ VALUE flushIO(VALUE self)
259
+ {
260
+ PortDescriptor *port = NULL;
261
+
262
+ Data_Get_Struct(self, PortDescriptor, port);
263
+
264
+ return INT2FIX( tcdrain(port->fd) );
265
+ }
266
+
267
+
268
+ VALUE bytesAvailableIO(VALUE self)
269
+ {
270
+
271
+ PortDescriptor *port = NULL;
272
+
273
+ Data_Get_Struct(self, PortDescriptor, port);
274
+
275
+ int bytesQueued;
276
+
277
+ if (ioctl(port->fd, FIONREAD, &bytesQueued) == -1)
278
+ {
279
+ return INT2FIX(0);
280
+ }
281
+ return INT2FIX(bytesQueued);
282
+ }
283
+
284
+
285
+ VALUE openIO(VALUE self)
286
+ {
287
+
288
+ PortDescriptor *port = NULL;
289
+
290
+ Data_Get_Struct(self, PortDescriptor, port);
291
+
292
+ if ((port->fd = open(port->settings.ComPort, O_RDWR | O_NOCTTY | O_SYNC)) != -1)
293
+ {
294
+
295
+ port->status = 0;
296
+
297
+ {
298
+ rb_iv_set(self, "@open", INT2FIX(port->status));
299
+ }
300
+
301
+ tcgetattr(port->fd, &port->previousPosixConfig);
302
+ port->posixConfig = port->previousPosixConfig;
303
+ cfmakeraw(&port->posixConfig);
304
+
305
+
306
+ port->posixConfig.c_cflag |= CREAD | CLOCAL;
307
+ port->posixConfig.c_lflag &= (~(ICANON| ECHO| ECHOE| ECHOK| ECHONL| ISIG));
308
+ port->posixConfig.c_iflag &= (~(INPCK| IGNPAR| PARMRK| ISTRIP| ICRNL| IXANY));
309
+ port->posixConfig.c_oflag &= (~OPOST);
310
+ port->posixConfig.c_cc[VMIN] = 0;
311
+ port->posixConfig.c_cc[VTIME] = 0;
312
+
313
+ port->toBeUpdated = T_ALL;
314
+
315
+ setSettings(self);
316
+
317
+ } else
318
+ {
319
+ port->status = 1;
320
+ rb_raise(rb_eException, "Unable to open comport: %s\n", port->settings.ComPort);
321
+ }
322
+
323
+ return INT2FIX(port->status);
324
+ }
325
+
326
+
327
+ VALUE writeIO(VALUE self, VALUE message)
328
+ {
329
+
330
+ {
331
+ Check_Type(message, T_STRING);
332
+ }
333
+
334
+ int recv;
335
+ int len;
336
+
337
+ PortDescriptor *port = NULL;
338
+
339
+ Data_Get_Struct(self, PortDescriptor, port);
340
+
341
+ len = (int) RSTRING_LEN(message);
342
+ char cStr[len];
343
+ strcpy(cStr, RSTRING_PTR(message));
344
+
345
+ recv = (int) write(port->fd, cStr, (size_t) sizeof(cStr));
346
+
347
+ if (recv < 0){
348
+ rb_raise(rb_eEOFError, "TX: writing of the %d bytes has failed", len);
349
+ }
350
+
351
+ return INT2FIX(recv);
352
+ }
353
+
354
+
355
+ VALUE readIO(VALUE self, VALUE rb_int)
356
+ {
357
+
358
+ {
359
+ Check_Type(rb_int, T_FIXNUM);
360
+ }
361
+
362
+ int recv;
363
+
364
+ PortDescriptor *port = NULL;
365
+
366
+ Data_Get_Struct(self, PortDescriptor, port);
367
+
368
+ int len = FIX2INT(rb_int);
369
+
370
+ char in[len];
371
+
372
+ recv = (int) read(port->fd, in, sizeof(in));
373
+ if (recv > 0)
374
+ return rb_str_new(in, recv);
375
+
376
+ return Qnil;
377
+ }
378
+
379
+
380
+ VALUE closeIO(VALUE self)
381
+ {
382
+
383
+ int closed;
384
+
385
+ PortDescriptor *port = NULL;
386
+
387
+ Data_Get_Struct(self, PortDescriptor, port);
388
+
389
+ flushIO(self);
390
+
391
+ tcsetattr(port->fd, TCSAFLUSH | TCSANOW, &port->previousPosixConfig);
392
+ closed = close(port->fd);
393
+
394
+ port->status = closed == 0 ? 1 : 0;
395
+
396
+ rb_iv_set(self, "@open", INT2FIX(port->status));
397
+ rb_iv_set(self, "@fd", INT2FIX(port->fd));
398
+
399
+ return INT2FIX(closed);
400
+
401
+ }
402
+
403
+
404
+ VALUE initializeStruct(VALUE self, VALUE portName)
405
+ {
406
+
407
+ {
408
+ Check_Type(portName, T_STRING);
409
+ }
410
+
411
+ PortDescriptor *port = NULL;
412
+
413
+ Data_Get_Struct(self, PortDescriptor, port);
414
+
415
+ port->settings.BaudRate = BAUD115200;
416
+ port->settings.Parity = PAR_NONE;
417
+ port->settings.FlowControl = FLOW_OFF;
418
+ port->settings.DataBits = DATA_8;
419
+ port->settings.StopBits = STOP_1;
420
+ port->settings.Timeout_Millisec = 0;
421
+
422
+ strcpy(port->settings.ComPort, RSTRING_PTR(portName));
423
+
424
+ platformInitIO(port);
425
+
426
+ rb_iv_set(self, "@port", portName);
427
+
428
+ return self;
429
+ }
@@ -0,0 +1,53 @@
1
+ /*
2
+ * Copyright (c) 2013, Ingenico Inc.
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
5
+ * provided that the above copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
8
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
9
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
10
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
11
+ * PERFORMANCE OF THIS SOFTWARE.
12
+ *
13
+ **/
14
+
15
+ #ifndef rs_232_port_h____FILEEXTENSION___
16
+ #define rs_232_port_h____FILEEXTENSION___
17
+
18
+ # include <ruby.h>
19
+ # include <stdio.h>
20
+ # include <string.h>
21
+ # include <unistd.h>
22
+ # include <fcntl.h>
23
+ # include <errno.h>
24
+ # include <termios.h>
25
+ # 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
+
53
+ #endif
@@ -0,0 +1,62 @@
1
+ /*
2
+ * Copyright (c) 2013, Ingenico Inc.
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
5
+ * provided that the above copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
8
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
9
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
10
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
11
+ * PERFORMANCE OF THIS SOFTWARE.
12
+ *
13
+ **/
14
+
15
+ #ifndef rs_232_structs_h
16
+ #define rs_232_structs_h
17
+
18
+ #include "constants.h"
19
+
20
+ /*
21
+ * structure to contain port settings
22
+ */
23
+
24
+ typedef struct PortSettings_T
25
+ {
26
+ char ComPort[40];
27
+ enum BaudRateType BaudRate;
28
+ enum DataBitsType DataBits;
29
+ enum ParityType Parity;
30
+ enum StopBitsType StopBits;
31
+ enum FlowType FlowControl;
32
+ long Timeout_Millisec;
33
+ } PortSettings;
34
+
35
+
36
+ /*
37
+ * port descriptor structure
38
+ */
39
+
40
+ typedef struct portDescriptor_T
41
+ {
42
+ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
43
+
44
+ HANDLE fd;
45
+ COMMCONFIG commConfig;
46
+ COMMTIMEOUTS commTimeouts;
47
+
48
+ #else
49
+
50
+ int fd;
51
+ struct termios posixConfig;
52
+ struct termios previousPosixConfig;
53
+
54
+ #endif
55
+
56
+ int status;
57
+ PortSettings settings;
58
+ int toBeUpdated;
59
+
60
+ } PortDescriptor;
61
+
62
+ #endif