1# Copyright (c) 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5from autotest_lib.client.common_lib import error 6import os 7 8class FrameSender(object): 9 """Context manager for sending management frames.""" 10 11 _sender_count = 0 12 13 def __init__(self, router, frame_type, channel, ssid_prefix=None, 14 num_bss=None, frame_count=None, delay=None, dest_addr=None, 15 probe_resp_footer=None, instance=0): 16 """ 17 @param router: LinuxRouter object router to send frames from. 18 @param frame_type: int management frame type. 19 @param channel: int targeted channel. 20 @param ssid_prefix: string SSID prefix for BSSes in the frames. 21 @param num_bss: int number of BSSes configured for sending frames. 22 @param frame_count: int number of frames to send, frame_count of 0 23 implies infinite number of frames. 24 @param delay: int delay in between frames in milliseconds. 25 @param dest_addr: MAC address of the destination address (DA). 26 @param probe_resp_footer: footer bytes for probe responses. 27 @param instance: int hostapd instance on router to send frames from. 28 """ 29 if router.board == "panther": 30 raise error.TestNAError('Panther router does not support manual ' 31 'beacon frame generation') 32 self._router = router 33 self._channel = channel 34 self._frame_type = frame_type 35 self._ssid_prefix = ssid_prefix 36 self._num_bss = num_bss 37 self._frame_count = frame_count 38 self._delay = delay 39 self._dest_addr = dest_addr 40 self._probe_resp_footer = probe_resp_footer 41 self._ap_interface = router.hostapd_instances[instance].interface 42 self._injection_interface = None 43 self._pid = None 44 45 self._index = FrameSender._sender_count 46 FrameSender._sender_count += 1 47 48 49 def __enter__(self): 50 self._injection_interface = self._router.get_configured_interface( 51 'monitor', same_phy_as=self._ap_interface) 52 self._pid = self._router.send_management_frame( 53 self._injection_interface, 54 self._frame_type, self._channel, ssid_prefix=self._ssid_prefix, 55 num_bss=self._num_bss, frame_count=self._frame_count, 56 delay=self._delay, dest_addr=self._dest_addr, 57 probe_resp_footer=self._probe_resp_footer) 58 return self 59 60 61 def __exit__(self, exception, value, traceback): 62 if self._injection_interface: 63 self._router.release_interface(self._injection_interface) 64 if self._pid: 65 # Kill process and wait for termination. 66 self._router.host.run( 67 'kill {pid};' 68 ' for i in $(seq 1 10); do' 69 ' kill -0 {pid} || break; sleep 0.2;' 70 ' done'.format(pid=self._pid), ignore_status=True) 71 self._router.host.get_file( 72 os.path.join( 73 self._router.logdir, self._router.MGMT_FRAME_SENDER_LOG_FILE), 74 'debug/frame_sender_%d.log' % self._index) 75