class PatronusFati::DataModels::Client

Constants

LOCAL_ATTRIBUTE_KEYS

Attributes

access_point_bssids[RW]
last_dbm[RW]
local_attributes[RW]
probes[RW]

Public Class Methods

current_expiration_threshold() click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 10
def self.current_expiration_threshold
  Time.now.to_i - CLIENT_EXPIRATION
end
new(mac) click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 72
def initialize(mac)
  super
  self.access_point_bssids = []
  self.local_attributes = { channel: 0, mac: mac }
  self.probes = {}
end

Public Instance Methods

add_access_point(bssid) click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 14
def add_access_point(bssid)
  access_point_bssids << bssid unless access_point_bssids.include?(bssid)
end
announce_changes() click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 18
def announce_changes
  return unless dirty? && valid? && worth_syncing?

  if active?
    status = new? ? :new : :changed
    PatronusFati.event_handler.event(:client, status, full_state, diagnostic_data)
  else
    PatronusFati.event_handler.event(
      :client, :offline, {
        'bssid' => local_attributes[:mac],
        'uptime' => presence.visible_time
      },
      diagnostic_data
    )

    # We need to reset the first seen so we get fresh duration information
    presence.first_seen = nil

    access_point_bssids.each do |bssid|
      DataModels::AccessPoint[bssid].remove_client(local_attributes[:mac])
      DataModels::Connection["#{bssid}^#{local_attributes[:mac]}"].link_lost = true
    end
  end

  mark_synced
end
cleanup_probes() click to toggle source

Probes don't have an explicit visibility window so this will only remove probes that haven't been seen in the entire duration of the time we track any visibility.

# File lib/patronus_fati/data_models/client.rb, line 48
def cleanup_probes
  return if probes.select { |_, pres| pres.dead? }.empty?
  set_sync_flag(:dirtyChildren)
  probes.reject! { |_, pres| pres.dead? }
end
diagnostic_data() click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 54
def diagnostic_data
  dd = super
  dd[:last_dbm] = last_dbm if last_dbm
  dd[:visible_time] = presence.visible_time
  dd
end
full_state() click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 61
def full_state
  {
    active: active?,
    bssid: local_attributes[:mac],
    channel: local_attributes[:channel],
    connected_access_points: access_point_bssids,
    probes: probes.keys,
    vendor: vendor
  }
end
remove_access_point(bssid) click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 79
def remove_access_point(bssid)
  access_point_bssids.delete(bssid)
end
track_probe(probe) click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 83
def track_probe(probe)
  return unless probe && probe.length > 0

  self.probes[probe] ||= Presence.new
  self.probes[probe].mark_visible
end
update(attrs) click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 90
def update(attrs)
  attrs.each do |k, v|
    next unless LOCAL_ATTRIBUTE_KEYS.include?(k)
    next if v.nil? || local_attributes[k] == v

    set_sync_flag(:dirtyAttributes)
    local_attributes[k] = v
  end
end
valid?() click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 100
def valid?
  !local_attributes[:mac].nil?
end
vendor() click to toggle source
# File lib/patronus_fati/data_models/client.rb, line 104
def vendor
  return unless local_attributes[:mac]
  result = Louis.lookup(local_attributes[:mac])
  result['long_vendor'] || result['short_vendor']
end
worth_syncing?() click to toggle source

This is a safety mechanism to check whether or not a client device is actually 'present'. This is intended to cut out the one time fake generated addresses from devices that generate random MAC addresses, probe quickly and disappear and requires us to either see a client connect to an access point, be visible for more than one interval, or have already been synced.

# File lib/patronus_fati/data_models/client.rb, line 116
def worth_syncing?
  access_point_bssids.any? || sync_flag?(:syncedOnline) || probes.any? ||
    (presence && presence.visible_time && presence.visible_time > INTERVAL_DURATION)
end