ant-wireless 0.1.0.pre.20210617213631 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47f23b13571d44d37275d309e73bf1b3b1d3b4f7e3c952f95fdf5b73321412b1
4
- data.tar.gz: 6bbccd101666ef42d12eab3d9b3d9e653634d97e19d9042f0c8282d74caf3fcb
3
+ metadata.gz: 0440d58876178ab22b480c72d95830474b407f7b1b366e518a7733a02abdd857
4
+ data.tar.gz: 2e0eb9be083381e57df2b13843894c33f43a957bff10a30fd06654fee41a5085
5
5
  SHA512:
6
- metadata.gz: 3cfbf1870872f9747df428d3ac4be4dd71b857bf47beb763f3d30fa517134b5d509e895ed975307b26de7936cee40dfc83f7b938e11679e61bf9e002d058acfb
7
- data.tar.gz: e7831b872fabbd850a946c88d053edc604aff86652e0efc6ffee9e593f92e5c52216a7382520765f2793a1e728b4457335ef3b9a999ec3d3eaa00699fdc89c2a
6
+ metadata.gz: 8237b0332974c4bc1afc2697b4502bb0048dbc00e6caf3ca4f004bc71a0f854fa997b0239d961dd0a0681dbeb3d3bbc370407c4900812233c6ae0a00fef7dbb1
7
+ data.tar.gz: e2e8f4dff3fc5d60181bd1b7a9f8fa3b5e7683d0c56243ffa0c4645cccc2b1692f738e39fc7f09ea63affaa6d126e4e9a254efbcbb624df14f811a78ccf17e72
checksums.yaml.gz.sig ADDED
Binary file
data/History.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Release History for ruby-ant
2
2
 
3
3
  ---
4
+ ## v0.2.0 [2021-09-22] Michael Granger <ged@FaerieMUD.org>
4
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
+
12
+
13
+ ## v0.1.0 [2021-08-26] Michael Granger <ged@FaerieMUD.org>
14
+
15
+ First release.
5
16
 
data/README.md CHANGED
@@ -20,8 +20,13 @@ manner.
20
20
 
21
21
  ## Prerequisites
22
22
 
23
- * Ruby
24
- * Garmin USB ANT Stick (https://buy.garmin.com/en-US/US/p/10997/pn/010-01058-00)
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
 
@@ -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:
@@ -490,7 +551,7 @@ Init_ant_ext()
490
551
  /*
491
552
  * Document-module: Ant
492
553
  *
493
- * This is an extension for using the ANT ultra-low power wireless protocol via
554
+ * This is an extension for using the ANT ultra-low power wireless protocol via
494
555
  * the Garmin USB ANT Stick. ANT can be used to send information
495
556
  * wirelessly from one device to another device, in a robust and flexible
496
557
  * manner.
@@ -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,9 @@ 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 );
524
589
 
525
590
  rb_define_singleton_method( rant_mAnt, "log_directory=", rant_s_log_directory_eq, 1 );
526
591
 
@@ -537,6 +602,7 @@ Init_ant_ext()
537
602
  EXPOSE_CONST( ANT_EXT_STRING_SIZE );
538
603
  EXPOSE_CONST( ANT_EXT_MESG_BITFIELD_DEVICE_ID );
539
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) );
540
606
  EXPOSE_CONST( ANT_EXT_MESG_BITFIELD_OVERWRITE_SHARED_ADR );
541
607
  EXPOSE_CONST( ANT_EXT_MESG_BITFIELD_TRANSMISSION_TYPE );
542
608
 
@@ -618,6 +684,9 @@ Init_ant_ext()
618
684
  EXPOSE_CONST( CAPABILITIES_SELECTIVE_DATA_UPDATE_ENABLED );
619
685
  EXPOSE_CONST( CAPABILITIES_ENCRYPTED_CHANNEL_ENABLED );
620
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
+
621
690
  EXPOSE_CONST( CHANNEL_NUMBER_MASK );
622
691
  EXPOSE_CONST( SEQUENCE_NUMBER_MASK );
623
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,12 +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
18
-
19
-
20
- # Loggability API -- send logs to the Ant logger
21
- log_to :ant
16
+ extend Loggability,
17
+ Ant::DataUtilities
22
18
 
23
19
 
24
20
  # Mapping of response message IDs to handler methods
@@ -51,17 +47,8 @@ module Ant::Channel::EventCallbacks
51
47
  SEQUENCE_NUMBER_MASK = 0xE0
52
48
 
53
49
 
54
- ### Default callback hook -- handles event callbacks.
55
- def handle_event_callback( channel_num, event_id, data )
56
- handler_method = HANDLER_METHODS[ event_id ] or
57
- raise "Unhandled channel event %p" % [ event_id ]
58
-
59
- if self.respond_to?( handler_method )
60
- self.public_send( handler_method, channel_num, data )
61
- else
62
- Ant::Channel::EventCallbacks.log_event_callback( channel_num, handler_method, event_id, data )
63
- end
64
- end
50
+ # Loggability API -- send logs to the Ant logger
51
+ log_to :ant
65
52
 
66
53
 
67
54
  ### Log the channel event by default.
@@ -75,13 +62,25 @@ module Ant::Channel::EventCallbacks
75
62
  end
76
63
 
77
64
 
65
+ ### Default callback hook -- handles event callbacks.
66
+ def handle_event_callback( channel_num, event_id, data )
67
+ handler_method = Ant::Channel::EventCallbacks::HANDLER_METHODS[ event_id ] or
68
+ raise "Unhandled channel event %p" % [ event_id ]
69
+
70
+ if self.respond_to?( handler_method )
71
+ self.public_send( handler_method, channel_num, data )
72
+ else
73
+ Ant::Channel::EventCallbacks.log_event_callback( channel_num, handler_method, event_id, data )
74
+ end
75
+ end
76
+
77
+
78
78
  ### Handle an TX event.
79
79
  def on_event_tx( channel_num, data )
80
- # self.log.info "Broadcast message on channel %d was transmitted." % [ channel_num ]
81
-
82
- # data = SecureRandom.bytes( 8 )
83
- # self.log.debug "Sending our own broadcast data: %p." % [ data ]
84
- # 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 )
85
84
  end
86
85
 
87
86
 
@@ -139,18 +138,27 @@ module Ant::Channel::EventCallbacks
139
138
  end
140
139
 
141
140
 
142
- # def on_event_rx_flag_acknowledged( channel_num, data )
143
- #
144
- # end
141
+ def on_event_rx_flag_acknowledged( channel_num, data )
142
+ flags = data.bytes[ 9 ]
143
+ if flags & Ant::ANT_EXT_MESG_BITFIELD_DEVICE_ID
144
+ usDeviceNumber = data.bytes[10] | (data.bytes[11] << 8)
145
+ ucDeviceType = data.bytes[12]
146
+ ucTransmissionType = data.bytes[13]
147
+ self.log.debug "Got an acknowledge on Chan ID(%d/%d/%d)" %
148
+ [usDeviceNumber, ucDeviceType, ucTransmissionType]
149
+ end
150
+
151
+ self.on_event_rx_acknowledged( channel_num, data )
152
+ end
153
+
145
154
 
146
- ### Handle an RX_FLAG_BURST_PACKET event.
147
155
  def on_event_rx_flag_burst_packet( channel_num, data )
148
156
  flags = data.bytes[ 9 ]
149
157
  if flags & Ant::ANT_EXT_MESG_BITFIELD_DEVICE_ID
150
158
  usDeviceNumber = data.bytes[10] | (data.bytes[11] << 8)
151
159
  ucDeviceType = data.bytes[12]
152
160
  ucTransmissionType = data.bytes[13]
153
- 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)" %
154
162
  [usDeviceNumber, ucDeviceType, ucTransmissionType]
155
163
  end
156
164
 
@@ -158,14 +166,13 @@ module Ant::Channel::EventCallbacks
158
166
  end
159
167
 
160
168
 
161
- ### Handle an RX_FLAG_BROADCAST event.
162
169
  def on_event_rx_flag_broadcast( channel_num, data )
163
170
  flags = data.bytes[ 9 ]
164
171
  if flags & Ant::ANT_EXT_MESG_BITFIELD_DEVICE_ID
165
172
  usDeviceNumber = data.bytes[10] | (data.bytes[11] << 8)
166
173
  ucDeviceType = data.bytes[12]
167
174
  ucTransmissionType = data.bytes[13]
168
- 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)" %
169
176
  [usDeviceNumber, ucDeviceType, ucTransmissionType]
170
177
  end
171
178
 
@@ -173,23 +180,21 @@ module Ant::Channel::EventCallbacks
173
180
  end
174
181
 
175
182
 
176
- # def on_event_rx_acknowledged( channel_num, data )
177
- #
178
- # end
183
+ def on_event_rx_acknowledged( channel_num, data )
184
+ self.log.debug "Acknowledged: Rx [%d]:\n%s" % [ data.bytes[0], Ant::DataUtilities.hexdump(data[1..9]) ]
185
+ end
179
186
 
180
187
 
181
- ### Handle an RX_BURST_PACKET event.
182
188
  def on_event_rx_burst_packet( channel_num, data )
183
189
  channel = (data.bytes[0] & CHANNEL_NUMBER_MASK) >> 5
184
190
  sequence_num = data.bytes[0] & SEQUENCE_NUMBER_MASK
185
191
 
186
- self.log.info "Burst (0x%02x): Rx: %d:\n%s" % [ channel, sequence_num, hexdump(data[1..8]) ]
192
+ self.log.debug "Burst (0x%02x): Rx: %d:\n%s" % [ channel, sequence_num, Ant::DataUtilities.hexdump(data[1..9]) ]
187
193
  end
188
194
 
189
195
 
190
- ### Handle an RX_BROADCAST event.
191
196
  def on_event_rx_broadcast( channel_num, data )
192
- self.log.info "Broadcast: Rx:\n%s" % [ hexdump(data[1..8]) ]
197
+ self.log.debug "Broadcast: Rx [%d]:\n%s" % [ data.bytes[0], Ant::DataUtilities.hexdump(data[1..9]) ]
193
198
  end
194
199
 
195
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
@@ -31,6 +33,7 @@ class Ant::Channel
31
33
 
32
34
 
33
35
  ##
36
+ # :singleton-method: registry
34
37
  # Channel registry, keyed by channel number.
35
38
  singleton_class.attr_reader( :registry )
36
39
 
@@ -43,24 +46,68 @@ class Ant::Channel
43
46
 
44
47
 
45
48
  ### Set up the given +mod+ as the handler module for channel events.
46
- def set_event_handlers( mod=Ant::Channel::EventCallbacks )
47
- self.extend( mod )
48
- self.on_event( &self.method(:handle_event_callback) )
49
+ def set_event_handlers( object=self )
50
+ self.on_event( &object.method(:handle_event_callback) )
51
+ end
52
+
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?
49
94
  end
50
95
 
51
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
+