class Panopticon::WlanCapture

Constants

CHAN
DEFAULT_IFNAME
DEFAULT_INTERVAL
LIMIT_IDX

Attributes

channel_walk[R]
current_channel[R]
duration[R]
filesize[R]
utilization[R]
utilization_channel[R]

Public Class Methods

new(ifname=DEFAULT_IFNAME, channels=CHAN, interval = DEFAULT_INTERVAL) click to toggle source
# File lib/panopticon/wlan_capture.rb, line 18
def initialize ifname=DEFAULT_IFNAME, channels=CHAN, interval = DEFAULT_INTERVAL
  @th_shark = nil
  @th_capture = nil
  @black_list = []

  @ifname = ifname || DEFAULT_IFNAME
  @channels = channels || CHAN
  @interval = interval || DEFAULT_INTERVAL

  init_status()

  @wlan_utilization = Panopticon::WlanUtilization.new(@ifname)
end

Public Instance Methods

modify_channels(channels) click to toggle source
# File lib/panopticon/wlan_capture.rb, line 70
def modify_channels channels
  @channels = channels
end
run_capture(fpath) click to toggle source
# File lib/panopticon/wlan_capture.rb, line 32
def run_capture fpath
  init_device()
  init_status()
  start_time = Time.now.to_i

  stdin, stdout, stderr, @th_tshark = *Open3.popen3(
    "tshark -i #{@ifname} -F pcapng -w #{fpath}")

  while @th_tshark.alive?
    sleep 1

    # update status
    @duration = Time.now.to_i - start_time
    @filesize = File.size?(fpath) || 0

    # do something here to run before channel transition
    ary = @wlan_utilization.current_data()
    @utilization_channel = ary[0]
    @utilization = ary[3]

    prev_channel = @current_channel
    @current_chanenl = move_channel(@current_channel, @channels)
    @channel_walk += 1
    $log.debug("channel moved to #{@current_channel} from #{prev_channel} (dur=#{@duration}, size=#{@filesize}, walk=#{@channel_walk}, utilization=#{@utilization} uch=#{@utilization_channel})")
  end
rescue => e
  $log.warn("run_capture detected unknown error (#{e})")
end
stop_capture() click to toggle source
# File lib/panopticon/wlan_capture.rb, line 61
def stop_capture
  if @th_tshark == nil
    $log.err("tried to kill tshark, but it's not executed? (or already dead?)")
    return
  end

  Process.kill("INT", @th_tshark.pid)
end

Private Instance Methods

init_device() click to toggle source
# File lib/panopticon/wlan_capture.rb, line 82
def init_device
  unless @ifname.match(/^(wlan\d+|wlx.+)$/)
    $log.debug("non-wlan device skips device initialization")
    return
  end

  unless system("ip link set #{@ifname} down")
    raise "failed to turn down #{@ifname}"
  end
  unless system("iw #{@ifname} set monitor fcsfail otherbss control")
    raise "failed to set #{@ifname} to monitor mode"
  end
  unless system("ip link set #{@ifname} up")
    raise "failed to turn up #{@ifname}"
  end
  unless system("iw #{@ifname} set channel #{@current_channel}")
    raise "failed to set channel #{@current_channel} on #{@ifname}"
  end
end
init_status() click to toggle source
# File lib/panopticon/wlan_capture.rb, line 75
def init_status
  @duration = 0
  @current_channel = @channels[0] || 1
  @filesize = 0
  @channel_walk = 0
end
move_channel(current, channels) click to toggle source
# File lib/panopticon/wlan_capture.rb, line 102
def move_channel current, channels
  unless @ifname.match(/^(wlan\d+|wlx.+)$/)
    $log.debug("non-wlan device skips channel transition")
    return
  end

  next_channel = pick_channel(current, channels)

  while !system("iw #{@ifname} set channel #{next_channel}")
    # what if we got unplugged ifname? => should we die?
    $log.debug("channel transition failed, added to black list (channel=#{next_channel})")
    @black_list << next_channel
    sleep 1
    next_channel = pick_channel(next_channel, channels)
  end

  @current_channel = next_channel
end
pick_channel(current, channels) click to toggle source
# File lib/panopticon/wlan_capture.rb, line 121
def pick_channel current, channels
  idx = channels.index(current)
  idx += 1
  next_channel = channels[idx % channels.length] || 1

  # we have black list
  while @black_list.include?(next_channel)
    idx += 1
    next_channel = channels[idx % channels.length] || 1
  end

  return next_channel
end