rubyserial 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/LICENSE +13 -0
- data/README.md +27 -0
- data/Rakefile +2 -0
- data/lib/rubyserial.rb +21 -0
- data/lib/rubyserial/linux_constants.rb +214 -0
- data/lib/rubyserial/osx_constants.rb +181 -0
- data/lib/rubyserial/posix.rb +84 -0
- data/lib/rubyserial/version.rb +5 -0
- data/lib/rubyserial/windows.rb +74 -0
- data/lib/rubyserial/windows_constants.rb +275 -0
- data/rubyserial.gemspec +19 -0
- metadata +72 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 768694b356264952b50a41408e6aecd0e2bd0f74
|
4
|
+
data.tar.gz: 6e88db468ceb626d7d66c48687873a42afb994ad
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e8610224155564d6a8acc8f3f922c3ce5ed0cc7fbcde57ff3aca9ccda649f24b53bbd1df5e1986d4175f4489f5a8ff48dd48f47ab3df2cbeefa075d53943376b
|
7
|
+
data.tar.gz: 6f8974af626202bb8a7f67ae28a5e25a62487cde2b06000dfcfab18d8b9fc39949dd7fcd0793ef474365c46f5f9186894abf2151c9bbe3078c06456cfe5da92c
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2014 The Hybrid Group
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# rubyserial
|
2
|
+
|
3
|
+
A simple ruby gem which allows you to read and write from a serial port.
|
4
|
+
|
5
|
+
Usage:
|
6
|
+
```ruby
|
7
|
+
require 'rubyserial'
|
8
|
+
s = Serial.new("/dev/ttyACM0", 57600)
|
9
|
+
```
|
10
|
+
|
11
|
+
#####write(string) -> int
|
12
|
+
```
|
13
|
+
returns the number of bytes written.
|
14
|
+
RubySerial::Exception on error.
|
15
|
+
```
|
16
|
+
######read(length) -> string
|
17
|
+
```
|
18
|
+
returns a string up to "length".
|
19
|
+
read is not guarenteed to return the entire "length" specified.
|
20
|
+
returns "" on no data
|
21
|
+
RubySerial::Exception on error.
|
22
|
+
```
|
23
|
+
|
24
|
+
######RubySerial::Exception
|
25
|
+
```
|
26
|
+
returns the underlying system error code
|
27
|
+
```
|
data/Rakefile
ADDED
data/lib/rubyserial.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'ffi'
|
4
|
+
include RbConfig
|
5
|
+
|
6
|
+
module RubySerial
|
7
|
+
class Exception < Exception
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
if CONFIG['host_os'] =~ /mswin|windows|mingw/i
|
12
|
+
require 'rubyserial/windows_constants'
|
13
|
+
require 'rubyserial/windows'
|
14
|
+
else
|
15
|
+
if CONFIG['host_os'] =~ /linux/i
|
16
|
+
require 'rubyserial/linux_constants'
|
17
|
+
else
|
18
|
+
require 'rubyserial/osx_constants'
|
19
|
+
end
|
20
|
+
require 'rubyserial/posix'
|
21
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module RubySerial
|
4
|
+
module Posix
|
5
|
+
extend FFI::Library
|
6
|
+
ffi_lib FFI::Library::LIBC
|
7
|
+
|
8
|
+
O_NONBLOCK = 00004000
|
9
|
+
O_NOCTTY = 00000400
|
10
|
+
O_RDWR = 00000002
|
11
|
+
F_GETFL = 3
|
12
|
+
F_SETFL = 4
|
13
|
+
VTIME = 5
|
14
|
+
TCSANOW = 0
|
15
|
+
TCSETS = 0x5402
|
16
|
+
IGNPAR = 0000004
|
17
|
+
CREAD = 0000200
|
18
|
+
CLOCAL = 0004000
|
19
|
+
VMIN = 6
|
20
|
+
NCCS = 19
|
21
|
+
|
22
|
+
DATA_BITS = {
|
23
|
+
5 => 0000000,
|
24
|
+
6 => 0000020,
|
25
|
+
7 => 0000040,
|
26
|
+
8 => 0000060
|
27
|
+
}
|
28
|
+
|
29
|
+
BAUDE_RATES = {
|
30
|
+
0 => 0000000,
|
31
|
+
50 => 0000001,
|
32
|
+
75 => 0000002,
|
33
|
+
110 => 0000003,
|
34
|
+
134 => 0000004,
|
35
|
+
150 => 0000005,
|
36
|
+
200 => 0000006,
|
37
|
+
300 => 0000007,
|
38
|
+
600 => 0000010,
|
39
|
+
1200 => 0000011,
|
40
|
+
1800 => 0000012,
|
41
|
+
2400 => 0000013,
|
42
|
+
4800 => 0000014,
|
43
|
+
9600 => 0000015,
|
44
|
+
19200 => 0000016,
|
45
|
+
38400 => 0000017,
|
46
|
+
57600 => 0010001,
|
47
|
+
115200 => 0010002,
|
48
|
+
230400 => 0010003,
|
49
|
+
460800 => 0010004,
|
50
|
+
500000 => 0010005,
|
51
|
+
576000 => 0010006,
|
52
|
+
921600 => 0010007,
|
53
|
+
1000000 => 0010010,
|
54
|
+
1152000 => 0010011,
|
55
|
+
1500000 => 0010012,
|
56
|
+
2000000 => 0010013,
|
57
|
+
2500000 => 0010014,
|
58
|
+
3000000 => 0010015,
|
59
|
+
3500000 => 0010016,
|
60
|
+
4000000 => 0010017
|
61
|
+
}
|
62
|
+
|
63
|
+
ERROR_CODES = {
|
64
|
+
1 => "EPERM",
|
65
|
+
2 => "ENOENT",
|
66
|
+
3 => "ESRCH",
|
67
|
+
4 => "EINTR",
|
68
|
+
5 => "EIO",
|
69
|
+
6 => "ENXIO",
|
70
|
+
7 => "E2BIG",
|
71
|
+
8 => "ENOEXEC",
|
72
|
+
9 => "EBADF",
|
73
|
+
10 => "ECHILD",
|
74
|
+
11 => "EAGAIN",
|
75
|
+
12 => "ENOMEM",
|
76
|
+
13 => "EACCES",
|
77
|
+
14 => "EFAULT",
|
78
|
+
15 => "ENOTBLK",
|
79
|
+
16 => "EBUSY",
|
80
|
+
17 => "EEXIST",
|
81
|
+
18 => "EXDEV",
|
82
|
+
19 => "ENODEV",
|
83
|
+
20 => "ENOTDIR ",
|
84
|
+
21 => "EISDIR",
|
85
|
+
22 => "EINVAL",
|
86
|
+
23 => "ENFILE",
|
87
|
+
24 => "EMFILE",
|
88
|
+
25 => "ENOTTY",
|
89
|
+
26 => "ETXTBSY",
|
90
|
+
27 => "EFBIG",
|
91
|
+
28 => "ENOSPC",
|
92
|
+
29 => "ESPIPE",
|
93
|
+
30 => "EROFS",
|
94
|
+
31 => "EMLINK",
|
95
|
+
32 => "EPIPE",
|
96
|
+
33 => "EDOM",
|
97
|
+
34 => "ERANGE",
|
98
|
+
35 => "EDEADLK",
|
99
|
+
36 => "ENAMETOOLONG",
|
100
|
+
37 => "ENOLCK ",
|
101
|
+
38 => "ENOSYS",
|
102
|
+
39 => "ENOTEMPTY",
|
103
|
+
40 => "ELOOP",
|
104
|
+
42 => "ENOMSG",
|
105
|
+
43 => "EIDRM",
|
106
|
+
44 => "ECHRNG",
|
107
|
+
45 => "EL2NSYNC",
|
108
|
+
46 => "EL3HLT",
|
109
|
+
47 => "EL3RST",
|
110
|
+
48 => "ELNRNG",
|
111
|
+
49 => "EUNATCH",
|
112
|
+
50 => "ENOCSI",
|
113
|
+
51 => "EL2HLT",
|
114
|
+
52 => "EBADE",
|
115
|
+
53 => "EBADR",
|
116
|
+
54 => "EXFULL",
|
117
|
+
55 => "ENOANO",
|
118
|
+
56 => "EBADRQC",
|
119
|
+
57 => "EBADSLT",
|
120
|
+
59 => "EBFONT",
|
121
|
+
60 => "ENOSTR",
|
122
|
+
61 => "ENODATA",
|
123
|
+
62 => "ETIME",
|
124
|
+
63 => "ENOSR",
|
125
|
+
64 => "ENONET",
|
126
|
+
65 => "ENOPKG",
|
127
|
+
66 => "EREMOTE",
|
128
|
+
67 => "ENOLINK",
|
129
|
+
68 => "EADV",
|
130
|
+
69 => "ESRMNT",
|
131
|
+
70 => "ECOMM",
|
132
|
+
71 => "EPROTO",
|
133
|
+
72 => "EMULTIHOP",
|
134
|
+
73 => "EDOTDOT",
|
135
|
+
74 => "EBADMSG",
|
136
|
+
75 => "EOVERFLOW",
|
137
|
+
76 => "ENOTUNIQ",
|
138
|
+
77 => "EBADFD",
|
139
|
+
78 => "EREMCHG",
|
140
|
+
79 => "ELIBACC",
|
141
|
+
80 => "ELIBBAD",
|
142
|
+
81 => "ELIBSCN",
|
143
|
+
82 => "ELIBMAX",
|
144
|
+
83 => "ELIBEXEC",
|
145
|
+
84 => "EILSEQ",
|
146
|
+
85 => "ERESTART",
|
147
|
+
86 => "ESTRPIPE",
|
148
|
+
87 => "EUSERS",
|
149
|
+
88 => "ENOTSOCK",
|
150
|
+
89 => "EDESTADDRREQ",
|
151
|
+
90 => "EMSGSIZE",
|
152
|
+
91 => "EPROTOTYPE",
|
153
|
+
92 => "ENOPROTOOPT",
|
154
|
+
93 => "EPROTONOSUPPORT",
|
155
|
+
94 => "ESOCKTNOSUPPORT",
|
156
|
+
95 => "EOPNOTSUPP",
|
157
|
+
96 => "EPFNOSUPPORT",
|
158
|
+
97 => "EAFNOSUPPORT",
|
159
|
+
98 => "EADDRINUSE",
|
160
|
+
99 => "EADDRNOTAVAIL",
|
161
|
+
100 => "ENETDOWN",
|
162
|
+
101 => "ENETUNREACH",
|
163
|
+
102 => "ENETRESET",
|
164
|
+
103 => "ECONNABORTED",
|
165
|
+
104 => "ECONNRESET",
|
166
|
+
105 => "ENOBUFS",
|
167
|
+
106 => "EISCONN",
|
168
|
+
107 => "ENOTCONN",
|
169
|
+
108 => "ESHUTDOWN",
|
170
|
+
109 => "ETOOMANYREFS",
|
171
|
+
110 => "ETIMEDOUT",
|
172
|
+
111 => "ECONNREFUSED",
|
173
|
+
112 => "EHOSTDOWN",
|
174
|
+
113 => "EHOSTUNREACH",
|
175
|
+
114 => "EALREADY",
|
176
|
+
115 => "EINPROGRESS",
|
177
|
+
116 => "ESTALE",
|
178
|
+
117 => "EUCLEAN",
|
179
|
+
118 => "ENOTNAM",
|
180
|
+
119 => "ENAVAIL",
|
181
|
+
120 => "EISNAM",
|
182
|
+
121 => "EREMOTEIO",
|
183
|
+
122 => "EDQUOT",
|
184
|
+
123 => "ENOMEDIUM",
|
185
|
+
124 => "EMEDIUMTYPE",
|
186
|
+
125 => "ECANCELED",
|
187
|
+
126 => "ENOKEY",
|
188
|
+
127 => "EKEYEXPIRED",
|
189
|
+
128 => "EKEYREVOKED",
|
190
|
+
129 => "EKEYREJECTED",
|
191
|
+
130 => "EOWNERDEAD",
|
192
|
+
131 => "ENOTRECOVERABLE"
|
193
|
+
}
|
194
|
+
|
195
|
+
class Termios < FFI::Struct
|
196
|
+
layout :c_iflag, :uint,
|
197
|
+
:c_oflag, :uint,
|
198
|
+
:c_cflag, :uint,
|
199
|
+
:c_lflag, :uint,
|
200
|
+
:c_line, :uchar,
|
201
|
+
:cc_c, [ :uchar, NCCS ],
|
202
|
+
:c_ispeed, :uint,
|
203
|
+
:c_ospeed, :uint
|
204
|
+
end
|
205
|
+
|
206
|
+
attach_function :ioctl, [ :int, :ulong, RubySerial::Posix::Termios], :int
|
207
|
+
attach_function :tcsetattr, [ :int, :int, RubySerial::Posix::Termios ], :int
|
208
|
+
attach_function :fcntl, [:int, :int, :varargs], :int
|
209
|
+
attach_function :open, [:pointer, :int], :int
|
210
|
+
attach_function :close, [:int], :int
|
211
|
+
attach_function :write, [:int, :pointer, :int],:int
|
212
|
+
attach_function :read, [:int, :pointer, :int],:int
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module RubySerial
|
4
|
+
module Posix
|
5
|
+
extend FFI::Library
|
6
|
+
ffi_lib FFI::Library::LIBC
|
7
|
+
|
8
|
+
O_RDWR = 0x0002
|
9
|
+
O_NOCTTY = 0x20000
|
10
|
+
O_NONBLOCK = 0x0004
|
11
|
+
F_GETFL = 3
|
12
|
+
F_SETFL = 4
|
13
|
+
IGNPAR = 0x00000004
|
14
|
+
VMIN = 16
|
15
|
+
VTIME = 17
|
16
|
+
CLOCAL = 0x00008000
|
17
|
+
CREAD = 0x00000800
|
18
|
+
TCSANOW = 0
|
19
|
+
NCCS = 20
|
20
|
+
|
21
|
+
DATA_BITS = {
|
22
|
+
5 => 0x00000000,
|
23
|
+
6 => 0x00000100,
|
24
|
+
7 => 0x00000200,
|
25
|
+
8 => 0x00000300
|
26
|
+
}
|
27
|
+
|
28
|
+
BAUDE_RATES = {
|
29
|
+
0 => 0,
|
30
|
+
50 => 50,
|
31
|
+
75 => 75,
|
32
|
+
110 => 110,
|
33
|
+
134 => 134,
|
34
|
+
150 => 150,
|
35
|
+
200 => 200,
|
36
|
+
300 => 300,
|
37
|
+
600 => 600,
|
38
|
+
1200 => 1200,
|
39
|
+
1800 => 1800,
|
40
|
+
2400 => 2400,
|
41
|
+
4800 => 4800,
|
42
|
+
9600 => 9600,
|
43
|
+
19200 => 19200,
|
44
|
+
38400 => 38400,
|
45
|
+
7200 => 7200,
|
46
|
+
14400 => 14400,
|
47
|
+
28800 => 28800,
|
48
|
+
57600 => 57600,
|
49
|
+
76800 => 76800,
|
50
|
+
115200 => 115200,
|
51
|
+
230400 => 230400
|
52
|
+
}
|
53
|
+
|
54
|
+
ERROR_CODES = {
|
55
|
+
1 => "EPERM",
|
56
|
+
2 => "ENOENT",
|
57
|
+
3 => "ESRCH",
|
58
|
+
4 => "EINTR",
|
59
|
+
5 => "EIO",
|
60
|
+
6 => "ENXIO",
|
61
|
+
7 => "E2BIG",
|
62
|
+
8 => "ENOEXEC",
|
63
|
+
9 => "EBADF",
|
64
|
+
10 => "ECHILD",
|
65
|
+
11 => "EDEADLK",
|
66
|
+
12 => "ENOMEM",
|
67
|
+
13 => "EACCES",
|
68
|
+
14 => "EFAULT",
|
69
|
+
15 => "ENOTBLK",
|
70
|
+
16 => "EBUSY",
|
71
|
+
17 => "EEXIST",
|
72
|
+
18 => "EXDEV",
|
73
|
+
19 => "ENODEV",
|
74
|
+
20 => "ENOTDIR",
|
75
|
+
21 => "EISDIR",
|
76
|
+
22 => "EINVAL",
|
77
|
+
23 => "ENFILE",
|
78
|
+
24 => "EMFILE",
|
79
|
+
25 => "ENOTTY",
|
80
|
+
26 => "ETXTBSY",
|
81
|
+
27 => "EFBIG",
|
82
|
+
28 => "ENOSPC",
|
83
|
+
29 => "ESPIPE",
|
84
|
+
30 => "EROFS",
|
85
|
+
31 => "EMLINK",
|
86
|
+
32 => "EPIPE",
|
87
|
+
33 => "EDOM",
|
88
|
+
34 => "ERANGE",
|
89
|
+
35 => "EAGAIN",
|
90
|
+
36 => "EINPROGRESS",
|
91
|
+
37 => "EALREADY",
|
92
|
+
38 => "ENOTSOCK",
|
93
|
+
39 => "EDESTADDRREQ",
|
94
|
+
40 => "EMSGSIZE",
|
95
|
+
41 => "EPROTOTYPE",
|
96
|
+
42 => "ENOPROTOOPT",
|
97
|
+
43 => "EPROTONOSUPPORT",
|
98
|
+
44 => "ESOCKTNOSUPPORT",
|
99
|
+
45 => "ENOTSUP",
|
100
|
+
46 => "EPFNOSUPPORT",
|
101
|
+
47 => "EAFNOSUPPORT",
|
102
|
+
48 => "EADDRINUSE",
|
103
|
+
49 => "EADDRNOTAVAIL",
|
104
|
+
50 => "ENETDOWN",
|
105
|
+
51 => "ENETUNREACH",
|
106
|
+
52 => "ENETRESET",
|
107
|
+
53 => "ECONNABORTED",
|
108
|
+
54 => "ECONNRESET",
|
109
|
+
55 => "ENOBUFS",
|
110
|
+
56 => "EISCONN",
|
111
|
+
57 => "ENOTCONN",
|
112
|
+
58 => "ESHUTDOWN",
|
113
|
+
59 => "ETOOMANYREFS",
|
114
|
+
60 => "ETIMEDOUT",
|
115
|
+
61 => "ECONNREFUSED",
|
116
|
+
62 => "ELOOP",
|
117
|
+
63 => "ENAMETOOLONG",
|
118
|
+
64 => "EHOSTDOWN",
|
119
|
+
65 => "EHOSTUNREACH",
|
120
|
+
66 => "ENOTEMPTY",
|
121
|
+
67 => "EPROCLIM",
|
122
|
+
68 => "EUSERS",
|
123
|
+
69 => "EDQUOT",
|
124
|
+
70 => "ESTALE",
|
125
|
+
71 => "EREMOTE",
|
126
|
+
72 => "EBADRPC",
|
127
|
+
73 => "ERPCMISMATCH",
|
128
|
+
74 => "EPROGUNAVAIL",
|
129
|
+
75 => "EPROGMISMATCH",
|
130
|
+
76 => "EPROCUNAVAIL",
|
131
|
+
77 => "ENOLCK",
|
132
|
+
78 => "ENOSYS",
|
133
|
+
79 => "EFTYPE",
|
134
|
+
80 => "EAUTH",
|
135
|
+
81 => "ENEEDAUTH",
|
136
|
+
82 => "EPWROFF",
|
137
|
+
83 => "EDEVERR",
|
138
|
+
84 => "EOVERFLOW",
|
139
|
+
85 => "EBADEXEC",
|
140
|
+
86 => "EBADARCH",
|
141
|
+
87 => "ESHLIBVERS",
|
142
|
+
88 => "EBADMACHO",
|
143
|
+
89 => "ECANCELED",
|
144
|
+
90 => "EIDRM",
|
145
|
+
91 => "ENOMSG",
|
146
|
+
92 => "EILSEQ",
|
147
|
+
93 => "ENOATTR",
|
148
|
+
94 => "EBADMSG",
|
149
|
+
95 => "EMULTIHOP",
|
150
|
+
96 => "ENODATA",
|
151
|
+
97 => "ENOLINK",
|
152
|
+
98 => "ENOSR",
|
153
|
+
99 => "ENOSTR",
|
154
|
+
100 => "EPROTO",
|
155
|
+
101 => "ETIME",
|
156
|
+
102 => "EOPNOTSUPP",
|
157
|
+
103 => "ENOPOLICY",
|
158
|
+
104 => "ENOTRECOVERABLE",
|
159
|
+
105 => "EOWNERDEAD",
|
160
|
+
106 => "ELAST"
|
161
|
+
}
|
162
|
+
|
163
|
+
class Termios < FFI::Struct
|
164
|
+
layout :c_iflag, :ulong,
|
165
|
+
:c_oflag, :ulong,
|
166
|
+
:c_cflag, :ulong,
|
167
|
+
:c_lflag, :ulong,
|
168
|
+
:c_line, :uchar,
|
169
|
+
:cc_c, [ :uchar, NCCS ],
|
170
|
+
:c_ispeed, :ulong,
|
171
|
+
:c_ospeed, :ulong
|
172
|
+
end
|
173
|
+
|
174
|
+
attach_function :tcsetattr, [ :int, :int, RubySerial::Posix::Termios ], :int
|
175
|
+
attach_function :fcntl, [:int, :int, :varargs], :int
|
176
|
+
attach_function :open, [:pointer, :int], :int
|
177
|
+
attach_function :close, [:int], :int
|
178
|
+
attach_function :write, [:int, :pointer, :int],:int
|
179
|
+
attach_function :read, [:int, :pointer, :int],:int
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
class Serial
|
4
|
+
def initialize(address, baude_rate=9600, data_bits=8)
|
5
|
+
file_opts = RubySerial::Posix::O_RDWR | RubySerial::Posix::O_NOCTTY
|
6
|
+
@fd = RubySerial::Posix.open(address, file_opts)
|
7
|
+
|
8
|
+
if @fd == -1
|
9
|
+
raise RubySerial::Exception, RubySerial::Posix::ERROR_CODES[FFI.errno]
|
10
|
+
else
|
11
|
+
@open = true
|
12
|
+
end
|
13
|
+
|
14
|
+
fl = RubySerial::Posix.fcntl(@fd, RubySerial::Posix::F_GETFL, :int, 0)
|
15
|
+
if fl == -1
|
16
|
+
raise RubySerial::Exception, RubySerial::Posix::ERROR_CODES[FFI.errno]
|
17
|
+
end
|
18
|
+
|
19
|
+
err = RubySerial::Posix.fcntl(@fd, RubySerial::Posix::F_SETFL, :int, ~RubySerial::Posix::O_NONBLOCK & fl)
|
20
|
+
if err == -1
|
21
|
+
raise RubySerial::Exception, RubySerial::Posix::ERROR_CODES[FFI.errno]
|
22
|
+
end
|
23
|
+
|
24
|
+
@config = build_config(baude_rate, data_bits)
|
25
|
+
|
26
|
+
err = RubySerial::Posix.tcsetattr(@fd, RubySerial::Posix::TCSANOW, @config)
|
27
|
+
if err == -1
|
28
|
+
raise RubySerial::Exception, RubySerial::Posix::ERROR_CODES[FFI.errno]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def closed?
|
33
|
+
!@open
|
34
|
+
end
|
35
|
+
|
36
|
+
def close
|
37
|
+
err = RubySerial::Posix.close(@fd)
|
38
|
+
if err == -1
|
39
|
+
raise RubySerial::Exception, RubySerial::Posix::ERROR_CODES[FFI.errno]
|
40
|
+
else
|
41
|
+
@open = false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def write(data)
|
46
|
+
n = 0
|
47
|
+
while data.size > n do
|
48
|
+
buff = FFI::MemoryPointer.from_string(data[n..-1].to_s)
|
49
|
+
i = RubySerial::Posix.write(@fd, buff, buff.size)
|
50
|
+
if i == -1
|
51
|
+
raise RubySerial::Exception, RubySerial::Posix::ERROR_CODES[FFI.errno]
|
52
|
+
else
|
53
|
+
n = n+i
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def read(size)
|
59
|
+
buff = FFI::MemoryPointer.new :char, size
|
60
|
+
i = RubySerial::Posix.read(@fd, buff, size)
|
61
|
+
if i == -1
|
62
|
+
raise RubySerial::Exception, RubySerial::Posix::ERROR_CODES[FFI.errno]
|
63
|
+
end
|
64
|
+
buff.get_bytes(0, i)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def build_config(baude_rate, data_bits)
|
70
|
+
config = RubySerial::Posix::Termios.new
|
71
|
+
|
72
|
+
config[:c_iflag] = RubySerial::Posix::IGNPAR
|
73
|
+
config[:c_ispeed] = RubySerial::Posix::BAUDE_RATES[baude_rate]
|
74
|
+
config[:c_ospeed] = RubySerial::Posix::BAUDE_RATES[baude_rate]
|
75
|
+
config[:c_cflag] = RubySerial::Posix::DATA_BITS[data_bits] |
|
76
|
+
RubySerial::Posix::CREAD |
|
77
|
+
RubySerial::Posix::CLOCAL |
|
78
|
+
RubySerial::Posix::BAUDE_RATES[baude_rate]
|
79
|
+
|
80
|
+
config[:cc_c][RubySerial::Posix::VMIN] = 0
|
81
|
+
|
82
|
+
config
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
class Serial
|
4
|
+
def initialize(address, baude_rate=9600, data_bits=8)
|
5
|
+
file_opts = RubySerial::Win32::GENERIC_READ | RubySerial::Win32::GENERIC_WRITE
|
6
|
+
@fd = RubySerial::Win32.CreateFileA(address, file_opts, 0, nil, RubySerial::Win32::OPEN_EXISTING, 0, nil)
|
7
|
+
err = FFI.errno
|
8
|
+
if err != 0
|
9
|
+
raise RubySerial::Exception, RubySerial::Win32::ERROR_CODES[err]
|
10
|
+
else
|
11
|
+
@open = true
|
12
|
+
end
|
13
|
+
|
14
|
+
RubySerial::Win32::DCB.new.tap do |dcb|
|
15
|
+
dcb[:dcblength] = RubySerial::Win32::DCB::Sizeof
|
16
|
+
err = RubySerial::Win32.GetCommState @fd, dcb
|
17
|
+
if err == 0
|
18
|
+
raise RubySerial::Exception, RubySerial::Win32::ERROR_CODES[FFI.errno]
|
19
|
+
end
|
20
|
+
dcb[:baudrate] = baude_rate
|
21
|
+
dcb[:bytesize] = data_bits
|
22
|
+
dcb[:stopbits] = RubySerial::Win32::DCB::ONESTOPBIT
|
23
|
+
dcb[:parity] = RubySerial::Win32::DCB::NOPARITY
|
24
|
+
err = RubySerial::Win32.SetCommState @fd, dcb
|
25
|
+
if err == 0
|
26
|
+
raise RubySerial::Exception, RubySerial::Win32::ERROR_CODES[FFI.errno]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
RubySerial::Win32::CommTimeouts.new.tap do |timeouts|
|
31
|
+
timeouts[:read_interval_timeout] = 50
|
32
|
+
timeouts[:read_total_timeout_multiplier] = 50
|
33
|
+
timeouts[:read_total_timeout_constant] = 10
|
34
|
+
timeouts[:write_total_timeout_multiplier] = 50
|
35
|
+
timeouts[:write_total_timeout_constant] = 10
|
36
|
+
err = RubySerial::Win32.SetCommTimeouts @fd, timeouts
|
37
|
+
if err == 0
|
38
|
+
raise RubySerial::Exception, RubySerial::Win32::ERROR_CODES[FFI.errno]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def read(size)
|
44
|
+
buff = FFI::MemoryPointer.new :char, size
|
45
|
+
count = FFI::MemoryPointer.new :uint32, 1
|
46
|
+
err = RubySerial::Win32.ReadFile(@fd, buff, size, count, nil)
|
47
|
+
if err == 0
|
48
|
+
raise RubySerial::Exception, RubySerial::Win32::ERROR_CODES[FFI.errno]
|
49
|
+
end
|
50
|
+
buff.get_bytes(0, count.read_string.unpack('H4').join().to_i(16))
|
51
|
+
end
|
52
|
+
|
53
|
+
def write(data)
|
54
|
+
buff = FFI::MemoryPointer.from_string(data.to_s)
|
55
|
+
count = FFI::MemoryPointer.new :uint32, 1
|
56
|
+
err = RubySerial::Win32.WriteFile(@fd, buff, buff.size, count, nil)
|
57
|
+
if err == 0
|
58
|
+
raise RubySerial::Exception, RubySerial::Win32::ERROR_CODES[FFI.errno]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def close
|
63
|
+
err = RubySerial::Win32.CloseHandle(@fd)
|
64
|
+
if err == 0
|
65
|
+
raise RubySerial::Exception, RubySerial::Win32::ERROR_CODES[FFI.errno]
|
66
|
+
else
|
67
|
+
@open = false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def closed?
|
72
|
+
!@open
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,275 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module RubySerial
|
4
|
+
module Win32
|
5
|
+
extend FFI::Library
|
6
|
+
ffi_lib 'kernel32'
|
7
|
+
ffi_convention :stdcall
|
8
|
+
|
9
|
+
GENERIC_READ = 0x80000000
|
10
|
+
GENERIC_WRITE = 0x40000000
|
11
|
+
OPEN_EXISTING = 3
|
12
|
+
|
13
|
+
ERROR_CODES = {
|
14
|
+
5 => "ERROR_ACCESS_DENIED",
|
15
|
+
57 => "ERROR_ADAP_HDW_ERR",
|
16
|
+
85 => "ERROR_ALREADY_ASSIGNED",
|
17
|
+
183 => "ERROR_ALREADY_EXISTS",
|
18
|
+
7 => "ERROR_ARENA_TRASHED",
|
19
|
+
174 => "ERROR_ATOMIC_LOCKS_NOT_SUPPORTED",
|
20
|
+
199 => "ERROR_AUTODATASEG_EXCEEDS_64k",
|
21
|
+
160 => "ERROR_BAD_ARGUMENTS",
|
22
|
+
22 => "ERROR_BAD_COMMAND",
|
23
|
+
66 => "ERROR_BAD_DEV_TYPE",
|
24
|
+
119 => "ERROR_BAD_DRIVER_LEVEL",
|
25
|
+
10 => "ERROR_BAD_ENVIRONMENT",
|
26
|
+
193 => "ERROR_BAD_EXE_FORMAT",
|
27
|
+
222 => "ERROR_BAD_FILE_TYPE",
|
28
|
+
11 => "ERROR_BAD_FORMAT",
|
29
|
+
24 => "ERROR_BAD_LENGTH",
|
30
|
+
67 => "ERROR_BAD_NET_NAME",
|
31
|
+
58 => "ERROR_BAD_NET_RESP",
|
32
|
+
53 => "ERROR_BAD_NETPATH",
|
33
|
+
161 => "ERROR_BAD_PATHNAME",
|
34
|
+
230 => "ERROR_BAD_PIPE",
|
35
|
+
60 => "ERROR_BAD_REM_ADAP",
|
36
|
+
159 => "ERROR_BAD_THREADID_ADDR",
|
37
|
+
20 => "ERROR_BAD_UNIT",
|
38
|
+
109 => "ERROR_BROKEN_PIPE",
|
39
|
+
111 => "ERROR_BUFFER_OVERFLOW",
|
40
|
+
142 => "ERROR_BUSY_DRIVE",
|
41
|
+
170 => "ERROR_BUSY",
|
42
|
+
120 => "ERROR_CALL_NOT_IMPLEMENTED",
|
43
|
+
173 => "ERROR_CANCEL_VIOLATION",
|
44
|
+
266 => "ERROR_CANNOT_COPY",
|
45
|
+
82 => "ERROR_CANNOT_MAKE",
|
46
|
+
221 => "ERROR_CHECKOUT_REQUIRED",
|
47
|
+
129 => "ERROR_CHILD_NOT_COMPLETE",
|
48
|
+
23 => "ERROR_CRC",
|
49
|
+
16 => "ERROR_CURRENT_DIRECTORY",
|
50
|
+
303 => "ERROR_DELETE_PENDING",
|
51
|
+
55 => "ERROR_DEV_NOT_EXIST",
|
52
|
+
145 => "ERROR_DIR_NOT_EMPTY",
|
53
|
+
144 => "ERROR_DIR_NOT_ROOT",
|
54
|
+
130 => "ERROR_DIRECT_ACCESS_HANDLE",
|
55
|
+
267 => "ERROR_DIRECTORY",
|
56
|
+
157 => "ERROR_DISCARDED",
|
57
|
+
107 => "ERROR_DISK_CHANGE",
|
58
|
+
112 => "ERROR_DISK_FULL",
|
59
|
+
302 => "ERROR_DISK_TOO_FRAGMENTED",
|
60
|
+
108 => "ERROR_DRIVE_LOCKED",
|
61
|
+
52 => "ERROR_DUP_NAME",
|
62
|
+
196 => "ERROR_DYNLINK_FROM_INVALID_RING",
|
63
|
+
276 => "ERROR_EA_FILE_CORRUPT",
|
64
|
+
255 => "ERROR_EA_LIST_INCONSISTENT",
|
65
|
+
277 => "ERROR_EA_TABLE_FULL",
|
66
|
+
275 => "ERROR_EAS_DIDNT_FIT",
|
67
|
+
282 => "ERROR_EAS_NOT_SUPPORTED",
|
68
|
+
203 => "ERROR_ENVVAR_NOT_FOUND",
|
69
|
+
101 => "ERROR_EXCL_SEM_ALREADY_OWNED",
|
70
|
+
217 => "ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY",
|
71
|
+
218 => "ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY",
|
72
|
+
216 => "ERROR_EXE_MACHINE_TYPE_MISMATCH",
|
73
|
+
192 => "ERROR_EXE_MARKED_INVALID",
|
74
|
+
83 => "ERROR_FAIL_I24",
|
75
|
+
350 => "ERROR_FAIL_NOACTION_REBOOT",
|
76
|
+
352 => "ERROR_FAIL_RESTART",
|
77
|
+
351 => "ERROR_FAIL_SHUTDOWN",
|
78
|
+
220 => "ERROR_FILE_CHECKED_OUT",
|
79
|
+
80 => "ERROR_FILE_EXISTS",
|
80
|
+
2 => "ERROR_FILE_NOT_FOUND",
|
81
|
+
223 => "ERROR_FILE_TOO_LARGE",
|
82
|
+
206 => "ERROR_FILENAME_EXCED_RANGE",
|
83
|
+
224 => "ERROR_FORMS_AUTH_REQUIRED",
|
84
|
+
31 => "ERROR_GEN_FAILURE",
|
85
|
+
39 => "ERROR_HANDLE_DISK_FULL",
|
86
|
+
38 => "ERROR_HANDLE_EOF",
|
87
|
+
308 => "ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT",
|
88
|
+
304 => "ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING",
|
89
|
+
202 => "ERROR_INFLOOP_IN_RELOC_CHAIN",
|
90
|
+
122 => "ERROR_INSUFFICIENT_BUFFER",
|
91
|
+
12 => "ERROR_INVALID_ACCESS",
|
92
|
+
487 => "ERROR_INVALID_ADDRESS",
|
93
|
+
104 => "ERROR_INVALID_AT_INTERRUPT_TIME",
|
94
|
+
9 => "ERROR_INVALID_BLOCK",
|
95
|
+
117 => "ERROR_INVALID_CATEGORY",
|
96
|
+
13 => "ERROR_INVALID_DATA",
|
97
|
+
15 => "ERROR_INVALID_DRIVE",
|
98
|
+
278 => "ERROR_INVALID_EA_HANDLE",
|
99
|
+
254 => "ERROR_INVALID_EA_NAME",
|
100
|
+
151 => "ERROR_INVALID_EVENT_COUNT",
|
101
|
+
191 => "ERROR_INVALID_EXE_SIGNATURE",
|
102
|
+
186 => "ERROR_INVALID_FLAG_NUMBER",
|
103
|
+
1 => "ERROR_INVALID_FUNCTION",
|
104
|
+
6 => "ERROR_INVALID_HANDLE",
|
105
|
+
124 => "ERROR_INVALID_LEVEL",
|
106
|
+
153 => "ERROR_INVALID_LIST_FORMAT",
|
107
|
+
307 => "ERROR_INVALID_LOCK_RANGE",
|
108
|
+
195 => "ERROR_INVALID_MINALLOCSIZE",
|
109
|
+
190 => "ERROR_INVALID_MODULETYPE",
|
110
|
+
123 => "ERROR_INVALID_NAME",
|
111
|
+
301 => "ERROR_INVALID_OPLOCK_PROTOCOL",
|
112
|
+
182 => "ERROR_INVALID_ORDINAL",
|
113
|
+
87 => "ERROR_INVALID_PARAMETER",
|
114
|
+
86 => "ERROR_INVALID_PASSWORD",
|
115
|
+
198 => "ERROR_INVALID_SEGDPL",
|
116
|
+
180 => "ERROR_INVALID_SEGMENT_NUMBER",
|
117
|
+
209 => "ERROR_INVALID_SIGNAL_NUMBER",
|
118
|
+
189 => "ERROR_INVALID_STACKSEG",
|
119
|
+
188 => "ERROR_INVALID_STARTING_CODESEG",
|
120
|
+
114 => "ERROR_INVALID_TARGET_HANDLE",
|
121
|
+
118 => "ERROR_INVALID_VERIFY_SWITCH",
|
122
|
+
197 => "ERROR_IOPL_NOT_ENABLED",
|
123
|
+
147 => "ERROR_IS_JOIN_PATH",
|
124
|
+
133 => "ERROR_IS_JOIN_TARGET",
|
125
|
+
134 => "ERROR_IS_JOINED",
|
126
|
+
146 => "ERROR_IS_SUBST_PATH",
|
127
|
+
149 => "ERROR_IS_SUBST_TARGET",
|
128
|
+
135 => "ERROR_IS_SUBSTED",
|
129
|
+
194 => "ERROR_ITERATED_DATA_EXCEEDS_64k",
|
130
|
+
138 => "ERROR_JOIN_TO_JOIN",
|
131
|
+
140 => "ERROR_JOIN_TO_SUBST",
|
132
|
+
154 => "ERROR_LABEL_TOO_LONG",
|
133
|
+
167 => "ERROR_LOCK_FAILED",
|
134
|
+
33 => "ERROR_LOCK_VIOLATION",
|
135
|
+
212 => "ERROR_LOCKED",
|
136
|
+
353 => "ERROR_MAX_SESSIONS_REACHED",
|
137
|
+
164 => "ERROR_MAX_THRDS_REACHED",
|
138
|
+
208 => "ERROR_META_EXPANSION_TOO_LONG",
|
139
|
+
126 => "ERROR_MOD_NOT_FOUND",
|
140
|
+
234 => "ERROR_MORE_DATA",
|
141
|
+
317 => "ERROR_MR_MID_NOT_FOUND",
|
142
|
+
131 => "ERROR_NEGATIVE_SEEK",
|
143
|
+
215 => "ERROR_NESTING_NOT_ALLOWED",
|
144
|
+
88 => "ERROR_NET_WRITE_FAULT",
|
145
|
+
64 => "ERROR_NETNAME_DELETED",
|
146
|
+
65 => "ERROR_NETWORK_ACCESS_DENIED",
|
147
|
+
54 => "ERROR_NETWORK_BUSY",
|
148
|
+
232 => "ERROR_NO_DATA",
|
149
|
+
18 => "ERROR_NO_MORE_FILES",
|
150
|
+
259 => "ERROR_NO_MORE_ITEMS",
|
151
|
+
113 => "ERROR_NO_MORE_SEARCH_HANDLES",
|
152
|
+
89 => "ERROR_NO_PROC_SLOTS",
|
153
|
+
205 => "ERROR_NO_SIGNAL_SENT",
|
154
|
+
62 => "ERROR_NO_SPOOL_SPACE",
|
155
|
+
125 => "ERROR_NO_VOLUME_LABEL",
|
156
|
+
26 => "ERROR_NOT_DOS_DISK",
|
157
|
+
8 => "ERROR_NOT_ENOUGH_MEMORY",
|
158
|
+
136 => "ERROR_NOT_JOINED",
|
159
|
+
158 => "ERROR_NOT_LOCKED",
|
160
|
+
288 => "ERROR_NOT_OWNER",
|
161
|
+
21 => "ERROR_NOT_READY",
|
162
|
+
17 => "ERROR_NOT_SAME_DEVICE",
|
163
|
+
137 => "ERROR_NOT_SUBSTED",
|
164
|
+
50 => "ERROR_NOT_SUPPORTED",
|
165
|
+
309 => "ERROR_NOTIFICATION_GUID_ALREADY_DEFINED",
|
166
|
+
110 => "ERROR_OPEN_FAILED",
|
167
|
+
300 => "ERROR_OPLOCK_NOT_GRANTED",
|
168
|
+
28 => "ERROR_OUT_OF_PAPER",
|
169
|
+
84 => "ERROR_OUT_OF_STRUCTURES",
|
170
|
+
14 => "ERROR_OUTOFMEMORY",
|
171
|
+
299 => "ERROR_PARTIAL_COPY",
|
172
|
+
148 => "ERROR_PATH_BUSY",
|
173
|
+
3 => "ERROR_PATH_NOT_FOUND",
|
174
|
+
231 => "ERROR_PIPE_BUSY",
|
175
|
+
229 => "ERROR_PIPE_LOCAL",
|
176
|
+
233 => "ERROR_PIPE_NOT_CONNECTED",
|
177
|
+
63 => "ERROR_PRINT_CANCELLED",
|
178
|
+
61 => "ERROR_PRINTQ_FULL",
|
179
|
+
127 => "ERROR_PROC_NOT_FOUND",
|
180
|
+
402 => "ERROR_PROCESS_MODE_ALREADY_BACKGROUND",
|
181
|
+
403 => "ERROR_PROCESS_MODE_NOT_BACKGROUND",
|
182
|
+
30 => "ERROR_READ_FAULT",
|
183
|
+
72 => "ERROR_REDIR_PAUSED",
|
184
|
+
201 => "ERROR_RELOC_CHAIN_XEEDS_SEGLIM",
|
185
|
+
51 => "ERROR_REM_NOT_LIST",
|
186
|
+
71 => "ERROR_REQ_NOT_ACCEP",
|
187
|
+
207 => "ERROR_RING2_STACK_IN_USE",
|
188
|
+
200 => "ERROR_RING2SEG_MUST_BE_MOVABLE",
|
189
|
+
143 => "ERROR_SAME_DRIVE",
|
190
|
+
318 => "ERROR_SCOPE_NOT_FOUND",
|
191
|
+
27 => "ERROR_SECTOR_NOT_FOUND",
|
192
|
+
306 => "ERROR_SECURITY_STREAM_IS_INCONSISTENT",
|
193
|
+
132 => "ERROR_SEEK_ON_DEVICE",
|
194
|
+
25 => "ERROR_SEEK",
|
195
|
+
102 => "ERROR_SEM_IS_SET",
|
196
|
+
187 => "ERROR_SEM_NOT_FOUND",
|
197
|
+
105 => "ERROR_SEM_OWNER_DIED",
|
198
|
+
121 => "ERROR_SEM_TIMEOUT",
|
199
|
+
106 => "ERROR_SEM_USER_LIMIT",
|
200
|
+
36 => "ERROR_SHARING_BUFFER_EXCEEDED",
|
201
|
+
70 => "ERROR_SHARING_PAUSED",
|
202
|
+
32 => "ERROR_SHARING_VIOLATION",
|
203
|
+
305 => "ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME",
|
204
|
+
162 => "ERROR_SIGNAL_PENDING",
|
205
|
+
156 => "ERROR_SIGNAL_REFUSED",
|
206
|
+
141 => "ERROR_SUBST_TO_JOIN",
|
207
|
+
139 => "ERROR_SUBST_TO_SUBST",
|
208
|
+
0 => "ERROR_SUCCESS",
|
209
|
+
150 => "ERROR_SYSTEM_TRACE",
|
210
|
+
210 => "ERROR_THREAD_1_INACTIVE",
|
211
|
+
400 => "ERROR_THREAD_MODE_ALREADY_BACKGROUND",
|
212
|
+
401 => "ERROR_THREAD_MODE_NOT_BACKGROUND",
|
213
|
+
56 => "ERROR_TOO_MANY_CMDS",
|
214
|
+
214 => "ERROR_TOO_MANY_MODULES",
|
215
|
+
152 => "ERROR_TOO_MANY_MUXWAITERS",
|
216
|
+
68 => "ERROR_TOO_MANY_NAMES",
|
217
|
+
4 => "ERROR_TOO_MANY_OPEN_FILES",
|
218
|
+
298 => "ERROR_TOO_MANY_POSTS",
|
219
|
+
103 => "ERROR_TOO_MANY_SEM_REQUESTS",
|
220
|
+
100 => "ERROR_TOO_MANY_SEMAPHORES",
|
221
|
+
69 => "ERROR_TOO_MANY_SESS",
|
222
|
+
155 => "ERROR_TOO_MANY_TCBS",
|
223
|
+
59 => "ERROR_UNEXP_NET_ERR",
|
224
|
+
240 => "ERROR_VC_DISCONNECTED",
|
225
|
+
226 => "ERROR_VIRUS_DELETED",
|
226
|
+
225 => "ERROR_VIRUS_INFECTED",
|
227
|
+
128 => "ERROR_WAIT_NO_CHILDREN",
|
228
|
+
29 => "ERROR_WRITE_FAULT",
|
229
|
+
19 => "ERROR_WRITE_PROTECT",
|
230
|
+
34 => "ERROR_WRONG_DISK",
|
231
|
+
258 => "WAIT_TIMEOUT"
|
232
|
+
}
|
233
|
+
|
234
|
+
class DCB < FFI::Struct
|
235
|
+
layout :dcblength, :uint32,
|
236
|
+
:baudrate, :uint32,
|
237
|
+
:flags, :uint32, # :flag is actually a bit fields compound:
|
238
|
+
:wreserved, :uint16, # uint32 fBinary :1;
|
239
|
+
:xonlim, :uint16, # uint32 fParity :1;
|
240
|
+
:xofflim, :uint16, # uint32 fParity :1;
|
241
|
+
:bytesize, :uint8, # uint32 fOutxCtsFlow :1;
|
242
|
+
:parity, :uint8, # uint32 fOutxDsrFlow :1;
|
243
|
+
:stopbits, :uint8, # uint32 fDtrControl :2;
|
244
|
+
:xonchar, :int8, # uint32 fDsrSensitivity :1;
|
245
|
+
:xoffchar, :int8, # uint32 fTXContinueOnXoff :1;
|
246
|
+
:errorchar, :int8, # uint32 fOutX :1;
|
247
|
+
:eofchar, :int8, # uint32 fInX :1;
|
248
|
+
:evtchar, :int8, # uint32 fErrorChar :1;
|
249
|
+
:wreserved1, :uint16 # uint32 fNull :1;
|
250
|
+
# uint32 fRtsControl :2;
|
251
|
+
# uint32 fAbortOnError :1;
|
252
|
+
# uint32 fDummy2 :17;
|
253
|
+
Sizeof = 28
|
254
|
+
ONESTOPBIT = 0
|
255
|
+
NOPARITY = 0
|
256
|
+
end
|
257
|
+
|
258
|
+
class CommTimeouts < FFI::Struct
|
259
|
+
layout :read_interval_timeout, :uint32,
|
260
|
+
:read_total_timeout_multiplier, :uint32,
|
261
|
+
:read_total_timeout_constant, :uint32,
|
262
|
+
:write_total_timeout_multiplier, :uint32,
|
263
|
+
:write_total_timeout_constant, :uint32
|
264
|
+
end
|
265
|
+
|
266
|
+
attach_function :CreateFileA, [:pointer, :uint32, :uint32, :pointer, :uint32, :uint32, :pointer], :pointer
|
267
|
+
attach_function :CloseHandle, [:pointer], :int
|
268
|
+
attach_function :ReadFile, [:pointer, :pointer, :uint32, :pointer, :pointer], :int32
|
269
|
+
attach_function :WriteFile, [:pointer, :pointer, :uint32, :pointer, :pointer], :int32
|
270
|
+
attach_function :GetCommState, [:pointer, RubySerial::Win32::DCB], :int32
|
271
|
+
attach_function :SetCommState, [:pointer, RubySerial::Win32::DCB], :int32
|
272
|
+
attach_function :GetCommTimeouts, [:pointer, RubySerial::Win32::CommTimeouts], :int32
|
273
|
+
attach_function :SetCommTimeouts, [:pointer, RubySerial::Win32::CommTimeouts], :int32
|
274
|
+
end
|
275
|
+
end
|
data/rubyserial.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "rubyserial/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "rubyserial"
|
6
|
+
s.version = RubySerial::VERSION
|
7
|
+
s.summary = "ffi ruby serialport gem"
|
8
|
+
s.description = "ffi ruby serialport gem"
|
9
|
+
s.homepage = "https://github.com/hybridgroup/rubyserial"
|
10
|
+
s.authors = ["Adrian Zankich", "Theron Boerner", "Javier Cervantes"]
|
11
|
+
s.platform = Gem::Platform::RUBY
|
12
|
+
s.license = 'Apache 2.0'
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
s.add_runtime_dependency 'ffi', '~> 1.9.3'
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubyserial
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Adrian Zankich
|
8
|
+
- Theron Boerner
|
9
|
+
- Javier Cervantes
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2014-07-01 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: ffi
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - "~>"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.9.3
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - "~>"
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: 1.9.3
|
29
|
+
description: ffi ruby serialport gem
|
30
|
+
email:
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- ".gitignore"
|
36
|
+
- Gemfile
|
37
|
+
- LICENSE
|
38
|
+
- README.md
|
39
|
+
- Rakefile
|
40
|
+
- lib/rubyserial.rb
|
41
|
+
- lib/rubyserial/linux_constants.rb
|
42
|
+
- lib/rubyserial/osx_constants.rb
|
43
|
+
- lib/rubyserial/posix.rb
|
44
|
+
- lib/rubyserial/version.rb
|
45
|
+
- lib/rubyserial/windows.rb
|
46
|
+
- lib/rubyserial/windows_constants.rb
|
47
|
+
- rubyserial.gemspec
|
48
|
+
homepage: https://github.com/hybridgroup/rubyserial
|
49
|
+
licenses:
|
50
|
+
- Apache 2.0
|
51
|
+
metadata: {}
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project:
|
68
|
+
rubygems_version: 2.2.2
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: ffi ruby serialport gem
|
72
|
+
test_files: []
|