Exemple #1
0
    def cleanup(self):
        instance = ByteBlower.InstanceGet()

        self.wireless_endpoint.Lock(False)

        if self.meetingpoint is not None:
            instance.MeetingPointRemove(self.meetingpoint)
Exemple #2
0
    def __setup_byteblower_port(self):
        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        # Connect to the server
        self.server = instance.ServerAdd(self.server_address)

        # create and configure the port.
        self.port = self.server.PortCreate(self.server_interface)

        # configure the MAC address on the port
        port_layer2_config = self.port.Layer2EthIISet()
        port_layer2_config.MacSet(self.port_mac_address)

        # configure the IP addressing on the port
        port_layer3_config = self.port.Layer3IPv4Set()
        if type(self.port_ip_address
                ) is str and self.port_ip_address == 'dhcp':
            # DHCP is configured on the DHCP protocol
            dhcp_protocol = port_layer3_config.ProtocolDhcpGet()
            dhcp_protocol.Perform()
        else:
            # Static addressing
            port_layer3_config.IpSet(self.port_ip_address[0])
            port_layer3_config.NetmaskSet(self.port_ip_address[1])
            port_layer3_config.GatewaySet(self.port_ip_address[2])

        print("Created port", self.port.DescriptionGet())
    def cleanup(self):
        instance = ByteBlower.InstanceGet()

        # Cleanup
        if self.meetingpoint is not None:
            instance.MeetingPointRemove(self.meetingpoint)
        if self.server is not None:
            instance.ServerRemove(self.server)
    def run(self):
        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_an_wireless_endpoint_uuid(
            )

        if self.wireless_endpoint_uuid is None:
            print("The MeetingPoint has no available Wireless Endpoints.")
            print("Aborting the example.")
            return

        # Get the WirelessEndpoint device
        # We don't need to lock the Wireless Endpoint to get the
        # polling results.
        self.wireless_endpoint = self.meetingpoint.DeviceGet(
            self.wireless_endpoint_uuid)
        device_info = self.wireless_endpoint.DeviceInfoGet()
        print("Using wireless endpoint", device_info.GivenNameGet())

        network_info = device_info.NetworkInfoGet()
        interfaces = network_info.InterfaceGet()

        network_interface = None
        for network_interface in interfaces:
            if network_interface.DisplayNameGet() == self.wireless_interface:
                break

        if network_interface is None:
            print("ERROR: could not find the specified interface")
            return 1

        headers = ('"SSID"', '"BSSID"', '"Channel"', '"RSSI (dBm)"',
                   '"Tx Rate (bps)"')
        results = []
        for _ in range(self.duration_s):
            # Synchronize the local API object with the values
            #  cached in the MeetingPoint
            network_info.Refresh()

            # Collect the results and print them out.
            result = ("\"" + network_interface.WiFiSsidGet() + "\"",
                      "\"" + network_interface.WiFiBssidGet() + "\"",
                      network_interface.WiFiChannelGet(),
                      network_interface.WiFiRssiGet(),
                      network_interface.WiFiTxRateGet())
            print(network_interface.DisplayNameGet(), result)

            results.append(result)
            time.sleep(1)

        instance.MeetingPointRemove(self.meetingpoint)
    def cleanup(self):
        for bb_port in self.client_bb_ports:
            self.server.PortDestroy(bb_port)
        if self.server_bb_port:
            self.server.PortDestroy(self.server_bb_port)
            self.server_bb_port = None

        # Disconnect from the ByteBlower server
        if self.server:
            ByteBlower.InstanceGet().ServerRemove(self.server)
            self.server = None
Exemple #6
0
    def cleanup(self):
        instance = ByteBlower.InstanceGet()

        # Cleanup

        for wireless_endpoint in self.wireless_endpoints:
            wireless_endpoint.Lock(False)

        if self.meetingpoint is not None:
            instance.MeetingPointRemove(self.meetingpoint)

        if self.server is not None:
            instance.ServerRemove(self.server)
Exemple #7
0
    def cleanup(self):
        """Clean up the created objects"""
        byteblower_instance = ByteBlower.InstanceGet()
        if self.port_1:
            self.server.PortDestroy(self.port_1)
            self.port_1 = None

        if self.port_2:
            self.server.PortDestroy(self.port_2)
            self.port_2 = None

        if self.server is not None:
            byteblower_instance.ServerRemove(self.server)
            self.server = None
Exemple #8
0
    def run(self):
        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(
            self.wireless_endpoint_uuid)
        device_info = self.wireless_endpoint.DeviceInfoGet()
        print("Using wireless endpoint", device_info.GivenNameGet())

        duration_scenario = 5000000000
        self.wireless_endpoint.ScenarioDurationSet(duration_scenario)

        # Make sure we are the only users for the wireless endpoint
        self.wireless_endpoint.Lock(True)

        # Upload the configuration to the wireless endpoint
        self.wireless_endpoint.Prepare()

        from time import sleep

        # starting the wireless endpoint
        starttime_posix = self.wireless_endpoint.Start()
        # Current POSIX timestamp on the meetingpoint
        current_time_posix = self.meetingpoint.TimestampGet()

        time_to_wait_ns = starttime_posix - current_time_posix
        # Wait 200 ms longer, to make sure the wireless endpoint has started.
        time_to_wait_ns += 200000000

        print("Waiting for", time_to_wait_ns / 1000000000.0,
              "to start the wireless endpoint")
        sleep(time_to_wait_ns / 1000000000.0)

        print("wireless endpoint will be running for",
              duration_scenario / 1000000000.0, "seconds")

        print("Waiting for the test to finish")
        sleep(duration_scenario / 1000000000.0)

        self.wireless_endpoint.Lock(False)
    def __exit__(self, *args, **kwargs):
        instance = ByteBlower.InstanceGet()

        if self.wireless_endpoint is not None:
            self.wireless_endpoint.Lock(False)

        if self.meetingpoint is not None:
            instance.MeetingPointRemove(self.meetingpoint)
            self.meetingpoint = None

        if self.port is not None:
            self.server.PortDestroy(self.port)
            self.port = None

        if self.server is not None:
            instance.ServerRemove(self.server)
            self.server = None
    def __enter__(self):
        instance = ByteBlower.InstanceGet()

        # Connect to the server
        self.server = instance.ServerAdd(self.server_address)

        # create and configure the port.
        self.port = self.server.PortCreate(self.server_interface)

        # configure the MAC address on the port
        port_layer2_config = self.port.Layer2EthIISet()
        port_layer2_config.MacSet(self.port_mac_address)

        # configure the IP addressing on the port
        port_layer3_config = self.port.Layer3IPv4Set()
        if type(self.port_ip_address) is str and self.port_ip_address == 'dhcp':
            # DHCP is configured on the DHCP protocol
            dhcp_protocol = port_layer3_config.ProtocolDhcpGet()
            dhcp_protocol.Perform()
        else:
            # Static addressing
            port_layer3_config.IpSet(self.port_ip_address[0])
            port_layer3_config.NetmaskSet(self.port_ip_address[1])
            port_layer3_config.GatewaySet(self.port_ip_address[2])

        print("Created port", self.port.DescriptionGet())

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(self.wireless_endpoint_uuid)
        print("Using wireless endpoint", self.wireless_endpoint.DescriptionGet())

        # Now we have the correct information to start configuring the flow.

        # Claim the wireless endpoint for ourselves.  This means that nobody
        # but us can use this device.
        self.wireless_endpoint.Lock(True)

        return self
def inspect_trunk(server, trunkbase=''):
    """
        Inspect a trunk-interface of a server to detect connected modems
    """
    byteblower_instance = ByteBlower.InstanceGet()
    server = byteblower_instance.ServerAdd(server)

    ports = []
    for an_bb_interface in server.InterfaceNamesGet():
        if not an_bb_interface.startswith(trunkbase):
            continue

        port = server.PortCreate(an_bb_interface)
        port_l2 = port.Layer2EthIISet()
        port_l2.MacSet(a_mac_address())

        port_l3 = port.Layer3IPv4Set()
        port_l3.ProtocolDhcpGet().PerformAsync()
        ports.append(port)

    responding_ports = []
    for a_port in ports:
        try:
            l3 = a_port.Layer3IPv4Get()
            dhcp = l3.ProtocolDhcpGet()
            dhcp.Perform()
            l3.ResolveAsync(l3.GatewayGet())
            responding_ports.append(a_port)
        except DHCPFailed:
            server.PortDestroy(a_port)

    for a_port in responding_ports:
        l3 = a_port.Layer3IPv4Get()
        gateway_addr = l3.GatewayGet()
        try:
            mac_gw = l3.Resolve(gateway_addr)
            vendor_string = lookup_vendor_name(mac_gw)

            result_format = "%s, %s, %s, %s"
            print(result_format % (a_port.InterfaceNameGet(), l3.IpGet(),
                  mac_gw, vendor_string))
        except AddressResolutionFailed:
            pass

        server.PortDestroy(a_port)
Exemple #12
0
def main(server_address, src_interface, dst_interface, speed_mbps=999):
    byteblower_instance = ByteBlower.InstanceGet()
    server = None
    try:
        server = byteblower_instance.ServerAdd(server_address)

        src = create_port(server, src_interface)
        dst = create_port(server, dst_interface)
        a_mbit = 1e6

        n_req, fps, rx_echo, rx_replies = test_connection(
            src, dst, speed_mbps * a_mbit)
        summary_txt = """
            Send out %d Ping requests at %d Mbit/s (%.2f requests a second)
            %d (%.1f %% ) were received at the destination.
            %d (%.1f %% ) were answered at the source.
            """ % (n_req, speed_mbps, fps, rx_echo,
                   (100. * rx_echo) / n_req, rx_replies,
                   (100. * rx_replies) / n_req)
        print(summary_txt)
    finally:
        if server is not None:
            byteblower_instance.ServerRemove(server)
Exemple #13
0
    def run(self):
        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        self.__setup_byteblower_port()

        http_server = self.__setup_http_server()

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # Get the maximum of devices allowed by the license, so we can limit
        # the number of devices we lock.
        byteblower_license = self.meetingpoint.ServiceInfoGet().LicenseGet()
        max_devices_allowed = byteblower_license.NumberOfWirelessEndpointsGet()

        # If no WirelessEndpoint UUID was given, search an available one.
        if not self.wireless_endpoint_uuids:
            self.wireless_endpoint_uuids = self.select_wireless_endpoint_uuids(
            )

        # Limit the number of wireless endpoints to the number we fetched earlier.
        if len(self.wireless_endpoint_uuids) > max_devices_allowed:
            first_devices = self.wireless_endpoint_uuids[:max_devices_allowed]
            self.wireless_endpoint_uuids = first_devices

        # Get the WirelessEndpoint devices
        self.wireless_endpoints = [
            self.meetingpoint.DeviceGet(uuid)
            for uuid in self.wireless_endpoint_uuids
        ]

        print("Using wireless endpoints:")
        for wireless_endpoint in self.wireless_endpoints:
            print(wireless_endpoint.DescriptionGet())

        # Now we have the correct information to start configuring the flows.
        for wireless_endpoint in self.wireless_endpoints:
            # Claim the wireless endpoint for ourselves.  This means that
            #  nobody but us can use this device.
            print("Locking device", wireless_endpoint.DeviceIdentifierGet())
            try:
                wireless_endpoint.Lock(True)
            except ConfigError as e:
                print("Could not lock!", e.getMessage(), file=sys.stderr)
                raise

        for wireless_endpoint in self.wireless_endpoints:
            self.__setup_http_client(wireless_endpoint, http_server)

        # now the flows are configured and the HTTP server is listening,
        # start the wireless endpoints.

        # Add all the wireless endpoint into a WirelessEndpointList.
        # Our API currently doesn't allow passing a pure python-list.
        all_wireless_endpoints = WirelessEndpointList()
        for wireless_endpoint in self.wireless_endpoints:
            all_wireless_endpoints.append(wireless_endpoint)

        # Send the Scenario to all wireless endpoints
        # Sending the scenario per device would take at least the number of
        # Wireless Endpoints in seconds, since they beat only once per second.
        # Using this technique they get their scenario in the next 2 heartbeats.
        print("Preparing the devices")
        self.meetingpoint.DevicesPrepare(all_wireless_endpoints)

        # Now we will start the wireless endpoints at once.
        # As with prepare, sending the start using the meetingpoint is a lot
        # faster than starting them one by one.  In fact it is the only way
        # to get them started in a coordinated way.
        # The meetingpoint will return the timestamp when the devices will
        # start.
        starttime_ns = self.meetingpoint.DevicesStart(all_wireless_endpoints)
        now_ns = self.meetingpoint.TimestampGet()
        time_to_wait_ns = starttime_ns - now_ns
        time_to_wait = datetime.timedelta(microseconds=time_to_wait_ns / 1000)
        print("Waiting for", time_to_wait.total_seconds(),
              "seconds for the devices to start.")
        time.sleep(time_to_wait.total_seconds())

        print("Devices started.")

        # We need to wait for the devices to become available again
        # This indicates that the scenarios are finished.

        still_running = True
        while still_running:
            time.sleep(1)

            still_running = False
            running_devices = 0

            for wireless_endpoint in self.wireless_endpoints:
                allowed_statusses = [
                    DeviceStatus.Reserved, DeviceStatus.Available
                ]

                # The wireless Endpoint is running a test when it is
                # - Armed
                # - Running
                # If the device is Available or Reserved (= Available + Locked)
                # the device is not running a test.
                if wireless_endpoint.StatusGet() not in allowed_statusses:
                    still_running = True
                    running_devices += 1

            print(running_devices, "running,",
                  len(http_server.ClientIdentifiersGet()), "clients connected")

        print("All devices finished.")

        # Wireless Endpoint has returned. Collect and process the results.

        # It was a new HTTP server. There will thus be only 1 client.
        client_idents = http_server.ClientIdentifiersGet()
        if len(client_idents) == 0:
            print("Nothing connected")
            sys.exit(-1)

        # save the results to CSV, this allows further analysis afterwards
        collected_results = self.collect_results(http_server)

        return collected_results
Exemple #14
0
    def run(self):
        byteblower_instance = ByteBlower.InstanceGet()

        print("Connecting to ByteBlower server %s..." % self.server_address)
        self.server = byteblower_instance.ServerAdd(self.server_address)

        print("Creating ports")
        # Do check the provision_port code. The vlan has
        # a small impact there.
        self.port_1 = self.provision_port(self.port_1_config)
        self.port_2 = self.provision_port(self.port_2_config)

        # Creating the stream where we'll sent the traffic from.
        # Most is the same as the basic IPv4 example.
        stream = self.port_1.TxStreamAdd()
        stream.NumberOfFramesSet(self.number_of_frames)
        stream.InterFrameGapSet(self.interframegap_ns)

        frame = stream.FrameAdd()

        # Collect the basic addressing info for the Tx side.
        # VLAN id handled lower in the code.
        src_ip = self.port_1_config['ip_address']
        src_mac = self.port_1.Layer2EthIIGet().MacGet()

        dst_ip = self.port_2_config['ip_address']
        dst_mac = self.port_1.Layer3IPv4Get().Resolve(dst_ip)

        frame_size = 512
        udp_src = 4096
        udp_dest = 4096
        payload = 'a' * (frame_size - 42)

        from scapy.layers.inet import UDP, IP, Ether
        from scapy.all import Raw

        # We will need to add a VLAN layer in the frame to transmit.
        # In scapy Vlans are represented in the Dot1Q class.
        from scapy.all import Dot1Q

        udp_payload = Raw(payload.encode('ascii', 'strict'))
        udp_header = UDP(dport=udp_dest, sport=udp_src)
        ip_header = IP(src=src_ip, dst=dst_ip)
        eth_header = Ether(src=src_mac, dst=dst_mac)

        # A stream will always send the packet just as configured.
        # When the Tx ByteBlower port has a VLAN, we need to add it to frame to
        # be sent.  The following lines are the only difference compared to
        # the basic IPv4 example.
        if 'vlan' in self.port_1_config:
            vlan_id = self.port_1_config['vlan']
            vlan_header = Dot1Q(vlan=vlan_id)
            scapy_frame = eth_header / vlan_header / ip_header / udp_header / udp_payload
        else:
            scapy_frame = eth_header / ip_header / udp_header / udp_payload

        # As noted above, the remainder of the stream config is the same again.
        frame_content = bytearray(bytes(scapy_frame))
        hexbytes = ''.join((format(b, "02x") for b in frame_content))
        frame.BytesSet(hexbytes)

        # create a trigger to count the number of received frames.
        # Similar to the stream we will need to make a slight modification
        # for the Vlan layer.
        trigger = self.port_2.RxTriggerBasicAdd()

        # The BPF filter on a trigger is promiscous: it will be applied to all
        # traffic that arrives at the Physical interface.
        #
        # When we expect to receive packets with a VLAN, we need to add
        # this element to the filter.
        if 'vlan' in self.port_2_config:
            rx_vlan_id = str(self.port_2_config['vlan'])
            bpf_filter = "vlan {} and ip dst {} and udp port {}".format(
                rx_vlan_id, dst_ip, udp_dest)
        else:
            bpf_filter = "ip dst {} and udp port {}".format(dst_ip, udp_dest)
        trigger.FilterSet(bpf_filter)

        # The above filter was the last change necessary in this method.
        # The remainder, result gathering and cleanup is the same.

        # VLAN info will be list in the port description below.
        print("Current ByteBlower configuration:")
        print("port1:", self.port_1.DescriptionGet())
        print("port2:", self.port_2.DescriptionGet())

        print("Starting traffic")
        trigger.ResultClear()
        stream_history = stream.ResultHistoryGet()
        trigger_history = trigger.ResultHistoryGet()

        duration_ns = self.interframegap_ns * self.number_of_frames
        duration_s = duration_ns / 1000000000 + 1

        # Running the test. No difference here.
        # For more info on specific methods, do look into
        # the API specification (http:\\api.byteblower.com)
        # or the ipv4.py example.
        stream.Start()
        for iteration in range(1, int(duration_s)):
            sleep(1)

            stream_history.Refresh()
            trigger_history.Refresh()

            last_interval_tx = stream_history.IntervalLatestGet()
            last_interval_rx = trigger_history.IntervalLatestGet()

            print("Sent {TX} frames, received {RX} frames".format(
                TX=last_interval_tx.PacketCountGet(),
                RX=last_interval_rx.PacketCountGet()))

        print("Done sending traffic (time elapsed)")

        print("Waiting for a second")
        sleep(1)

        # Collect and show the results.
        stream_result = stream.ResultGet()
        trigger_result = trigger.ResultGet()
        stream_result.Refresh()
        print("Stream result:", stream_result.DescriptionGet())
        trigger_result.Refresh()
        print("Trigger result:", trigger_result.DescriptionGet())

        tx_frames = stream_result.PacketCountGet()
        rx_frames = trigger_result.PacketCountGet()

        print("Sent {TX} frames, received {RX} frames".format(
            TX=tx_frames, RX=rx_frames))

        return [tx_frames, rx_frames]
Exemple #15
0
    def run(self):
        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search for any available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(
            self.wireless_endpoint_uuid)
        device_info = self.wireless_endpoint.DeviceInfoGet()
        logging.info("Using wireless endpoint %s", device_info.GivenNameGet())

        # The network monitor is part of scenario.
        self.wireless_endpoint.Lock(True)
        scenario_duration_ns = int(self.duration.total_seconds() * 1000000000)
        self.wireless_endpoint.ScenarioDurationSet(scenario_duration_ns)

        # Add the monitor to the scenario.
        # The Wi-Fi statistics are captured as soon as the scenario starts.
        monitor = device_info.NetworkInfoMonitorAdd()

        # We want to have history samples every interval_duration seconds.
        # The Wireless Endpoint will take new snapshot every
        # interval_duration_ns.
        interval_duration_s = self.interval_duration.total_seconds()
        interval_duration_ns = int(interval_duration_s * 1e9)
        monitor_history = monitor.ResultHistoryGet()
        monitor_history.SamplingIntervalDurationSet(interval_duration_ns)

        # Start the test-run.
        logging.info("Starting the wireless endpoint")
        self.wireless_endpoint.Prepare()
        start_time = self.wireless_endpoint.Start()

        # Wait for the device to start
        logging.info('Waiting for the wireless endpoint to start')
        current_time = self.meetingpoint.TimestampGet()
        time_to_sleep = (start_time - current_time) / 1000000000
        time.sleep(int(time_to_sleep))

        # Wait for the test to finish
        logging.info('Waiting for the wireless endpoint to finish the test')
        time.sleep(self.duration.total_seconds())

        # Wait for the device to start beating again.
        # Default heartbeat interval is 1 seconds, so lets wait for 2 beats
        logging.info('Waiting for the wireless endpoint to be communicating '
                     'with the server')
        time.sleep(2)

        # Get the results on the wireless endpoint
        logging.info('Fetching the results')
        self.wireless_endpoint.ResultGet()

        logging.info('Parsing the results')
        monitor_history.Refresh()

        # Collect the results from the NetworkInfoMonitor
        headers = ('Time', 'SSID', 'BSSID', 'Channel', 'RSSI (dBm)',
                   'Tx Rate (bps)"')
        logging.info(" ".join(headers))
        # Looping over the collected results.
        for sample in monitor_history.IntervalGet():

            # The moment when this sample was taken.
            timestamp = sample.TimestampGet()

            # Each sample from the interval includes a list of all
            # interfaces active at the point in time.
            interfaces = sample.InterfaceGet()

            for network_interface in interfaces:
                # The results for this interface at this moment.
                is_connected_to_wifi = network_interface.WiFiSsidGet() != ""
                if is_connected_to_wifi:
                    logging.info("%d %s %s %s %d %d %d", timestamp,
                                 network_interface.DisplayNameGet(),
                                 network_interface.WiFiSsidGet(),
                                 network_interface.WiFiBssidGet(),
                                 network_interface.WiFiChannelGet(),
                                 network_interface.WiFiRssiGet(),
                                 network_interface.WiFiTxRateGet())

        return self.collect_results(monitor_history)
Exemple #16
0
 def cleanup(self):
     instance = ByteBlower.InstanceGet()
     if self.meetingpoint is not None:
         instance.MeetingPointRemove(self.meetingpoint)
    def run(self):

        # duration of the samples taken. (nanoseconds)
        sample_duration = 1000000000

        # number of samples to take:
        # ( test_duration / sample_duration) is just enough, so we are doubling
        # this so we have more than enough
        sample_count = int(2 * (self.duration / sample_duration))

        instance = ByteBlower.InstanceGet()

        # Connect to the server
        self.server = instance.ServerAdd(self.server_address)

        # create and configure the port.
        self.port = self.server.PortCreate(self.server_interface)

        # configure the MAC address on the port
        port_layer2_config = self.port.Layer2EthIISet()
        port_layer2_config.MacSet(self.port_mac_address)

        # configure the IP addressing on the port
        port_layer3_config = self.port.Layer3IPv4Set()
        if type(self.port_ip_address) is str and self.port_ip_address == 'dhcp':
            # DHCP is configured on the DHCP protocol
            dhcp_protocol = port_layer3_config.ProtocolDhcpGet()
            dhcp_protocol.Perform()
        else:
            # Static addressing
            port_layer3_config.IpSet(self.port_ip_address[0])
            port_layer3_config.NetmaskSet(self.port_ip_address[1])
            port_layer3_config.GatewaySet(self.port_ip_address[2])

        print("Created port", self.port.DescriptionGet())

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(self.wireless_endpoint_uuid)
        print("Using wireless endpoint", self.wireless_endpoint.DescriptionGet())

        # Now we have the correct information to start configuring the flow.

        # Claim the wireless endpoint for ourselves.  This means that nobody
        # but us can use this device.
        self.wireless_endpoint.Lock(True)

        # Configure the HTTP server, running on the ByteBlower port.
        http_server = self.port.ProtocolHttpServerAdd()
        if self.port_tcp_port is None:
            self.port_tcp_port = random.randint(10000, 40000)

        # Configure the TCP port on which the HTTP server wll listen
        http_server.PortSet(self.port_tcp_port)

        # Configure the receive window.
        http_server.ReceiveWindowScalingEnable(True)
        http_server.ReceiveWindowScalingValueSet(7)

        # Tell the ByteBlower to sample every sample_duration and keep up to
        # sample_count samples (see top of this function)
        http_server.HistorySamplingIntervalDurationSet(sample_duration)
        http_server.HistorySamplingBufferLengthSet(sample_count)

        # A HTTP server will not listen for new connections as long it is not
        # started.  You can compare it to e.g. Apache or nginx, it won't accept
        # new connections as long the daemon is not started.
        http_server.Start()

        print("HTTP server configuration:", http_server.DescriptionGet())

        # Configure the client.
        http_client = self.wireless_endpoint.ProtocolHttpClientAdd()
        # Configure the remote endpoint to which it must connect.
        # This is the IP address and port of the HTTP server configured above
        http_client.RemoteAddressSet(self.port.Layer3IPv4Get().IpGet())
        http_client.RemotePortSet(self.port_tcp_port)

        http_client.RequestDurationSet(self.duration)
        http_client.RequestInitialTimeToWaitSet(0)
        # What will we do? HTTP Get or HTTP PUT?
        http_client.HttpMethodSet(self.http_method)

        http_client.TypeOfServiceSet(self.tos)

        print("HTTP client configuration:", http_client.DescriptionGet())

        # Add a NetworkInfoMonitor, to monitor the RSSI over time :
        device_info = self.wireless_endpoint.DeviceInfoGet()
        self.network_info_monitor = device_info.NetworkInfoMonitorAdd()

        # Send the scenario to the wireless endpoint
        self.wireless_endpoint.Prepare()

        # Start the wireless endpoint.
        # Actually, the function will return earlier, since the MeetingPoint
        # schedules the start some time in the future, to make sure all
        # devices start at the same time.
        self.wireless_endpoint.Start()

        # Wait until the device returns.
        # As long the device is running, the device will be in
        # - DeviceStatus_Starting
        # - DeviceStatus_Running
        # As soon the device has finished the test, it will return to
        # 'DeviceStatus_Reserved', since we have a Lock on the device.
        status = self.wireless_endpoint.StatusGet()
        start_moment = datetime.datetime.now()
        while status != DeviceStatus.Reserved:
            time.sleep(1)
            status = self.wireless_endpoint.StatusGet()
            now = datetime.datetime.now()
            print(str(now), ":: Running for", str(now - start_moment), "::",
                  http_server.ClientIdentifiersGet().size(), "client(s) connected")

        # Wireless Endpoint has returned. Collect and process the results.

        # Fetch the results from the wireless endpoint, they will be stored
        # at the MeetingPoint, we will fetch the results in a following step.
        self.wireless_endpoint.ResultGet()

        # Fetch the results of our created NetworkInfoMonitor
        network_info_history = self.network_info_monitor.ResultHistoryGet()
        network_info_history.Refresh()

        # Fetch the results of our HTTP Server.

        client_idents = http_server.ClientIdentifiersGet()
        if len(client_idents) == 0:
            print("Nothing connected")
            sys.exit(-1)

        client_identifier = client_idents[0]
        http_session = http_server.HttpSessionInfoGet(client_identifier)
        http_hist = http_session.ResultHistoryGet()
        http_hist.Refresh()

        # Now we have all results available in our API, we can process them.

        # We will store results in a list, containing dicts
        # { 'timestamp': ... , 'SSID': ... , 'BSSID': ... , 'throughput': ...
        results = []

        interval_snapshots = network_info_history.IntervalGet()
        for network_info_interval in interval_snapshots:
            # Find the corresponding HTTP snapshot
            timestamp = network_info_interval.TimestampGet()
            try:
                http_interval = http_hist.IntervalGetByTime(timestamp)
                # Get the average througput for this interval
                # type is byteblowerll.byteblower.DataRate
                rate = http_interval.AverageDataSpeedGet()

                rate_bps = rate.bitrate()

            except ConfigError as e:
                print("Couldn't fetch Throughput snapshot for timestamp", timestamp)
                print("Number of NetworkInfo snapshots:", len(interval_snapshots))
                print("Number of HTTP snapshots:", http_hist.IntervalLengthGet())
                print("ConfigError:", e.what())

                rate_bps = 0

            # Get the interfaces stored in this interval
            interfaces = network_info_interval.InterfaceGet()
            # Find the WiFi Interface
            network_interface = self.find_wifi_interface(interfaces)

            result = {
                'timestamp': timestamp,
                'throughput': int(rate_bps),

                # Default values
                'SSID': 'Unknown',
                'BSSID': 'Unknown',
                'RSSI': -127
            }

            if network_interface is None:
                print("WARNING: No WiFi interface found to query on timestamp",
                      timestamp)
            else:
                result.update({
                    'SSID': network_interface.WiFiSsidGet(),
                    'BSSID': network_interface.WiFiBssidGet(),
                    'RSSI': int(network_interface.WiFiRssiGet()),
                })

            results.append(result)

        self.server.PortDestroy(self.port)
        self.wireless_endpoint.Lock(False)
        return results
Exemple #18
0
    def run(self):
        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        # Connect to the server
        self.server = instance.ServerAdd(self.server_address)

        # create and configure the port.
        self.port = self.server.PortCreate(self.server_interface)

        # configure the MAC address on the port
        port_layer2_config = self.port.Layer2EthIISet()
        port_layer2_config.MacSet(self.port_mac_address)

        # configure the IP addressing on the port
        port_layer3_config = self.port.Layer3IPv6Set()
        if (type(self.port_ip_address) is str
                and self.port_ip_address.lower() == 'dhcp'):
            # DHCP is configured on the DHCP protocol
            dhcp_protocol = port_layer3_config.ProtocolDhcpGet()
            dhcp_protocol.Perform()
        elif (type(self.port_ip_address) is str
              and self.port_ip_address.lower() == 'slaac'):
            # wait for stateless autoconfiguration to complete
            port_layer3_config.StatelessAutoconfiguration()
        else:
            # Static addressing
            address = self.port_ip_address[0]
            prefixlength = self.port_ip_address[1]
            ip = "{}/{}".format(address, prefixlength)
            port_layer3_config.IpManualAdd(ip)

        print("Created port", self.port.DescriptionGet())

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(
            self.wireless_endpoint_uuid)
        print("Using wireless endpoint",
              self.wireless_endpoint.DescriptionGet())

        # Now we have the correct information to start configuring the flow.

        # The ByteBlower port will transmit frames to the wireless endpoint,
        # This means we need to create a 'stream' on the ByteBlower port and
        # a Trigger on the WirelessEndpoint

        stream = self.wireless_endpoint.TxStreamAdd()
        stream.InterFrameGapSet(self.interframe_gap_nanoseconds)
        stream.NumberOfFramesSet(self.number_of_frames)

        # a stream needs to send some data, so lets create a frame
        # For the frame, we need:
        # - The destination IP address (The IP address of the ByteBlower port)
        # - The source and destination UDP ports
        #   (we configured this on top of this script)
        # - a payload to transmit.

        port_layer3_config = self.port.Layer3IPv6Get()
        ipv6_addresses = port_layer3_config.IpLinkLocalGet()
        if self.port_ip_address == "dhcp":
            ipv6_addresses = port_layer3_config.IpDhcpGet()
        elif self.port_ip_address == "slaac":
            ipv6_addresses = port_layer3_config.IpStatelessGet()
        elif isinstance(self.port_ip_address, list):
            ipv6_addresses = port_layer3_config.IpManualGet()

        port_ipv6 = None
        for ipv6_address in ipv6_addresses:
            port_ipv6 = ipv6_address.split("/")[0]

        payload = 'a' * (self.frame_size - 42)

        scapy_udp_payload = Raw(payload.encode('ascii', 'strict'))

        payload_array = bytearray(bytes(scapy_udp_payload))

        # The ByteBlower API expects an 'str' as input for the
        # frame.PayloadSet() method, we need to convert the bytearray
        hexbytes = ''.join((format(b, "02x") for b in payload_array))

        frame = stream.FrameAdd()
        frame.PayloadSet(hexbytes)

        stream.DestinationAddressSet(port_ipv6)
        stream.DestinationPortSet(self.udp_dstport)
        stream.SourcePortSet(self.udp_srcport)

        # The trigger on the WirelessEndpoint counts received frames
        # We need
        # - the source UDP port
        # - the destination UDP port
        # - the destination IP address
        trigger = self.port.RxTriggerBasicAdd()

        # Trigger on a ByteBlower port uses BPF
        # Note: We could generate a more effective filter which will only
        #       trigger the traffic, but for demo purposes and taking NAT into
        #       account, we just keep it simple.
        bpf = "ip6 host {} and udp port {}".format(port_ipv6, self.udp_dstport)
        trigger.FilterSet(bpf)

        # Now all configuration is made
        print(stream.DescriptionGet())
        print(trigger.DescriptionGet())

        # Make sure we are the only users for the wireless endpoint
        self.wireless_endpoint.Lock(True)

        # Upload the configuration to the wireless endpoint
        self.wireless_endpoint.Prepare()

        from time import sleep

        # POSIX timestamp in nanoseconds when the wireless endpoint will start
        starttime_posix = self.wireless_endpoint.Start()
        # Current POSIX timestamp on the meetingpoint
        current_time_posix = self.meetingpoint.TimestampGet()

        time_to_wait_ns = starttime_posix - current_time_posix
        # Wait 200 ms longer, to make sure the wireless endpoint has started.
        time_to_wait_ns += 200000000

        print("Waiting for", time_to_wait_ns / 1000000000.0,
              "to start the port")
        sleep(time_to_wait_ns / 1000000000.0)

        duration_ns = self.interframe_gap_nanoseconds * self.number_of_frames
        duration_ns += 1000000000
        print("Port will transmit for", duration_ns / 1000000000.0, "seconds")
        self.port.Start()

        print("Waiting for the test to finish")
        sleep(duration_ns / 1000000000.0)

        # get the results from the wireless endpoint
        self.wireless_endpoint.ResultGet()

        self.wireless_endpoint.Lock(False)

        tx_result = stream.ResultGet()
        tx_result.Refresh()
        rx_result = trigger.ResultGet()
        rx_result.Refresh()

        print("Transmitted", tx_result.PacketCountGet(), "packets")
        print("Received   ", rx_result.PacketCountGet(), "packets")

        return {
            'tx': tx_result.PacketCountGet(),
            'rx': rx_result.PacketCountGet()
        }
Exemple #19
0
    def run(self):
        byteblower_instance = ByteBlower.InstanceGet()

        print("Connecting to ByteBlower server %s..." % self.server_address)
        self.server = byteblower_instance.ServerAdd(self.server_address)

        # Create the port which will be the HTTP server (port_1)
        print("Creating TX port")
        self.port = self.server.PortCreate(self.server_interface)

        # configure the MAC address on the port
        port_layer2_config = self.port.Layer2EthIISet()
        port_layer2_config.MacSet(self.port_mac_address)

        # configure the IP addressing on the port
        port_layer3_config = self.port.Layer3IPv4Set()

        if (type(self.port_ip_address) is str
                and self.port_ip_address == 'dhcp'):
            # DHCP is configured on the DHCP protocol
            dhcp_protocol = port_layer3_config.ProtocolDhcpGet()
            dhcp_protocol.Perform()
        else:
            # Static addressing
            port_layer3_config.IpSet(self.port_ip_address[0])
            port_layer3_config.NetmaskSet(self.port_ip_address[1])
            port_layer3_config.GatewaySet(self.port_ip_address[2])

        # Connect to the meetingpoint
        self.meetingpoint = byteblower_instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(self.wireless_endpoint_uuid)
        print("Using wireless endpoint",
              self.wireless_endpoint.DescriptionGet())

        # the destination MAC is the MAC address of the destination port if
        # the destination port is in the same subnet as the source port,
        # otherwise it will be the MAC address of the gateway.
        # ByteBlower has a function to resolve the correct MAC address in
        # the Layer3 configuration object
        network_info = self.wireless_endpoint.DeviceInfoGet().NetworkInfoGet()
        wireless_endpoint_ipv4 = network_info.IPv4Get()

        port_mac = self.port.Layer2EthIIGet().MacGet()
        port_layer3_config = self.port.Layer3IPv4Get()
        port_ipv4 = port_layer3_config.IpGet()

        # destination MAC must be resolved, since we do not know whether
        # the wireless endpoint is available on the local LAN
        destination_mac = port_layer3_config.Resolve(wireless_endpoint_ipv4)

        payload = 'a' * (self.frame_size - 42)

        duration_ns = self.interframe_gap_nanoseconds * self.number_of_frames

        # Add 2 seconds of rollout, so frames in transit can be counted too
        duration_ns += 2 * 1000 * 1000 * 1000

        # create a latency-enabled trigger.  A trigger is an object which
        # receives data.  The Basic trigger just count packets,
        # a LatencyBasic trigger analyzes the timestamps embedded in the
        # received frame.
        latency_trigger = self.wireless_endpoint.RxLatencyBasicAdd()

        # configure the trigger
        latency_trigger.DurationSet(duration_ns)
        latency_trigger.FilterUdpSourcePortSet(self.udp_srcport)
        latency_trigger.FilterUdpDestinationPortSet(self.udp_dstport)
        latency_trigger.FilterSourceAddressSet(port_ipv4)

        stream = self.port.TxStreamAdd()
        stream.InterFrameGapSet(self.interframe_gap_nanoseconds)
        stream.NumberOfFramesSet(self.number_of_frames)

        from scapy.layers.inet import UDP, IP, Ether
        from scapy.all import Raw
        udp_payload = Raw(payload.encode('ascii', 'strict'))
        udp_header = UDP(dport=self.udp_dstport, sport=self.udp_srcport, chksum=0)
        ip_header = IP(src=port_ipv4, dst=wireless_endpoint_ipv4)
        eth_header = Ether(src=port_mac, dst=destination_mac)
        scapy_frame = eth_header / ip_header / udp_header / udp_payload

        frame_content = bytearray(bytes(scapy_frame))

        # The ByteBlower API expects an 'str' as input for the
        # frame.BytesSet() method, we need to convert the bytearray
        hexbytes = ''.join((format(b, "02x") for b in frame_content))

        # Since a stream transmits frames, we need to tell the stream which
        # frames we want to transmit
        frame = stream.FrameAdd()
        frame.BytesSet(hexbytes)

        # Enable latency for this frame.  The frame frame contents will be
        # altered so it contains a timestamp.
        frame_tag = frame.FrameTagTimeGet()
        frame_tag.Enable(True)

        # Make sure we are the only users for the wireless endpoint
        self.wireless_endpoint.Lock(True)

        # Upload the configuration to the wireless endpoint
        self.wireless_endpoint.Prepare()

        # print the configuration
        # This makes it easy to review what we have done until now
        print("Current ByteBlower configuration:")
        print("port:", self.port.DescriptionGet())
        print("wireless endpoint:", self.wireless_endpoint.DescriptionGet())

        # start the traffic, clear the latency trigger.  Triggers are active
        # as soon they are created, so we may want to clear the data it already
        # has collected.
        print("Starting traffic")
        latency_trigger.ResultClear()

        duration_ns = self.interframe_gap_nanoseconds * self.number_of_frames

        from time import sleep
        # POSIX timestamp in nanoseconds when the wireless endpoint will start
        starttime_posix = self.wireless_endpoint.Start()
        # Current POSIX timestamp on the meetingpoint
        current_time_posix = self.meetingpoint.TimestampGet()

        time_to_wait_ns = starttime_posix - current_time_posix
        # Wait 200 ms longer, to make sure the wireless endpoint has started.
        time_to_wait_ns += 200000000

        print("Waiting for", time_to_wait_ns / 1000000000.0, "to start the port")
        sleep(time_to_wait_ns / 1000000000.0)

        stream.Start()

        print("Waiting for the test to finish")
        sleep(duration_ns / 1000000000.0)

        print("Done sending traffic (time elapsed)")

        # Waiting for a second after the stream is finished.
        # This has the advantage that frames that were transmitted but were
        # not received yet, can be processed by the server
        print("Waiting for a second")
        sleep(1)

        # During the test itself we queried the interval counters, there are
        # also cumulative counters.  The last cumulative counter available in
        # the history is also available as the Result
        self.wireless_endpoint.ResultGet()
        stream_result = stream.ResultGet()
        latency_result = latency_trigger.ResultGet()
        stream_result.Refresh()
        latency_result.Refresh()

        tx_frames = stream_result.PacketCountGet()
        rx_frames = latency_result.PacketCountGet()
        latency_min = 0
        latency_max = 0
        latency_avg = 0
        jitter = 0
        if latency_result.PacketCountValidGet() > 0:
            latency_min = latency_result.LatencyMinimumGet()
            latency_avg = latency_result.LatencyAverageGet()
            latency_max = latency_result.LatencyMaximumGet()
            jitter = latency_result.JitterGet()

        print("Sent {TX} frames, received {RX} frames".format(TX=tx_frames, RX=rx_frames))
        print("Latency (Average, minimum, maximum, jitter): {AVG}ns, {MIN}ns, {MAX}ns, {JIT}ns".format(
            AVG=latency_avg,
            MIN=latency_min,
            MAX=latency_max,
            JIT=jitter
        ))

        # It is considered good practice to clean up your objects.  This tells the ByteBlower server it can
        # clean up its resources.
        self.server.PortDestroy(self.port)
        self.wireless_endpoint.Lock(False)

        return [tx_frames, rx_frames, latency_min, latency_avg, latency_max, jitter]
    def run(self):
        byteblower_instance = ByteBlower.InstanceGet()

        print("Connecting to ByteBlower server %s..." % self.server_address)
        self.server = byteblower_instance.ServerAdd(self.server_address)

        # Create the port which will be the HTTP server (port_1)
        print("Creating TX port")
        self.port_1 = self.provision_port(self.port_1_config)

        print("Creating RX port")
        # Create the port which will be the HTTP client (port_2)
        self.port_2 = self.provision_port(self.port_2_config)

        # now create the stream.
        # A stream transmits frames on the port on which it is created.
        stream = self.port_1.TxStreamAdd()

        # set the number of frames to transmit
        stream.NumberOfFramesSet(self.number_of_frames)

        # set the speed of the transmission
        stream.InterFrameGapSet(self.interframegap_ns)

        # Since a stream transmits frames, we need to tell the stream which
        # frames we want to transmit
        frame = stream.FrameAdd()

        # collect the frame header info.  We need to provide the
        # Layer2 (ethernet) and Layer3 (IPv4) addresses.
        src_ip = self.port_1_config['ip_address']
        src_mac = self.port_1.Layer2EthIIGet().MacGet()

        dst_ip = self.port_2_config['ip_address']

        # the destination MAC is the MAC address of the destination port if
        # the destination port is in the same subnet as the source port,
        # otherwise it will be the MAC address of the gateway.
        # ByteBlower has a function to resolve the correct MAC address in
        # the Layer3 configuration object
        dst_mac = self.port_1.Layer3IPv6Get().Resolve(dst_ip)

        frame_size = 512
        udp_src = 4096
        udp_dest = 4096
        payload = 'a' * (frame_size - 42)

        from scapy.layers.inet6 import UDP, IPv6, Ether
        from scapy.all import Raw
        udp_payload = Raw(payload.encode('ascii', 'strict'))
        udp_header = UDP(dport=udp_dest, sport=udp_src)
        ip_header = IPv6(src=src_ip, dst=dst_ip)
        eth_header = Ether(src=src_mac, dst=dst_mac)
        scapy_frame = eth_header / ip_header / udp_header / udp_payload

        frame_content = bytearray(bytes(scapy_frame))

        # The ByteBlower API expects an 'str' as input for the
        # frame.BytesSet() method, we need to convert the bytearray
        hex_bytes = ''.join((format(b, "02x") for b in frame_content))
        frame.BytesSet(hex_bytes)

        # Create a trigger.  A trigger is an object which receives data.
        # The Basic trigger just count packets
        trigger = self.port_2.RxTriggerBasicAdd()

        # Every trigger needs to know on which frames it will work.
        # The default filter is no filter, so it will analyze every frame,
        # which is not what we want here.
        # We will filter on the destination IP and the destination UDP port
        bpf_filter = "ip6 dst {} and udp port {}".format(dst_ip, udp_dest)
        trigger.FilterSet(bpf_filter)

        # print the configuration, this makes it easy to review what we have
        # done until now
        print("Current ByteBlower configuration:")
        print("port1:", self.port_1.DescriptionGet())
        print("port2:", self.port_2.DescriptionGet())

        # Start the traffic and clear the trigger.
        # Triggers are active as soon they are created, so we may want to clear
        # the data it already has collected.
        print("Starting traffic")
        trigger.ResultClear()
        stream_history = stream.ResultHistoryGet()
        trigger_history = trigger.ResultHistoryGet()

        duration_ns = self.interframegap_ns * self.number_of_frames
        duration_s = duration_ns / 1000000000 + 1

        stream.Start()

        # duration_s is a float, so we need to cast it to an integer first
        for iteration in range(1, int(duration_s)):
            # sleep one second
            sleep(1)

            # Refresh the history, the ByteBlower server will create interval
            # and cumulative results every second (by default).
            # The Refresh method will synchronize the server data with
            # the client.
            stream_history.Refresh()
            trigger_history.Refresh()

            last_interval_tx = stream_history.IntervalLatestGet()
            last_interval_rx = trigger_history.IntervalLatestGet()

            print("Sent {TX} frames, received {RX} frames".format(
                TX=last_interval_tx.PacketCountGet(),
                RX=last_interval_rx.PacketCountGet()))

        print("Done sending traffic (time elapsed)")

        # Waiting for a second after the stream is finished.
        # This has the advantage that frames that were transmitted but not
        # received yet, can be processed by the server
        print("Waiting for a second")
        sleep(1)

        # During the test itself we queried the interval counters, there are
        # also cumulative counters.  The last cumulative counter available in
        # the history is also available as the Result
        stream_result = stream.ResultGet()
        trigger_result = trigger.ResultGet()
        stream_result.Refresh()
        print("Stream result:", stream_result.DescriptionGet())
        trigger_result.Refresh()
        print("Trigger result:", trigger_result.DescriptionGet())

        tx_frames = stream_result.PacketCountGet()
        rx_frames = trigger_result.PacketCountGet()

        print("Sent {TX} frames, received {RX} frames".format(TX=tx_frames,
                                                              RX=rx_frames))

        return [tx_frames, rx_frames]
    def run(self):
        byteblower_instance = ByteBlower.InstanceGet()

        print("Connecting to ByteBlower server %s..." % self.server_address)
        self.server = byteblower_instance.ServerAdd(self.server_address)

        # Create the port which will be the HTTP server (port_1)
        print("Creating HTTP Server port")
        self.server_bb_port = self.provision_port(self.server_bb_port_config)

        print("Creating HTTP Client port")
        # Create the port which will be the HTTP client (port_2)
        self.client_bb_port = self.provision_port(self.client_bb_port_config)

        http_server_ip_address = self.server_bb_port_config['ip_address']

        # create a HTTP server
        http_server = self.server_bb_port.ProtocolHttpServerAdd()
        server_tcp_port = self.server_bb_port_config['tcp_listen_port']
        http_server.PortSet(server_tcp_port)

        # The HTTP Server still needs to be started explicitly. 
        # You'll notice a difference for the HTTP Clients.
        http_server.Start()

        # This section differs from the basic TCP example.
        # We will create multiple clients onto the same the ByteBlowerPort.
        http_clients = []

        # We'll use the max_duration for the stop condition further in
        # the script.
        max_duration = 0

        # Configure each client one-by-one.
        # This part is the same as the basic TCP example.
        for client_config in self.http_client_configs:
            # create a new HTTP Client and configure it.
            # This part is the same for 1 or multiple ones.
            #
            # You can configure multiple clients to connect to the
            # the same server. You can even mix different HTTP Methods.
            http_client = self.client_bb_port.ProtocolHttpClientAdd()

            http_client.RemoteAddressSet(http_server_ip_address)
            http_client.RemotePortSet(server_tcp_port)

            http_client.HttpMethodSet(client_config['http_method'])
            http_client.RequestDurationSet(client_config['duration'])

            # The client configured duration is in nanoseconds, we want to keep
            # the max_duration as simple as 'seconds', so convert the value.
            client_duration_s = client_config['duration'] / 1e9
            max_duration = max(max_duration, client_duration_s)

            # The RequestStartType is the main configuration difference 
            # Between 2 TCP clients and multiple ones. Rather than starting
            # the client directly, we'll schedule when to start.
            http_client.RequestStartTypeSet(RequestStartType.Scheduled)
            http_clients.append(http_client)

        print("Server port:", self.server_bb_port.DescriptionGet())
        print("Client port:", self.client_bb_port.DescriptionGet())

        # This is another difference with the basic TCP example.
        # The Start method on a ByteBlower Port starts all scheduled traffic
        # types.  This example this means all configured HTTPClients.
        self.client_bb_port.Start()

        # Unlike before we now have several HTTPClients running together.
        # This makes determining when the scenario is finished more 
        # complex.
        # Below we show two different stop conditions:
        #    1. a time based one. (required)
        #    2. a client based one. (optional)
        #
        # Always use the time stop-condition. This provides a guaranteed
        # end in case when the flows can't connect. 
        #
        # A little bit of extra_time gives the HTTPClients some time extra
        # to make the actual connection.
        extra_time = 2
        start_moment = time.time()
        time_elapsed = 0
        while time_elapsed <= (extra_time + max_duration):
            time.sleep(1)

            time_elapsed = time.time() - start_moment
            print('%.2fs :: Waiting for clients to finish.' % time_elapsed)

            # Below is the second type of stop condition, a client based one.
            any_client_running = False

            # Consider a client finished when the state is either:
            # - Finished
            # - Error
            finished_states = [
                HTTPRequestStatus.Error,
                HTTPRequestStatus.Finished
            ]

            for http_client in http_clients:
                # Update the local API object with the  with the info on the
                # ByteBlowerServer.
                http_client.Refresh()

                # Check the status.
                status = http_client.RequestStatusGet()
                this_client_running = status not in finished_states
                any_client_running = any_client_running or this_client_running

            # all clients finished?  No need to wait any longer.
            if not any_client_running:
                break

        # Stop the HTTP Server. 
        # This step is optional but has the advantage of stopping traffic
        # to/from the HTTP Clients
        http_server.Stop()

        server_number_of_clients = len(http_server.ClientIdentifiersGet())

        print("")
        print("HTTP Server info     ")
        print("-" * 10)

        print("Connected clients     : {} ".format(server_number_of_clients))
        print("")

        print("HTTP Client info     ")
        print("-" * 10)

        # Process each of the clients.
        results = []
        for client in http_clients:
            results.append(self.process_http_client(client))

        return results
Exemple #22
0
config = {
    'meetingpoint': 'byteblower-tutorial-1300.lab.byteblower.excentis.com'
}


def device_status_to_str(state):
    """
        Convert the value to an actual name.
    """
    for (name, val) in DeviceStatus.__dict__.items():
        if val == state:
            return name


api = ByteBlower.InstanceGet()
meetingPoint = api.MeetingPointAdd(config['meetingpoint'])


def list_devices():
    """
        List Wireless Endpoint devices.
        Returns the results as a list of dictionaries.
    """
    devices_list = []
    for dev in meetingPoint.DeviceListGet():
        devices_list.append({
            'uuid': dev.DeviceIdentifierGet(),
            'name': dev.DeviceInfoGet().GivenNameGet(),
            'state': device_status_to_str(dev.StatusGet())
        })
Exemple #23
0
    def run(self):
        # duration of the samples taken. (nanoseconds)
        sample_duration = 100000000

        # number of samples to take:
        # ( test_duration / sample_duration) is just enough, so we are doubling
        # this so we have more than enough
        sample_count = int(math.ceil(2 * (self.duration / sample_duration)))

        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        # Connect to the server
        self.server = instance.ServerAdd(self.server_address)

        # create and configure the port.
        self.port = self.server.PortCreate(self.server_interface)

        # configure the MAC address on the port
        port_layer2_config = self.port.Layer2EthIISet()
        port_layer2_config.MacSet(self.port_mac_address)

        # configure the IP addressing on the port
        port_layer3_config = self.port.Layer3IPv6Set()
        if (type(self.port_ip_address) is str
                and self.port_ip_address.lower() == 'dhcp'):
            # DHCP is configured on the DHCP protocol
            dhcp_protocol = port_layer3_config.ProtocolDhcpGet()
            dhcp_protocol.Perform()
        elif (type(self.port_ip_address) is str
              and self.port_ip_address.lower() == 'slaac'):
            # wait for stateless autoconfiguration to complete
            port_layer3_config.StatelessAutoconfiguration()
        else:
            # Static addressing
            address = self.port_ip_address[0]
            prefixlength = self.port_ip_address[1]
            ip = "{}/{}".format(address, prefixlength)
            port_layer3_config.IpManualAdd(ip)

        print("Created port", self.port.DescriptionGet())

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(
            self.wireless_endpoint_uuid)
        print("Using wireless endpoint",
              self.wireless_endpoint.DescriptionGet())

        # Now we have the correct information to start configuring the flow.

        # Claim the wireless endpoint for ourselves.  This means that nobody
        # but us can use this device.
        self.wireless_endpoint.Lock(True)

        # Configure the HTTP server, running on the ByteBlower port.
        http_server = self.port.ProtocolHttpServerAdd()
        if self.port_tcp_port is None:
            self.port_tcp_port = random.randint(10000, 40000)

        # Configure the TCP port on which the HTTP server wll listen
        http_server.PortSet(self.port_tcp_port)

        # Configure the receive window.
        http_server.ReceiveWindowScalingEnable(True)
        http_server.ReceiveWindowScalingValueSet(7)

        # Tell the ByteBlower to sample every sample_duration and keep up to
        # sample_count samples (see top of this function)
        http_server.HistorySamplingIntervalDurationSet(sample_duration)
        http_server.HistorySamplingBufferLengthSet(sample_count)

        # A HTTP server will not listen for new connections as long it is not
        # started.  You can compare it to e.g. Apache or nginx, it won't accept
        # new connections as long the daemon is not started.
        http_server.Start()

        print("HTTP server configuration:", http_server.DescriptionGet())

        # Configure the client.
        http_client = self.wireless_endpoint.ProtocolHttpClientAdd()
        # Configure the remote endpoint to which it must connect.
        # This is the IP address and port of the HTTP server configured above
        port_layer3_config = self.port.Layer3IPv6Get()

        ipv6_addresses = port_layer3_config.IpLinkLocalGet()
        if self.port_ip_address == "dhcp":
            ipv6_addresses = port_layer3_config.IpDhcpGet()
        elif self.port_ip_address == "slaac":
            ipv6_addresses = port_layer3_config.IpStatelessGet()
        elif isinstance(self.port_ip_address, list):
            ipv6_addresses = port_layer3_config.IpManualGet()

        address = None
        for ipv6_address in ipv6_addresses:
            address = ipv6_address.split("/")[0]

        http_client.RemoteAddressSet(address)
        http_client.RemotePortSet(self.port_tcp_port)

        http_client.RequestDurationSet(self.duration)
        http_client.RequestInitialTimeToWaitSet(0)
        # What will we do? HTTP Get or HTTP PUT?
        http_client.HttpMethodSet(self.http_method)

        http_client.TypeOfServiceSet(self.tos)
        print("HTTP client configuration:", http_client.DescriptionGet())

        try:
            self.wireless_endpoint.Prepare()
            self.wireless_endpoint.Start()
        except Exception as e:
            print("Error couldn't start the WE")
            print(e.message)
            sys.exit(-1)

        # Wait until the device returns.
        # As long the device is running, the device will be in
        # - DeviceStatus_Starting
        # - DeviceStatus_Running
        # As soon the device has finished the test, it will return to
        # 'DeviceStatus_Reserved', since we have a Lock on the device.
        status = self.wireless_endpoint.StatusGet()
        start_moment = datetime.datetime.now()
        while status != DeviceStatus.Reserved:
            time.sleep(1)
            status = self.wireless_endpoint.StatusGet()
            now = datetime.datetime.now()
            print(str(now), ":: Running for", str(now - start_moment), "::",
                  http_server.ClientIdentifiersGet().size(),
                  "client(s) connected")

        # Wireless Endpoint has returned. Collect and process the results.

        # It was a new HTTP server. There will thus be only 1 client.
        client_idents = http_server.ClientIdentifiersGet()
        if len(client_idents) == 0:
            print("Nothing connected")
            sys.exit(-1)

        first = client_idents[0]

        http_session = http_server.HttpSessionInfoGet(first)
        http_hist = http_session.ResultHistoryGet()

        http_hist.Refresh()

        # save the results to CSV, this allows further analysis afterwards
        collected_results = self.collect_results(http_hist)

        cumulative_result = http_hist.CumulativeLatestGet()
        mbit_s = cumulative_result.AverageDataSpeedGet().MbpsGet()

        print("Average throughput", mbit_s, "Mbps")

        print("Removing the server")
        self.port.ProtocolHttpServerRemove(http_server)
        print("Removing the client")
        self.wireless_endpoint.ProtocolHttpClientRemove(http_client)

        # Cleanup
        self.wireless_endpoint.Lock(False)
        return collected_results
    def run(self):
        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        # Connect to the server
        self.server = instance.ServerAdd(self.server_address)

        # create and configure the port.
        self.port = self.server.PortCreate(self.server_interface)

        # configure the MAC address on the port
        port_layer2_config = self.port.Layer2EthIISet()
        port_layer2_config.MacSet(self.port_mac_address)

        # configure the IP addressing on the port
        port_layer3_config = self.port.Layer3IPv6Set()
        if (type(self.port_ip_address) is str
                and self.port_ip_address.lower() == 'dhcp'):
            # DHCP is configured on the DHCP protocol
            dhcp_protocol = port_layer3_config.ProtocolDhcpGet()
            dhcp_protocol.Perform()
        elif (type(self.port_ip_address) is str
              and self.port_ip_address.lower() == 'slaac'):
            # wait for stateless autoconfiguration to complete
            port_layer3_config.StatelessAutoconfiguration()
        else:
            # Static addressing
            address = self.port_ip_address[0]
            prefixlength = self.port_ip_address[1]
            ip = "{}/{}".format(address, prefixlength)
            port_layer3_config.IpManualAdd(ip)

        print("Created port", self.port.DescriptionGet())

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(
            self.wireless_endpoint_uuid)
        print("Using wireless endpoint",
              self.wireless_endpoint.DescriptionGet())

        # Now we have the correct information to start configuring the flow.

        # The ByteBlower port will transmit frames to the wireless endpoint,
        # This means we need to create a 'stream' on the ByteBlower port
        #  and a Trigger on the WirelessEndpoint

        stream = self.port.TxStreamAdd()
        stream.InterFrameGapSet(self.interframe_gap_nanoseconds)
        stream.NumberOfFramesSet(self.number_of_frames)

        # a stream needs to send some data, so lets create a frame
        # For the frame, we need:
        # - The source MAC address (MAC address of the ByteBlower port
        #   in our case)
        # - The destination MAC address.  This can be the MAC address of the
        #   WirelessEndpoint, a router, ... This will resolved later on.
        # - The source IP address (The IP address of the ByteBlower port)
        # - The destination IP address (The IP address of the WirelessEndpoint)
        # - The source and destination UDP ports (we configured this on top of
        #   this script)
        # - a payload to transmit.

        port_mac = self.port.Layer2EthIIGet().MacGet()
        port_layer3_config = self.port.Layer3IPv6Get()

        ipv6_addresses = port_layer3_config.IpLinkLocalGet()
        if self.port_ip_address == "dhcp":
            ipv6_addresses = port_layer3_config.IpDhcpGet()
        elif self.port_ip_address == "slaac":
            ipv6_addresses = port_layer3_config.IpStatelessGet()
        elif isinstance(self.port_ip_address, list):
            ipv6_addresses = port_layer3_config.IpManualGet()

        port_ipv6 = None
        for ipv6_address in ipv6_addresses:
            port_ipv6 = ipv6_address.split("/")[0]

        # destination MAC must be resolved, since we do not know whether the WE
        # is available on the local LAN
        destination_mac = None
        wireless_endpoint_ipv6 = None
        all_we_addresses = self.select_wireless_endpoint_addresses()
        for address in all_we_addresses:
            wireless_endpoint_ipv6 = address.split('/')[0]
            try:
                destination_mac = port_layer3_config.Resolve(
                    wireless_endpoint_ipv6)
                break
            except:
                pass

        payload = 'a' * (self.frame_size - 42)

        from scapy.layers.inet6 import UDP, IPv6, Ether
        from scapy.all import Raw
        udp_payload = Raw(payload.encode('ascii', 'strict'))
        udp_header = UDP(dport=self.udp_dstport, sport=self.udp_srcport)
        ip_header = IPv6(src=port_ipv6, dst=wireless_endpoint_ipv6)
        eth_header = Ether(src=port_mac, dst=destination_mac)
        scapy_frame = eth_header / ip_header / udp_header / udp_payload

        frame_content = bytearray(bytes(scapy_frame))

        # The ByteBlower API expects an 'str' as input for the
        # frame.BytesSet() method, we need to convert the bytearray
        hexbytes = ''.join((format(b, "02x") for b in frame_content))

        frame = stream.FrameAdd()
        frame.BytesSet(hexbytes)

        # The trigger on the WirelessEndpoint counts received frames
        # We need
        # - the source UDP port
        # - the destination UDP port
        # - the originating IP address
        # - the duration of the session.  This can be calculated from the
        #   stream settings as
        #   interframegap (nanoseconds/frame) * number of frames (frames)
        #   some fixed rollout can be added too
        trigger = self.wireless_endpoint.RxTriggerBasicAdd()

        # Add 2 seconds of rollout, so frames in transit can be counted too
        duration_ns = self.interframe_gap_nanoseconds * self.number_of_frames
        duration_ns += 2000000000

        trigger.DurationSet(duration_ns)
        trigger.FilterUdpSourcePortSet(self.udp_srcport)
        trigger.FilterUdpDestinationPortSet(self.udp_dstport)
        trigger.FilterSourceAddressSet(port_ipv6)

        # Now all configuration is made
        print(stream.DescriptionGet())
        print(trigger.DescriptionGet())

        # Make sure we are the only users for the wireless endpoint
        self.wireless_endpoint.Lock(True)

        # Upload the configuration to the wireless endpoint
        self.wireless_endpoint.Prepare()

        from time import sleep

        # POSIX timestamp in nanoseconds when the wireless endpoint will start
        starttime_posix = self.wireless_endpoint.Start()
        # Current POSIX timestamp on the meetingpoint
        current_time_posix = self.meetingpoint.TimestampGet()

        time_to_wait_ns = starttime_posix - current_time_posix
        # Wait 200 ms longer, to make sure the wireless endpoint has started.
        time_to_wait_ns += 200000000

        print("Waiting for", time_to_wait_ns / 1000000000.0,
              "to start the port")
        sleep(time_to_wait_ns / 1000000000.0)

        print("Port will transmit for", duration_ns / 1000000000.0, "seconds")
        self.port.Start()

        print("Waiting for the test to finish")
        sleep(duration_ns / 1000000000.0)

        # get the results from the wireless endpoint
        self.wireless_endpoint.ResultGet()

        self.wireless_endpoint.Lock(False)

        tx_result = stream.ResultGet()
        tx_result.Refresh()
        rx_result = trigger.ResultGet()
        rx_result.Refresh()

        print("Transmitted", tx_result.PacketCountGet(), "packets")
        print("Received   ", rx_result.PacketCountGet(), "packets")

        return {
            'tx': tx_result.PacketCountGet(),
            'rx': rx_result.PacketCountGet()
        }
Exemple #25
0
    def run(self):
        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        # Connect to the server
        self.server = instance.ServerAdd(self.server_address)

        # create and configure the port.
        self.port = self.server.PortCreate(self.server_interface)

        # configure the MAC address on the port
        port_layer2_config = self.port.Layer2EthIISet()
        port_layer2_config.MacSet(self.port_mac_address)

        # configure the IP addressing on the port
        port_layer3_config = self.port.Layer3IPv4Set()
        if (type(self.port_ip_address) is str
                and self.port_ip_address == 'dhcp'):
            # DHCP is configured on the DHCP protocol
            dhcp_protocol = port_layer3_config.ProtocolDhcpGet()
            dhcp_protocol.Perform()
        else:
            # Static addressing
            port_layer3_config.IpSet(self.port_ip_address[0])
            port_layer3_config.NetmaskSet(self.port_ip_address[1])
            port_layer3_config.GatewaySet(self.port_ip_address[2])

        print("Created port", self.port.DescriptionGet())

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(
            self.wireless_endpoint_uuid)
        print("Using wireless endpoint",
              self.wireless_endpoint.DescriptionGet())

        # The wireless endpoint device info
        device_info = self.wireless_endpoint.DeviceInfoGet()

        # Now we have the correct information to start configuring the flow.

        # The ByteBlower port will transmit frames to the wireless endpoint,
        # This means we need to create a 'stream' on the ByteBlower port
        # and a Trigger on the WirelessEndpoint

        stream = self.wireless_endpoint.TxStreamAdd()
        stream.InterFrameGapSet(self.interframe_gap_nanoseconds)
        number_of_frames = int(self.duration / self.interframe_gap_nanoseconds)
        stream.NumberOfFramesSet(number_of_frames)

        # a stream needs to send some data, so lets create a frame
        # For the frame, we need:
        # - The destination IP address (The IP address of the ByteBlower port)
        # - The source and destination UDP ports (we configured this on top of
        #   this script)
        # - a payload to transmit.

        port_layer3_config = self.port.Layer3IPv4Get()
        port_ipv4 = port_layer3_config.IpGet()

        payload = 'a' * (self.frame_size - 42)
        scapy_udp_payload = Raw(payload.encode('ascii', 'strict'))

        payload_array = bytearray(bytes(scapy_udp_payload))

        # The ByteBlower API expects an 'str' as input for the
        # frame.BytesSet() method, we need to convert the bytearray
        hexbytes = ''.join((format(b, "02x") for b in payload_array))

        frame = stream.FrameAdd()
        frame.PayloadSet(hexbytes)

        stream.DestinationAddressSet(port_ipv4)
        stream.DestinationPortSet(self.udp_dstport)
        stream.SourcePortSet(self.udp_srcport)

        # The trigger on the WirelessEndpoint counts received frames
        # We need
        # - the source UDP port
        # - the destination UDP port
        # - the destination IP address
        trigger = self.port.RxTriggerBasicAdd()

        # Trigger on a ByteBlower port uses BPF
        # Note: We could generate a more effective filter which will only
        #       trigger the traffic, but for demo purposes and taking NAT into
        #       account, we just keep it simple.
        bpf = "ip host %s and udp port %d" % (port_ipv4, self.udp_dstport)
        trigger.FilterSet(bpf)

        # We also want the network information over time,
        # so we can compare the RSSI vs the Loss

        monitor = device_info.NetworkInfoMonitorAdd()

        # Now all configuration is made
        print(stream.DescriptionGet())
        print(trigger.DescriptionGet())
        print(monitor.DescriptionGet())

        # Make sure we are the only users for the wireless endpoint
        self.wireless_endpoint.Lock(True)

        # Upload the configuration to the wireless endpoint
        self.wireless_endpoint.Prepare()

        from time import sleep

        # POSIX timestamp in nanoseconds when the wireless endpoint will start
        starttime_posix = self.wireless_endpoint.Start()
        # Current POSIX timestamp on the meetingpoint
        current_time_posix = self.meetingpoint.TimestampGet()

        time_to_wait_ns = starttime_posix - current_time_posix
        # Wait 200 ms longer, to make sure the wireless endpoint has started.
        time_to_wait_ns += 200000000

        print("Waiting for", time_to_wait_ns / 1000000000.0,
              "to start the port")
        sleep(time_to_wait_ns / 1000000000.0)

        duration_ns = self.duration + 1000000000
        print("Port will transmit for", duration_ns / 1000000000.0, "seconds")
        self.port.Start()

        print("Waiting for the test to finish")
        for i in range(int(duration_ns / 1000000000)):
            # Refresh the stream results
            stream.ResultHistoryGet().Refresh()

            # Refresh the trigger results
            trigger.ResultHistoryGet().Refresh()

            self.wireless_endpoint.Refresh()
            status = self.wireless_endpoint.StatusGet()
            if status in [DeviceStatus.Reserved, DeviceStatus.Unavailable]:
                break
            sleep(1)

        print("Wait for the device to beat")
        # Usually one second
        sleep(1)

        # get the results from the wireless endpoint
        self.wireless_endpoint.ResultGet()

        self.wireless_endpoint.Lock(False)

        stream_history = stream.ResultHistoryGet()
        stream_history.Refresh()
        trigger_history = trigger.ResultHistoryGet()
        trigger_history.Refresh()
        monitor_history = monitor.ResultHistoryGet()
        monitor_history.Refresh()

        results = []

        for network_info_interval in monitor_history.IntervalGet():
            timestamp = network_info_interval.TimestampGet()
            network_interfaces = network_info_interval.InterfaceGet()
            network_interface = self.find_wifi_interface(network_interfaces)

            result = {
                'timestamp': timestamp,
                'rssi': -127,
                'ssid': '',
                'bssid': '',
                'tx_frames': 0,
                'rx_frames': 0,
                'loss': 0,
                'throughput': 0
            }
            if network_interface is not None:
                result['rssi'] = network_interface.WiFiRssiGet()
                result['ssid'] = network_interface.WiFiSsidGet()
                result['bssid'] = network_interface.WiFiBssidGet()

            try:
                stream_interval = stream_history.IntervalGetByTime(timestamp)
                result['tx_frames'] = stream_interval.PacketCountGet()
            except ConfigError as e:
                print("ERROR: Could not get result for stream on timestamp",
                      timestamp, ":", str(e))

            try:
                trigger_interval = trigger_history.IntervalGetByTime(timestamp)
                result['rx_frames'] = trigger_interval.PacketCountGet()

                throughput = self.frame_size * result['rx_frames'] * 8
                result['throughput'] = throughput
            except ConfigError as e:
                print("ERROR: Could not get result for trigger on timestamp",
                      timestamp, ":", str(e))

            if result['tx_frames'] != 0:
                lost_frames = result['tx_frames'] - result['rx_frames']
                loss = lost_frames * 100.0 / result['tx_frames']
                result['loss'] = loss

            results.append(result)

        return results
    def run(self):
        instance = ByteBlower.InstanceGet()
        assert isinstance(instance, ByteBlower)

        # Connect to the server
        self.server = instance.ServerAdd(self.server_address)

        # create and configure the port.
        self.port = self.server.PortCreate(self.server_interface)

        # configure the MAC address on the port
        port_layer2_config = self.port.Layer2EthIISet()
        port_layer2_config.MacSet(self.port_mac_address)

        # configure the IP addressing on the port
        port_layer3_config = self.port.Layer3IPv4Set()
        if type(self.port_ip_address
                ) is str and self.port_ip_address == "dhcp":
            # DHCP is configured on the DHCP protocol
            dhcp_protocol = port_layer3_config.ProtocolDhcpGet()
            dhcp_protocol.Perform()
        else:
            # Static addressing
            port_layer3_config.IpSet(self.port_ip_address[0])
            port_layer3_config.NetmaskSet(self.port_ip_address[1])
            port_layer3_config.GatewaySet(self.port_ip_address[2])

        print("Created port", self.port.DescriptionGet())

        # Connect to the meetingpoint
        self.meetingpoint = instance.MeetingPointAdd(self.meetingpoint_address)

        # If no WirelessEndpoint UUID was given, search an available one.
        if self.wireless_endpoint_uuid is None:
            self.wireless_endpoint_uuid = self.select_wireless_endpoint_uuid()

        # Get the WirelessEndpoint device
        self.wireless_endpoint = self.meetingpoint.DeviceGet(
            self.wireless_endpoint_uuid)
        self.wireless_endpoint.Lock(True)

        device_info = self.wireless_endpoint.DeviceInfoGet()

        # The network monitor is part of scenario.
        self.wireless_endpoint.Lock(True)

        # Add the monitor to the scenario.
        # The Wi-Fi statistics are captured as soon as the scenario starts.
        monitor = device_info.NetworkInfoMonitorAdd()

        traffic_flows = []
        for traffic_config in self.traffic:
            traffic_type = traffic_config["type"]
            if "tcp" == traffic_type:
                traffic_flows.append(
                    TCPTraffic(self.wireless_endpoint, self.port,
                               traffic_config))
            elif "udp" == traffic_type and "up" == traffic_config["direction"]:
                traffic_flows.append(
                    UDPTrafficUp(self.wireless_endpoint, self.port,
                                 traffic_config))
            elif "udp" == traffic_type and "down" == traffic_config[
                    "direction"]:
                traffic_flows.append(
                    UDPTrafficDown(self.wireless_endpoint, self.port,
                                   traffic_config))

        try:
            self.wireless_endpoint.Prepare()
            starttime = self.wireless_endpoint.Start()
            wait_time_ns = starttime - self.meetingpoint.TimestampGet()
            time.sleep(max(0, wait_time_ns / 1e9))
        except Exception as e:
            print("Error couldn't start the WE")
            print(str(e))
            sys.exit(-1)

        print("Starting the ByteBlower")
        self.port.Start()

        # Wait until the device returns.
        # As long the device is running, the device will be in
        # - DeviceStatus_Starting
        # - DeviceStatus_Running
        # As soon the device has finished the test, it will return to
        # 'DeviceStatus_Reserved', since we have a Lock on the device.
        status = self.wireless_endpoint.StatusGet()
        start_moment = datetime.datetime.now()
        while status != DeviceStatus.Reserved:
            time.sleep(1)
            status = self.wireless_endpoint.StatusGet()
            now = datetime.datetime.now()

        # Wireless Endpoint has returned. Collect and process the results.
        self.wireless_endpoint.ResultGet()
        traffic_results = []
        for config, flow in zip(self.traffic, traffic_flows):
            flow_result = flow.gather_results()
            flow_result["config"] = config
            traffic_results.append(flow_result)

        monitor_history = monitor.ResultHistoryGet()
        monitor_history.Refresh()
        monitor_results = []
        for sample in monitor_history.IntervalGet():
            current_sample = {"timestamp": sample.TimestampGet()}
            nics = []
            for network_interface in sample.InterfaceGet():
                current = {
                    "name": network_interface.DisplayNameGet(),
                    "Ssid": network_interface.WiFiSsidGet(),
                    "BSSID": network_interface.WiFiBssidGet(),
                    "Channel": network_interface.WiFiChannelGet(),
                    "RSSI": network_interface.WiFiRssiGet(),
                    "TxRate": network_interface.WiFiTxRateGet(),
                }
                nics.append(current)
            current_sample["interfaces"] = nics
            monitor_results.append(current_sample)

        # Cleanup
        self.server.PortDestroy(self.port)
        self.wireless_endpoint.Lock(False)
        return {"traffic": traffic_results, "networkinfo": monitor_results}