rubyserial-with-blocking 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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