You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
3.2 KiB
75 lines
3.2 KiB
# Copyright (c) 2014 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
from autotest_lib.client.common_lib import error
|
|
import os
|
|
|
|
class FrameSender(object):
|
|
"""Context manager for sending management frames."""
|
|
|
|
_sender_count = 0
|
|
|
|
def __init__(self, router, frame_type, channel, ssid_prefix=None,
|
|
num_bss=None, frame_count=None, delay=None, dest_addr=None,
|
|
probe_resp_footer=None, instance=0):
|
|
"""
|
|
@param router: LinuxRouter object router to send frames from.
|
|
@param frame_type: int management frame type.
|
|
@param channel: int targeted channel.
|
|
@param ssid_prefix: string SSID prefix for BSSes in the frames.
|
|
@param num_bss: int number of BSSes configured for sending frames.
|
|
@param frame_count: int number of frames to send, frame_count of 0
|
|
implies infinite number of frames.
|
|
@param delay: int delay in between frames in milliseconds.
|
|
@param dest_addr: MAC address of the destination address (DA).
|
|
@param probe_resp_footer: footer bytes for probe responses.
|
|
@param instance: int hostapd instance on router to send frames from.
|
|
"""
|
|
if router.board == "panther":
|
|
raise error.TestNAError('Panther router does not support manual '
|
|
'beacon frame generation')
|
|
self._router = router
|
|
self._channel = channel
|
|
self._frame_type = frame_type
|
|
self._ssid_prefix = ssid_prefix
|
|
self._num_bss = num_bss
|
|
self._frame_count = frame_count
|
|
self._delay = delay
|
|
self._dest_addr = dest_addr
|
|
self._probe_resp_footer = probe_resp_footer
|
|
self._ap_interface = router.hostapd_instances[instance].interface
|
|
self._injection_interface = None
|
|
self._pid = None
|
|
|
|
self._index = FrameSender._sender_count
|
|
FrameSender._sender_count += 1
|
|
|
|
|
|
def __enter__(self):
|
|
self._injection_interface = self._router.get_configured_interface(
|
|
'monitor', same_phy_as=self._ap_interface)
|
|
self._pid = self._router.send_management_frame(
|
|
self._injection_interface,
|
|
self._frame_type, self._channel, ssid_prefix=self._ssid_prefix,
|
|
num_bss=self._num_bss, frame_count=self._frame_count,
|
|
delay=self._delay, dest_addr=self._dest_addr,
|
|
probe_resp_footer=self._probe_resp_footer)
|
|
return self
|
|
|
|
|
|
def __exit__(self, exception, value, traceback):
|
|
if self._injection_interface:
|
|
self._router.release_interface(self._injection_interface)
|
|
if self._pid:
|
|
# Kill process and wait for termination.
|
|
self._router.host.run(
|
|
'kill {pid};'
|
|
' for i in $(seq 1 10); do'
|
|
' kill -0 {pid} || break; sleep 0.2;'
|
|
' done'.format(pid=self._pid), ignore_status=True)
|
|
self._router.host.get_file(
|
|
os.path.join(
|
|
self._router.logdir, self._router.MGMT_FRAME_SENDER_LOG_FILE),
|
|
'debug/frame_sender_%d.log' % self._index)
|