rubyserial-with-blocking 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d6381caf1cc6b6fcebd72e2c632a92bfbaa46f5c
4
+ data.tar.gz: 0ec74868ab6b407eb1c6c85af4b910de845a55d7
5
+ SHA512:
6
+ metadata.gz: adc8fcf13dce6cc2f6715a3cb0a0198754698ca45d7d53c98d0f37745c8d135b65a57c042aa889c43ac60664a7238d1735c628f4f0d9366d6dee45b9b2a05694
7
+ data.tar.gz: a06a5331e0b171e7995b5eff36b64e28b5209b4af8fc2778727f4a3666ecad446676a22cece19a5df99c6a97dc713bd00220be252ed8782fc470d95178fcd2bb
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ /vendor
3
+ Gemfile.lock
4
+ socat.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --warnings
3
+ --require spec_helper
@@ -0,0 +1,18 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - ruby-head
7
+ - jruby
8
+ - jruby-head
9
+ - rbx-2.2.10
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: jruby-head
13
+ - rvm: ruby-head
14
+ install:
15
+ #- sudo apt-get update && sudo apt-get install --force-yes socat
16
+ script:
17
+ - bundle install
18
+ - bundle exec rspec -fd
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gemspec
5
+ gem 'rspec', '~> 3.0.0'
@@ -0,0 +1,7 @@
1
+ #guard(:rspec, all_on_start: true) do #, cli: '--format nested --debug --color' do
2
+ guard :rspec, cmd: "bundle exec rspec" do
3
+ watch(%r{^spec/.+[_-]spec\.rb$})
4
+ watch(%r{^lib/rubyserial/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ watch('lib/rubyserial.rb') { "spec" }
7
+ end
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.
@@ -0,0 +1,76 @@
1
+ # THIS IS ONLY THE FORK!
2
+
3
+ it is adding blocking read functionality. I added a config hash to the c'tor so
4
+ that you can control VMIN & VTIME termio settings for the device. VMIN was fixed
5
+ to 0 before resulting in effectively always returning immediatly from the read
6
+ call and you could not just block wait for input. But polling is bad. The other
7
+ thing i did was to add a getter for the file descriptor. This makes it possible
8
+ to use the serial device in a select call. You can also use select to avoid
9
+ polling but much more it is useful to use it to let the OS block wait on
10
+ multiple IO sources simultaneously.
11
+
12
+ It made the changes in a way which will not break existing code. Old code just
13
+ does what it did before.
14
+
15
+ To block reading add vmin: Serial.new(path, nil, nil, vmin: 1). This will block
16
+ until at least one character was read.
17
+
18
+ To wait for multiple input sources use select:
19
+
20
+ sp = Serial.new(path)
21
+ # combine some sources in1, in2, and the serial port
22
+ result = IO.select([in1, in2, IO.new(sp.fd)])
23
+
24
+ The IO#select call returns and array of arrays with file descriptors ready for
25
+ reading (it's more complex, see IO#select manual)
26
+
27
+
28
+ ----
29
+
30
+ # rubyserial
31
+
32
+ RubySerial is a simple Ruby gem for reading from and writing to serial ports.
33
+
34
+ Unlike other Ruby serial port implementations, it supports all of the most popular Ruby implementations (MRI, JRuby, & Rubinius) on the most popular operating systems (OSX, Linux, & Windows). And it does not require any native compilation thanks to using RubyFFI [https://github.com/ffi/ffi](https://github.com/ffi/ffi).
35
+
36
+ The interface to RubySerial should be (mostly) compatible with other Ruby serialport gems, so you should be able to drop in the new gem, change the `require` and use it as a replacement. If not, please let us know so we can address any issues.
37
+
38
+ [![Build Status](https://travis-ci.org/hybridgroup/rubyserial.svg)](https://travis-ci.org/hybridgroup/rubyserial)
39
+ [![Build status](https://ci.appveyor.com/api/projects/status/946nlaqy4443vb99/branch/master?svg=true)](https://ci.appveyor.com/project/zankich/rubyserial/branch/master)
40
+
41
+ ## Installation
42
+
43
+ $ gem install rubyserial
44
+
45
+ ## Usage
46
+
47
+ ```ruby
48
+ require 'rubyserial'
49
+ serialport = Serial.new '/dev/ttyACM0', 57600
50
+ ```
51
+
52
+ ## Methods
53
+
54
+ **write(data : String) -> Int**
55
+
56
+ Returns the number of bytes written.
57
+ Emits a `RubySerial::Exception` on error.
58
+
59
+ **read(length : Int) -> String**
60
+
61
+ Returns a string up to `length` long. It is not guaranteed to return the entire
62
+ length specified, and will return an empty string if no data is
63
+ available. Emits a `RubySerial::Exception` on error.
64
+
65
+ **getbyte -> Fixnum or nil**
66
+
67
+ Returns an 8 bit byte or nil if no data is available.
68
+ Emits a `RubySerial::Exception` on error.
69
+
70
+ **RubySerial::Exception**
71
+
72
+ A wrapper exception type, that returns the underlying system error code.
73
+
74
+ ## License
75
+
76
+ Apache 2.0. See `LICENSE` for more details.
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,25 @@
1
+ platform:
2
+ - x64
3
+
4
+ install:
5
+ - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
6
+ - ruby -v
7
+ - gem install bundler
8
+ - bundle install
9
+ - ps: Start-FileDownload https://github.com/hybridgroup/rubyserial/raw/appveyor_deps/com0com.cer
10
+ - ps: C:\"Program Files"\"Microsoft SDKs"\Windows\v7.1\Bin\CertMgr.exe /add com0com.cer /s /r localMachine root
11
+ - ps: C:\"Program Files"\"Microsoft SDKs"\Windows\v7.1\Bin\CertMgr.exe /add com0com.cer /s /r localMachine trustedpublisher
12
+ - ps: Start-FileDownload https://github.com/hybridgroup/rubyserial/raw/appveyor_deps/setup_com0com_W7_x64_signed.exe
13
+ - ps: $env:CNC_INSTALL_CNCA0_CNCB0_PORTS="YES"
14
+ - ps: .\setup_com0com_W7_x64_signed.exe /S
15
+ - ps: sleep 60
16
+
17
+ test_script:
18
+ - ps: rspec spec -fd
19
+
20
+ environment:
21
+ matrix:
22
+ - ruby_version: "200-x64"
23
+ - ruby_version: "21-x64"
24
+
25
+ build: off
@@ -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