Пример #1
0
    def test_client_association_dummy(self):
        sta = env.Station.create()

        debug("Connect dummy STA to wlan0")
        env.agents[0].radios[0].vaps[0].associate(sta)
        debug(
            "Send client association control request to the chosen BSSID (UNBLOCK)"
        )
        env.beerocks_cli_command('client_allow {} {}'.format(
            sta.mac, env.agents[0].radios[1].mac))
        time.sleep(1)

        debug(
            "Confirming Client Association Control Request message was received (UNBLOCK)"
        )
        self.check_log(env.agents[0].radios[1],
                       r"Got client allow request for {}".format(sta.mac))

        debug("Send client association control request to all other (BLOCK) ")
        env.beerocks_cli_command('client_disallow {} {}'.format(
            sta.mac, env.agents[0].radios[0].mac))
        time.sleep(1)

        debug(
            "Confirming Client Association Control Request message was received (BLOCK)"
        )
        self.check_log(env.agents[0].radios[0],
                       r"Got client disallow request for {}".format(sta.mac))
Пример #2
0
def _docker_wait_for_log(container: str, program: str, regex: str, start_line: int,
                         timeout: float) -> bool:
    logfilename = os.path.join(rootdir, 'logs', container, 'beerocks_{}.log'.format(program))
    # WSL doesn't support symlinks on NTFS, so resolve the symlink manually
    if on_wsl:
        logfilename = os.path.join(
            rootdir, 'logs', container,
            subprocess.check_output(["tail", "-2", logfilename]).decode('utf-8').
            rstrip(' \t\r\n\0'))

    deadline = time.monotonic() + timeout
    try:
        while True:
            with open(logfilename) as logfile:
                for (i, v) in enumerate(logfile.readlines()):
                    if i <= start_line:
                        continue
                    search = re.search(regex, v)
                    if search:
                        debug("Found '{}'\n\tin {}".format(regex, logfilename))
                        return (True, i, search.groups())
            if time.monotonic() < deadline:
                time.sleep(.3)
            else:
                err("Can't find '{}'\n\tin log of {} on {} after {}s".format(regex, program,
                                                                             container, timeout))
                return (False, start_line, None)
    except OSError:
        err("Can't read log of {} on {}".format(program, container))
        return (False, start_line, None)
    def runTest(self):
        # Locate test participants
        agent = self.dev.DUT.agent_entity
        controller = self.dev.lan.controller_entity
        sta = self.dev.wifi

        # Regression check
        # Don't connect nonexistent Station
        self.dev.DUT.wired_sniffer.start(self.__class__.__name__ + "-" + self.dev.DUT.name)
        sta_mac = "11:11:33:44:55:66"
        debug("Send link metrics query for unconnected STA")
        controller.ucc_socket.dev_send_1905(agent.mac, 0x800D,
                                            tlv(0x95, 0x0006, '{sta_mac}'.format(sta_mac=sta_mac)))
        self.check_log(agent,
                       "client with mac address {sta_mac} not found".format(sta_mac=sta_mac))
        time.sleep(1)

        debug('sta: {}'.format(sta.mac))
        sta.wifi_connect_check(agent.radios[0].vaps[0])

        time.sleep(1)

        mid = controller.ucc_socket.dev_send_1905(agent.mac, 0x800D,
                                                  tlv(0x95, 0x0006,
                                                      '{sta_mac}'.format(sta_mac=sta.mac)))
        time.sleep(1)
        self.check_log(agent,
                       "Send AssociatedStaLinkMetrics to controller, mid = {}".format(mid),
                       timeout=20)
Пример #4
0
    def test_client_association(self):
        debug("Send topology request to agent 1")
        env.controller.dev_send_1905(env.agents[0].mac, 0x0002)
        debug("Confirming topology query was received")
        self.check_log(env.agents[0], r"TOPOLOGY_QUERY_MESSAGE")

        debug("Send client association control message")
        env.controller.dev_send_1905(
            env.agents[0].mac, 0x8016,
            tlv(
                0x9D, 0x000F, "{%s 0x00 0x1E 0x01 {0x000000110022}}" %
                env.agents[0].radios[0].mac))  # noqa E501

        debug(
            "Confirming client association control message has been received on agent"
        )
        # check that both radio agents received it,in the future we'll add a check to verify which
        # radio the query was intended for.
        self.check_log(env.agents[0].radios[0],
                       r"CLIENT_ASSOCIATION_CONTROL_REQUEST_MESSAGE")
        self.check_log(env.agents[0].radios[1],
                       r"CLIENT_ASSOCIATION_CONTROL_REQUEST_MESSAGE")

        debug("Confirming ACK message was received on controller")
        self.check_log(env.controller, r"ACK_MESSAGE")
Пример #5
0
    def check_cmdu_type(
        self, msg: str, msg_type: int, eth_src: str, eth_dst: str = None, mid: int = None
    ) -> [sniffer.Packet]:
        """Verify that the wired sniffer has captured a CMDU.

        Mark failure if the CMDU is not found.

        Parameters
        ----------
        msg: str
            Message to show in case of failure. It is formatted in a context like
            "No CMDU <msg> found".

        msg_type: int
            CMDU message type that is expected.

        eth_src: str
            MAC address of the sender that is expected.

        eth_dst: str
            MAC address of the destination that is expected. If omitted, the IEEE1905.1 multicast
            MAC address is used.

        mid: int
            Message Identifier that is expected. If omitted, the MID is not checked.

        Returns
        -------
        [sniffer.Packet]
            The matching packets.
        """
        debug("Checking for CMDU {} (0x{:04x}) from {}".format(msg, msg_type, eth_src))
        result = self.dev.DUT.wired_sniffer.get_cmdu_capture_type(msg_type, eth_src, eth_dst, mid)
        assert result, "No CMDU {} found".format(msg)
        return result
Пример #6
0
 def start(self, outputfile_basename):
     '''Start tcpdump to outputfile.'''
     debug("Starting tcpdump, output file {}.pcap".format(
         outputfile_basename))
     os.makedirs(os.path.join(self.tcpdump_log_dir, 'logs'), exist_ok=True)
     self.current_outputfile = os.path.join(self.tcpdump_log_dir,
                                            outputfile_basename) + ".pcap"
     self.checkpoint_frame_number = 0
     command = [
         "tcpdump", "-i", self.interface, '-U', '-w',
         self.current_outputfile, "ether proto 0x88CC or ether proto 0x893A"
     ]
     self.tcpdump_proc = subprocess.Popen(command, stderr=subprocess.PIPE)
     # tcpdump takes a while to start up. Wait for the appropriate output before continuing.
     # poll() so we exit the loop if tcpdump terminates for any reason.
     while not self.tcpdump_proc.poll():
         line = self.tcpdump_proc.stderr.readline()
         debug(line.decode()[:-1])  # strip off newline
         if line.startswith(b"tcpdump: listening on " +
                            self.interface.encode()):
             # Make sure it doesn't block due to stderr buffering
             self.tcpdump_proc.stderr.close()
             break
     else:
         err("tcpdump terminated")
         self.tcpdump_proc = None
         self.current_outputfile = None
Пример #7
0
    def check_cmdu_has_tlvs(
        self, packet: sniffer.Packet, tlv_type: int
    ) -> [sniffer.Tlv]:
        '''Check that the packet has at least one TLV of the given type.

        Mark failure if no TLV of that type is found.

        Parameters
        ----------
        packet: Union[sniffer.Packet]
            The packet to verify. If it is empty or it is not an IEEE1905
            packet, an AssertionError is raised.

        tlv_type: int
            The type of TLV to look for.

        Returns
        -------
        [sniffer.Tlv]
            List of TLVs of the requested type. An AssertionError is raised if
            no TLV is found.
        '''
        assert packet, "No packet found"
        assert packet.ieee1905, "Packet is not IEEE1905: {}".format(packet)
        tlvs = [tlv for tlv in packet.ieee1905_tlvs if tlv.tlv_type == tlv_type]
        if not tlvs:
            debug("  {}".format(packet))
            assert False, "No TLV of type 0x{:02x} found in packet".format(tlv_type)
        return tlvs
Пример #8
0
    def test_higher_layer_data_payload_trigger(self):
        mac_gateway_hex = '0x' + env.controller.mac.replace(':', '')
        debug("mac_gateway_hex = " + mac_gateway_hex)
        payload = 199 * (mac_gateway_hex + " ") + mac_gateway_hex

        debug("Send Higher Layer Data message")
        # MCUT sends Higher Layer Data message to CTT Agent1 by providing:
        # Higher layer protocol = "0x00"
        # Higher layer payload = 200 concatenated copies of the ALID of the MCUT (1200 octets)
        mid = env.controller.dev_send_1905(
            env.agents[0].mac, 0x8018, tlv(0xA0, 0x04b1,
                                           "{0x00 %s}" % payload))

        debug("Confirming higher layer data message was received in the agent")

        self.check_log(env.agents[0], r"HIGHER_LAYER_DATA_MESSAGE")

        debug("Confirming matching protocol and payload length")

        self.check_log(env.agents[0], r"protocol: 0")
        self.check_log(env.agents[0], r"payload_length: 0x4b0")

        debug("Confirming ACK message was received in the controller")
        self.check_log(env.controller,
                       r"ACK_MESSAGE, mid=0x{:04x}".format(mid))
Пример #9
0
    def test_client_association_link_metrics(self):
        ''' This test verifies that a MAUT with an associated STA responds to
        an Associated STA Link Metrics Query message with an Associated STA Link Metrics
        Response message containing an Associated STA Link Metrics TLV for the associated STA.'''

        sta_mac = "11:11:33:44:55:66"
        debug("Send link metrics query for unconnected STA")
        env.controller.dev_send_1905(
            env.agents[0].mac, 0x800D,
            tlv(0x95, 0x0006, '{sta_mac}'.format(sta_mac=sta_mac)))
        self.check_log(
            env.agents[0],
            "client with mac address {sta_mac} not found".format(
                sta_mac=sta_mac))
        time.sleep(1)

        sta = env.Station.create()
        debug('sta: {}'.format(sta.mac))

        env.agents[0].radios[0].vaps[0].associate(sta)

        time.sleep(1)

        mid = env.controller.dev_send_1905(
            env.agents[0].mac, 0x800D,
            tlv(0x95, 0x0006, '{sta_mac}'.format(sta_mac=sta.mac)))
        time.sleep(1)
        self.check_log(
            env.agents[0],
            "Send AssociatedStaLinkMetrics to controller, mid = {}".format(
                mid))
Пример #10
0
    def check_cmdu(
            self, msg: str,
            match_function: Callable[[sniffer.Packet],
                                     bool]) -> [sniffer.Packet]:
        """Verify that the wired_sniffer has captured a CMDU that satisfies match_function.

        Mark failure if no satisfying packet is found.

        Parameters
        ----------
        msg: str
            Message to show in case of failure. It is formatted in a context like
            "No CMDU <msg> found".

        match_function: Callable[[sniffer.Packet], bool]
            A function that returns True if it is the expected packet. It is called on every
            packet returned by Sniffer.get_packet_capture until it returns True.

        Returns
        -------
        [sniffer.Packet]
            The matching packets.
        """
        debug("Checking for CMDU {}".format(msg))
        capture = env.wired_sniffer.get_packet_capture()
        result = [
            packet for packet in capture
            if packet.ieee1905 and match_function(packet)
        ]
        if not result:
            self.fail("No CMDU {} found".format(msg))
        return result
Пример #11
0
    def check_cmdu(
        self, msg: str, match_function: Callable[[sniffer.Packet], bool]
    ) -> [sniffer.Packet]:
        """Verify that the wired_sniffer has captured a CMDU that satisfies match_function.

        Mark failure if no satisfying packet is found.

        Parameters
        ----------
        msg: str
            Message to show in case of failure. It is formatted in a context like
            "No CMDU <msg> found".

        match_function: Callable[[sniffer.Packet], bool]
            A function that returns True if it is the expected packet. It is called on every packet
            returned by get_packet_capture.

        Returns
        -------
        [sniffer.Packet]
            The matching packets.
        """
        debug("Checking for CMDU {}".format(msg))
        result = self.dev.DUT.wired_sniffer.get_cmdu_capture(match_function)
        assert result, "No CMDU {} found".format(msg)
        return result
Пример #12
0
 def check_cmdu_type_single(
     self, msg: str, msg_type: int, eth_src: str, eth_dst: str = None, mid: int = None
 ) -> sniffer.Packet:
     '''Like check_cmdu_type, but also check that only a single CMDU is found.'''
     debug("Checking for single CMDU {} (0x{:04x}) from {}".format(msg, msg_type, eth_src))
     cmdus = self.check_cmdu_type(msg, msg_type, eth_src, eth_dst, mid)
     assert len(cmdus) == 1, "Multiple CMDUs {} found".format(msg)
     return cmdus[0]
Пример #13
0
    def test_ap_capability_query(self):
        env.controller.dev_send_1905(env.agents[0].mac, 0x8001)
        time.sleep(1)

        debug("Confirming ap capability query has been received on agent")
        self.check_log(env.agents[0], "AP_CAPABILITY_QUERY_MESSAGE")

        debug(
            "Confirming ap capability report has been received on controller")
        self.check_log(env.controller, "AP_CAPABILITY_REPORT_MESSAGE")
Пример #14
0
 def check_cmdu_has_tlv_single(
     self, packet: Union[sniffer.Packet, None], tlv_type: int
 ) -> sniffer.Tlv:
     '''Like check_cmdu_has_tlvs, but also check that only one TLV of that type is found.'''
     tlvs = self.check_cmdu_has_tlvs(packet, tlv_type)
     if len(tlvs) > 1:
         debug("  {}".format(packet))
         assert False, "More than one ({}) TLVs of type 0x{:02x} found".format(
             len(tlvs), tlv_type)
     return tlvs[0]
Пример #15
0
 def check_no_cmdu_type(
     self, msg: str, msg_type: int, eth_src: str, eth_dst: str = None
 ) -> NoReturn:
     '''Like check_cmdu_type, but check that *no* machting CMDU is found.'''
     debug("Checking for no CMDU {} (0x{:04x}) from {}".format(msg, msg_type, eth_src))
     result = self.dev.DUT.wired_sniffer.get_cmdu_capture_type(msg_type, eth_src, eth_dst)
     if result:
         for packet in result:
             debug("  {}".format(packet))
         assert False, "Unexpected CMDU {}".format(msg)
Пример #16
0
    def test_link_metric_query(self):
        env.controller.dev_send_1905(env.agents[0].mac, 0x0005,
                                     tlv(0x08, 0x0002, "0x00 0x02"))
        time.sleep(1)

        debug("Confirming link metric query has been received on agent")
        self.check_log(env.agents[0], "Received LINK_METRIC_QUERY_MESSAGE")

        debug(
            "Confirming link metric response has been received on controller")
        self.check_log(env.controller, "Received LINK_METRIC_RESPONSE_MESSAGE")
        self.check_log(env.controller, "Received TLV_TRANSMITTER_LINK_METRIC")
        self.check_log(env.controller, "Received TLV_RECEIVER_LINK_METRIC")
Пример #17
0
    def test_combined_infra_metrics(self):
        debug("Send AP Metrics query message to agent 1")
        vap1 = env.agents[0].radios[0].vaps[0]
        vap2 = env.agents[1].radios[1].vaps[0]
        env.controller.dev_send_1905(
            env.agents[0].mac, 0x800B,
            tlv(0x93, 0x0007, "0x01 {%s}" % (vap1.bssid)))
        self.check_log(env.controller, "Received AP_METRICS_RESPONSE_MESSAGE")

        debug("Send AP Metrics query message to agent 2")
        env.controller.dev_send_1905(
            env.agents[1].mac, 0x800B,
            tlv(0x93, 0x0007, "0x01 {%s}" % vap2.bssid))
        self.check_log(env.controller, "Received AP_METRICS_RESPONSE_MESSAGE")

        debug("Send 1905 Link metric query to agent 1 (neighbor gateway)")
        env.controller.dev_send_1905(
            env.agents[0].mac, 0x0005,
            tlv(0x08, 0x0008, "0x01 {%s} 0x02" % env.controller.mac))
        self.check_log(env.agents[0], "Received LINK_METRIC_QUERY_MESSAGE")
        self.check_log(env.controller, "Received LINK_METRIC_RESPONSE_MESSAGE")
        self.check_log(env.controller, "Received TLV_TRANSMITTER_LINK_METRIC")
        self.check_log(env.controller, "Received TLV_RECEIVER_LINK_METRIC")

        # Trigger combined infra metrics
        debug("Send Combined infrastructure metrics message to agent 1")
        env.controller.dev_send_1905(env.agents[0].mac, 0x8013)
        self.check_log(env.agents[0],
                       "Received COMBINED_INFRASTRUCTURE_METRICS")
        self.check_log(env.agents[0], "Received TLV_TRANSMITTER_LINK_METRIC")
        self.check_log(env.agents[0], "Received TLV_RECEIVER_LINK_METRIC")
Пример #18
0
    def get_packet_capture(self):
        '''Get a list of packets from the last started tcpdump.'''
        if not self.current_outputfile:
            err("get_packet_capture but no capture file")
            return []
        tshark_command = ['tshark', '-r', self.current_outputfile, '-T', 'json',
                          '-Y', 'frame.number >= {}'.format(self.checkpoint_frame_number)]
        tshark_result = subprocess.run(tshark_command, stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
        if tshark_result.returncode != 0:
            debug(tshark_result.stderr)
            debug("tshark failed: {}".format(tshark_result.returncode))
        # Regardless of the exit code, try to make something of the JSON that comes out, if any.
        try:
            # tlvs which have the same type are all recorded with the same key therefore we lose
            # all but one of them if we use json.loads(tshark_result.stdout) directly.
            # https://stackoverflow.com/questions/29321677/python-json-parser-allow-duplicate-keys
            def rename_duplicate_key(key, dct):
                counter = 0
                unique_key = key

                while unique_key in dct:
                    counter += 1
                    unique_key = '{} {}'.format(key, counter + 1)
                return unique_key

            def rename_duplicates(pairs):
                dct = OrderedDict()
                for key, value in pairs:
                    if key in dct:
                        key = rename_duplicate_key(key, dct)
                    dct[key] = value

                return dct

            decoder = json.JSONDecoder(object_pairs_hook=rename_duplicates)
            capture = decoder.decode(tshark_result.stdout.decode('utf8'))

            return [Packet(x) for x in capture]
        except json.JSONDecodeError as error:
            err("capture JSON decoding failed: {}".format(error))
            return []
Пример #19
0
 def start(self, outputfile_basename):
     '''Start tcpdump if enabled by config.'''
     if opts.tcpdump:
         debug("Starting tcpdump, output file {}.pcap".format(
             outputfile_basename))
         os.makedirs(os.path.join(opts.tcpdump_dir, 'logs'), exist_ok=True)
         outputfile = os.path.join(opts.tcpdump_dir,
                                   outputfile_basename) + ".pcap"
         command = ["tcpdump", "-i", self.interface, "-w", outputfile]
         self.tcpdump_proc = subprocess.Popen(command,
                                              stderr=subprocess.PIPE)
         # tcpdump takes a while to start up. Wait for the appropriate output before continuing.
         # poll() so we exit the loop if tcpdump terminates for any reason.
         while not self.tcpdump_proc.poll():
             line = self.tcpdump_proc.stderr.readline()
             debug(line.decode()[:-1])  # strip off newline
             if line.startswith(b"tcpdump: listening on " +
                                self.interface.encode()):
                 # Make sure it doesn't block due to stderr buffering
                 self.tcpdump_proc.stderr.close()
                 break
         else:
             err("tcpdump terminated")
             self.tcpdump_proc = None
Пример #20
0
    def test_client_steering_policy(self):
        debug("Send client steering policy to agent 1")
        mid = env.controller.dev_send_1905(
            env.agents[0].mac, 0x8003,
            tlv(0x89, 0x000C,
                "{0x00 0x00 0x01 {0x112233445566 0x01 0xFF 0x14}}")
        )  # noqa E501
        time.sleep(1)
        debug("Confirming client steering policy has been received on agent")

        self.check_log(env.agents[0].radios[0],
                       r"MULTI_AP_POLICY_CONFIG_REQUEST_MESSAGE")
        time.sleep(1)
        debug(
            "Confirming client steering policy ack message has been received on the controller"
        )
        self.check_log(env.controller,
                       r"ACK_MESSAGE, mid=0x{:04x}".format(mid))
Пример #21
0
    def test_multi_ap_policy_config_w_steering_policy(self):
        debug(
            "Send multi-ap policy config request with steering policy to agent 1"
        )
        mid = env.controller.dev_send_1905(
            env.agents[0].mac, 0x8003,
            tlv(
                0x89, 0x000C, "{0x00 0x00 0x01 {%s 0x01 0xFF 0x14}}" %
                env.agents[0].radios[0].mac))  # noqa E501
        time.sleep(1)
        debug(
            "Confirming multi-ap policy config request has been received on agent"
        )

        self.check_log(env.agents[0],
                       r"MULTI_AP_POLICY_CONFIG_REQUEST_MESSAGE")
        time.sleep(1)
        debug(
            "Confirming multi-ap policy config ack message has been received on the controller"
        )
        self.check_log(env.controller,
                       r"ACK_MESSAGE, mid=0x{:04x}".format(mid))
Пример #22
0
def launch_environment_docker(unique_id: str, skip_init: bool = False, tag: str = ""):
    global wired_sniffer
    iface = _get_bridge_interface('prplMesh-net-{}'.format(unique_id))
    wired_sniffer = sniffer.Sniffer(iface, opts.tcpdump_dir)

    gateway = 'gateway-' + unique_id
    repeater1 = 'repeater1-' + unique_id
    repeater2 = 'repeater2-' + unique_id

    if not skip_init:
        command = [os.path.join(rootdir, "tests", "test_gw_repeater.sh"), "-f", "-u", unique_id,
                   "-g", gateway, "-r", repeater1, "-r", repeater2, "-d", "7"]
        if tag:
            command += ["-t", tag]
        wired_sniffer.start('init')
        try:
            subprocess.check_call(command)
        finally:
            wired_sniffer.stop()

    global controller, agents
    controller = ALEntityDocker(gateway, True)
    agents = (ALEntityDocker(repeater1), ALEntityDocker(repeater2))

    debug('controller: {}'.format(controller.mac))
    debug('agent1: {}'.format(agents[0].mac))
    debug('agent1 wlan0: {}'.format(agents[0].radios[0].mac))
    debug('agent1 wlan2: {}'.format(agents[0].radios[1].mac))
    debug('agent2: {}'.format(agents[1].mac))
    debug('agent2 wlan0: {}'.format(agents[1].radios[0].mac))
    debug('agent2 wlan2: {}'.format(agents[1].radios[1].mac))
Пример #23
0
 def test_topology(self):
     mid = env.controller.dev_send_1905(env.agents[0].mac, 0x0002)
     debug("Confirming topology query was received")
     self.check_log(env.agents[0],
                    r"TOPOLOGY_QUERY_MESSAGE.*mid={:d}".format(mid))
Пример #24
0
def launch_environment_docker(unique_id: str, skip_init: bool = False):
    global wired_sniffer
    wired_sniffer = sniffer.Sniffer(_get_bridge_interface(unique_id))

    gateway = 'gateway-' + unique_id
    repeater1 = 'repeater1-' + unique_id
    repeater2 = 'repeater2-' + unique_id

    if not skip_init:
        wired_sniffer.start('init')
        try:
            subprocess.check_call((os.path.join(rootdir, "tests", "test_gw_repeater.sh"),
                                   "-f", "-u", unique_id, "-g", gateway,
                                   "-r", repeater1, "-r", repeater2, "-d", "7"))
        finally:
            wired_sniffer.stop()

    global controller, agents
    controller = ALEntityDocker(gateway, True)
    agents = (ALEntityDocker(repeater1), ALEntityDocker(repeater2))

    debug('controller: {}'.format(controller.mac))
    debug('agent1: {}'.format(agents[0].mac))
    debug('agent1 wlan0: {}'.format(agents[0].radios[0].mac))
    debug('agent1 wlan2: {}'.format(agents[0].radios[1].mac))
    debug('agent2: {}'.format(agents[1].mac))
    debug('agent2 wlan0: {}'.format(agents[1].radios[0].mac))
    debug('agent2 wlan2: {}'.format(agents[1].radios[1].mac))
Пример #25
0
    def test_client_steering_dummy(self):
        sta = env.Station.create()

        debug("Connect dummy STA to wlan0")
        env.agents[0].radios[0].vaps[0].associate(sta)
        debug("Send steer request ")
        env.beerocks_cli_command("steer_client {} {}".format(
            sta.mac, env.agents[0].radios[1].mac))
        time.sleep(1)

        debug(
            "Confirming Client Association Control Request message was received (UNBLOCK)"
        )
        self.check_log(env.agents[0].radios[1], r"Got client allow request")

        debug(
            "Confirming Client Association Control Request message was received (BLOCK)"
        )
        self.check_log(env.agents[0].radios[0], r"Got client disallow request")

        debug(
            "Confirming Client Association Control Request message was received (BLOCK)"
        )
        self.check_log(env.agents[1].radios[0], r"Got client disallow request")

        debug(
            "Confirming Client Association Control Request message was received (BLOCK)"
        )
        self.check_log(env.agents[1].radios[1], r"Got client disallow request")

        debug(
            "Confirming Client Steering Request message was received - mandate"
        )
        self.check_log(env.agents[0].radios[0], r"Got steer request")

        debug("Confirming BTM Report message was received")
        self.check_log(env.controller, r"CLIENT_STEERING_BTM_REPORT_MESSAGE")

        debug("Confirming ACK message was received")
        self.check_log(env.agents[0].radios[0], r"ACK_MESSAGE")

        debug("Disconnect dummy STA from wlan0")
        env.agents[0].radios[0].vaps[0].disassociate(sta)
        # Make sure that controller sees disconnect before connect by waiting a little
        time.sleep(1)

        debug("Connect dummy STA to wlan2")
        env.agents[0].radios[1].vaps[0].associate(sta)
        debug("Confirm steering success by client connected")
        self.check_log(env.controller,
                       r"steering successful for sta {}".format(sta.mac))
        self.check_log(
            env.controller,
            r"sta {} disconnected due to steering request".format(sta.mac))

        # Make sure that all blocked agents send UNBLOCK messages at the end of
        # disallow period (default 25 sec)
        time.sleep(25)

        debug(
            "Confirming Client Association Control Request message was received (UNBLOCK)"
        )
        self.check_log(env.agents[0].radios[0], r"Got client allow request")

        debug(
            "Confirming Client Association Control Request message was received (UNBLOCK)"
        )
        self.check_log(env.agents[1].radios[0], r"Got client allow request")

        debug(
            "Confirming Client Association Control Request message was received (UNBLOCK)"
        )
        self.check_log(env.agents[1].radios[1], r"Got client allow request")
Пример #26
0
    def test_client_steering_mandate(self):
        debug("Send topology request to agent 1")
        env.controller.dev_send_1905(env.agents[0].mac, 0x0002)
        time.sleep(1)
        debug("Confirming topology query was received")
        self.check_log(env.agents[0], "TOPOLOGY_QUERY_MESSAGE")

        debug("Send topology request to agent 2")
        env.controller.dev_send_1905(env.agents[1].mac, 0x0002)
        time.sleep(1)
        debug("Confirming topology query was received")
        self.check_log(env.agents[1], "TOPOLOGY_QUERY_MESSAGE")

        debug(
            "Send Client Steering Request message for Steering Mandate to CTT Agent1"
        )
        env.controller.dev_send_1905(
            env.agents[0].mac, 0x8014,
            tlv(
                0x9B, 0x001b,
                "{%s 0xe0 0x0000 0x1388 0x01 {0x000000110022} 0x01 {%s 0x73 0x24}}"
                % (env.agents[0].radios[0].mac,
                   env.agents[1].radios[0].mac)))  # noqa E501
        time.sleep(1)
        debug(
            "Confirming Client Steering Request message was received - mandate"
        )
        self.check_log(env.agents[0].radios[0], "Got steer request")

        debug("Confirming BTM Report message was received")
        self.check_log(env.controller, "CLIENT_STEERING_BTM_REPORT_MESSAGE")

        debug("Checking BTM Report source bssid")
        self.check_log(
            env.controller,
            "BTM_REPORT from source bssid %s" % env.agents[0].radios[0].mac)

        debug("Confirming ACK message was received")
        self.check_log(env.agents[0].radios[0], "ACK_MESSAGE")

        env.controller.dev_send_1905(
            env.agents[0].mac, 0x8014,
            tlv(0x9B, 0x000C, "{%s 0x00 0x000A 0x0000 0x00}" %
                env.agents[0].radios[0].mac))  # noqa E501
        time.sleep(1)
        debug(
            "Confirming Client Steering Request message was received - Opportunity"
        )
        self.check_log(env.agents[0].radios[0],
                       "CLIENT_STEERING_REQUEST_MESSAGE")

        debug("Confirming ACK message was received")
        self.check_log(env.controller, "ACK_MESSAGE")

        debug("Confirming steering completed message was received")
        self.check_log(env.controller, "STEERING_COMPLETED_MESSAGE")

        debug("Confirming ACK message was received")
        self.check_log(env.agents[0].radios[0], "ACK_MESSAGE")
Пример #27
0
def beerocks_cli_command(command: str) -> bytes:
    '''Execute `command` beerocks_cli command on the controller and return its output.'''
    debug("Send CLI command " + command)
    res = controller.prplmesh_command("bin/beerocks_cli", "-c", command)
    debug("  Response: " + res.decode('utf-8', errors='replace').strip())
    return res
Пример #28
0
    def test_client_capability_query(self):
        sta1 = env.Station.create()
        sta2 = env.Station.create()

        debug("Send client capability query for unconnected STA")
        env.controller.dev_send_1905(
            env.agents[0].mac, 0x8009,
            tlv(0x90, 0x000C, '{} {}'.format(env.agents[0].radios[0].mac,
                                             sta1.mac)))
        time.sleep(1)
        debug("Confirming client capability query has been received on agent")
        # check that both radio agents received it, in the future we'll add a check to verify which
        # radio the query was intended for.
        self.check_log(env.agents[0], r"CLIENT_CAPABILITY_QUERY_MESSAGE")

        debug(
            "Confirming client capability report message has been received on controller"
        )
        self.check_log(env.controller,
                       r"Received CLIENT_CAPABILITY_REPORT_MESSAGE")
        self.check_log(
            env.controller,
            r"Result Code= FAILURE, client MAC= {}, BSSID= {}".format(
                sta1.mac, env.agents[0].radios[0].mac))

        debug("Connect dummy STA to wlan0")
        env.agents[0].radios[0].vaps[0].associate(sta2)

        debug("Send client capability query for connected STA")
        env.controller.dev_send_1905(
            env.agents[0].mac, 0x8009,
            tlv(0x90, 0x000C, '{} {}'.format(env.agents[0].radios[0].mac,
                                             sta2.mac)))
        time.sleep(1)

        debug(
            "Confirming client capability report message has been received on controller"
        )
        self.check_log(env.controller,
                       r"Received CLIENT_CAPABILITY_REPORT_MESSAGE")
        self.check_log(
            env.controller,
            r"Result Code= SUCCESS, client MAC= {}, BSSID= {}".format(
                sta2.mac, env.agents[0].radios[0].mac))
Пример #29
0
    def test_combined_infra_metrics(self):
        debug("Send AP Metrics query message to agent 1")
        env.controller.dev_send_1905(
            env.agents[0].mac, 0x800B,
            tlv(0x93, 0x0007, "0x01 {%s}" % (env.agents[0].radios[0].mac)))
        self.check_log(env.agents[0].radios[0],
                       "Received AP_METRICS_QUERY_MESSAGE")
        # TODO agent should send response autonomously, with same MID.
        # AP metrics TLV
        tlv1 = tlv(
            0x94, 0x000d,
            "{%s} 0x01 0x0002 0x01 0x1f2f3f" % (env.agents[0].radios[0].mac))
        # STA metrics TLV with no metrics
        tlv2 = tlv(0x96, 0x0007, "{55:44:33:22:11:00} 0x00")
        # STA metrics TLV for STA connected to this BSS
        tlv3 = tlv(
            0x96, 0x001a,
            "{66:44:33:22:11:00} 0x01 {%s} 0x11223344 0x1a2a3a4a 0x1b2b3b4b 0x55"
            % env.agents[0].radios[0].mac)  # noqa E501
        # STA traffic stats TLV for same STA
        tlv4 = tlv(
            0xa2, 0x0022,
            "{55:44:33:22:11:00} 0x10203040 0x11213141 0x12223242 0x13233343 0x14243444 0x15253545 0x16263646"
        )  # noqa E501
        env.agents[0].dev_send_1905(env.controller.mac, 0x800C, tlv1, tlv2,
                                    tlv3, tlv4)
        self.check_log(env.controller, "Received AP_METRICS_RESPONSE_MESSAGE")

        debug("Send AP Metrics query message to agent 2")
        env.controller.dev_send_1905(
            env.agents[1].mac, 0x800B,
            tlv(0x93, 0x0007, "0x01 {%s}" % env.agents[1].radios[1].mac))
        self.check_log(env.agents[1].radios[1],
                       "Received AP_METRICS_QUERY_MESSAGE")
        # TODO agent should send response autonomously
        # Same as above but with different STA MAC addresses, different values and
        # skipping the empty one
        tlv1 = tlv(
            0x94, 0x000d,
            "{%s} 0x01 0x0002 0x01 0x1f2f3f" % (env.agents[1].radios[1].mac))
        tlv3 = tlv(
            0x96, 0x001a,
            "{77:44:33:22:11:00} 0x01 {%s} 0x19293949 0x10203040 0x11213141 0x99"
            % env.agents[1].radios[1].mac)  # noqa E501
        tlv4 = tlv(
            0xa2, 0x0022,
            "{77:44:33:22:11:00} 0xa0203040 0xa1213141 0xa2223242 0xa3233343 0xa4243444 0xa5253545 0xa6263646"
        )  # noqa E501
        env.agents[1].dev_send_1905(env.controller.mac, 0x800C, tlv1, tlv3,
                                    tlv4)
        self.check_log(env.controller, "Received AP_METRICS_RESPONSE_MESSAGE")

        debug("Send 1905 Link metric query to agent 1 (neighbor gateway)")
        env.controller.dev_send_1905(
            env.agents[0].mac, 0x0005,
            tlv(0x08, 0x0008, "0x01 {%s} 0x02" % env.controller.mac))
        self.check_log(env.agents[0], "Received LINK_METRIC_QUERY_MESSAGE")
        self.check_log(env.controller, "Received LINK_METRIC_RESPONSE_MESSAGE")
        self.check_log(env.controller, "Received TLV_TRANSMITTER_LINK_METRIC")
        self.check_log(env.controller, "Received TLV_RECEIVER_LINK_METRIC")

        # Trigger combined infra metrics
        debug("Send Combined infrastructure metrics message to agent 1")
        env.controller.dev_send_1905(env.agents[0].mac, 0x8013)
        self.check_log(env.agents[0],
                       "Received COMBINED_INFRASTRUCTURE_METRICS")
        self.check_log(env.agents[0], "Received TLV_TRANSMITTER_LINK_METRIC")
        self.check_log(env.agents[0], "Received TLV_RECEIVER_LINK_METRIC")
Пример #30
0
    def test_channel_selection(self):
        debug("Send channel preference query")
        env.controller.dev_send_1905(env.agents[0].mac, 0x8004)
        time.sleep(1)
        debug("Confirming channel preference query has been received on agent")
        self.check_log(env.agents[0].radios[0],
                       "CHANNEL_PREFERENCE_QUERY_MESSAGE")
        self.check_log(env.agents[0].radios[1],
                       "CHANNEL_PREFERENCE_QUERY_MESSAGE")

        debug("Send empty channel selection request")
        cs_req_mid = env.controller.dev_send_1905(env.agents[0].mac, 0x8006,
                                                  tlv(0x00, 0x0000, "{}"))
        time.sleep(1)

        debug(
            "Confirming channel selection request has been received on controller"
        )
        self.check_log(
            env.controller,
            r"CHANNEL_SELECTION_RESPONSE_MESSAGE, mid={}".format(cs_req_mid))

        debug(
            "Confirming empty channel selection request has been received on agent"
        )
        self.check_log(env.agents[0].radios[0],
                       "CHANNEL_SELECTION_REQUEST_MESSAGE")
        self.check_log(env.agents[0].radios[1],
                       "CHANNEL_SELECTION_REQUEST_MESSAGE")

        debug(
            "Confirming OPERATING_CHANNEL_REPORT_MESSAGE message has been received on \
            controller with mid")

        result, ocrm_line, mid_match = self.check_log(
            env.controller, r'.+OPERATING_CHANNEL_REPORT_MESSAGE,\smid=(\d+)')
        if (mid_match):
            debug("Confirming ACK_MESSAGE from the controller \
                with same mid as OPERATING_CHANNEL_REPORT_MESSAGE")
            self.check_log(env.agents[0].radios[0],
                           "ACK_MESSAGE, mid={}".format(mid_match[0]))
            self.check_log(env.agents[0].radios[1],
                           "ACK_MESSAGE, mid={}".format(mid_match[0]))

        tp20dBm = 0x14
        tp21dBm = 0x15

        for payload_transmit_power in (tp20dBm, tp21dBm):
            debug(
                "Send empty channel selection request with changing tx_power_limit"
            )
            cs_req_mid = env.controller.dev_send_1905(
                env.agents[0].mac, 0x8006,
                tlv(
                    0x8D, 0x0007,
                    '{} 0x{:02x}'.format(env.agents[0].radios[0].mac,
                                         payload_transmit_power)),
                tlv(
                    0x8D, 0x0007,
                    '{} 0x{:02x}'.format(env.agents[0].radios[1].mac,
                                         payload_transmit_power)))
            time.sleep(1)

            self.check_log(
                env.controller,
                r"CHANNEL_SELECTION_RESPONSE_MESSAGE, mid={}".format(
                    cs_req_mid))

            self.check_log(env.agents[0].radios[0],
                           "CHANNEL_SELECTION_REQUEST_MESSAGE")
            self.check_log(env.agents[0].radios[1],
                           "CHANNEL_SELECTION_REQUEST_MESSAGE")

            self.check_log(
                env.agents[0].radios[0],
                "tlvTransmitPowerLimit {}".format(payload_transmit_power))
            self.check_log(
                env.agents[0].radios[1],
                "tlvTransmitPowerLimit {}".format(payload_transmit_power))

            self.check_log(env.controller,
                           "tx_power={}".format(payload_transmit_power))

            result, ocrm_line, mid_match = self.check_log(
                env.controller,
                r'.+OPERATING_CHANNEL_REPORT_MESSAGE,\smid=(\d+)', ocrm_line)
            if (result):
                self.check_log(env.agents[0].radios[0],
                               "ACK_MESSAGE, mid={}".format(mid_match[0]))

                self.check_log(env.agents[0].radios[1],
                               "ACK_MESSAGE, mid={}".format(mid_match[0]))

        # payload_wlan0 - request for change channel on 6
        payload_wlan0 = (
            "0x14 "
            "{0x51 {0x0C {0x01 0x02 0x03 0x04 0x05 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D} 0x00}} "
            "{0x52 {0x00 0x00}} "
            "{0x53 {0x08 {0x01 0x02 0x03 0x04 0x05 0x07 0x08 0x09} 0x00}} "
            "{0x54 {0x08 {0x05 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D} 0x00}} "
            "{0x73 {0x00 0x00}} "
            "{0x74 {0x00 0x00}} "
            "{0x75 {0x00 0x00}} "
            "{0x76 {0x00 0x00}} "
            "{0x77 {0x00 0x00}} "
            "{0x78 {0x00 0x00}} "
            "{0x79 {0x00 0x00}} "
            "{0x7A {0x00 0x00}} "
            "{0x7B {0x00 0x00}} "
            "{0x7C {0x00 0x00}} "
            "{0x7D {0x00 0x00}} "
            "{0x7E {0x00 0x00}} "
            "{0x7F {0x00 0x00}} "
            "{0x80 {0x00 0x00}} "
            "{0x81 {0x00 0x00}} "
            "{0x82 {0x00 0x00}} ")

        # payload_wlan2  - request for change channel on 36
        payload_wlan2 = ("0x14 "
                         "{0x51 {0x00 0x00}} "
                         "{0x52 {0x00 0x00}} "
                         "{0x53 {0x00 0x00}} "
                         "{0x54 {0x00 0x00}} "
                         "{0x73 0x03 {0x28 0x2C 0x30} 0x00} "
                         "{0x74 0x01 {0x2C} 0x00} "
                         "{0x75 {0x00 0x00}} "
                         "{0x76 {0x00 0x00}} "
                         "{0x77 {0x00 0x00}} "
                         "{0x78 {0x00 0x00}} "
                         "{0x79 {0x00 0x00}} "
                         "{0x7A {0x00 0x00}} "
                         "{0x7B {0x00 0x00}} "
                         "{0x7C {0x00 0x00}} "
                         "{0x7D {0x00 0x00}} "
                         "{0x7E {0x00 0x00}} "
                         "{0x7F {0x00 0x00}} "
                         "{0x80 0x05 {0x3A 0x6A 0x7A 0x8A 0x9B} 0x00} "
                         "{0x81 {0x00 0x00}} "
                         "{0x82 {0x00 0x00}}")
        """
        Step 1: Trigger channel selection to channel 6 and 36. Check that
                operating channel report was sent.

        Step 2: Trigger channel selection to channel 6 and 36 again - check that
                operating channel report is sent again. This is to catch bugs
                when we don't send channel report when there is no need to
                switch channel
        """
        for i in range(1, 3):
            debug("Send channel selection request, step {}".format(i))
            mid = env.controller.dev_send_1905(
                env.agents[0].mac, 0x8006,
                tlv(0x8B, 0x005F, '{} {}'.format(env.agents[0].radios[0].mac,
                                                 payload_wlan0)),
                tlv(0x8D, 0x0007,
                    '{} 0x{:2x}'.format(env.agents[0].radios[0].mac, tp20dBm)),
                tlv(0x8B, 0x004C, '{} {}'.format(env.agents[0].radios[1].mac,
                                                 payload_wlan2)),
                tlv(0x8D, 0x0007,
                    '{} 0x{:2x}'.format(env.agents[0].radios[1].mac, tp20dBm)))
            time.sleep(1)

            debug(
                "Confirming channel selection request has been received on controller,\
                    step {}".format(i))
            self.check_log(
                env.controller,
                r"CHANNEL_SELECTION_RESPONSE_MESSAGE, mid={}".format(mid))

            debug(
                "Confirming channel selection request has been received on agent,step {}"
                .format(i))

            self.check_log(env.agents[0].radios[0],
                           "CHANNEL_SELECTION_REQUEST_MESSAGE")
            self.check_log(env.agents[0].radios[1],
                           "CHANNEL_SELECTION_REQUEST_MESSAGE")

            debug(
                "Confirming tlvTransmitPowerLimit has been received with correct value on \
                    agent, step {}".format(i))

            self.check_log(env.agents[0].radios[0],
                           "tlvTransmitPowerLimit {}".format(tp20dBm))

            self.check_log(env.agents[0].radios[0],
                           "ACTION_APMANAGER_HOSTAP_CHANNEL_SWITCH_ACS_START")

            self.check_log(env.agents[0].radios[1],
                           "tlvTransmitPowerLimit {}".format(tp20dBm))

            self.check_log(env.agents[0].radios[0],
                           "ACTION_APMANAGER_HOSTAP_CHANNEL_SWITCH_ACS_START")

            debug(
                "Confirming CHANNEL_SELECTION_RESPONSE_MESSAGE has been received, \
                step {}".format(i))

            self.check_log(env.controller,
                           "CHANNEL_SELECTION_RESPONSE_MESSAGE")

            debug(
                "Confirming OPERATING_CHANNEL_REPORT_MESSAGE has been received on \
                controller step {}".format(i))

            result, ocrm_line, mid_match = self.check_log(
                env.controller,
                r'.+OPERATING_CHANNEL_REPORT_MESSAGE,\smid=(\d+)', ocrm_line)

            if (mid_match):
                self.check_log(env.agents[0].radios[0],
                               "ACK_MESSAGE, mid={}".format(mid_match[0]))

                self.check_log(env.agents[0].radios[1],
                               "ACK_MESSAGE, mid={}".format(mid_match[0]))

            debug(
                "Confirming tx_power has been received with correct value on controller, \
                step {}".format(i))
            self.check_log(env.controller, "tx_power={}".format(tp20dBm))