Module: Ant::ResponseCallbacks

Extended by:
DataUtilities, Loggability
Defined in:
lib/ant/response_callbacks.rb

Overview

A module that handles response callbacks by logging them.

Constant Summary collapse

HANDLER_METHODS =

Mapping of response message IDs to handler methods

{
  Ant::Message::MESG_STARTUP_MESG_ID              => :on_startup_mesg,

  Ant::Message::MESG_CAPABILITIES_ID              => :on_capabilities,
  Ant::Message::MESG_CHANNEL_STATUS_ID            => :on_channel_status,
  Ant::Message::MESG_VERSION_ID                   => :on_version,
  Ant::Message::MESG_CHANNEL_ID_ID                => :on_channel_id,
  Ant::Message::MESG_EVENT_BUFFERING_CONFIG_ID    => :on_event_buffering_config,
  Ant::Message::MESG_GET_SERIAL_NUM_ID            => :on_get_serial_num,

  Ant::Message::MESG_RESPONSE_EVENT_ID            => :on_response_event,

  Ant::Message::MESG_NETWORK_KEY_ID               => :on_network_key,
  Ant::Message::MESG_ASSIGN_CHANNEL_ID            => :on_assign_channel,
  Ant::Message::MESG_UNASSIGN_CHANNEL_ID          => :on_unassign_channel,
  Ant::Message::MESG_CHANNEL_RADIO_FREQ_ID        => :on_channel_radio_freq,
  Ant::Message::MESG_OPEN_CHANNEL_ID              => :on_open_channel,

  Ant::Message::MESG_RX_EXT_MESGS_ENABLE_ID       => :on_rx_ext_mesgs_enable,
  Ant::Message::MESG_CLOSE_CHANNEL_ID             => :on_close_channel,
  Ant::Message::MESG_REQUEST_ID                   => :on_request,

  Ant::Message::MESG_BROADCAST_DATA_ID            => :on_broadcast_data,
  Ant::Message::MESG_ACKNOWLEDGED_DATA_ID         => :on_acknowledged_data,
  Ant::Message::MESG_BURST_DATA_ID                => :on_burst_data,
  Ant::Message::MESG_ADV_BURST_DATA_ID            => :on_adv_burst_data,

  Ant::Message::MESG_CHANNEL_MESG_PERIOD_ID       => :on_channel_mesg_period,
  Ant::Message::MESG_CHANNEL_SEARCH_TIMEOUT_ID    => :on_channel_search_timeout,

  Ant::Message::MESG_RADIO_TX_POWER_ID            => :on_radio_tx_power,

  Ant::Message::MESG_AUTO_FREQ_CONFIG_ID          => :on_auto_freq_config,
  Ant::Message::MESG_CONFIG_ADV_BURST_ID          => :on_config_adv_burst_id,

  # :TODO: There are many other MESG_ constants, but I think most or all of
  # them are only used for the serial protocol.
}

Constants included from DataUtilities

DataUtilities::VISIBLES

Class Method Summary collapse

Methods included from DataUtilities

hexdump

Class Method Details

.handle_response_callback(channel_num, message_id, data) ⇒ Object

Default callback hook – handles response callbacks.



62
63
64
65
66
67
68
69
70
71
# File 'lib/ant/response_callbacks.rb', line 62

def self::handle_response_callback( channel_num, message_id, data )
  handler_method = Ant::ResponseCallbacks::HANDLER_METHODS[ message_id ] or
    raise "Unhandled response message ID %p" % [ message_id ]

  if self.respond_to?( handler_method, true )
    self.send( handler_method, channel_num, data )
  else
    Ant::ResponseCallbacks.log_response_callback( channel_num, handler_method, message_id, data )
  end
end

.log_response_callback(channel_num, handler_method, message_id, data) ⇒ Object

Log the response event by default.



75
76
77
78
79
80
81
82
# File 'lib/ant/response_callbacks.rb', line 75

def self::log_response_callback( channel_num, handler_method, message_id, data )
  self.log.debug "Response for channel %d: %#0x (%s): %s" % [
    channel_num,
    message_id,
    handler_method,
    data.bytes[ 0..3 ].map {|b| "%#02x" % b }.join( ' ' )
  ]
end

.log_response_event(channel_num, data, err_desc, log_desc) ⇒ Object

Log a success or an error message for a response event message.



105
106
107
108
109
110
111
112
113
114
# File 'lib/ant/response_callbacks.rb', line 105

def log_response_event( channel_num, data, err_desc, log_desc )
  status = data.bytes[ 2 ]
  channel = Ant::Channel.registry[ channel_num ]

  if status.nonzero?
    self.log.error "Error while %s on %p: %#02x" % [ err_desc, channel, status ]
  else
    self.log.info( log_desc )
  end
end

.on_acknowledged_data(channel_num, data) ⇒ Object

Handle acknowledged_data response event.



210
211
212
# File 'lib/ant/response_callbacks.rb', line 210

def on_acknowledged_data( channel_num, data )
  self.log_response_event( channel_num, data, "sending acked data", "Acked data sent." )
end

.on_assign_channel(channel_num, data) ⇒ Object

Handle channel assignment event response messages.



147
148
149
150
# File 'lib/ant/response_callbacks.rb', line 147

def on_assign_channel( channel_num, data )
  self.log_response_event( channel_num, data, "assigning channel",
    "Channel %d assigned." % [channel_num] )
end

.on_auto_freq_config(channel_num, data) ⇒ Object

Handle on_rx_ext_mesgs_enable response event.



235
236
237
238
# File 'lib/ant/response_callbacks.rb', line 235

def on_auto_freq_config( channel_num, data )
  self.log_response_event( channel_num, data, "enabling frequency agility",
    "Enabled frequency agility." )
end

.on_broadcast_data(channel_num, data) ⇒ Object

Handle broadcast_data response event.



204
205
206
# File 'lib/ant/response_callbacks.rb', line 204

def on_broadcast_data( channel_num, data )
  self.log_response_event( channel_num, data, "sending broadcast data", "Sent broadcast data." )
end

.on_burst_data(channel_num, data) ⇒ Object

Handle burst_data response event.



216
217
218
# File 'lib/ant/response_callbacks.rb', line 216

def on_burst_data( channel_num, data )
  self.log_response_event( channel_num, data, "sending burst data", "Burst data sent." )
end

.on_capabilities(channel_num, data) ⇒ Object

Handle capabilities response event.



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/ant/response_callbacks.rb', line 290

def on_capabilities( channel_num, data )
  std_opts  = Ant::BitVector.new( data.bytes[2] )
       adv_opts  = Ant::BitVector.new( data.bytes[3] )
       adv_opts2 = Ant::BitVector.new( data.bytes[4] )
       adv_opts3 = Ant::BitVector.new( data.bytes[6] )
       adv_opts4 = Ant::BitVector.new( data.bytes[7] )

  caps = {
    max_channels: data.bytes[0],
    max_networks: data.bytes[1],
    max_sensrcore_channels: data.bytes[5],

    rx_channels_enabled: std_opts.off?( Ant::CAPABILITIES_NO_RX_CHANNELS ),
    tx_channels_enabled: std_opts.off?( Ant::CAPABILITIES_NO_TX_CHANNELS ),
    rx_messages_enabled: std_opts.off?( Ant::CAPABILITIES_NO_RX_MESSAGES ),
    tx_messages_enabled: std_opts.off?( Ant::CAPABILITIES_NO_TX_MESSAGES ),
    ackd_messages_enabled: std_opts.off?( Ant::CAPABILITIES_NO_ACKD_MESSAGES ),
    burst_transfer_enabled: std_opts.off?( Ant::CAPABILITIES_NO_BURST_TRANSFER ),

    overun_underrun: adv_opts.on?( Ant::CAPABILITIES_OVERUN_UNDERRUN ),
    network_enabled: adv_opts.on?( Ant::CAPABILITIES_NETWORK_ENABLED ),
    api_version2: adv_opts.on?( Ant::CAPABILITIES_AP1_VERSION_2 ),
    serial_number_enabled: adv_opts.on?( Ant::CAPABILITIES_SERIAL_NUMBER_ENABLED ),
    per_channel_tx_power_enabled: adv_opts.on?( Ant::CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED ),
    low_priority_search_enabled: adv_opts.on?( Ant::CAPABILITIES_LOW_PRIORITY_SEARCH_ENABLED ),
    script_enabled: adv_opts.on?( Ant::CAPABILITIES_SCRIPT_ENABLED ),
    search_list_enabled: adv_opts.on?( Ant::CAPABILITIES_SEARCH_LIST_ENABLED ),

    led_enabled: adv_opts2.on?( Ant::CAPABILITIES_LED_ENABLED ),
    ext_message_enabled: adv_opts2.on?( Ant::CAPABILITIES_EXT_MESSAGE_ENABLED ),
    scan_mode_enabled: adv_opts2.on?( Ant::CAPABILITIES_SCAN_MODE_ENABLED ),
    prox_search_enabled: adv_opts2.on?( Ant::CAPABILITIES_PROX_SEARCH_ENABLED ),
    ext_assign_enabled: adv_opts2.on?( Ant::CAPABILITIES_EXT_ASSIGN_ENABLED ),
    antfs_enabled: adv_opts2.on?( Ant::CAPABILITIES_FS_ANTFS_ENABLED ),
    fit1_enabled: adv_opts2.on?( Ant::CAPABILITIES_FIT1_ENABLED ),

    advanced_burst_enabled: adv_opts3.on?( Ant::CAPABILITIES_ADVANCED_BURST_ENABLED ),
    event_buffering_enabled: adv_opts3.on?( Ant::CAPABILITIES_EVENT_BUFFERING_ENABLED ),
    event_filtering_enabled: adv_opts3.on?( Ant::CAPABILITIES_EVENT_FILTERING_ENABLED ),
    high_duty_search_mode_enabled: adv_opts3.on?( Ant::CAPABILITIES_HIGH_DUTY_SEARCH_MODE_ENABLED ),
    active_search_sharing_mode_enabled: adv_opts3.on?( Ant::CAPABILITIES_ACTIVE_SEARCH_SHARING_MODE_ENABLED ),
    selective_data_update_enabled: adv_opts3.on?( Ant::CAPABILITIES_SELECTIVE_DATA_UPDATE_ENABLED ),
    encrypted_channel_enabled: adv_opts3.on?( Ant::CAPABILITIES_ENCRYPTED_CHANNEL_ENABLED ),

    rfactive_notification_enabled: adv_opts4.on?( Ant::CAPABILITIES_RFACTIVE_NOTIFICATION_ENABLED ),
  }.freeze

  caplist = caps.keys.select do |cap|
    caps[ cap ]
  end
  self.log.info "ANT Capabilities: %s" % [ caplist.sort.join(' ') ]

  Ant.instance_variable_set( :@capabilities, caps );
end

.on_channel_id(channel_num, data) ⇒ Object

Handle channel ID event response messages.



161
162
163
# File 'lib/ant/response_callbacks.rb', line 161

def on_channel_id( channel_num, data )
  self.log_response_event( channel_num, data, "setting channel ID", "Channel ID set." )
end

.on_channel_mesg_period(channel_num, data) ⇒ Object

Handle channel_mesg_period response events.



186
187
188
# File 'lib/ant/response_callbacks.rb', line 186

def on_channel_mesg_period( channel_num, data )
  self.log_response_event( channel_num, data, "setting channel period", "Channel period assigned." )
end

.on_channel_radio_freq(channel_num, data) ⇒ Object

Handle redio frequency event response messages.



167
168
169
170
# File 'lib/ant/response_callbacks.rb', line 167

def on_channel_radio_freq( channel_num, data )
  self.log_response_event( channel_num, data, "setting channel radio frequency",
    "Channel radio frequency set." )
end

.on_channel_search_timeout(channel_num, data) ⇒ Object

Handle channel_search_timeout response event.



192
193
194
# File 'lib/ant/response_callbacks.rb', line 192

def on_channel_search_timeout( channel_num, data )
  self.log_response_event( channel_num, data, "setting search timeout", "Search timeout." )
end

.on_channel_status(channel_num, data) ⇒ Object

Handle channel_status response event.



222
223
224
# File 'lib/ant/response_callbacks.rb', line 222

def on_channel_status( channel_num, data )
  self.log_response_event( channel_num, data, "requesting channel status", "Got channel status." )
end

.on_close_channel(channel_num, data) ⇒ Object

Handle channel close event response messages.



180
181
182
# File 'lib/ant/response_callbacks.rb', line 180

def on_close_channel( channel_num, data )
  self.log_response_event( channel_num, data, "closing channel", "Channel closed." )
end

.on_config_adv_burst_id(type, data) ⇒ Object

Handle callback when requesting advanced burst configuration.



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/ant/response_callbacks.rb', line 242

def on_config_adv_burst_id( type, data )
  self.log.debug "Advanced burst config/capabilities: 0x%02x: %p" % [ type, data ]

  # Advanced burst capabilities
  if type == 0
    max_packet_length, features = data.unpack( 'CV' )
    features = Ant::BitVector.new( features )

    caps = {
      max_packet_length: max_packet_length,
      frequency_hopping: features.on?( Ant::ADV_BURST_CONFIG_FREQ_HOP )
    }

    self.log.info "Advanced burst capabilities: %p" % [ caps ]
    Ant.instance_variable_set( :@advanced_burst_capabilities, caps );

  # Advanced burst current configuration
  elsif type == 1
    enabled, max_packet_length, required, optional, stall_count, retry_count =
      data.unpack( 'CCVVvC' )
    required = Ant::BitVector.new( required )
    optional = Ant::BitVector.new( optional )

    required_features = []
    required_features << :frequency_hopping if required.on?( Ant::ADV_BURST_CONFIG_FREQ_HOP )

    optional_features = []
    optional_features << :frequency_hopping if optional.on?( Ant::ADV_BURST_CONFIG_FREQ_HOP )

    config = {
      enabled: enabled == 1,
      max_packet_length: max_packet_length,
      required_features: required_features,
      optional_features: optional_features,
      stall_count: stall_count,
      retry_count_extension: retry_count
    }

    self.log.info "Advanced burst configuration: %p" % [ config ]
    Ant.instance_variable_set( :@advanced_burst_config, config );

  else
    self.log.warn "Unknown advanced burst response type %p." % [ type ]
  end
end

.on_get_serial_num(channel_num, data) ⇒ Object

Handle serial number response event.



347
348
349
350
351
352
# File 'lib/ant/response_callbacks.rb', line 347

def on_get_serial_num( channel_num, data )
  serial = data.unpack1( 'L<' )

  self.log.debug "ANT device serial number: %d." % [ serial ]
  Ant.instance_variable_set( :@serial_num, serial )
end

.on_network_key(channel_num, data) ⇒ Object

Handle network key event response messages.



141
142
143
# File 'lib/ant/response_callbacks.rb', line 141

def on_network_key( channel_num, data )
  self.log_response_event( channel_num, data, "setting network key", "Network key set" )
end

.on_open_channel(channel_num, data) ⇒ Object

Handle channel open event response messages.



174
175
176
# File 'lib/ant/response_callbacks.rb', line 174

def on_open_channel( channel_num, data )
  self.log_response_event( channel_num, data, "opening channel", "Channel opened." )
end

.on_radio_tx_power(channel_num, data) ⇒ Object

Handle radio_tx_power response event.



198
199
200
# File 'lib/ant/response_callbacks.rb', line 198

def on_radio_tx_power( channel_num, data )
  self.log_response_event( channel_num, data, "setting transmit power", "Transmit power changed." )
end

.on_request(channel_num, data) ⇒ Object

Handle request response event.



356
357
358
# File 'lib/ant/response_callbacks.rb', line 356

def on_request( channel_num, data )
  self.log_response_event( channel_num, data, "requesting an unsupported message", "[n/a]" )
end

.on_response_event(channel_num, data) ⇒ Object

Handle event response messages.



98
99
100
101
# File 'lib/ant/response_callbacks.rb', line 98

def on_response_event( channel_num, data )
  response_event = data.bytes[ 1 ]
  self.handle_response_callback( channel_num, response_event, data )
end

.on_rx_ext_mesgs_enable(channel_num, data) ⇒ Object

Handle on_rx_ext_mesgs_enable response event.



228
229
230
231
# File 'lib/ant/response_callbacks.rb', line 228

def on_rx_ext_mesgs_enable( channel_num, data )
  self.log_response_event( channel_num, data, "enabling extended message: not supported",
    "Enabled extended messages." )
end

.on_startup_mesg(channel_num, data) ⇒ Object

Handle startup response messages.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/ant/response_callbacks.rb', line 118

def on_startup_mesg( channel_num, data )
  reason = case data.bytes[ 0 ]
    when Ant::RESET_POR
      "RESET_POR"
    when Ant::RESET_SUSPEND
      "RESET_SUSPEND "
    when Ant::RESET_SYNC
      "RESET_SYNC "
    when Ant::RESET_CMD
      "RESET_CMD "
    when Ant::RESET_WDT
      "RESET_WDT "
    when Ant::RESET_RST
      "RESET_RST "
    else
      "UNKNOWN REASON"
    end

  self.log.info "Reset complete: %s" % [ reason ]
end

.on_unassign_channel(channel_num, data) ⇒ Object

Handle channel unassignment event response messages.



154
155
156
157
# File 'lib/ant/response_callbacks.rb', line 154

def on_unassign_channel( channel_num, data )
  self.log_response_event( channel_num, data, "unassigning channel",
    "Channel %d unassigned." % [channel_num] )
end

.on_version(channel_num, data) ⇒ Object

Handle version number response messages.



90
91
92
93
94
# File 'lib/ant/response_callbacks.rb', line 90

def on_version( channel_num, data )
  version = data.strip
  self.log.info "ANT Version %s" % [ version ]
  Ant.instance_variable_set( :@hardware_version, version )
end