ant-wireless 0.1.0.pre.20210810141303 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.md +27 -0
- data/README.md +14 -2
- data/ext/ant_ext/ant_ext.c +97 -1
- data/ext/ant_ext/channel.c +147 -32
- data/ext/ant_ext/extconf.rb +1 -0
- data/lib/ant/bitvector.rb +197 -0
- data/lib/ant/channel/event_callbacks.rb +13 -17
- data/lib/ant/channel.rb +52 -5
- data/lib/ant/response_callbacks.rb +117 -334
- data/lib/ant.rb +18 -4
- data/spec/ant_spec.rb +9 -0
- data/spec/bitvector_spec.rb +141 -0
- data/spec/spec_helper.rb +2 -0
- data.tar.gz.sig +0 -0
- metadata +49 -8
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b16333eed832c3068cd6e95d167bffe8132aaba7543ccabd773d809fac840199
|
4
|
+
data.tar.gz: 92d089d1bcf5121dd46477befeabc33e43abbac10de105d3d94d176b54c9af8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51dbc06b6c199f16404fb0d79fd78e10cf53c4ca68e221462d225e1dff171a51f5f1807da2ebe2719e45109e981ece26781090ebd583d4c8c01d6e1539c5e43a
|
7
|
+
data.tar.gz: da1492d614d52e83402c85bbeed0d45d03f7f101bd6b5036ae9bc7a488dfbd5df41ee5aa2a0a3b0a7b4e7019c4d95bc55d0167a3a6e77c1825565ca299ba492e
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/History.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
# Release History for ruby-ant
|
2
2
|
|
3
3
|
---
|
4
|
+
## v0.3.0 [2021-10-11] Michael Granger <ged@FaerieMUD.org>
|
4
5
|
|
6
|
+
Enhancements:
|
7
|
+
|
8
|
+
- Add frequency agility config to Channel
|
9
|
+
- Add tunable transmit power knob
|
10
|
+
|
11
|
+
|
12
|
+
## v0.2.1 [2021-09-30] Michael Granger <ged@FaerieMUD.org>
|
13
|
+
|
14
|
+
Bugfixes:
|
15
|
+
|
16
|
+
- Add missing files to the manifest
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
## v0.2.0 [2021-09-22] Michael Granger <ged@FaerieMUD.org>
|
21
|
+
|
22
|
+
Enhancements:
|
23
|
+
|
24
|
+
- Add channel period, search timeout, and introspection methods
|
25
|
+
- Add Ant.initialized? predicate
|
26
|
+
- Make the default response and event callback modules more useful.
|
27
|
+
|
28
|
+
|
29
|
+
## v0.1.0 [2021-08-26] Michael Granger <ged@FaerieMUD.org>
|
30
|
+
|
31
|
+
First release.
|
5
32
|
|
data/README.md
CHANGED
@@ -20,8 +20,13 @@ manner.
|
|
20
20
|
|
21
21
|
## Prerequisites
|
22
22
|
|
23
|
-
* Ruby
|
24
|
-
* Garmin USB ANT Stick
|
23
|
+
* Ruby 2.7.x or later
|
24
|
+
* [Garmin USB ANT Stick][antstick]
|
25
|
+
* [ANT SDK][antsdk]
|
26
|
+
|
27
|
+
Note that we had trouble compiling the latest ANT SDK on some platforms, so we are currently using a modified version of it with a reworked build system for MacOS and FreeBSD. That is available under the same licensing terms at:
|
28
|
+
|
29
|
+
https://github.com/RavnGroup/Garmin-ANT-SDK
|
25
30
|
|
26
31
|
|
27
32
|
## Installation
|
@@ -52,6 +57,12 @@ This task will install dependencies, and do any other necessary setup for develo
|
|
52
57
|
|
53
58
|
## License
|
54
59
|
|
60
|
+
Portions of this code are from StaticCling, and are used under the
|
61
|
+
terms of the 3-Clause BSD License. Specifics can be found in the
|
62
|
+
appropriate files.
|
63
|
+
|
64
|
+
This software is:
|
65
|
+
|
55
66
|
Copyright (c) 2021, Ravn Group
|
56
67
|
|
57
68
|
Permission is hereby granted, free of charge, to any person obtaining
|
@@ -76,4 +87,5 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
76
87
|
|
77
88
|
[ant]: https://www.thisisant.com/
|
78
89
|
[antstick]: https://buy.garmin.com/en-US/US/p/10997/pn/010-01058-00
|
90
|
+
[antsdk]: https://www.thisisant.com/developer/resources/downloads/#software_tab
|
79
91
|
|
data/ext/ant_ext/ant_ext.c
CHANGED
@@ -225,6 +225,17 @@ rant_s_init( int argc, VALUE *argv, VALUE _module )
|
|
225
225
|
}
|
226
226
|
|
227
227
|
|
228
|
+
static VALUE
|
229
|
+
rant_s_initialized_p( VALUE _module )
|
230
|
+
{
|
231
|
+
#ifdef HAVE_ANT_ISINITIALIZED
|
232
|
+
const bool initialized = ANT_IsInitialized();
|
233
|
+
return initialized ? Qtrue : Qfalse;
|
234
|
+
#else
|
235
|
+
rb_notimplement();
|
236
|
+
#endif
|
237
|
+
}
|
238
|
+
|
228
239
|
|
229
240
|
/*
|
230
241
|
* call-seq:
|
@@ -291,13 +302,39 @@ rant_s_set_network_key( VALUE _module, VALUE network_number, VALUE key )
|
|
291
302
|
}
|
292
303
|
|
293
304
|
if ( !ANT_SetNetworkKey(ucNetNumber, (unsigned char *)pucKey) ) {
|
294
|
-
|
305
|
+
rant_log( "error", "could not set the network key." );
|
295
306
|
}
|
296
307
|
|
297
308
|
return Qtrue;
|
298
309
|
}
|
299
310
|
|
300
311
|
|
312
|
+
/*
|
313
|
+
* call-seq:
|
314
|
+
* Ant.transmit_power = 4
|
315
|
+
*
|
316
|
+
* Set the transmit power level for all channels. Valid values are 0-4; default
|
317
|
+
* is 3 = 0dBm.
|
318
|
+
*
|
319
|
+
* # Set transmit power to -5 dBm
|
320
|
+
* Ant.transmit_power = 2
|
321
|
+
*/
|
322
|
+
static VALUE
|
323
|
+
rant_s_transmit_power_eq( VALUE _module, VALUE power )
|
324
|
+
{
|
325
|
+
const unsigned char ucTransmitPower = NUM2CHR( power );
|
326
|
+
BOOL rval;
|
327
|
+
|
328
|
+
if ( ucTransmitPower < 0 || ucTransmitPower > 4 ) {
|
329
|
+
rb_raise( rb_eArgError, "expected a value between 0 and 4, got %d", ucTransmitPower );
|
330
|
+
}
|
331
|
+
|
332
|
+
rval = ANT_SetTransmitPower( ucTransmitPower );
|
333
|
+
|
334
|
+
return rval ? Qtrue : Qfalse;
|
335
|
+
}
|
336
|
+
|
337
|
+
|
301
338
|
/*
|
302
339
|
* call-seq:
|
303
340
|
* Ant.assign_channel( channel, channel_type, network_number=0, extended_options=0x0, timeout=0 ) -> channel
|
@@ -463,6 +500,56 @@ rant_s_on_response( int argc, VALUE *argv, VALUE module )
|
|
463
500
|
}
|
464
501
|
|
465
502
|
|
503
|
+
/*
|
504
|
+
* call-seq:
|
505
|
+
* Ant.request_capabilities
|
506
|
+
*
|
507
|
+
* Request the current ANT device's capabilities. These will be delivered
|
508
|
+
* via a callback to the #on_capabilities response callback, which by default
|
509
|
+
* extracts them into a Hash which is stored at Ant.capabilities.
|
510
|
+
*
|
511
|
+
*/
|
512
|
+
static VALUE
|
513
|
+
rant_s_request_capabilities( VALUE module )
|
514
|
+
{
|
515
|
+
bool rval = ANT_RequestMessage( 0, MESG_CAPABILITIES_ID );
|
516
|
+
return rval ? Qtrue : Qfalse;
|
517
|
+
}
|
518
|
+
|
519
|
+
|
520
|
+
/*
|
521
|
+
* call-seq:
|
522
|
+
* Ant.request_serial_num
|
523
|
+
*
|
524
|
+
* Request the current ANT device's serial number. The result will be delivered
|
525
|
+
* via a callback to the #on_get_serial_num response callback, which by default
|
526
|
+
* extracts it and stores it at Ant.serial_number.
|
527
|
+
*
|
528
|
+
*/
|
529
|
+
static VALUE
|
530
|
+
rant_s_request_serial_num( VALUE module )
|
531
|
+
{
|
532
|
+
bool rval = ANT_RequestMessage( 0, MESG_GET_SERIAL_NUM_ID );
|
533
|
+
return rval ? Qtrue : Qfalse;
|
534
|
+
}
|
535
|
+
|
536
|
+
|
537
|
+
/*
|
538
|
+
* call-seq:
|
539
|
+
* Ant.request_version
|
540
|
+
*
|
541
|
+
* Request the current device's ANT version. The result will be delivered
|
542
|
+
* via a callback to the #on_version response callback, which by default
|
543
|
+
* extracts it and stores it at Ant.hardware_version.
|
544
|
+
*
|
545
|
+
*/
|
546
|
+
static VALUE
|
547
|
+
rant_s_request_version( VALUE module )
|
548
|
+
{
|
549
|
+
bool rval = ANT_RequestMessage( 0, MESG_VERSION_ID );
|
550
|
+
return rval ? Qtrue : Qfalse;
|
551
|
+
}
|
552
|
+
|
466
553
|
|
467
554
|
/*
|
468
555
|
* call-seq:
|
@@ -508,11 +595,13 @@ Init_ant_ext()
|
|
508
595
|
rb_define_singleton_method( rant_mAnt, "device_serial_number", rant_s_device_serial_number, 0 );
|
509
596
|
|
510
597
|
rb_define_singleton_method( rant_mAnt, "init", rant_s_init, -1 );
|
598
|
+
rb_define_singleton_method( rant_mAnt, "initialized?", rant_s_initialized_p, 0 );
|
511
599
|
// rb_define_singleton_method( rant_mAnt, "init_ext", rant_s_init_ext, 4 );
|
512
600
|
rb_define_singleton_method( rant_mAnt, "close", rant_s_close, 0 );
|
513
601
|
rb_define_singleton_method( rant_mAnt, "reset", rant_s_reset, 0 );
|
514
602
|
|
515
603
|
rb_define_singleton_method( rant_mAnt, "set_network_key", rant_s_set_network_key, 2 );
|
604
|
+
rb_define_singleton_method( rant_mAnt, "transmit_power=", rant_s_transmit_power_eq, 1 );
|
516
605
|
rb_define_singleton_method( rant_mAnt, "assign_channel", rant_s_assign_channel, -1 );
|
517
606
|
|
518
607
|
rb_define_singleton_method( rant_mAnt, "use_extended_messages=",
|
@@ -521,6 +610,9 @@ Init_ant_ext()
|
|
521
610
|
rb_define_singleton_method( rant_mAnt, "on_response", rant_s_on_response, -1 );
|
522
611
|
// EXPORT void ANT_UnassignAllResponseFunctions(); //Unassigns all response functions
|
523
612
|
|
613
|
+
rb_define_singleton_method( rant_mAnt, "request_capabilities", rant_s_request_capabilities, 0 );
|
614
|
+
rb_define_singleton_method( rant_mAnt, "request_serial_num", rant_s_request_serial_num, 0 );
|
615
|
+
rb_define_singleton_method( rant_mAnt, "request_version", rant_s_request_version, 0 );
|
524
616
|
|
525
617
|
rb_define_singleton_method( rant_mAnt, "log_directory=", rant_s_log_directory_eq, 1 );
|
526
618
|
|
@@ -537,6 +629,7 @@ Init_ant_ext()
|
|
537
629
|
EXPOSE_CONST( ANT_EXT_STRING_SIZE );
|
538
630
|
EXPOSE_CONST( ANT_EXT_MESG_BITFIELD_DEVICE_ID );
|
539
631
|
EXPOSE_CONST( ANT_EXT_MESG_BIFIELD_EXTENSION );
|
632
|
+
rb_define_const( rant_mAnt, "ANT_EXT_MESG_BITFIELD_EXTENSION", INT2FIX(ANT_EXT_MESG_BIFIELD_EXTENSION) );
|
540
633
|
EXPOSE_CONST( ANT_EXT_MESG_BITFIELD_OVERWRITE_SHARED_ADR );
|
541
634
|
EXPOSE_CONST( ANT_EXT_MESG_BITFIELD_TRANSMISSION_TYPE );
|
542
635
|
|
@@ -618,6 +711,9 @@ Init_ant_ext()
|
|
618
711
|
EXPOSE_CONST( CAPABILITIES_SELECTIVE_DATA_UPDATE_ENABLED );
|
619
712
|
EXPOSE_CONST( CAPABILITIES_ENCRYPTED_CHANNEL_ENABLED );
|
620
713
|
|
714
|
+
// Not in the header; this is taken from 9.5.7.4, ANT Message Protocol and Usage v5.1
|
715
|
+
rb_define_const( rant_mAnt, "CAPABILITIES_RFACTIVE_NOTIFICATION_ENABLED", INT2FIX(0) );
|
716
|
+
|
621
717
|
EXPOSE_CONST( CHANNEL_NUMBER_MASK );
|
622
718
|
EXPOSE_CONST( SEQUENCE_NUMBER_MASK );
|
623
719
|
EXPOSE_CONST( SEQUENCE_NUMBER_ROLLOVER );
|
data/ext/ant_ext/channel.c
CHANGED
@@ -128,6 +128,12 @@ rant_channel_init( VALUE self, VALUE channel_number, VALUE channel_type, VALUE n
|
|
128
128
|
rb_iv_set( self, "@network_number", network_number );
|
129
129
|
rb_iv_set( self, "@extended_options", extended_options );
|
130
130
|
|
131
|
+
rb_iv_set( self, "@device_type", Qnil );
|
132
|
+
rb_iv_set( self, "@device_number", Qnil );
|
133
|
+
rb_iv_set( self, "@transmission_type", Qnil );
|
134
|
+
rb_iv_set( self, "@rf_frequency", Qnil );
|
135
|
+
rb_iv_set( self, "@agility_frequencies", Qnil );
|
136
|
+
|
131
137
|
rb_hash_aset( registry, channel_number, self );
|
132
138
|
|
133
139
|
return self;
|
@@ -173,8 +179,8 @@ rant_channel_set_channel_id( int argc, VALUE *argv, VALUE self )
|
|
173
179
|
rb_scan_args( argc, argv, "31", &device_number, &device_type, &transmission_type, &timeout );
|
174
180
|
|
175
181
|
usDeviceNumber = NUM2USHORT( device_number );
|
176
|
-
ucDeviceType =
|
177
|
-
ucTransmissionType =
|
182
|
+
ucDeviceType = NUM2CHR( device_type );
|
183
|
+
ucTransmissionType = NUM2CHR( transmission_type );
|
178
184
|
|
179
185
|
if ( RTEST(timeout) )
|
180
186
|
ulResponseTime = NUM2UINT( timeout );
|
@@ -186,13 +192,139 @@ rant_channel_set_channel_id( int argc, VALUE *argv, VALUE self )
|
|
186
192
|
rb_raise( rb_eRuntimeError, "Failed to set the channel id." );
|
187
193
|
}
|
188
194
|
|
195
|
+
rb_iv_set( self, "@device_type", device_type );
|
196
|
+
rb_iv_set( self, "@device_number", device_number );
|
197
|
+
rb_iv_set( self, "@transmission_type", transmission_type );
|
198
|
+
|
199
|
+
return Qtrue;
|
200
|
+
}
|
201
|
+
|
202
|
+
|
203
|
+
/*
|
204
|
+
* call-seq:
|
205
|
+
* channel.set_channel_period( period, timeout=0 )
|
206
|
+
*
|
207
|
+
* This message configures the messaging +period+ of a specific channel where:
|
208
|
+
* Messaging period = channel period time +period+ * 32768.
|
209
|
+
*
|
210
|
+
* E.g.: To send or receive a message at 4Hz, set the channel period to 8192 (32768/4).
|
211
|
+
*
|
212
|
+
* Note: The minimum acceptable channel period is difficult to specify as it is
|
213
|
+
* system dependent and depends on the number of configured channels and their use.
|
214
|
+
* Caution should be used to appropriately test the system when high data rates are
|
215
|
+
* used, especially in combination with multiple channels.
|
216
|
+
*
|
217
|
+
*/
|
218
|
+
static VALUE
|
219
|
+
rant_channel_set_channel_period( int argc, VALUE *argv, VALUE self )
|
220
|
+
{
|
221
|
+
rant_channel_t *ptr = rant_get_channel( self );
|
222
|
+
VALUE period, timeout;
|
223
|
+
unsigned int ulResponseTime = 0;
|
224
|
+
unsigned short usMesgPeriod;
|
225
|
+
bool result;
|
226
|
+
|
227
|
+
rb_scan_args( argc, argv, "11", &period, &timeout );
|
228
|
+
|
229
|
+
usMesgPeriod = NUM2USHORT( period );
|
230
|
+
if ( RTEST(timeout) )
|
231
|
+
ulResponseTime = NUM2UINT( timeout );
|
232
|
+
|
233
|
+
result = ANT_SetChannelPeriod_RTO( ptr->channel_num, usMesgPeriod, ulResponseTime );
|
234
|
+
|
235
|
+
if ( !result )
|
236
|
+
rb_raise( rb_eRuntimeError, "Failed to set the channel period." );
|
237
|
+
|
238
|
+
return Qtrue;
|
239
|
+
}
|
240
|
+
|
241
|
+
|
242
|
+
/*
|
243
|
+
* call-seq:
|
244
|
+
* channel.set_channel_search_timeout( search_timeout, timeout=0 )
|
245
|
+
*
|
246
|
+
* Configure the length of time that the receiver will search for a channel
|
247
|
+
* before timing out. Note that a value of zero will disable high priority
|
248
|
+
* search mode, and a value of 255 sets an infinite search time-out. The
|
249
|
+
* exception to this is the AP1 module, which has only a high priority search
|
250
|
+
* mode. For AP1 only, a value of 0 is an immediate search timeout, and a value
|
251
|
+
* of 255 corresponds to approximately 10.5 minutes.
|
252
|
+
*
|
253
|
+
*/
|
254
|
+
static VALUE
|
255
|
+
rant_channel_set_channel_search_timeout( int argc, VALUE *argv, VALUE self )
|
256
|
+
{
|
257
|
+
rant_channel_t *ptr = rant_get_channel( self );
|
258
|
+
VALUE search_timeout, timeout;
|
259
|
+
unsigned int ulResponseTime = 0;
|
260
|
+
unsigned char ucSearchTimeout;
|
261
|
+
bool result;
|
262
|
+
|
263
|
+
rb_scan_args( argc, argv, "11", &search_timeout, &timeout );
|
264
|
+
|
265
|
+
ucSearchTimeout = NUM2CHR( search_timeout );
|
266
|
+
if ( RTEST(timeout) )
|
267
|
+
ulResponseTime = NUM2UINT( timeout );
|
268
|
+
|
269
|
+
result = ANT_SetChannelSearchTimeout_RTO( ptr->channel_num, ucSearchTimeout, ulResponseTime );
|
270
|
+
|
271
|
+
if ( !result )
|
272
|
+
rb_raise( rb_eRuntimeError, "Failed to set the channel search timeout." );
|
273
|
+
|
274
|
+
return Qtrue;
|
275
|
+
}
|
276
|
+
|
277
|
+
|
278
|
+
/*
|
279
|
+
* call-seq:
|
280
|
+
* channel.set_channel_rf_freq( frequency )
|
281
|
+
*
|
282
|
+
* Set the ANT RF +frequency+.
|
283
|
+
*
|
284
|
+
*/
|
285
|
+
static VALUE
|
286
|
+
rant_channel_set_channel_rf_freq( VALUE self, VALUE frequency )
|
287
|
+
{
|
288
|
+
rant_channel_t *ptr = rant_get_channel( self );
|
289
|
+
unsigned short ucRFFreq = NUM2USHORT( frequency );
|
290
|
+
|
291
|
+
if ( ucRFFreq > 124 ) {
|
292
|
+
rb_raise( rb_eArgError, "frequency must be between 0 and 124." );
|
293
|
+
}
|
294
|
+
|
295
|
+
ANT_SetChannelRFFreq( ptr->channel_num, ucRFFreq );
|
296
|
+
|
297
|
+
rb_iv_set( self, "@rf_frequency", frequency );
|
298
|
+
|
299
|
+
return Qtrue;
|
300
|
+
}
|
301
|
+
|
302
|
+
|
303
|
+
static VALUE
|
304
|
+
rant_channet_set_frequency_agility( VALUE self, VALUE freq1, VALUE freq2, VALUE freq3 )
|
305
|
+
{
|
306
|
+
rant_channel_t *ptr = rant_get_channel( self );
|
307
|
+
unsigned char ucFreq1 = NUM2CHR( freq1 ),
|
308
|
+
ucFreq2 = NUM2CHR( freq2 ),
|
309
|
+
ucFreq3 = NUM2CHR( freq3 );
|
310
|
+
VALUE frequencies = rb_ary_new_from_args( 3, freq1, freq2, freq3 );
|
311
|
+
|
312
|
+
if ( ucFreq1 > 124 || ucFreq2 > 124 || ucFreq3 > 124 ) {
|
313
|
+
rb_raise( rb_eArgError, "frequencies must be between 0 and 124." );
|
314
|
+
}
|
315
|
+
|
316
|
+
rant_log_obj( self, "info",
|
317
|
+
"Configuring channel %d to use frequency agility on %d, %d, and %d MHz.",
|
318
|
+
ptr->channel_num, ucFreq1 + 2400, ucFreq2 + 2400, ucFreq3 + 2400 );
|
319
|
+
ANT_ConfigFrequencyAgility( ptr->channel_num, ucFreq1, ucFreq2, ucFreq3 );
|
320
|
+
|
321
|
+
rb_ary_freeze( frequencies );
|
322
|
+
rb_iv_set( self, "@agility_frequencies", frequencies );
|
323
|
+
|
189
324
|
return Qtrue;
|
190
325
|
}
|
191
326
|
|
192
327
|
|
193
|
-
// ANT_SetChannelPeriod_RTO(UCHAR ucANTChannel_, USHORT usMesgPeriod_, ULONG ulResponseTime_);
|
194
|
-
// ANT_SetChannelSearchTimeout_RTO(UCHAR ucANTChannel_, UCHAR ucSearchTimeout_, ULONG ulResponseTime_);
|
195
|
-
// ANT_SetChannelRFFreq_RTO(UCHAR ucANTChannel_, UCHAR ucRFFreq_, ULONG ulResponseTime_);
|
196
328
|
|
197
329
|
|
198
330
|
/*
|
@@ -450,29 +582,6 @@ rant_channel_send_broadcast_data( VALUE self, VALUE data )
|
|
450
582
|
}
|
451
583
|
|
452
584
|
|
453
|
-
/*
|
454
|
-
* call-seq:
|
455
|
-
* channel.set_channel_rf_freq( frequency )
|
456
|
-
*
|
457
|
-
* Set the ANT RF +frequency+.
|
458
|
-
*
|
459
|
-
*/
|
460
|
-
static VALUE
|
461
|
-
rant_channel_set_channel_rf_freq( VALUE self, VALUE frequency )
|
462
|
-
{
|
463
|
-
rant_channel_t *ptr = rant_get_channel( self );
|
464
|
-
unsigned short ucRFFreq = NUM2USHORT( frequency );
|
465
|
-
|
466
|
-
if ( ucRFFreq > 124 ) {
|
467
|
-
rb_raise( rb_eArgError, "frequency must be between 0 and 124." );
|
468
|
-
}
|
469
|
-
|
470
|
-
ANT_SetChannelRFFreq( ptr->channel_num, ucRFFreq );
|
471
|
-
|
472
|
-
return Qtrue;
|
473
|
-
}
|
474
|
-
|
475
|
-
|
476
585
|
void
|
477
586
|
init_ant_channel()
|
478
587
|
{
|
@@ -501,12 +610,18 @@ init_ant_channel()
|
|
501
610
|
rb_attr( rant_cAntChannel, rb_intern("network_number"), 1, 0, 0 );
|
502
611
|
rb_attr( rant_cAntChannel, rb_intern("extended_options"), 1, 0, 0 );
|
503
612
|
|
613
|
+
rb_attr( rant_cAntChannel, rb_intern("device_number"), 1, 0, 0 );
|
614
|
+
rb_attr( rant_cAntChannel, rb_intern("device_type"), 1, 0, 0 );
|
615
|
+
rb_attr( rant_cAntChannel, rb_intern("transmission_type"), 1, 0, 0 );
|
616
|
+
rb_attr( rant_cAntChannel, rb_intern("rf_frequency"), 1, 0, 0 );
|
617
|
+
rb_attr( rant_cAntChannel, rb_intern("agility_frequencies"), 1, 0, 0 );
|
618
|
+
|
504
619
|
rb_define_method( rant_cAntChannel, "set_channel_id", rant_channel_set_channel_id, -1 );
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
// rant_channel_set_channel_search_timeout, -1 );
|
620
|
+
rb_define_method( rant_cAntChannel, "set_channel_period", rant_channel_set_channel_period, -1 );
|
621
|
+
rb_define_method( rant_cAntChannel, "set_channel_search_timeout",
|
622
|
+
rant_channel_set_channel_search_timeout, -1 );
|
509
623
|
rb_define_method( rant_cAntChannel, "set_channel_rf_freq", rant_channel_set_channel_rf_freq, 1 );
|
624
|
+
rb_define_method( rant_cAntChannel, "set_frequency_agility", rant_channet_set_frequency_agility, 3 );
|
510
625
|
|
511
626
|
rb_define_method( rant_cAntChannel, "open", rant_channel_open, -1 );
|
512
627
|
rb_define_method( rant_cAntChannel, "close", rant_channel_close, -1 );
|
data/ext/ant_ext/extconf.rb
CHANGED
@@ -0,0 +1,197 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
3
|
+
# vim: set nosta noet ts=4 sw=4:
|
4
|
+
|
5
|
+
require 'ant' unless defined?( Ant )
|
6
|
+
|
7
|
+
# Ant::BitVector -- a convenience class for manipulating and
|
8
|
+
# comparing bit vectors.
|
9
|
+
#
|
10
|
+
# This is a slightly-modified version of the same utility in StaticCling.
|
11
|
+
#
|
12
|
+
# == Synopsis
|
13
|
+
#
|
14
|
+
# require 'ant/bitvector'
|
15
|
+
#
|
16
|
+
# vector = Ant::BitVector.new
|
17
|
+
#
|
18
|
+
# vector.on( 4 ) # => 16
|
19
|
+
# vector.on( 12 ) # => 4112
|
20
|
+
# vector.toggle( 4 ) # => 4096
|
21
|
+
# vector.on?( 4 ) # => false
|
22
|
+
# vector.size # => 13
|
23
|
+
# vector.to_hex # => 0x1000
|
24
|
+
#
|
25
|
+
# vector2 = Ant::BitVector.new( 5 )
|
26
|
+
# vector > vector2 # => true
|
27
|
+
#
|
28
|
+
# vector2.each_with_index do |bit, i|
|
29
|
+
# puts "Bit %d is %s" % [ i + 1, bit.zero? ? 'off' : 'on' ]
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# Bit 1 is on
|
33
|
+
# Bit 2 is off
|
34
|
+
# Bit 3 is on
|
35
|
+
#
|
36
|
+
# == Version
|
37
|
+
#
|
38
|
+
# $Id$
|
39
|
+
#
|
40
|
+
# == Author
|
41
|
+
#
|
42
|
+
# * Mahlon E. Smith <mahlon@martini.nu>
|
43
|
+
#
|
44
|
+
# == License
|
45
|
+
#
|
46
|
+
# Copyright (c) 2000-2013, Mahlon E. Smith <mahlon@martini.nu>
|
47
|
+
#
|
48
|
+
# All rights reserved.
|
49
|
+
#
|
50
|
+
# Redistribution and use in source and binary forms, with or without
|
51
|
+
# modification, are permitted provided that the following conditions are met:
|
52
|
+
#
|
53
|
+
# * Redistributions of source code must retain the above copyright notice,
|
54
|
+
# this list of conditions and the following disclaimer.
|
55
|
+
#
|
56
|
+
# * Redistributions in binary form must reproduce the above copyright
|
57
|
+
# notice, this list of conditions and the following disclaimer in the
|
58
|
+
# documentation and/or other materials provided with the distribution.
|
59
|
+
#
|
60
|
+
# * Neither the name of the author, nor the names of contributors may be
|
61
|
+
# used to endorse or promote products derived from this software without
|
62
|
+
# specific prior written permission.
|
63
|
+
#
|
64
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
65
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
66
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
67
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
68
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
69
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
70
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
71
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
72
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
73
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
74
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
75
|
+
#
|
76
|
+
class Ant::BitVector
|
77
|
+
include Enumerable,
|
78
|
+
Comparable
|
79
|
+
|
80
|
+
### Create a new bit vector object, optionally from a pre-existing
|
81
|
+
### +init+ number (Any number that ruby supports natively should be
|
82
|
+
### fine -- 0b, 0x, or decimal.)
|
83
|
+
def initialize( init=0 )
|
84
|
+
unless init.respond_to?( :to_i )
|
85
|
+
raise ArgumentError, "I don't know what to do with a %s object." % [ init.class.name ]
|
86
|
+
end
|
87
|
+
|
88
|
+
@bv = init.to_i
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
######
|
93
|
+
public
|
94
|
+
######
|
95
|
+
|
96
|
+
# let any additional methods fall through to Fixnum/Bignum objs,
|
97
|
+
# and return new vector objects. This allows for doing bitwise math
|
98
|
+
# or simple addition/subtraction on two BitVector objects.
|
99
|
+
%w{ % & * ** + - / << >> ^ | ~ }.each do |op|
|
100
|
+
define_method( op.to_sym ) do |arg|
|
101
|
+
res = @bv.send( op.to_sym, arg.bv )
|
102
|
+
return self.class.new( res )
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
##
|
108
|
+
# Allow external access to the underlying Fixnum/Bignum
|
109
|
+
attr_reader :bv
|
110
|
+
|
111
|
+
|
112
|
+
### Return the bit vector as a decimal.
|
113
|
+
def to_i
|
114
|
+
return @bv
|
115
|
+
end
|
116
|
+
alias_method :to_int, :to_i
|
117
|
+
alias_method :to_dec, :to_i
|
118
|
+
|
119
|
+
|
120
|
+
### Return the bit vector as a binary string.
|
121
|
+
def to_bin
|
122
|
+
return "0b%s" % @bv.to_s(2)
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
### Return the bit vector as a hexidecimal string.
|
127
|
+
def to_hex
|
128
|
+
return "0x%04x" % @bv
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
### Return the length of the vector in bytes.
|
133
|
+
def size
|
134
|
+
return @bv.to_s(2).length
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
### Switch a +bit+ on.
|
139
|
+
def on( bit )
|
140
|
+
@bv = @bv | ( 1 << bit )
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
### Return boolean true if given +bit+ is currently on.
|
145
|
+
def on?( bit )
|
146
|
+
return @bv[ bit ].zero? ? false : true
|
147
|
+
end
|
148
|
+
alias_method :[], :on?
|
149
|
+
|
150
|
+
|
151
|
+
### Switch a +bit+ off.
|
152
|
+
def off( bit )
|
153
|
+
@bv = @bv & ~( 1 << bit )
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
### Return boolean true if given +bit+ is currently +off+.
|
158
|
+
def off?( bit )
|
159
|
+
return ! self.on?( bit )
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
### Swap the current state of the given +bit+.
|
164
|
+
def toggle( bit )
|
165
|
+
@bv = @bv ^ ( 1 << bit )
|
166
|
+
end
|
167
|
+
alias_method :flip, :toggle
|
168
|
+
|
169
|
+
|
170
|
+
### Set a +bit+ to +bool+ -- either true (on) or false (off).
|
171
|
+
### Any value other than nil or false is treated as true.
|
172
|
+
### This form also accepts ranges of bits, a la: vector[ 1..4 ] = true
|
173
|
+
def []=( bit, bool )
|
174
|
+
if bit.respond_to?( :each )
|
175
|
+
bit.each { |b| bool ? self.on( b ) : self.off( b ) }
|
176
|
+
else
|
177
|
+
bool ? self.on( bit ) : self.off( bit )
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
### Yield each binary position, least significant +bit+ first.
|
183
|
+
def each
|
184
|
+
@bv.to_s(2).reverse.each_byte do |bit|
|
185
|
+
yield bit.chr.to_i
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
### Comparision operator for Comparable mixin, fallthrough to
|
191
|
+
### Fixnum/Bignum. Compares current state against +cmp+.
|
192
|
+
def <=>( cmp )
|
193
|
+
@bv <=> cmp.bv
|
194
|
+
end
|
195
|
+
|
196
|
+
end # class Ant::BitVector
|
197
|
+
|