• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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