serialport 1.2.2 → 1.3.2

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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YjQyZmY0M2ZiNGMzNjAzNjBmNDRjM2FlMTAwNDA5ZmJhYzc2MWU1YQ==
5
- data.tar.gz: !binary |-
6
- NmY1ZTRmNzEyOTM2ZWNiOWJjODJkZTkwYjNlMTk2NzliNmIyOWM3Mw==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- M2U0NTJkYzM2Y2JiZGU2ODhlMjVhNDcyMTNkZTNmNTM5Yjc4ODRlMzE3ZDFj
10
- YjBlNWY0Y2ZhYjc3ZGZkMmRmZjgzZTllOWIwOGEwYzQ5N2IzN2NhMjY5YjIz
11
- MjQ0YjM0ZWRiMDU3YzdmNzkzYzE5MzBkYmVkMWE5ZTJkZDJmNjE=
12
- data.tar.gz: !binary |-
13
- YjZhNzNlYjJiNDJiZWVjMWIwNTQzYzc5ZjNjYzRhNmE2MDA1OWY3ZTljNWU3
14
- ODIwN2QzMzA3ZjM5ZTUxMDcxNDE0YTc5ZjJlNjc0ZGZiNjFlMGJhNGVhYWFj
15
- OTE4NjVlNjkwOTFlZDM3NTQ4NDM5OTUzMDhlNTgyOTIzOGNjZWQ=
2
+ SHA256:
3
+ metadata.gz: c546c402122eaa69e8cf05c259b42e7fde1ab9d09f6cc8c02561d99826e76039
4
+ data.tar.gz: 40368e821d7a75588188736bb265c572012e77822027dcce617a0c9499cbb810
5
+ SHA512:
6
+ metadata.gz: 7eafdaa9d95e78327f3bf020ff9519e9454db9fdc072163b3a5279edb292872261b2314cb253e4dc1f2bd99f35a2e81e4d96dd6ee64a6ffe2184fe1e30f59873
7
+ data.tar.gz: 7d745881cf1ee1f48c337210b529f4073ae68c1b4f06557241b2192a1e6608a2b208ba2c695da40a4f5ef4cd4206d601e4896af4c3f46cd7f2c2b558e3f14fe4
data/.gitignore CHANGED
@@ -7,8 +7,10 @@
7
7
  /ext/native/*.o
8
8
  /ext/native/*.so
9
9
  /ext/native/Makefile
10
+ lib/*.so
10
11
  .*.swp
11
12
  tags
12
13
  *.gem
13
14
  *.bundle
14
15
  Gemfile.lock
16
+ .yardoc
data/CHANGELOG CHANGED
@@ -1,28 +1,35 @@
1
- 1.2.2 => 11/03/2013: [FIXED] warning: already initialized constant VERSION
1
+ 1.3.1 => 07/26/2014: [FIXED] Ruby 2.2 support
2
+ [NEW] UNIX MARK/SPACE parity (CMSPAR) support
2
3
 
3
- 1.2.1 => 10/25/2013: [FIXED] removed absurd circular dependency
4
+ 1.3.0 => 11/17/2013: [NEW] flush_input() and flush_output() methods [Manuel A. Güílamo (MaG)]
4
5
 
5
- 1.2.0 => 10/25/2013: [NEW] rake-compiler, bundler, and travis ci integration
6
+ 1.2.3 => 11/04/2013: [FIXED] Improved documentation (yard)
6
7
 
7
- 1.1.0 => 05/14/2012: [NEW] Ruby 2.0 Support [Aaron Patterson (tenderlove)]
8
+ 1.2.2 => 11/03/2013: [FIXED] warning: already initialized constant VERSION
9
+
10
+ 1.2.1 => 10/25/2013: [FIXED] removed absurd circular dependency
11
+
12
+ 1.2.0 => 10/25/2013: [NEW] rake-compiler, bundler, and travis ci integration
13
+
14
+ 1.1.0 => 05/14/2012: [NEW] Ruby 2.0 Support [Aaron Patterson (tenderlove)]
8
15
  [FIXED] Support for baud rates up to 1000000 in Windows [Will Koehler (willkoehler)]
9
16
 
10
- 1.0.4 => 07/17/2010: [FIXED] [Windows] No longer restricted to specific bitrates
11
- [FIXED] [Windows] Removed potentially insecure sprintf() use
12
- [FIXED] [Windows] Workaround for rb_sys_fail not checking GetLastError()
13
-
14
- 1.0.3 => 04/08/2010: [FIXED] [Windows] Could not specify 10 or "COM10" or higher
15
- [FIXED] [Windows] Warning passing INT instead of LONG to GetCommModemStatus
17
+ 1.0.4 => 07/17/2010: [FIXED] [Windows] No longer restricted to specific bitrates
18
+ [FIXED] [Windows] Removed potentially insecure sprintf() use
19
+ [FIXED] [Windows] Workaround for rb_sys_fail not checking GetLastError()
20
+
21
+ 1.0.3 => 04/08/2010: [FIXED] [Windows] Could not specify 10 or "COM10" or higher
22
+ [FIXED] [Windows] Warning passing INT instead of LONG to GetCommModemStatus
16
23
 
17
- 1.0.2 => 04/06/2010: [FIXED] Passing a block into open did not properly handle a return from within the block
24
+ 1.0.2 => 04/06/2010: [FIXED] Passing a block into open did not properly handle a return from within the block
18
25
 
19
- 1.0.1 => 01/20/2010: [FIXED] Conditional RB_SERIAL_EXPORT needed for Visual Studio bonked GCC
26
+ 1.0.1 => 01/20/2010: [FIXED] Conditional RB_SERIAL_EXPORT needed for Visual Studio bonked GCC
20
27
 
21
28
  1.0.0 => 01/12/2010: [FIXED] x86_64 segmentation faults
22
- [NEW] Windows Ruby 1.9 support
29
+ [NEW] Windows Ruby 1.9 support
23
30
 
24
31
  0.7.4 => 10/12/2009: [NEW] Conditional 1.8.6 & 1.9 support (POSIX only).
25
- [NEW] MinGW support.
32
+ [NEW] MinGW support.
26
33
 
27
34
  0.7.3 => 10/09/2009: [NEW] POSIX Ruby 1.9 support
28
35
 
data/CHECKLIST CHANGED
@@ -1,5 +1,12 @@
1
- # Ruby-Serialport Gem Pre-Push Checklist
1
+ # Ruby-Serialport Gem Release Checklist
2
2
 
3
+ * Update documentation
3
4
  * Update lib/serialport/version.rb
4
5
  * Update CHANGELOG
5
6
  * Update README
7
+ * `rake build`
8
+ * `rake install`
9
+ * Test build
10
+ * `git tag -a v{VERSION} -m "v{VERSION}: {ONE-LINE DESCRIPTION}"`
11
+ * Merge and Push
12
+ * `rake release`
data/MANIFEST CHANGED
@@ -1,9 +1,8 @@
1
1
  CHANGELOG
2
2
  MANIFEST
3
- README
3
+ README.md
4
4
  Rakefile
5
5
  serialport.gemspec
6
- VERSION
7
6
  ext/native/extconf.rb
8
7
  ext/native/posix_serialport_impl.c
9
8
  ext/native/serialport.c
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Ruby/SerialPort
2
+
3
+ [![Build Status](https://travis-ci.org/hparra/ruby-serialport.png?branch=v1.2.2)](https://travis-ci.org/hparra/ruby-serialport)
4
+
5
+ ## Description
6
+
7
+ Ruby/SerialPort is a Ruby library that provides a class for using RS-232 serial ports. This class also contains low-level functions to check and set the current state of the signals on the line.
8
+
9
+ The native Windows version of this library supports the Microsoft Visual C++, Borland C++, and MinGW compilers.
10
+
11
+ There is an alternative gem with MRI, JRuby, and Rubinius support. See below.
12
+
13
+ ## Installation
14
+
15
+ Install the gem as normal: `sudo gem install serialport`
16
+
17
+ ## Testing
18
+
19
+ Use Ruby's version of miniterm: `ruby test/miniterm.rb`
20
+
21
+ ## API
22
+
23
+ See <http://rubydoc.info/gems/serialport/SerialPort> or run `yard`
24
+
25
+ ## Issues
26
+
27
+ See <https://github.com/hparra/ruby-serialport/issues>
28
+
29
+ ## Alternatives
30
+
31
+ The [Hybrid Group](http://hybridgroup.com/)'s MRI, JRuby, & Rubinius compatible [rubyserial](https://github.com/hybridgroup/rubyserial) gem may provide improved compatibilty in modern environments.
32
+
33
+ ## License
34
+
35
+ GPL
36
+
37
+ ## Authors
38
+
39
+ * Guillaume Pierronnet <moumar@netcourrier.com>
40
+ * Alan Stern <stern@rowland.harvard.edu>
41
+ * Tobin Richard <tobin.richard@gmail.com>
42
+ * Hector Parra <hector@hectorparra.com>
43
+ * Ryan C. Payne <rpayne-oss@bullittsystems.com>
@@ -3,6 +3,7 @@
3
3
  * Alan Stern <stern@rowland.harvard.edu>
4
4
  * Daniel E. Shipton <dshipton@redshiptechnologies.com>
5
5
  * Ryan C. Payne <rpayne-oss@bullittsystems.com>
6
+ * Manuel "MaG" A. Güílamo <maguilamo.c@gmail.com>
6
7
  *
7
8
  * This code is hereby licensed for public consumption under either the
8
9
  * GNU GPL v2 or greater.
@@ -109,7 +110,6 @@ VALUE sp_create_impl(class, _port)
109
110
  struct termios params;
110
111
 
111
112
  NEWOBJ(sp, struct RFile);
112
- rb_secure(4);
113
113
  OBJSETUP(sp, class, T_FILE);
114
114
  MakeOpenFile((VALUE) sp, fp);
115
115
 
@@ -125,8 +125,7 @@ VALUE sp_create_impl(class, _port)
125
125
  break;
126
126
 
127
127
  case T_STRING:
128
- Check_SafeStr(_port);
129
- port = RSTRING_PTR(_port);
128
+ port = StringValueCStr(_port);
130
129
  break;
131
130
 
132
131
  default:
@@ -352,15 +351,38 @@ VALUE sp_set_modem_params_impl(argc, argv, self)
352
351
  case EVEN:
353
352
  params.c_cflag |= PARENB;
354
353
  params.c_cflag &= ~PARODD;
354
+ #ifdef CMSPAR
355
+ params.c_cflag &= ~CMSPAR;
356
+ #endif
355
357
  break;
356
358
 
357
359
  case ODD:
358
360
  params.c_cflag |= PARENB;
359
361
  params.c_cflag |= PARODD;
362
+ #ifdef CMSPAR
363
+ params.c_cflag &= ~CMSPAR;
364
+ #endif
360
365
  break;
361
366
 
367
+ #ifdef CMSPAR
368
+ case SPACE:
369
+ params.c_cflag |= PARENB;
370
+ params.c_cflag &= ~PARODD;
371
+ params.c_cflag |= CMSPAR;
372
+ break;
373
+
374
+ case MARK:
375
+ params.c_cflag |= PARENB;
376
+ params.c_cflag |= PARODD;
377
+ params.c_cflag |= CMSPAR;
378
+ break;
379
+ #endif
380
+
362
381
  case NONE:
363
382
  params.c_cflag &= ~PARENB;
383
+ #ifdef CMSPAR
384
+ params.c_cflag &= ~CMSPAR;
385
+ #endif
364
386
  break;
365
387
 
366
388
  default:
@@ -730,4 +752,38 @@ VALUE sp_get_dtr_impl(self)
730
752
  return INT2FIX(ls.dtr);
731
753
  }
732
754
 
755
+ VALUE sp_flush_input_data_impl(self)
756
+ VALUE self;
757
+ {
758
+ int fd;
759
+ int ret;
760
+
761
+ fd = get_fd_helper(self);
762
+
763
+ ret = tcflush(fd, TCIFLUSH);
764
+ if(ret<0) {
765
+ return Qfalse;
766
+ }
767
+
768
+ return Qtrue;
769
+ }
770
+
771
+ VALUE sp_flush_output_data_impl(self)
772
+ VALUE self;
773
+ {
774
+ int fd;
775
+ int ret;
776
+
777
+ fd = get_fd_helper(self);
778
+
779
+ ret = tcflush(fd, TCOFLUSH);
780
+ if(ret<0) {
781
+ return Qfalse;
782
+ }
783
+
784
+ return Qtrue;
785
+ }
786
+
787
+
788
+
733
789
  #endif /* !defined(OS_MSWIN) && !defined(OS_BCCWIN) && !defined(OS_MINGW) */
@@ -11,11 +11,6 @@
11
11
  * You should have received a copy of the GNU General Public License
12
12
  * along with this program; if not, write to the Free Software
13
13
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14
- *
15
- * For documentation on serial programming, see the excellent:
16
- * "Serial Programming Guide for POSIX Operating Systems"
17
- * written Michael R. Sweet.
18
- * http://www.easysw.com/~mike/serial/
19
14
  */
20
15
 
21
16
  #include "serialport.h"
@@ -26,7 +21,10 @@ VALUE sBaud, sDataBits, sStopBits, sParity; /* strings */
26
21
  VALUE sRts, sDtr, sCts, sDsr, sDcd, sRi;
27
22
 
28
23
  /*
29
- * :nodoc: This method is private and will be called by SerialPort#new or SerialPort#open.
24
+ * @api private
25
+ *
26
+ * @see SerialPort#new
27
+ * @see SerialPort#open
30
28
  */
31
29
  static VALUE sp_create(class, _port)
32
30
  VALUE class, _port;
@@ -40,16 +38,26 @@ static VALUE sp_create(class, _port)
40
38
  * an ArgumentError.
41
39
  *
42
40
  * When using a hash the following keys are recognized:
43
- * ["baud"] Integer from 50 to 256000, depends on platform
41
+ * ["baud"] Integer from 50 to 256000, depending on platform
44
42
  * ["data_bits"] Integer from 5 to 8 (4 is allowed on Windows too)
45
- * ["stop_bits"] An integer, only allowed values are 1 or 2 (1.5 is not supported)
43
+ * ["stop_bits"] Integer, only allowed values are 1 or 2 (1.5 is not supported)
46
44
  * ["parity"] One of the constants NONE, EVEN or ODD (Windows allows also MARK and SPACE)
47
45
  *
48
46
  * When using separate arguments, they are interpreted as:
49
- * (baud, data_bits = 8, stop_bits = 1, parity = (previous_databits==8 ? NONE : EVEN))
47
+ * (baud, data_bits = 8, stop_bits = 1, parity = (previous_databits == 8 ? NONE : EVEN))
48
+ * A baudrate of nil will keep the old value.
49
+ * The default parity depends on the number of databits configured before this function call.
50
+ *
51
+ * @overload set_modem_params(baud, data_bits, stop_bits, parity)
52
+ * @param baud [Integer] the baud rate
53
+ * @param data_bits [Integer] the number of data bits
54
+ * @param stop_bits [Integer] the number of stop bits
55
+ * @param parity [Integer] the type of parity checking
56
+ * @overload set_modem_params(hash)
57
+ * @param opts [Hash] the options to configure port
50
58
  *
51
- * Nota: A baudrate of nil will keep the old value. The default parity depends on the
52
- * number of databits configured before this function call.
59
+ * @return [Hash] the original paramters
60
+ * @raise [ArgumentError] if values are invalide or unsupported
53
61
  */
54
62
  static VALUE sp_set_modem_params(argc, argv, self)
55
63
  int argc;
@@ -59,11 +67,11 @@ static VALUE sp_set_modem_params(argc, argv, self)
59
67
  }
60
68
 
61
69
  /*
62
- * Send a break for the given time.
63
- *
64
- * <tt>time</tt> is an integer of tenths-of-a-second for the break.
70
+ * Send a break for the given time
65
71
  *
66
- * Note: Under Posix, this value is very approximate.
72
+ * @param time [Integer] break time in tenths-of-a-second
73
+ * @return [nil]
74
+ * @note (POSIX) this value is very approximate
67
75
  */
68
76
  static VALUE sp_break(self, time)
69
77
  VALUE self, time;
@@ -72,7 +80,10 @@ static VALUE sp_break(self, time)
72
80
  }
73
81
 
74
82
  /*
75
- * Get the state (0 or 1) of the DTR line (not available on Windows)
83
+ * Get the state of the DTR line
84
+ *
85
+ * @note (Windows) DTR is not available
86
+ * @return [Integer] the state of DTR line, 0 or 1
76
87
  */
77
88
  static VALUE sp_get_dtr(self)
78
89
  VALUE self;
@@ -81,7 +92,10 @@ static VALUE sp_get_dtr(self)
81
92
  }
82
93
 
83
94
  /*
84
- * Get the flow control. The result is either NONE, HARD, SOFT or (HARD | SOFT)
95
+ * Get the flow control flag
96
+ *
97
+ * @return [Integer] the flow control flag
98
+ * @see SerialPort#set_flow_control
85
99
  */
86
100
  static VALUE sp_get_flow_control(self)
87
101
  VALUE self;
@@ -90,8 +104,10 @@ static VALUE sp_get_flow_control(self)
90
104
  }
91
105
 
92
106
  /*
93
- * Get the timeout value (in milliseconds) for reading.
94
- * See SerialPort#set_read_timeout for details.
107
+ * Get the read timeout value
108
+ *
109
+ * @return [Integer] the read timeout, in milliseconds
110
+ * @see SerialPort#set_read_timeout
95
111
  */
96
112
  static VALUE sp_get_read_timeout(self)
97
113
  VALUE self;
@@ -100,7 +116,10 @@ static VALUE sp_get_read_timeout(self)
100
116
  }
101
117
 
102
118
  /*
103
- * Get the state (0 or 1) of the RTS line (not available on Windows)
119
+ * Get the state of the RTS line
120
+ *
121
+ * @return [Integer] the state of RTS line, 0 or 1
122
+ * @note (Windows) RTS is not available
104
123
  */
105
124
  static VALUE sp_get_rts(self)
106
125
  VALUE self;
@@ -109,9 +128,10 @@ static VALUE sp_get_rts(self)
109
128
  }
110
129
 
111
130
  /*
112
- * Get the write timeout (in milliseconds)
131
+ * Get the write timeout
113
132
  *
114
- * Note: Under Posix, write timeouts are not implemented.
133
+ * @return [Integer] the write timeout, in milliseconds
134
+ * @note (POSIX) write timeouts are not implemented
115
135
  */
116
136
  static VALUE sp_get_write_timeout(self)
117
137
  VALUE self;
@@ -120,7 +140,10 @@ static VALUE sp_get_write_timeout(self)
120
140
  }
121
141
 
122
142
  /*
123
- * Set the state (0 or 1) of the DTR line
143
+ * Set the state of the DTR line
144
+ *
145
+ * @param val [Integer] the desired state of the DTR line, 0 or 1
146
+ * @return [Integer] the original +val+ parameter
124
147
  */
125
148
  static VALUE sp_set_dtr(self, val)
126
149
  VALUE self, val;
@@ -129,11 +152,14 @@ static VALUE sp_set_dtr(self, val)
129
152
  }
130
153
 
131
154
  /*
132
- * Set the flow control to either NONE, HARD, SOFT or (HARD | SOFT)
155
+ * Set the flow control
133
156
  *
134
- * Note: SerialPort::HARD mode is not supported on all platforms.
135
- * SerialPort::HARD uses RTS/CTS handshaking; DSR/DTR is not
136
- * supported.
157
+ * @param val [Integer] the flow control flag,
158
+ * +NONE+, +HARD+, +SOFT+, or (+HARD+ | +SOFT+)
159
+ * @return [Integer] the original +val+ parameter
160
+ * @note SerialPort::HARD mode is not supported on all platforms.
161
+ * @note SerialPort::HARD uses RTS/CTS handshaking.
162
+ * DSR/DTR is not supported.
137
163
  */
138
164
  static VALUE sp_set_flow_control(self, val)
139
165
  VALUE self, val;
@@ -149,7 +175,9 @@ static VALUE sp_set_flow_control(self, val)
149
175
  * requested number of bytes is available or the interval between the
150
176
  * arrival of two bytes exceeds the timeout value.
151
177
  *
152
- * Note: Read timeouts don't mix well with multi-threading.
178
+ * @param timeout [Integer] the read timeout in milliseconds
179
+ * @return [Integer] the original +timeout+ parameter
180
+ * @note Read timeouts don't mix well with multi-threading
153
181
  */
154
182
  static VALUE sp_set_read_timeout(self, val)
155
183
  VALUE self, val;
@@ -158,7 +186,10 @@ static VALUE sp_set_read_timeout(self, val)
158
186
  }
159
187
 
160
188
  /*
161
- * Set the state (0 or 1) of the RTS line
189
+ * Set the state of the RTS line
190
+ *
191
+ * @param val [Integer] the state of RTS line, 0 or 1
192
+ * @return [Integer] the original +val+ parameter
162
193
  */
163
194
  static VALUE sp_set_rts(self, val)
164
195
  VALUE self, val;
@@ -167,9 +198,11 @@ static VALUE sp_set_rts(self, val)
167
198
  }
168
199
 
169
200
  /*
170
- * Set a write timeout (in milliseconds)
201
+ * Set a write timeout
171
202
  *
172
- * Note: Under Posix, write timeouts are not implemented.
203
+ * @param val [Integer] the write timeout in milliseconds
204
+ * @return [Integer] the original +val+ parameter
205
+ * @note (POSIX) write timeouts are not implemented
173
206
  */
174
207
  static VALUE sp_set_write_timeout(self, val)
175
208
  VALUE self, val;
@@ -178,6 +211,7 @@ static VALUE sp_set_write_timeout(self, val)
178
211
  }
179
212
 
180
213
  /*
214
+ * @private helper
181
215
  */
182
216
  static void get_modem_params(self, mp)
183
217
  VALUE self;
@@ -187,7 +221,11 @@ static void get_modem_params(self, mp)
187
221
  }
188
222
 
189
223
  /*
190
- * Set the baud rate, see SerialPort#set_modem_params for details.
224
+ * Set the baud rate
225
+ *
226
+ * @param data_rate [Integer] the baud rate
227
+ * @return [Integer] the original +data_rate+ parameter
228
+ * @see SerialPort#set_modem_params
191
229
  */
192
230
  static VALUE sp_set_data_rate(self, data_rate)
193
231
  VALUE self, data_rate;
@@ -202,7 +240,11 @@ static VALUE sp_set_data_rate(self, data_rate)
202
240
  }
203
241
 
204
242
  /*
205
- * Set the data bits, see SerialPort#set_modem_params for details.
243
+ * Set the data bits
244
+ *
245
+ * @param data_bits [Integer] the number of data bits
246
+ * @return [Integer] the original +data_bits+ parameter
247
+ * @see SerialPort#set_modem_params
206
248
  */
207
249
  static VALUE sp_set_data_bits(self, data_bits)
208
250
  VALUE self, data_bits;
@@ -217,7 +259,11 @@ static VALUE sp_set_data_bits(self, data_bits)
217
259
  }
218
260
 
219
261
  /*
220
- * Set the stop bits, see SerialPort#set_modem_params for details.
262
+ * Set the stop bits
263
+ *
264
+ * @param stop_bits [Integer] the number of stop bits
265
+ * @return [Integer] the original +stop_bits+ parameter
266
+ * @see SerialPort#set_modem_params
221
267
  */
222
268
  static VALUE sp_set_stop_bits(self, stop_bits)
223
269
  VALUE self, stop_bits;
@@ -232,7 +278,11 @@ static VALUE sp_set_stop_bits(self, stop_bits)
232
278
  }
233
279
 
234
280
  /*
235
- * Set the parity, see SerialPort#set_modem_params for details.
281
+ * Set the parity
282
+ *
283
+ * @param parity [Integer] the parity type
284
+ * @return [Integer] the original +parity+ parameter
285
+ * @see SerialPort#set_modem_params
236
286
  */
237
287
  static VALUE sp_set_parity(self, parity)
238
288
  VALUE self, parity;
@@ -247,7 +297,10 @@ static VALUE sp_set_parity(self, parity)
247
297
  }
248
298
 
249
299
  /*
250
- * Get the current baud rate, see SerialPort#get_modem_params for details.
300
+ * Get the current baud rate
301
+ *
302
+ * @return [Integer] the current baud rate
303
+ * @see SerialPort#set_modem_params
251
304
  */
252
305
  static VALUE sp_get_data_rate(self)
253
306
  VALUE self;
@@ -260,7 +313,10 @@ static VALUE sp_get_data_rate(self)
260
313
  }
261
314
 
262
315
  /*
263
- * Get the current data bits, see SerialPort#get_modem_params for details.
316
+ * Get the current data bits
317
+ *
318
+ * @return [Integer] the current number of data bits
319
+ * @see SerialPort#set_modem_params
264
320
  */
265
321
  static VALUE sp_get_data_bits(self)
266
322
  VALUE self;
@@ -273,7 +329,10 @@ static VALUE sp_get_data_bits(self)
273
329
  }
274
330
 
275
331
  /*
276
- * Get the current stop bits, see SerialPort#get_modem_params for details.
332
+ * Get the current stop bits
333
+ *
334
+ * @return [Integer] the current number of stop bits
335
+ * @see SerialPort#set_modem_params for details
277
336
  */
278
337
  static VALUE sp_get_stop_bits(self)
279
338
  VALUE self;
@@ -286,7 +345,10 @@ static VALUE sp_get_stop_bits(self)
286
345
  }
287
346
 
288
347
  /*
289
- * Get the current parity, see SerialPort#get_modem_params for details.
348
+ * Get the current parity
349
+ *
350
+ * @return [Integer] the current parity
351
+ * @see SerialPort#set_modem_params
290
352
  */
291
353
  static VALUE sp_get_parity(self)
292
354
  VALUE self;
@@ -299,13 +361,10 @@ static VALUE sp_get_parity(self)
299
361
  }
300
362
 
301
363
  /*
302
- * Get the configure of the serial port.
364
+ * Get the configure of the serial port
303
365
  *
304
- * Returned is a hash with the following keys:
305
- * ["baud"] Integer with the baud rate
306
- * ["data_bits"] Integer from 5 to 8 (4 is possible on Windows too)
307
- * ["stop_bits"] Integer, 1 or 2 (1.5 is not supported)
308
- * ["parity"] One of the constants NONE, EVEN or ODD (on Windows may also MARK or SPACE)
366
+ * @return [Hash] the serial port configuration
367
+ * @see SerialPort#set_modem_params
309
368
  */
310
369
  static VALUE sp_get_modem_params(self)
311
370
  VALUE self;
@@ -325,6 +384,9 @@ static VALUE sp_get_modem_params(self)
325
384
  return hash;
326
385
  }
327
386
 
387
+ /*
388
+ * @api private
389
+ */
328
390
  void get_line_signals_helper(obj, ls)
329
391
  VALUE obj;
330
392
  struct line_signals *ls;
@@ -333,7 +395,10 @@ void get_line_signals_helper(obj, ls)
333
395
  }
334
396
 
335
397
  /*
336
- * Get the state (0 or 1) of the CTS line
398
+ * Get the state of the CTS line
399
+ *
400
+ * @return [Integer] the state of the CTS line, 0 or 1
401
+ * @see SerialPort#get_signals
337
402
  */
338
403
  static VALUE sp_get_cts(self)
339
404
  VALUE self;
@@ -346,7 +411,10 @@ static VALUE sp_get_cts(self)
346
411
  }
347
412
 
348
413
  /*
349
- * Get the state (0 or 1) of the DSR line
414
+ * Get the state of the DSR line
415
+ *
416
+ * @return [Integer] the state of the DSR line, 0 or 1
417
+ * @see SerialPort#get_signals
350
418
  */
351
419
  static VALUE sp_get_dsr(self)
352
420
  VALUE self;
@@ -359,7 +427,10 @@ static VALUE sp_get_dsr(self)
359
427
  }
360
428
 
361
429
  /*
362
- * Get the state (0 or 1) of the DCD line
430
+ * Get the state of the DCD line
431
+ *
432
+ * @return [Integer] the state of the DCD line, 0 or 1
433
+ * @see SerialPort#get_signals
363
434
  */
364
435
  static VALUE sp_get_dcd(self)
365
436
  VALUE self;
@@ -372,7 +443,10 @@ static VALUE sp_get_dcd(self)
372
443
  }
373
444
 
374
445
  /*
375
- * Get the state (0 or 1) of the RI line
446
+ * Get the state of the RI line
447
+ *
448
+ * @return [Integer] the state of the RI line, 0 or 1
449
+ * @see SerialPort#get_signals
376
450
  */
377
451
  static VALUE sp_get_ri(self)
378
452
  VALUE self;
@@ -385,10 +459,13 @@ static VALUE sp_get_ri(self)
385
459
  }
386
460
 
387
461
  /*
388
- * Return a hash with the state of each line status bit. Keys are
389
- * "rts", "dtr", "cts", "dsr", "dcd", and "ri".
462
+ * Return a hash with the state of each line status bit.
463
+ * Keys:
464
+ * "rts", "dtr", "cts", "dsr", "dcd", and "ri".
390
465
  *
391
- * Note: Under Windows, the rts and dtr values are not included.
466
+ * @return [Hash] the state line info
467
+ * @note (Windows) the rts and dtr values are not included
468
+ * @note This method is implemented as both SerialPort#signals and SerialPort#get_signals
392
469
  */
393
470
  static VALUE sp_signals(self)
394
471
  VALUE self;
@@ -412,11 +489,29 @@ static VALUE sp_signals(self)
412
489
  return hash;
413
490
  }
414
491
 
415
- /*
416
- * This class is used for communication over a serial port.
417
- * In addition to the methods here, you can use everything
418
- * Ruby's IO-class provides (read, write, getc, readlines, ...)
492
+ /**
493
+ * Flush data received but not read.
494
+ *
495
+ * @return [Boolean] true on success or false if an error occurs.
419
496
  */
497
+ static VALUE sp_flush_input_data(self)
498
+ VALUE self;
499
+ {
500
+ return sp_flush_input_data_impl(self);
501
+ }
502
+
503
+ /**
504
+ * Flush data written but not transmitted.
505
+ *
506
+ * @return [Boolean] true on success or false if an error occurs.
507
+ */
508
+ static VALUE sp_flush_output_data(self)
509
+ VALUE self;
510
+ {
511
+ return sp_flush_output_data_impl(self);
512
+ }
513
+
514
+
420
515
  void Init_serialport()
421
516
  {
422
517
  sBaud = rb_str_new2("baud");
@@ -478,12 +573,41 @@ void Init_serialport()
478
573
  rb_define_method(cSerialPort, "dcd", sp_get_dcd, 0);
479
574
  rb_define_method(cSerialPort, "ri", sp_get_ri, 0);
480
575
 
576
+ rb_define_method(cSerialPort, "flush_input", sp_flush_input_data, 0);
577
+ rb_define_method(cSerialPort, "flush_output", sp_flush_output_data, 0);
578
+
579
+ /*
580
+ * 0
581
+ */
481
582
  rb_define_const(cSerialPort, "NONE", INT2FIX(NONE));
583
+
584
+ /*
585
+ * 1
586
+ */
482
587
  rb_define_const(cSerialPort, "HARD", INT2FIX(HARD));
588
+
589
+ /*
590
+ * 2
591
+ */
483
592
  rb_define_const(cSerialPort, "SOFT", INT2FIX(SOFT));
484
593
 
594
+ /*
595
+ * 0
596
+ */
485
597
  rb_define_const(cSerialPort, "SPACE", INT2FIX(SPACE));
598
+
599
+ /*
600
+ * 1
601
+ */
486
602
  rb_define_const(cSerialPort, "MARK", INT2FIX(MARK));
603
+
604
+ /*
605
+ * 2
606
+ */
487
607
  rb_define_const(cSerialPort, "EVEN", INT2FIX(EVEN));
608
+
609
+ /*
610
+ * 3
611
+ */
488
612
  rb_define_const(cSerialPort, "ODD", INT2FIX(ODD));
489
613
  }
@@ -65,10 +65,10 @@ struct line_signals
65
65
  #endif
66
66
 
67
67
  #else
68
- #define SPACE 0
69
- #define MARK 0
70
68
  #define EVEN 1
71
69
  #define ODD 2
70
+ #define SPACE 3
71
+ #define MARK 4
72
72
 
73
73
  #define RB_SERIAL_EXPORT
74
74
  #endif
@@ -94,4 +94,7 @@ VALUE RB_SERIAL_EXPORT sp_set_dtr_impl(VALUE self, VALUE val);
94
94
  VALUE RB_SERIAL_EXPORT sp_get_rts_impl(VALUE self);
95
95
  VALUE RB_SERIAL_EXPORT sp_get_dtr_impl(VALUE self);
96
96
 
97
+ VALUE RB_SERIAL_EXPORT sp_flush_input_data_impl(VALUE self);
98
+ VALUE RB_SERIAL_EXPORT sp_flush_output_data_impl(VALUE self);
99
+
97
100
  #endif
@@ -76,7 +76,6 @@ VALUE RB_SERIAL_EXPORT sp_create_impl(class, _port)
76
76
  DCB dcb;
77
77
 
78
78
  NEWOBJ(sp, struct RFile);
79
- rb_secure(4);
80
79
  OBJSETUP(sp, class, T_FILE);
81
80
  MakeOpenFile((VALUE) sp, fp);
82
81
 
@@ -94,8 +93,7 @@ VALUE RB_SERIAL_EXPORT sp_create_impl(class, _port)
94
93
  break;
95
94
 
96
95
  case T_STRING:
97
- Check_SafeStr(_port);
98
- str_port = RSTRING_PTR(_port);
96
+ str_port = StringValueCStr(_port);
99
97
  if (str_port[0] != '\\') /* Check for Win32 Device Namespace prefix "\\.\" */
100
98
  {
101
99
  snprintf(port, sizeof(port) - 1, "\\\\.\\%s", str_port);
@@ -620,4 +618,40 @@ VALUE RB_SERIAL_EXPORT sp_get_dtr_impl(self)
620
618
  return self;
621
619
  }
622
620
 
621
+ #define PURGE_RXABORT 0x02
622
+ #define PURGE_RXCLEAR 0x08
623
+ VALUE RB_SERIAL_EXPORT sp_flush_input_data_impl(self)
624
+ VALUE self;
625
+ {
626
+ BOOL ret;
627
+ HANDLE fh;
628
+
629
+ fh = get_handle_helper(self);
630
+
631
+ ret = PurgeComm(fh, (DWORD)(PURGE_RXCLEAR | PURGE_RXABORT));
632
+ if(!ret) {
633
+ return Qfalse;
634
+ }
635
+ return Qtrue;
636
+ }
637
+
638
+ #define PURGE_TXABORT 0x01
639
+ #define PURGE_TXCLEAR 0x04
640
+ VALUE RB_SERIAL_EXPORT sp_flush_output_data_impl(self)
641
+ VALUE self;
642
+ {
643
+ BOOL ret;
644
+ HANDLE fh;
645
+
646
+ fh = get_handle_helper(self);
647
+
648
+ ret = PurgeComm(fh, (DWORD)(PURGE_TXCLEAR | PURGE_TXABORT));
649
+ if(!ret) {
650
+ return Qfalse;
651
+ }
652
+ return Qtrue;
653
+ }
654
+
655
+
656
+
623
657
  #endif /* defined(OS_MSWIN) || defined(OS_BCCWIN) || defined(OS_MINGW) */
@@ -1,3 +1,3 @@
1
1
  class SerialPort
2
- VERSION = "1.2.2"
2
+ VERSION = "1.3.2"
3
3
  end
data/lib/serialport.rb CHANGED
@@ -1,18 +1,26 @@
1
1
  require 'serialport.so'
2
2
  require 'serialport/version'
3
3
 
4
+
5
+ # This class is used for communication over a serial port.
6
+ # In addition to the methods here, you can use Ruby IO methods, e.g. read, write, getc, readlines, etc.
7
+ #
8
+ # @see http://rubydoc.info/stdlib/core/IO Ruby IO class
9
+ # @see http://www.cmrr.umn.edu/~strupp/serial.html "Serial Programming Guide for POSIX Operating Systems"
4
10
  class SerialPort
5
11
  private_class_method(:create)
6
12
 
7
13
  # Creates a serial port object.
14
+ # Accepts the port identifier and a variable list for configuration as paramaters or hash.
15
+ # Please see SerialPort#set_modem_params
8
16
  #
9
- # <tt>port</tt> may be a port number
10
- # or the file name of a defice.
11
- # The number is portable; so 0 is mapped to "COM1" on Windows,
12
- # "/dev/ttyS0" on Linux, "/dev/cuaa0" on Mac OS X, etc.
13
- #
14
- # <tt>params</tt> can be used to configure the serial port.
15
- # See SerialPort#set_modem_params for details
17
+ # @overload new(port, *params)
18
+ # @param port [Integer] the serial port number,
19
+ # where 0 is mapped to "COM1" on Windows, "/dev/ttyS0" on Linux, "/dev/cuaa0" on Mac OS X, etc.
20
+ # @overload new(port, *params)
21
+ # @param port [String] the serial port file e.g. "/dev/ttyS0"
22
+ # @return [SerialPort]
23
+ # @see SerialPort#set_modem_params
16
24
  def SerialPort::new(port, *params)
17
25
  sp = create(port)
18
26
  begin
@@ -27,6 +35,10 @@ class SerialPort
27
35
  # This behaves like SerialPort#new, except that you can pass a block
28
36
  # to which the new serial port object will be passed. In this case
29
37
  # the connection is automaticaly closed when the block has finished.
38
+ #
39
+ # @yield [serial_port] the serial port number or filename
40
+ # @see SerialPort#new
41
+ # @see SerialPort#set_modem_params
30
42
  def SerialPort::open(port, *params)
31
43
  sp = create(port)
32
44
  begin
data/serialport.gemspec CHANGED
@@ -3,6 +3,7 @@ require File.expand_path('../lib/serialport/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "serialport"
6
+ s.license = "GPL-2"
6
7
  s.version = SerialPort::VERSION
7
8
  s.authors = ["Guillaume Pierronnet", "Alan Stern", "Daniel E. Shipton", "Tobin Richard", "Hector Parra", "Ryan C. Payne"]
8
9
  s.summary = "Library for using RS-232 serial ports."
@@ -18,5 +19,5 @@ Gem::Specification.new do |s|
18
19
  s.files = `git ls-files`.split($\)
19
20
  s.extensions = "ext/native/extconf.rb"
20
21
  s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
21
- s.extra_rdoc_files = ["LICENSE", "README"]
22
+ s.extra_rdoc_files = ["LICENSE", "README.md"]
22
23
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serialport
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Guillaume Pierronnet
@@ -10,51 +10,51 @@ authors:
10
10
  - Tobin Richard
11
11
  - Hector Parra
12
12
  - Ryan C. Payne
13
- autorequire:
13
+ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-11-04 00:00:00.000000000 Z
16
+ date: 2021-09-29 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: bundler
20
20
  requirement: !ruby/object:Gem::Requirement
21
21
  requirements:
22
- - - ! '>='
22
+ - - ">="
23
23
  - !ruby/object:Gem::Version
24
24
  version: '0'
25
25
  type: :development
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
28
  requirements:
29
- - - ! '>='
29
+ - - ">="
30
30
  - !ruby/object:Gem::Version
31
31
  version: '0'
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: rake
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  requirements:
36
- - - ! '>='
36
+ - - ">="
37
37
  - !ruby/object:Gem::Version
38
38
  version: '0'
39
39
  type: :development
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
42
42
  requirements:
43
- - - ! '>='
43
+ - - ">="
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: rake-compiler
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  requirements:
50
- - - ! '>='
50
+ - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 0.4.1
53
53
  type: :development
54
54
  prerelease: false
55
55
  version_requirements: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - ! '>='
57
+ - - ">="
58
58
  - !ruby/object:Gem::Version
59
59
  version: 0.4.1
60
60
  description: Ruby/SerialPort is a Ruby library that provides a class for using RS-232
@@ -65,16 +65,16 @@ extensions:
65
65
  - ext/native/extconf.rb
66
66
  extra_rdoc_files:
67
67
  - LICENSE
68
- - README
68
+ - README.md
69
69
  files:
70
- - .gitignore
71
- - .travis.yml
70
+ - ".gitignore"
71
+ - ".travis.yml"
72
72
  - CHANGELOG
73
73
  - CHECKLIST
74
74
  - Gemfile
75
75
  - LICENSE
76
76
  - MANIFEST
77
- - README
77
+ - README.md
78
78
  - Rakefile
79
79
  - ext/native/extconf.rb
80
80
  - ext/native/posix_serialport_impl.c
@@ -87,26 +87,26 @@ files:
87
87
  - test/miniterm.rb
88
88
  - test/set_readtimeout.rb
89
89
  homepage: http://github.com/hparra/ruby-serialport/
90
- licenses: []
90
+ licenses:
91
+ - GPL-2
91
92
  metadata: {}
92
- post_install_message:
93
+ post_install_message:
93
94
  rdoc_options: []
94
95
  require_paths:
95
96
  - lib
96
97
  required_ruby_version: !ruby/object:Gem::Requirement
97
98
  requirements:
98
- - - ! '>='
99
+ - - ">="
99
100
  - !ruby/object:Gem::Version
100
101
  version: '0'
101
102
  required_rubygems_version: !ruby/object:Gem::Requirement
102
103
  requirements:
103
- - - ! '>='
104
+ - - ">="
104
105
  - !ruby/object:Gem::Version
105
106
  version: '0'
106
107
  requirements: []
107
- rubyforge_project:
108
- rubygems_version: 2.0.3
109
- signing_key:
108
+ rubygems_version: 3.3.0.dev
109
+ signing_key:
110
110
  specification_version: 4
111
111
  summary: Library for using RS-232 serial ports.
112
112
  test_files: []
data/README DELETED
@@ -1,153 +0,0 @@
1
- -----Ruby/SerialPort-----
2
-
3
- -- Description --
4
-
5
- Ruby/SerialPort is a Ruby library that provides a class for using
6
- RS-232 serial ports. This class also contains low-level functions to
7
- check and set the current state of the signals on the line.
8
-
9
- The native Windows version of this library supports Microsoft's Visual C++, Borland's C++, and MinGW compilers.
10
-
11
- -- Installation --
12
-
13
- Then you can install the gem as normal:
14
- sudo gem install serialport
15
-
16
- -- Testing --
17
-
18
- * test/miniterm.rb
19
-
20
- Ruby's copy of miniterm.c !
21
-
22
-
23
- -- API --
24
-
25
- **** Class SerialPort, Parent IO ****
26
-
27
- ** Class constants **
28
-
29
- VERSION -> aString (EX: this release is "0.6")
30
- NONE, HARD, SOFT, SPACE, MARK, EVEN, ODD -> anInteger
31
-
32
- ** Class methods **
33
-
34
- * new(port_num [, modem_parameters]) -> aSerialPort
35
- * open(port_num [, modem_parameters]) -> aSerialPort
36
- * open(port_num [, modem_parameters]) {|aSerialPort| block} ->
37
- value of the block
38
-
39
- port_num -> anInteger: port number, 0 for first port which is
40
- "/dev/ttyS0" on GNU/Linux and "COM1" on Windows,
41
- or aString: file name of the device (example: "/dev/ttyS2")
42
-
43
- Optional modem_parameters:
44
-
45
- baud -> anInteger: from 50 to 1000000, depends on platform.
46
-
47
- data_bits -> anInteger: from 5 to 8 (4 is allowed on Windows)
48
-
49
- stop_bits -> anInteger: 1 or 2 (1.5 is not supported)
50
-
51
- parity -> anInteger: SerialPort::NONE, SerialPort::EVEN,
52
- SerialPort::ODD, SerialPort::MARK, SerialPort::SPACE
53
- (MARK and SPACE are not supported on Posix)
54
-
55
- Raise an argError on bad argument.
56
-
57
- SerialPort::new and SerialPort::open without a block return an
58
- instance of SerialPort. SerialPort::open with a block passes
59
- a SerialPort to the block and closes it when the block exits
60
- (like File::open).
61
-
62
-
63
- ** Instance methods **
64
-
65
- * modem_params() -> aHash
66
- * modem_params=(aHash) -> aHash
67
- * get_modem_params() -> aHash
68
- * set_modem_params(aHash) -> aHash
69
- * set_modem_params(baudrate [, databits [, stopbits [, parity]]])
70
-
71
- Get and set the modem parameters. Hash keys are "baud", "data_bits",
72
- "stop_bits", and "parity" (see above).
73
-
74
- Parameters not present in the hash or set to nil remain unchanged.
75
- Default parameter values for the set_modem_params method are:
76
- databits = 8, stopbits = 1, parity = (databits == 8 ?
77
- SerialPort::NONE : SerialPort::EVEN).
78
-
79
- * baud() -> anInteger
80
- * baud=(anInteger) -> anInteger
81
- * data_bits() -> 4, 5, 6, 7, or 8
82
- * data_bits=(anInteger) -> anInteger
83
- * stop_bits() -> 1 or 2
84
- * stop_bits=(anInteger) -> anInteger
85
- * parity() -> anInteger: SerialPort::NONE, SerialPort::EVEN,
86
- SerialPort::ODD, SerialPort::MARK, or SerialPort::SPACE
87
- * parity=(anInteger) -> anInteger
88
-
89
- Get and set the corresponding modem parameter.
90
-
91
- * flow_control() -> anInteger
92
- * flow_control=(anInteger) -> anInteger
93
-
94
- Get and set the flow control: SerialPort::NONE, SerialPort::HARD,
95
- SerialPort::SOFT, or (SerialPort::HARD | SerialPort::SOFT).
96
-
97
- Note: SerialPort::HARD mode is not supported on all platforms.
98
- SerialPort::HARD uses RTS/CTS handshaking; DSR/DTR is not
99
- supported.
100
-
101
- * read_timeout() -> anInteger
102
- * read_timeout=(anInteger) -> anInteger
103
- * write_timeout() -> anInteger
104
- * write_timeout=(anInteger) -> anInteger
105
-
106
- Get and set timeout values (in milliseconds) for reading and writing.
107
- A negative read timeout will return all the available data without
108
- waiting, a zero read timeout will not return until at least one
109
- byte is available, and a positive read timeout returns when the
110
- requested number of bytes is available or the interval between the
111
- arrival of two bytes exceeds the timeout value.
112
-
113
- Note: Read timeouts don't mix well with multi-threading.
114
-
115
- Note: Under Posix, write timeouts are not implemented.
116
-
117
- * break(time) -> nil
118
-
119
- Send a break for the given time.
120
-
121
- time -> anInteger: tenths-of-a-second for the break.
122
- Note: Under Posix, this value is very approximate.
123
-
124
- * signals() -> aHash
125
-
126
- Return a hash with the state of each line status bit. Keys are
127
- "rts", "dtr", "cts", "dsr", "dcd", and "ri".
128
-
129
- Note: Under Windows, the rts and dtr values are not included.
130
-
131
- * rts()
132
- * dtr()
133
- * cts()
134
- * dsr()
135
- * dcd()
136
- * ri() -> 0 or 1
137
-
138
- * rts=(0 or 1)
139
- * dtr=(0 or 1) -> 0 or 1
140
-
141
- Get and set the corresponding line status bit.
142
-
143
- Note: Under Windows, rts() and dtr() are not implemented.
144
-
145
- -- License --
146
-
147
- GPL
148
-
149
- Guillaume Pierronnet <moumar@netcourrier.com>
150
- Alan Stern <stern@rowland.harvard.edu>
151
- Tobin Richard <tobin.richard@gmail.com>
152
- Hector Parra <hector@hectorparra.com>
153
- Ryan C. Payne <rpayne-oss@bullittsystems.com>