ant-wireless 0.1.0 → 0.2.0

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,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60dd8cb782d7e1f500a55f7cd80b77fb2fcd3d9a58388a5e2fdff25ee5c70e2c
4
- data.tar.gz: e9c54e26b412c78b10d42a3d6df532b0e58ddab7775146602b38d52ae119e5aa
3
+ metadata.gz: 0440d58876178ab22b480c72d95830474b407f7b1b366e518a7733a02abdd857
4
+ data.tar.gz: 2e0eb9be083381e57df2b13843894c33f43a957bff10a30fd06654fee41a5085
5
5
  SHA512:
6
- metadata.gz: 50f34e579557e981f7f63610dedc06959ab1109e30a65e2d34d2fd33cc29f00c5ac955785e47e7d2b7c912e13999aedeaa0c961a5505b560d0d7e7092f3eb4d0
7
- data.tar.gz: 2a3892e482b4173861a1c61c3b194589e14baa6c9d440b02004d8e519c388a88bbc527d3192fe769a36d48dad3d54f4c9bb0f6fce08a9e9cb00876a9684fc0d2
6
+ metadata.gz: 8237b0332974c4bc1afc2697b4502bb0048dbc00e6caf3ca4f004bc71a0f854fa997b0239d961dd0a0681dbeb3d3bbc370407c4900812233c6ae0a00fef7dbb1
7
+ data.tar.gz: e2e8f4dff3fc5d60181bd1b7a9f8fa3b5e7683d0c56243ffa0c4645cccc2b1692f738e39fc7f09ea63affaa6d126e4e9a254efbcbb624df14f811a78ccf17e72
checksums.yaml.gz.sig CHANGED
Binary file
data/History.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Release History for ruby-ant
2
2
 
3
3
  ---
4
+ ## v0.2.0 [2021-09-22] Michael Granger <ged@FaerieMUD.org>
5
+
6
+ Enhancements:
7
+
8
+ - Add channel period, search timeout, and introspection methods
9
+ - Add Ant.initialized? predicate
10
+ - Make the default response and event callback modules more useful.
11
+
4
12
 
5
13
  ## v0.1.0 [2021-08-26] Michael Granger <ged@FaerieMUD.org>
6
14
 
data/README.md CHANGED
@@ -57,6 +57,12 @@ This task will install dependencies, and do any other necessary setup for develo
57
57
 
58
58
  ## License
59
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
+
60
66
  Copyright (c) 2021, Ravn Group
61
67
 
62
68
  Permission is hereby granted, free of charge, to any person obtaining
@@ -82,3 +88,4 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
82
88
  [ant]: https://www.thisisant.com/
83
89
  [antstick]: https://buy.garmin.com/en-US/US/p/10997/pn/010-01058-00
84
90
  [antsdk]: https://www.thisisant.com/developer/resources/downloads/#software_tab
91
+
@@ -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,7 +302,7 @@ 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
- rb_raise( rb_eRuntimeError, "could not set the network key." );
305
+ rant_log( "error", "could not set the network key." );
295
306
  }
296
307
 
297
308
  return Qtrue;
@@ -463,6 +474,56 @@ rant_s_on_response( int argc, VALUE *argv, VALUE module )
463
474
  }
464
475
 
465
476
 
477
+ /*
478
+ * call-seq:
479
+ * Ant.request_capabilities
480
+ *
481
+ * Request the current ANT device's capabilities. These will be delivered
482
+ * via a callback to the #on_capabilities response callback, which by default
483
+ * extracts them into a Hash which is stored at Ant.capabilities.
484
+ *
485
+ */
486
+ static VALUE
487
+ rant_s_request_capabilities( VALUE module )
488
+ {
489
+ bool rval = ANT_RequestMessage( 0, MESG_CAPABILITIES_ID );
490
+ return rval ? Qtrue : Qfalse;
491
+ }
492
+
493
+
494
+ /*
495
+ * call-seq:
496
+ * Ant.request_serial_num
497
+ *
498
+ * Request the current ANT device's serial number. The result will be delivered
499
+ * via a callback to the #on_get_serial_num response callback, which by default
500
+ * extracts it and stores it at Ant.serial_number.
501
+ *
502
+ */
503
+ static VALUE
504
+ rant_s_request_serial_num( VALUE module )
505
+ {
506
+ bool rval = ANT_RequestMessage( 0, MESG_GET_SERIAL_NUM_ID );
507
+ return rval ? Qtrue : Qfalse;
508
+ }
509
+
510
+
511
+ /*
512
+ * call-seq:
513
+ * Ant.request_version
514
+ *
515
+ * Request the current device's ANT version. The result will be delivered
516
+ * via a callback to the #on_version response callback, which by default
517
+ * extracts it and stores it at Ant.hardware_version.
518
+ *
519
+ */
520
+ static VALUE
521
+ rant_s_request_version( VALUE module )
522
+ {
523
+ bool rval = ANT_RequestMessage( 0, MESG_VERSION_ID );
524
+ return rval ? Qtrue : Qfalse;
525
+ }
526
+
466
527
 
467
528
  /*
468
529
  * call-seq:
@@ -508,6 +569,7 @@ Init_ant_ext()
508
569
  rb_define_singleton_method( rant_mAnt, "device_serial_number", rant_s_device_serial_number, 0 );
509
570
 
510
571
  rb_define_singleton_method( rant_mAnt, "init", rant_s_init, -1 );
572
+ rb_define_singleton_method( rant_mAnt, "initialized?", rant_s_initialized_p, 0 );
511
573
  // rb_define_singleton_method( rant_mAnt, "init_ext", rant_s_init_ext, 4 );
512
574
  rb_define_singleton_method( rant_mAnt, "close", rant_s_close, 0 );
513
575
  rb_define_singleton_method( rant_mAnt, "reset", rant_s_reset, 0 );
@@ -521,6 +583,10 @@ Init_ant_ext()
521
583
  rb_define_singleton_method( rant_mAnt, "on_response", rant_s_on_response, -1 );
522
584
  // EXPORT void ANT_UnassignAllResponseFunctions(); //Unassigns all response functions
523
585
 
586
+ rb_define_singleton_method( rant_mAnt, "request_capabilities", rant_s_request_capabilities, 0 );
587
+ rb_define_singleton_method( rant_mAnt, "request_serial_num", rant_s_request_serial_num, 0 );
588
+ rb_define_singleton_method( rant_mAnt, "request_version", rant_s_request_version, 0 );
589
+
524
590
  rb_define_singleton_method( rant_mAnt, "log_directory=", rant_s_log_directory_eq, 1 );
525
591
 
526
592
 
@@ -536,6 +602,7 @@ Init_ant_ext()
536
602
  EXPOSE_CONST( ANT_EXT_STRING_SIZE );
537
603
  EXPOSE_CONST( ANT_EXT_MESG_BITFIELD_DEVICE_ID );
538
604
  EXPOSE_CONST( ANT_EXT_MESG_BIFIELD_EXTENSION );
605
+ rb_define_const( rant_mAnt, "ANT_EXT_MESG_BITFIELD_EXTENSION", INT2FIX(ANT_EXT_MESG_BIFIELD_EXTENSION) );
539
606
  EXPOSE_CONST( ANT_EXT_MESG_BITFIELD_OVERWRITE_SHARED_ADR );
540
607
  EXPOSE_CONST( ANT_EXT_MESG_BITFIELD_TRANSMISSION_TYPE );
541
608
 
@@ -617,6 +684,9 @@ Init_ant_ext()
617
684
  EXPOSE_CONST( CAPABILITIES_SELECTIVE_DATA_UPDATE_ENABLED );
618
685
  EXPOSE_CONST( CAPABILITIES_ENCRYPTED_CHANNEL_ENABLED );
619
686
 
687
+ // Not in the header; this is taken from 9.5.7.4, ANT Message Protocol and Usage v5.1
688
+ rb_define_const( rant_mAnt, "CAPABILITIES_RFACTIVE_NOTIFICATION_ENABLED", INT2FIX(0) );
689
+
620
690
  EXPOSE_CONST( CHANNEL_NUMBER_MASK );
621
691
  EXPOSE_CONST( SEQUENCE_NUMBER_MASK );
622
692
  EXPOSE_CONST( SEQUENCE_NUMBER_ROLLOVER );
@@ -128,6 +128,11 @@ 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
+
131
136
  rb_hash_aset( registry, channel_number, self );
132
137
 
133
138
  return self;
@@ -173,8 +178,8 @@ rant_channel_set_channel_id( int argc, VALUE *argv, VALUE self )
173
178
  rb_scan_args( argc, argv, "31", &device_number, &device_type, &transmission_type, &timeout );
174
179
 
175
180
  usDeviceNumber = NUM2USHORT( device_number );
176
- ucDeviceType = NUM2USHORT( device_type );
177
- ucTransmissionType = NUM2USHORT( transmission_type );
181
+ ucDeviceType = NUM2CHR( device_type );
182
+ ucTransmissionType = NUM2CHR( transmission_type );
178
183
 
179
184
  if ( RTEST(timeout) )
180
185
  ulResponseTime = NUM2UINT( timeout );
@@ -186,13 +191,114 @@ rant_channel_set_channel_id( int argc, VALUE *argv, VALUE self )
186
191
  rb_raise( rb_eRuntimeError, "Failed to set the channel id." );
187
192
  }
188
193
 
194
+ rb_iv_set( self, "@device_type", device_type );
195
+ rb_iv_set( self, "@device_number", device_number );
196
+ rb_iv_set( self, "@transmission_type", transmission_type );
197
+
198
+ return Qtrue;
199
+ }
200
+
201
+
202
+ /*
203
+ * call-seq:
204
+ * channel.set_channel_period( period, timeout=0 )
205
+ *
206
+ * This message configures the messaging +period+ of a specific channel where:
207
+ * Messaging period = channel period time +period+ * 32768.
208
+ *
209
+ * E.g.: To send or receive a message at 4Hz, set the channel period to 8192 (32768/4).
210
+ *
211
+ * Note: The minimum acceptable channel period is difficult to specify as it is
212
+ * system dependent and depends on the number of configured channels and their use.
213
+ * Caution should be used to appropriately test the system when high data rates are
214
+ * used, especially in combination with multiple channels.
215
+ *
216
+ */
217
+ static VALUE
218
+ rant_channel_set_channel_period( int argc, VALUE *argv, VALUE self )
219
+ {
220
+ rant_channel_t *ptr = rant_get_channel( self );
221
+ VALUE period, timeout;
222
+ unsigned int ulResponseTime = 0;
223
+ unsigned short usMesgPeriod;
224
+ bool result;
225
+
226
+ rb_scan_args( argc, argv, "11", &period, &timeout );
227
+
228
+ usMesgPeriod = NUM2USHORT( period );
229
+ if ( RTEST(timeout) )
230
+ ulResponseTime = NUM2UINT( timeout );
231
+
232
+ result = ANT_SetChannelPeriod_RTO( ptr->channel_num, usMesgPeriod, ulResponseTime );
233
+
234
+ if ( !result )
235
+ rb_raise( rb_eRuntimeError, "Failed to set the channel period." );
236
+
237
+ return Qtrue;
238
+ }
239
+
240
+
241
+ /*
242
+ * call-seq:
243
+ * channel.set_channel_search_timeout( search_timeout, timeout=0 )
244
+ *
245
+ * Configure the length of time that the receiver will search for a channel
246
+ * before timing out. Note that a value of zero will disable high priority
247
+ * search mode, and a value of 255 sets an infinite search time-out. The
248
+ * exception to this is the AP1 module, which has only a high priority search
249
+ * mode. For AP1 only, a value of 0 is an immediate search timeout, and a value
250
+ * of 255 corresponds to approximately 10.5 minutes.
251
+ *
252
+ */
253
+ static VALUE
254
+ rant_channel_set_channel_search_timeout( int argc, VALUE *argv, VALUE self )
255
+ {
256
+ rant_channel_t *ptr = rant_get_channel( self );
257
+ VALUE search_timeout, timeout;
258
+ unsigned int ulResponseTime = 0;
259
+ unsigned char ucSearchTimeout;
260
+ bool result;
261
+
262
+ rb_scan_args( argc, argv, "11", &search_timeout, &timeout );
263
+
264
+ ucSearchTimeout = NUM2CHR( search_timeout );
265
+ if ( RTEST(timeout) )
266
+ ulResponseTime = NUM2UINT( timeout );
267
+
268
+ result = ANT_SetChannelSearchTimeout_RTO( ptr->channel_num, ucSearchTimeout, ulResponseTime );
269
+
270
+ if ( !result )
271
+ rb_raise( rb_eRuntimeError, "Failed to set the channel search timeout." );
272
+
273
+ return Qtrue;
274
+ }
275
+
276
+
277
+ /*
278
+ * call-seq:
279
+ * channel.set_channel_rf_freq( frequency )
280
+ *
281
+ * Set the ANT RF +frequency+.
282
+ *
283
+ */
284
+ static VALUE
285
+ rant_channel_set_channel_rf_freq( VALUE self, VALUE frequency )
286
+ {
287
+ rant_channel_t *ptr = rant_get_channel( self );
288
+ unsigned short ucRFFreq = NUM2USHORT( frequency );
289
+
290
+ if ( ucRFFreq > 124 ) {
291
+ rb_raise( rb_eArgError, "frequency must be between 0 and 124." );
292
+ }
293
+
294
+ ANT_SetChannelRFFreq( ptr->channel_num, ucRFFreq );
295
+
296
+ rb_iv_set( self, "@rf_frequency", frequency );
297
+
189
298
  return Qtrue;
190
299
  }
191
300
 
192
301
 
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
302
 
197
303
 
198
304
  /*
@@ -450,29 +556,6 @@ rant_channel_send_broadcast_data( VALUE self, VALUE data )
450
556
  }
451
557
 
452
558
 
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
559
  void
477
560
  init_ant_channel()
478
561
  {
@@ -501,11 +584,15 @@ init_ant_channel()
501
584
  rb_attr( rant_cAntChannel, rb_intern("network_number"), 1, 0, 0 );
502
585
  rb_attr( rant_cAntChannel, rb_intern("extended_options"), 1, 0, 0 );
503
586
 
587
+ rb_attr( rant_cAntChannel, rb_intern("device_number"), 1, 0, 0 );
588
+ rb_attr( rant_cAntChannel, rb_intern("device_type"), 1, 0, 0 );
589
+ rb_attr( rant_cAntChannel, rb_intern("transmission_type"), 1, 0, 0 );
590
+ rb_attr( rant_cAntChannel, rb_intern("rf_frequency"), 1, 0, 0 );
591
+
504
592
  rb_define_method( rant_cAntChannel, "set_channel_id", rant_channel_set_channel_id, -1 );
505
- // rb_define_method( rant_cAntChannel, "set_channel_period",
506
- // rant_channel_set_channel_period, -1 );
507
- // rb_define_method( rant_cAntChannel, "set_channel_search_timeout",
508
- // rant_channel_set_channel_search_timeout, -1 );
593
+ rb_define_method( rant_cAntChannel, "set_channel_period", rant_channel_set_channel_period, -1 );
594
+ rb_define_method( rant_cAntChannel, "set_channel_search_timeout",
595
+ rant_channel_set_channel_search_timeout, -1 );
509
596
  rb_define_method( rant_cAntChannel, "set_channel_rf_freq", rant_channel_set_channel_rf_freq, 1 );
510
597
 
511
598
  rb_define_method( rant_cAntChannel, "open", rant_channel_open, -1 );
@@ -14,6 +14,7 @@ have_header( 'ruby/thread.h' ) or
14
14
  abort "Your Ruby is too old!"
15
15
 
16
16
  have_func( 'ANT_Init', 'libant.h' )
17
+ have_func( 'ANT_IsInitialized', 'libant.h' )
17
18
  have_func( 'ANT_LibVersion', 'libant.h' )
18
19
  have_func( 'ANT_GetDeviceSerialNumber', 'libant.h' )
19
20
 
@@ -13,8 +13,8 @@ require 'ant/mixins'
13
13
  # Refs:
14
14
  # * 9.5.6.1 Channel Response / Event (0x40) [ANT Message Protocol and Usage, Rev 5.1]
15
15
  module Ant::Channel::EventCallbacks
16
- extend Loggability
17
- include Ant::DataUtilities
16
+ extend Loggability,
17
+ Ant::DataUtilities
18
18
 
19
19
 
20
20
  # Mapping of response message IDs to handler methods
@@ -62,13 +62,9 @@ module Ant::Channel::EventCallbacks
62
62
  end
63
63
 
64
64
 
65
- ###############
66
- module_function
67
- ###############
68
-
69
65
  ### Default callback hook -- handles event callbacks.
70
66
  def handle_event_callback( channel_num, event_id, data )
71
- handler_method = HANDLER_METHODS[ event_id ] or
67
+ handler_method = Ant::Channel::EventCallbacks::HANDLER_METHODS[ event_id ] or
72
68
  raise "Unhandled channel event %p" % [ event_id ]
73
69
 
74
70
  if self.respond_to?( handler_method )
@@ -81,10 +77,10 @@ module Ant::Channel::EventCallbacks
81
77
 
82
78
  ### Handle an TX event.
83
79
  def on_event_tx( channel_num, data )
84
- # self.log.info "Broadcast message on channel %d was transmitted." % [ channel_num ]
85
- data = SecureRandom.bytes( 8 )
86
- self.log.info "Sending our own broadcast data: \n%s" % [ hexdump(data) ]
87
- self.send_broadcast_data( data )
80
+ channel = Ant::Channel.registry[ channel_num ]
81
+ self.log.debug "%p ready for transmission." % [ channel ]
82
+ ident = [ 1, 33 ].pack( "CC" )
83
+ channel.send_broadcast_data( ident )
88
84
  end
89
85
 
90
86
 
@@ -148,7 +144,7 @@ module Ant::Channel::EventCallbacks
148
144
  usDeviceNumber = data.bytes[10] | (data.bytes[11] << 8)
149
145
  ucDeviceType = data.bytes[12]
150
146
  ucTransmissionType = data.bytes[13]
151
- self.log.info "Got an acknowledge on Chan ID(%d/%d/%d)" %
147
+ self.log.debug "Got an acknowledge on Chan ID(%d/%d/%d)" %
152
148
  [usDeviceNumber, ucDeviceType, ucTransmissionType]
153
149
  end
154
150
 
@@ -162,7 +158,7 @@ module Ant::Channel::EventCallbacks
162
158
  usDeviceNumber = data.bytes[10] | (data.bytes[11] << 8)
163
159
  ucDeviceType = data.bytes[12]
164
160
  ucTransmissionType = data.bytes[13]
165
- self.log.info "Got a burst on Chan ID(%d/%d/%d)" %
161
+ self.log.debug "Got a burst on Chan ID(%d/%d/%d)" %
166
162
  [usDeviceNumber, ucDeviceType, ucTransmissionType]
167
163
  end
168
164
 
@@ -176,7 +172,7 @@ module Ant::Channel::EventCallbacks
176
172
  usDeviceNumber = data.bytes[10] | (data.bytes[11] << 8)
177
173
  ucDeviceType = data.bytes[12]
178
174
  ucTransmissionType = data.bytes[13]
179
- self.log.info "Got a broadcast on Chan ID(%d/%d/%d)" %
175
+ self.log.debug "Got a broadcast on Chan ID(%d/%d/%d)" %
180
176
  [usDeviceNumber, ucDeviceType, ucTransmissionType]
181
177
  end
182
178
 
@@ -185,7 +181,7 @@ module Ant::Channel::EventCallbacks
185
181
 
186
182
 
187
183
  def on_event_rx_acknowledged( channel_num, data )
188
- self.log.info "Acknowledged: Rx:\n%s" % [ hexdump(data[1..9]) ]
184
+ self.log.debug "Acknowledged: Rx [%d]:\n%s" % [ data.bytes[0], Ant::DataUtilities.hexdump(data[1..9]) ]
189
185
  end
190
186
 
191
187
 
@@ -193,12 +189,12 @@ module Ant::Channel::EventCallbacks
193
189
  channel = (data.bytes[0] & CHANNEL_NUMBER_MASK) >> 5
194
190
  sequence_num = data.bytes[0] & SEQUENCE_NUMBER_MASK
195
191
 
196
- self.log.info "Burst (0x%02x): Rx: %d:\n%s" % [ channel, sequence_num, hexdump(data[1..9]) ]
192
+ self.log.debug "Burst (0x%02x): Rx: %d:\n%s" % [ channel, sequence_num, Ant::DataUtilities.hexdump(data[1..9]) ]
197
193
  end
198
194
 
199
195
 
200
196
  def on_event_rx_broadcast( channel_num, data )
201
- self.log.info "Broadcast: Rx:\n%s" % [ hexdump(data[1..9]) ]
197
+ self.log.debug "Broadcast: Rx [%d]:\n%s" % [ data.bytes[0], Ant::DataUtilities.hexdump(data[1..9]) ]
202
198
  end
203
199
 
204
200
 
data/lib/ant/channel.rb CHANGED
@@ -9,6 +9,7 @@ require 'ant' unless defined?( Ant )
9
9
  class Ant::Channel
10
10
  extend Loggability
11
11
 
12
+
12
13
  # The default network number
13
14
  DEFAULT_NETWORK_NUMBER = 0
14
15
 
@@ -20,7 +21,8 @@ class Ant::Channel
20
21
  # Autoloads
21
22
  #
22
23
 
23
- autoload :EventCallbacks, 'ant/channel/event_callbacks'
24
+ require 'ant/channel/event_callbacks'
25
+ include Ant::Channel::EventCallbacks
24
26
 
25
27
 
26
28
  # Loggability API -- log to the Ant logger
@@ -44,23 +46,68 @@ class Ant::Channel
44
46
 
45
47
 
46
48
  ### Set up the given +mod+ as the handler module for channel events.
47
- def set_event_handlers( object=Ant::Channel::EventCallbacks )
49
+ def set_event_handlers( object=self )
48
50
  self.on_event( &object.method(:handle_event_callback) )
49
51
  end
50
52
 
51
53
 
54
+ ### Return the ANT channel ID if one has been assigned.
55
+ def channel_id
56
+ device_number = self.device_number or return nil
57
+ device_type = self.device_type & 0x7f
58
+ pairing_bit = self.device_type & 0x80
59
+ transmission_type = self.transmission_type
60
+
61
+ return "%d/%d/%d%s" % [
62
+ device_number,
63
+ device_type,
64
+ transmission_type,
65
+ pairing_bit.nonzero? ? '+' : '',
66
+ ]
67
+ end
68
+
69
+
70
+ ### Return a human-readable description of the channel type.
71
+ def channel_type_description
72
+ case self.channel_type
73
+ when Ant::PARAMETER_RX_NOT_TX
74
+ return :slave
75
+ when Ant::PARAMETER_TX_NOT_RX
76
+ return :master
77
+ when Ant::PARAMETER_SHARED_CHANNEL
78
+ return :shared
79
+ when Ant::PARAMETER_NO_TX_GUARD_BAND
80
+ return :no_tx_guard_band
81
+ when Ant::PARAMETER_ALWAYS_RX_WILD_CARD_SEARCH_ID
82
+ return :always_rx_wild_card_search_id
83
+ when Ant::PARAMETER_RX_ONLY
84
+ return :rx_only
85
+ else
86
+ return nil
87
+ end
88
+ end
89
+
90
+
91
+ ### Returns +true+ if the channel is not closed.
92
+ def open?
93
+ return !self.closed?
94
+ end
95
+
96
+
52
97
  ### Return a human-readable version of the object suitable for debugging.
53
98
  def inspect
54
- return "#<%p:%#x {%d} %#02x on network %d: %d%s>" % [
99
+ return "#<%p:%#x %s {%s} #%d @%dMHz on network %d%s>" % [
55
100
  self.class,
56
101
  self.object_id,
102
+ self.channel_type_description,
103
+ self.channel_id || '-',
57
104
  self.channel_number,
58
- self.channel_type,
105
+ self.rf_frequency + 2400,
59
106
  self.network_number,
60
- self.extended_options,
61
107
  self.closed? ? " (closed)" : "",
62
108
  ]
63
109
  end
64
110
 
65
111
  end # class Ant::Channel
66
112
 
113
+
@@ -4,6 +4,7 @@
4
4
  require 'loggability'
5
5
 
6
6
  require 'ant' unless defined?( Ant )
7
+ require 'ant/bitvector'
7
8
 
8
9
 
9
10
  # A module that handles response callbacks by logging them.
@@ -16,91 +17,50 @@ module Ant::ResponseCallbacks
16
17
 
17
18
  # Mapping of response message IDs to handler methods
18
19
  HANDLER_METHODS = {
20
+ Ant::Message::MESG_STARTUP_MESG_ID => :on_startup_mesg,
21
+
22
+ Ant::Message::MESG_CAPABILITIES_ID => :on_capabilities,
23
+ Ant::Message::MESG_CHANNEL_STATUS_ID => :on_channel_status,
19
24
  Ant::Message::MESG_VERSION_ID => :on_version,
25
+ Ant::Message::MESG_CHANNEL_ID_ID => :on_channel_id,
26
+ Ant::Message::MESG_EVENT_BUFFERING_CONFIG_ID => :on_event_buffering_config,
27
+ Ant::Message::MESG_GET_SERIAL_NUM_ID => :on_get_serial_num,
28
+
20
29
  Ant::Message::MESG_RESPONSE_EVENT_ID => :on_response_event,
21
30
 
22
- Ant::Message::MESG_UNASSIGN_CHANNEL_ID => :on_unassign_channel,
31
+ Ant::Message::MESG_NETWORK_KEY_ID => :on_network_key,
23
32
  Ant::Message::MESG_ASSIGN_CHANNEL_ID => :on_assign_channel,
24
- Ant::Message::MESG_CHANNEL_MESG_PERIOD_ID => :on_channel_mesg_period,
25
- Ant::Message::MESG_CHANNEL_SEARCH_TIMEOUT_ID => :on_channel_search_timeout,
33
+ Ant::Message::MESG_UNASSIGN_CHANNEL_ID => :on_unassign_channel,
26
34
  Ant::Message::MESG_CHANNEL_RADIO_FREQ_ID => :on_channel_radio_freq,
27
- Ant::Message::MESG_NETWORK_KEY_ID => :on_network_key,
28
- Ant::Message::MESG_RADIO_TX_POWER_ID => :on_radio_tx_power,
29
- Ant::Message::MESG_RADIO_CW_MODE_ID => :on_radio_cw_mode,
30
- Ant::Message::MESG_SYSTEM_RESET_ID => :on_system_reset,
31
35
  Ant::Message::MESG_OPEN_CHANNEL_ID => :on_open_channel,
36
+
37
+ Ant::Message::MESG_RX_EXT_MESGS_ENABLE_ID => :on_rx_ext_mesgs_enable,
32
38
  Ant::Message::MESG_CLOSE_CHANNEL_ID => :on_close_channel,
33
39
  Ant::Message::MESG_REQUEST_ID => :on_request,
34
40
 
35
41
  Ant::Message::MESG_BROADCAST_DATA_ID => :on_broadcast_data,
36
42
  Ant::Message::MESG_ACKNOWLEDGED_DATA_ID => :on_acknowledged_data,
37
43
  Ant::Message::MESG_BURST_DATA_ID => :on_burst_data,
44
+ Ant::Message::MESG_ADV_BURST_DATA_ID => :on_adv_burst_data,
38
45
 
39
- Ant::Message::MESG_CHANNEL_ID_ID => :on_channel_id,
40
- Ant::Message::MESG_CHANNEL_STATUS_ID => :on_channel_status,
41
- Ant::Message::MESG_RADIO_CW_INIT_ID => :on_radio_cw_init,
42
- Ant::Message::MESG_CAPABILITIES_ID => :on_capabilities,
43
-
44
- Ant::Message::MESG_STACKLIMIT_ID => :on_stacklimit,
45
-
46
- Ant::Message::MESG_SCRIPT_DATA_ID => :on_script_data,
47
- Ant::Message::MESG_SCRIPT_CMD_ID => :on_script_cmd,
48
-
49
- Ant::Message::MESG_ID_LIST_ADD_ID => :on_id_list_add,
50
- Ant::Message::MESG_CRYPTO_ID_LIST_ADD_ID => :on_crypto_id_list_add,
51
- Ant::Message::MESG_ID_LIST_CONFIG_ID => :on_id_list_config,
52
- Ant::Message::MESG_CRYPTO_ID_LIST_CONFIG_ID => :on_crypto_id_list_config,
53
- Ant::Message::MESG_OPEN_RX_SCAN_ID => :on_open_rx_scan,
54
-
55
- Ant::Message::MESG_EXT_CHANNEL_RADIO_FREQ_ID => :on_ext_channel_radio_freq_id,
56
- Ant::Message::MESG_EXT_BROADCAST_DATA_ID => :on_ext_broadcast_data,
57
- Ant::Message::MESG_EXT_ACKNOWLEDGED_DATA_ID => :on_ext_acknowledged_data,
58
- Ant::Message::MESG_EXT_BURST_DATA_ID => :on_ext_burst_data,
59
-
60
- Ant::Message::MESG_CHANNEL_RADIO_TX_POWER_ID => :on_channel_radio_tx_power,
61
- Ant::Message::MESG_GET_SERIAL_NUM_ID => :on_get_serial_num,
62
- Ant::Message::MESG_GET_TEMP_CAL_ID => :on_get_temp_cal,
63
- Ant::Message::MESG_SET_LP_SEARCH_TIMEOUT_ID => :on_set_lp_search_timeout,
64
- Ant::Message::MESG_SET_TX_SEARCH_ON_NEXT_ID => :on_set_tx_search_on_next,
65
- Ant::Message::MESG_SERIAL_NUM_SET_CHANNEL_ID_ID => :on_serial_num_set_channel_id,
66
- Ant::Message::MESG_RX_EXT_MESGS_ENABLE_ID => :on_rx_ext_mesgs_enable,
67
- Ant::Message::MESG_RADIO_CONFIG_ALWAYS_ID => :on_radio_config_always,
68
- Ant::Message::MESG_ENABLE_LED_FLASH_ID => :on_enable_led_flash,
69
- Ant::Message::MESG_XTAL_ENABLE_ID => :on_xtal_enable,
70
- Ant::Message::MESG_ANTLIB_CONFIG_ID => :on_antlib_config,
71
- Ant::Message::MESG_STARTUP_MESG_ID => :on_startup_mesg,
72
- Ant::Message::MESG_AUTO_FREQ_CONFIG_ID => :on_auto_freq_config,
73
- Ant::Message::MESG_PROX_SEARCH_CONFIG_ID => :on_prox_search_config,
46
+ Ant::Message::MESG_CHANNEL_MESG_PERIOD_ID => :on_channel_mesg_period,
47
+ Ant::Message::MESG_CHANNEL_SEARCH_TIMEOUT_ID => :on_channel_search_timeout,
74
48
 
75
- Ant::Message::MESG_ADV_BURST_DATA_ID => :on_adv_burst_data,
76
- Ant::Message::MESG_EVENT_BUFFERING_CONFIG_ID => :on_event_buffering_config,
49
+ Ant::Message::MESG_RADIO_TX_POWER_ID => :on_radio_tx_power,
77
50
 
78
- Ant::Message::MESG_SET_SEARCH_CH_PRIORITY_ID => :on_set_search_ch_priority,
79
-
80
- Ant::Message::MESG_HIGH_DUTY_SEARCH_MODE_ID => :on_high_duty_search_mode,
81
- Ant::Message::MESG_CONFIG_ADV_BURST_ID => :on_config_adv_burst,
82
- Ant::Message::MESG_EVENT_FILTER_CONFIG_ID => :on_event_filter_config,
83
- Ant::Message::MESG_SDU_CONFIG_ID => :on_sdu_config,
84
- Ant::Message::MESG_SDU_SET_MASK_ID => :on_sdu_set_mask,
85
- Ant::Message::MESG_USER_CONFIG_PAGE_ID => :on_user_config_page,
86
- Ant::Message::MESG_ENCRYPT_ENABLE_ID => :on_encrypt_enable,
87
- Ant::Message::MESG_SET_CRYPTO_KEY_ID => :on_set_crypto_key,
88
- Ant::Message::MESG_SET_CRYPTO_INFO_ID => :on_set_crypto_info,
89
- Ant::Message::MESG_CUBE_CMD_ID => :on_cube_cmd,
90
-
91
- Ant::Message::MESG_ACTIVE_SEARCH_SHARING_ID => :on_active_search_sharing,
92
- Ant::Message::MESG_NVM_CRYPTO_KEY_OPS_ID => :on_nvm_crypto_key_ops,
51
+ # :TODO: There are many other MESG_ constants, but I think most or all of
52
+ # them are for the serial protocol.
93
53
  }
94
54
 
95
55
 
96
56
 
97
57
  ### Default callback hook -- handles response callbacks.
98
58
  def self::handle_response_callback( channel_num, message_id, data )
99
- handler_method = HANDLER_METHODS[ message_id ] or
59
+ handler_method = Ant::ResponseCallbacks::HANDLER_METHODS[ message_id ] or
100
60
  raise "Unhandled response message ID %p" % [ message_id ]
101
61
 
102
- if self.respond_to?( handler_method )
103
- self.public_send( handler_method, channel_num, data )
62
+ if self.respond_to?( handler_method, true )
63
+ self.send( handler_method, channel_num, data )
104
64
  else
105
65
  Ant::ResponseCallbacks.log_response_callback( channel_num, handler_method, message_id, data )
106
66
  end
@@ -124,7 +84,9 @@ module Ant::ResponseCallbacks
124
84
 
125
85
  ### Handle version number response messages.
126
86
  def on_version( channel_num, data )
127
- self.log.info "ANT Version %s" % [ data ]
87
+ version = data.strip
88
+ self.log.info "ANT Version %s" % [ version ]
89
+ Ant.instance_variable_set( :@hardware_version, version )
128
90
  end
129
91
 
130
92
 
@@ -135,6 +97,19 @@ module Ant::ResponseCallbacks
135
97
  end
136
98
 
137
99
 
100
+ ### Log a success or an error message for a response event message.
101
+ def log_response_event( channel_num, data, err_desc, log_desc )
102
+ status = data.bytes[ 2 ]
103
+ channel = Ant::Channel.registry[ channel_num ]
104
+
105
+ if status.nonzero?
106
+ self.log.error "Error while %s on %p: %#02x" % [ err_desc, channel, status ]
107
+ else
108
+ self.log.info( log_desc )
109
+ end
110
+ end
111
+
112
+
138
113
  ### Handle startup response messages.
139
114
  def on_startup_mesg( channel_num, data )
140
115
  reason = case data.bytes[ 0 ]
@@ -166,13 +141,15 @@ module Ant::ResponseCallbacks
166
141
 
167
142
  ### Handle channel assignment event response messages.
168
143
  def on_assign_channel( channel_num, data )
169
- self.log_response_event( channel_num, data, "assigning channel", "Channel assigned." )
144
+ self.log_response_event( channel_num, data, "assigning channel",
145
+ "Channel %d assigned." % [channel_num] )
170
146
  end
171
147
 
172
148
 
173
149
  ### Handle channel unassignment event response messages.
174
- def on_unassign_channel
175
- self.log_response_event( channel_num, data, "unassigning channel", "Channel unassigned." )
150
+ def on_unassign_channel( channel_num, data )
151
+ self.log_response_event( channel_num, data, "unassigning channel",
152
+ "Channel %d unassigned." % [channel_num] )
176
153
  end
177
154
 
178
155
 
@@ -201,328 +178,125 @@ module Ant::ResponseCallbacks
201
178
  end
202
179
 
203
180
 
204
- ### Log a success or an error message for a response event message.
205
- def log_response_event( channel_num, data, err_desc, log_desc )
206
- status = data.bytes[ 2 ]
207
- if status.nonzero?
208
- self.log.error "Error while %s: %#02x" % [ err_desc, status ]
209
- else
210
- self.log.info( log_desc )
211
- end
212
- end
213
-
214
-
215
181
  ### Handle channel_mesg_period response events.
216
182
  def on_channel_mesg_period( channel_num, data )
217
- self.log_response_event( channel_num, data, "channel_mesg_period", "Channel period assigned." )
183
+ self.log_response_event( channel_num, data, "setting channel period", "Channel period assigned." )
218
184
  end
219
185
 
220
186
 
221
187
  ### Handle channel_search_timeout response event.
222
188
  def on_channel_search_timeout( channel_num, data )
223
- self.log_response_event( channel_num, data, "channel_search_timeout", "Channel assigned." )
189
+ self.log_response_event( channel_num, data, "setting search timeout", "Search timeout." )
224
190
  end
225
191
 
226
192
 
227
193
  ### Handle radio_tx_power response event.
228
194
  def on_radio_tx_power( channel_num, data )
229
- self.log_response_event( channel_num, data, "radio_tx_power", "Channel assigned." )
230
- end
231
-
232
-
233
- ### Handle radio_cw_mode response event.
234
- def on_radio_cw_mode( channel_num, data )
235
- self.log_response_event( channel_num, data, "radio_cw_mode", "Channel assigned." )
236
- end
237
-
238
-
239
- ### Handle system_reset response event.
240
- def on_system_reset( channel_num, data )
241
- self.log_response_event( channel_num, data, "system_reset", "Channel assigned." )
242
- end
243
-
244
-
245
- ### Handle request response event.
246
- def on_request( channel_num, data )
247
- self.log_response_event( channel_num, data, "request", "Channel assigned." )
195
+ self.log_response_event( channel_num, data, "setting transmit power", "Transmit power changed." )
248
196
  end
249
197
 
250
198
 
251
199
  ### Handle broadcast_data response event.
252
200
  def on_broadcast_data( channel_num, data )
253
- self.log_response_event( channel_num, data, "broadcast_data", "Channel assigned." )
201
+ self.log_response_event( channel_num, data, "sending broadcast data", "Sent broadcast data." )
254
202
  end
255
203
 
256
204
 
257
205
  ### Handle acknowledged_data response event.
258
206
  def on_acknowledged_data( channel_num, data )
259
- self.log_response_event( channel_num, data, "acknowledged_data", "Channel assigned." )
207
+ self.log_response_event( channel_num, data, "sending acked data", "Acked data sent." )
260
208
  end
261
209
 
262
210
 
263
211
  ### Handle burst_data response event.
264
212
  def on_burst_data( channel_num, data )
265
- self.log_response_event( channel_num, data, "burst_data", "Channel assigned." )
213
+ self.log_response_event( channel_num, data, "sending burst data", "Burst data sent." )
266
214
  end
267
215
 
268
216
 
269
217
  ### Handle channel_status response event.
270
218
  def on_channel_status( channel_num, data )
271
- self.log_response_event( channel_num, data, "channel_status", "Channel assigned." )
219
+ self.log_response_event( channel_num, data, "requesting channel status", "Got channel status." )
272
220
  end
273
221
 
274
222
 
275
- ### Handle radio_cw_init response event.
276
- def on_radio_cw_init( channel_num, data )
277
- self.log_response_event( channel_num, data, "radio_cw_init", "Channel assigned." )
223
+ ### Handle on_rx_ext_mesgs_enable response event.
224
+ def on_rx_ext_mesgs_enable( channel_num, data )
225
+ self.log_response_event( channel_num, data, "enabling extended message: not supported",
226
+ "Enabled extended messages." )
278
227
  end
279
228
 
280
229
 
281
230
  ### Handle capabilities response event.
282
231
  def on_capabilities( channel_num, data )
283
- self.log_response_event( channel_num, data, "capabilities", "Channel assigned." )
284
- end
285
-
286
-
287
- ### Handle stacklimit response event.
288
- def on_stacklimit( channel_num, data )
289
- self.log_response_event( channel_num, data, "stacklimit", "Channel assigned." )
290
- end
291
-
292
-
293
- ### Handle script_data response event.
294
- def on_script_data( channel_num, data )
295
- self.log_response_event( channel_num, data, "script_data", "Channel assigned." )
296
- end
297
-
298
-
299
- ### Handle script_cmd response event.
300
- def on_script_cmd( channel_num, data )
301
- self.log_response_event( channel_num, data, "script_cmd", "Channel assigned." )
302
- end
303
-
304
-
305
- ### Handle id_list_add response event.
306
- def on_id_list_add( channel_num, data )
307
- self.log_response_event( channel_num, data, "id_list_add", "Channel assigned." )
308
- end
309
-
310
-
311
- ### Handle crypto_id_list_add response event.
312
- def on_crypto_id_list_add( channel_num, data )
313
- self.log_response_event( channel_num, data, "crypto_id_list_add", "Channel assigned." )
314
- end
315
-
316
-
317
- ### Handle id_list_config response event.
318
- def on_id_list_config( channel_num, data )
319
- self.log_response_event( channel_num, data, "id_list_config", "Channel assigned." )
320
- end
321
-
322
-
323
- ### Handle crypto_id_list_config response event.
324
- def on_crypto_id_list_config( channel_num, data )
325
- self.log_response_event( channel_num, data, "crypto_id_list_config", "Channel assigned." )
326
- end
327
-
328
-
329
- ### Handle open_rx_scan response event.
330
- def on_open_rx_scan( channel_num, data )
331
- self.log_response_event( channel_num, data, "open_rx_scan", "Channel assigned." )
332
- end
333
-
334
-
335
- ### Handle ext_channel_radio_freq_id response event.
336
- def on_ext_channel_radio_freq_id( channel_num, data )
337
- self.log_response_event( channel_num, data, "ext_channel_radio_freq_id", "Channel assigned." )
338
- end
339
-
340
-
341
- ### Handle ext_broadcast_data response event.
342
- def on_ext_broadcast_data( channel_num, data )
343
- self.log_response_event( channel_num, data, "ext_broadcast_data", "Channel assigned." )
344
- end
345
-
346
-
347
- ### Handle ext_acknowledged_data response event.
348
- def on_ext_acknowledged_data( channel_num, data )
349
- self.log_response_event( channel_num, data, "ext_acknowledged_data", "Channel assigned." )
350
- end
351
-
352
-
353
- ### Handle ext_burst_data response event.
354
- def on_ext_burst_data( channel_num, data )
355
- self.log_response_event( channel_num, data, "ext_burst_data", "Channel assigned." )
356
- end
357
-
232
+ std_opts = Ant::BitVector.new( data.bytes[2] )
233
+ adv_opts = Ant::BitVector.new( data.bytes[3] )
234
+ adv_opts2 = Ant::BitVector.new( data.bytes[4] )
235
+ adv_opts3 = Ant::BitVector.new( data.bytes[6] )
236
+ adv_opts4 = Ant::BitVector.new( data.bytes[7] )
237
+
238
+ caps = {
239
+ max_channels: data.bytes[0],
240
+ max_networks: data.bytes[1],
241
+ max_sensrcore_channels: data.bytes[5],
242
+
243
+ rx_channels_enabled: std_opts.off?( Ant::CAPABILITIES_NO_RX_CHANNELS ),
244
+ tx_channels_enabled: std_opts.off?( Ant::CAPABILITIES_NO_TX_CHANNELS ),
245
+ rx_messages_enabled: std_opts.off?( Ant::CAPABILITIES_NO_RX_MESSAGES ),
246
+ tx_messages_enabled: std_opts.off?( Ant::CAPABILITIES_NO_TX_MESSAGES ),
247
+ ackd_messages_enabled: std_opts.off?( Ant::CAPABILITIES_NO_ACKD_MESSAGES ),
248
+ burst_transfer_enabled: std_opts.off?( Ant::CAPABILITIES_NO_BURST_TRANSFER ),
249
+
250
+ overun_underrun: adv_opts.on?( Ant::CAPABILITIES_OVERUN_UNDERRUN ),
251
+ network_enabled: adv_opts.on?( Ant::CAPABILITIES_NETWORK_ENABLED ),
252
+ api_version2: adv_opts.on?( Ant::CAPABILITIES_AP1_VERSION_2 ),
253
+ serial_number_enabled: adv_opts.on?( Ant::CAPABILITIES_SERIAL_NUMBER_ENABLED ),
254
+ per_channel_tx_power_enabled: adv_opts.on?( Ant::CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED ),
255
+ low_priority_search_enabled: adv_opts.on?( Ant::CAPABILITIES_LOW_PRIORITY_SEARCH_ENABLED ),
256
+ script_enabled: adv_opts.on?( Ant::CAPABILITIES_SCRIPT_ENABLED ),
257
+ search_list_enabled: adv_opts.on?( Ant::CAPABILITIES_SEARCH_LIST_ENABLED ),
258
+
259
+ led_enabled: adv_opts2.on?( Ant::CAPABILITIES_LED_ENABLED ),
260
+ ext_message_enabled: adv_opts2.on?( Ant::CAPABILITIES_EXT_MESSAGE_ENABLED ),
261
+ scan_mode_enabled: adv_opts2.on?( Ant::CAPABILITIES_SCAN_MODE_ENABLED ),
262
+ prox_search_enabled: adv_opts2.on?( Ant::CAPABILITIES_PROX_SEARCH_ENABLED ),
263
+ ext_assign_enabled: adv_opts2.on?( Ant::CAPABILITIES_EXT_ASSIGN_ENABLED ),
264
+ antfs_enabled: adv_opts2.on?( Ant::CAPABILITIES_FS_ANTFS_ENABLED ),
265
+ fit1_enabled: adv_opts2.on?( Ant::CAPABILITIES_FIT1_ENABLED ),
266
+
267
+ advanced_burst_enabled: adv_opts3.on?( Ant::CAPABILITIES_ADVANCED_BURST_ENABLED ),
268
+ event_buffering_enabled: adv_opts3.on?( Ant::CAPABILITIES_EVENT_BUFFERING_ENABLED ),
269
+ event_filtering_enabled: adv_opts3.on?( Ant::CAPABILITIES_EVENT_FILTERING_ENABLED ),
270
+ high_duty_search_mode_enabled: adv_opts3.on?( Ant::CAPABILITIES_HIGH_DUTY_SEARCH_MODE_ENABLED ),
271
+ active_search_sharing_mode_enabled: adv_opts3.on?( Ant::CAPABILITIES_ACTIVE_SEARCH_SHARING_MODE_ENABLED ),
272
+ selective_data_update_enabled: adv_opts3.on?( Ant::CAPABILITIES_SELECTIVE_DATA_UPDATE_ENABLED ),
273
+ encrypted_channel_enabled: adv_opts3.on?( Ant::CAPABILITIES_ENCRYPTED_CHANNEL_ENABLED ),
274
+
275
+ rfactive_notification_enabled: adv_opts4.on?( Ant::CAPABILITIES_RFACTIVE_NOTIFICATION_ENABLED ),
276
+ }.freeze
277
+
278
+ caplist = caps.keys.select do |cap|
279
+ caps[ cap ]
280
+ end
281
+ self.log.info "ANT Capabilities: %s" % [ caplist.sort.join(' ') ]
358
282
 
359
- ### Handle channel_radio_tx_power response event.
360
- def on_channel_radio_tx_power( channel_num, data )
361
- self.log_response_event( channel_num, data, "channel_radio_tx_power", "Channel assigned." )
283
+ Ant.instance_variable_set( :@capabilities, caps );
362
284
  end
363
285
 
364
286
 
365
- ### Handle get_serial_num response event.
287
+ ### Handle serial number response event.
366
288
  def on_get_serial_num( channel_num, data )
367
- self.log_response_event( channel_num, data, "get_serial_num", "Channel assigned." )
368
- end
369
-
370
-
371
- ### Handle get_temp_cal response event.
372
- def on_get_temp_cal( channel_num, data )
373
- self.log_response_event( channel_num, data, "get_temp_cal", "Channel assigned." )
374
- end
375
-
376
-
377
- ### Handle set_lp_search_timeout response event.
378
- def on_set_lp_search_timeout( channel_num, data )
379
- self.log_response_event( channel_num, data, "set_lp_search_timeout", "Channel assigned." )
380
- end
381
-
382
-
383
- ### Handle set_tx_search_on_next response event.
384
- def on_set_tx_search_on_next( channel_num, data )
385
- self.log_response_event( channel_num, data, "set_tx_search_on_next", "Channel assigned." )
386
- end
387
-
388
-
389
- ### Handle serial_num_set_channel_id response event.
390
- def on_serial_num_set_channel_id( channel_num, data )
391
- self.log_response_event( channel_num, data, "serial_num_set_channel_id", "Channel assigned." )
392
- end
393
-
394
-
395
- ### Handle rx_ext_mesgs_enable response event.
396
- def on_rx_ext_mesgs_enable( channel_num, data )
397
- self.log_response_event( channel_num, data, "rx_ext_mesgs_enable", "Channel assigned." )
398
- end
399
-
400
-
401
- ### Handle radio_config_always response event.
402
- def on_radio_config_always( channel_num, data )
403
- self.log_response_event( channel_num, data, "radio_config_always", "Channel assigned." )
404
- end
405
-
406
-
407
- ### Handle enable_led_flash response event.
408
- def on_enable_led_flash( channel_num, data )
409
- self.log_response_event( channel_num, data, "enable_led_flash", "Channel assigned." )
410
- end
411
-
412
-
413
- ### Handle xtal_enable response event.
414
- def on_xtal_enable( channel_num, data )
415
- self.log_response_event( channel_num, data, "xtal_enable", "Channel assigned." )
416
- end
417
-
418
-
419
- ### Handle antlib_config response event.
420
- def on_antlib_config( channel_num, data )
421
- self.log_response_event( channel_num, data, "antlib_config", "Channel assigned." )
422
- end
423
-
424
-
425
- ### Handle auto_freq_config response event.
426
- def on_auto_freq_config( channel_num, data )
427
- self.log_response_event( channel_num, data, "auto_freq_config", "Channel assigned." )
428
- end
289
+ serial = data.unpack1( 'L<' )
429
290
 
430
-
431
- ### Handle prox_search_config response event.
432
- def on_prox_search_config( channel_num, data )
433
- self.log_response_event( channel_num, data, "prox_search_config", "Channel assigned." )
434
- end
435
-
436
-
437
- ### Handle adv_burst_data response event.
438
- def on_adv_burst_data( channel_num, data )
439
- self.log_response_event( channel_num, data, "adv_burst_data", "Channel assigned." )
440
- end
441
-
442
-
443
- ### Handle event_buffering_config response event.
444
- def on_event_buffering_config( channel_num, data )
445
- self.log_response_event( channel_num, data, "event_buffering_config", "Channel assigned." )
446
- end
447
-
448
-
449
- ### Handle set_search_ch_priority response event.
450
- def on_set_search_ch_priority( channel_num, data )
451
- self.log_response_event( channel_num, data, "set_search_ch_priority", "Channel assigned." )
452
- end
453
-
454
-
455
- ### Handle high_duty_search_mode response event.
456
- def on_high_duty_search_mode( channel_num, data )
457
- self.log_response_event( channel_num, data, "high_duty_search_mode", "Channel assigned." )
458
- end
459
-
460
-
461
- ### Handle config_adv_burst response event.
462
- def on_config_adv_burst( channel_num, data )
463
- self.log_response_event( channel_num, data, "config_adv_burst", "Channel assigned." )
464
- end
465
-
466
-
467
- ### Handle event_filter_config response event.
468
- def on_event_filter_config( channel_num, data )
469
- self.log_response_event( channel_num, data, "event_filter_config", "Channel assigned." )
470
- end
471
-
472
-
473
- ### Handle sdu_config response event.
474
- def on_sdu_config( channel_num, data )
475
- self.log_response_event( channel_num, data, "sdu_config", "Channel assigned." )
476
- end
477
-
478
-
479
- ### Handle sdu_set_mask response event.
480
- def on_sdu_set_mask( channel_num, data )
481
- self.log_response_event( channel_num, data, "sdu_set_mask", "Channel assigned." )
482
- end
483
-
484
-
485
- ### Handle user_config_page response event.
486
- def on_user_config_page( channel_num, data )
487
- self.log_response_event( channel_num, data, "user_config_page", "Channel assigned." )
488
- end
489
-
490
-
491
- ### Handle encrypt_enable response event.
492
- def on_encrypt_enable( channel_num, data )
493
- self.log_response_event( channel_num, data, "encrypt_enable", "Channel assigned." )
494
- end
495
-
496
-
497
- ### Handle set_crypto_key response event.
498
- def on_set_crypto_key( channel_num, data )
499
- self.log_response_event( channel_num, data, "set_crypto_key", "Channel assigned." )
291
+ self.log.debug "ANT device serial number: %d." % [ serial ]
292
+ Ant.instance_variable_set( :@serial_num, serial )
500
293
  end
501
294
 
502
295
 
503
- ### Handle set_crypto_info response event.
504
- def on_set_crypto_info( channel_num, data )
505
- self.log_response_event( channel_num, data, "set_crypto_info", "Channel assigned." )
506
- end
507
-
508
-
509
- ### Handle cube_cmd response event.
510
- def on_cube_cmd( channel_num, data )
511
- self.log_response_event( channel_num, data, "cube_cmd", "Channel assigned." )
512
- end
513
-
514
-
515
- ### Handle active_search_sharing response event.
516
- def on_active_search_sharing( channel_num, data )
517
- self.log_response_event( channel_num, data, "active_search_sharing", "Channel assigned." )
518
- end
519
-
520
-
521
- ### Handle nvm_crypto_key_ops response event.
522
- def on_nvm_crypto_key_ops( channel_num, data )
523
- self.log_response_event( channel_num, data, "nvm_crypto_key_ops", "Channel assigned." )
296
+ ### Handle request response event.
297
+ def on_request( channel_num, data )
298
+ self.log_response_event( channel_num, data, "requesting an unsupported message", "[n/a]" )
524
299
  end
525
300
 
526
-
527
301
  end # module Ant::ResponseCallbacks
528
302
 
data/lib/ant.rb CHANGED
@@ -12,7 +12,7 @@ module Ant
12
12
  extend Loggability
13
13
 
14
14
  # Package version
15
- VERSION = '0.1.0'
15
+ VERSION = '0.2.0'
16
16
 
17
17
  # A Range for matching valid ANT device numbers
18
18
  VALID_DEVICE_NUMBERS = ( 0...65535 ).freeze
@@ -35,6 +35,23 @@ module Ant
35
35
  autoload :DataUtilities, 'ant/mixins'
36
36
 
37
37
 
38
+ # Capabilities hash -- set asynchronously by calling Ant.request_capabilities
39
+ @capabilities = nil
40
+ singleton_class.attr_reader( :capabilities )
41
+
42
+ # Serial number -- set asynchronously by calling Ant.request_serial_num
43
+ @serial_num = nil
44
+ singleton_class.attr_reader( :serial_num )
45
+
46
+ # Version of ANT supported by the hardware -- set asynchronously by calling
47
+ # Ant.request_version
48
+ @hardware_version = nil
49
+ singleton_class.attr_reader( :hardware_version )
50
+
51
+ # Add some convenience aliases
52
+ singleton_class.alias_method( :is_initialized?, :initialized? )
53
+
54
+
38
55
  ### Set up the given +object+ as the handler for response callbacks. It must
39
56
  ### respond to :handle_response_callback.
40
57
  def self::set_response_handler( object=Ant::ResponseCallbacks )
data/spec/ant_spec.rb CHANGED
@@ -33,6 +33,15 @@ RSpec.describe( Ant ) do
33
33
  end
34
34
 
35
35
 
36
+ it "knows if it's been initialized or not", :hardware do
37
+ expect( Ant ).to_not be_initialized
38
+ Ant.init
39
+ expect( Ant ).to be_initialized
40
+ Ant.close
41
+ expect( Ant ).to_not be_initialized
42
+ end
43
+
44
+
36
45
  it "can validate a device number" do
37
46
  expect( described_class.validate_device_number(111) ).to eq( 111 )
38
47
  expect {
data/spec/spec_helper.rb CHANGED
@@ -20,6 +20,8 @@ RSpec.configure do |config|
20
20
  Ant.init
21
21
  Ant.close
22
22
  rescue => err
23
+ $stderr.puts "%p while initializing hardware: %s; disabling hardware specs" %
24
+ [ err.class, err.message ]
23
25
  config.filter_run_excluding( :hardware )
24
26
  end
25
27
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ant-wireless
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Granger
@@ -34,7 +34,7 @@ cert_chain:
34
34
  MCh97sQ/Z/MOusb5+QddBmB+k8EicXyGNl4b5L4XpL7fIQu+Y96TB3JEJlShxFD9
35
35
  k9FjI4d9EP54gS/4
36
36
  -----END CERTIFICATE-----
37
- date: 2021-08-26 00:00:00.000000000 Z
37
+ date: 2021-09-22 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: rake-compiler
metadata.gz.sig CHANGED
Binary file