|
| 1 | +#!/usr/bin/env python3 |
| 2 | +""" |
| 3 | + zbnt/python-client |
| 4 | + Copyright (C) 2020 Oscar R. |
| 5 | +
|
| 6 | + This program is free software: you can redistribute it and/or modify |
| 7 | + it under the terms of the GNU General Public License as published by |
| 8 | + the Free Software Foundation, either version 3 of the License, or |
| 9 | + (at your option) any later version. |
| 10 | +
|
| 11 | + This program is distributed in the hope that it will be useful, |
| 12 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | + GNU General Public License for more details. |
| 15 | +
|
| 16 | + You should have received a copy of the GNU General Public License |
| 17 | + along with this program. If not, see <https://www.gnu.org/licenses/>. |
| 18 | +""" |
| 19 | + |
| 20 | +import asyncio |
| 21 | +from zbnt import ZbntClient, TrafficGenerator, Devices, Properties, discover_devices |
| 22 | + |
| 23 | +output_file = open("results.csv", "w") |
| 24 | + |
| 25 | +def write_fd_measurement(dev_id, measurement_data): |
| 26 | + measurement_data = list(measurement_data) |
| 27 | + measurement_data[-1] = measurement_data[-1].hex() |
| 28 | + |
| 29 | + output_file.write(",".join(map(str, measurement_data))) |
| 30 | + output_file.write("\n") |
| 31 | + |
| 32 | +async def main(): |
| 33 | + # Scan for devices, ask the user to select one if multiple devices are found |
| 34 | + |
| 35 | + devices = await discover_devices(4) |
| 36 | + |
| 37 | + if len(devices) == 0: |
| 38 | + print("Error: No devices found") |
| 39 | + exit(1) |
| 40 | + |
| 41 | + if len(devices) > 1: |
| 42 | + print("Available devices:\n") |
| 43 | + |
| 44 | + for i in range(len(devices)): |
| 45 | + print("{0}) {1} ({2})".format(i + 1, devices[i]["name"], devices[i]["address"])) |
| 46 | + |
| 47 | + req_dev = int(input("\nSelect a device [1-{0}]: ".format(len(devices)))) - 1 |
| 48 | + |
| 49 | + if req_dev < 0 or req_dev >= len(devices): |
| 50 | + print("Error: Invalid device selected") |
| 51 | + exit(1) |
| 52 | + |
| 53 | + print("") |
| 54 | + else: |
| 55 | + req_dev = 0 |
| 56 | + |
| 57 | + req_dev = devices[req_dev] |
| 58 | + |
| 59 | + # Connect to selected device, load a bitstream |
| 60 | + |
| 61 | + print("- Connecting to {0} ({1})".format(req_dev["name"], req_dev["address"])) |
| 62 | + |
| 63 | + client = await ZbntClient.connect(req_dev["address"], req_dev["port"]) |
| 64 | + |
| 65 | + if client == None: |
| 66 | + print("Error: Failed to connect to device") |
| 67 | + exit(1) |
| 68 | + |
| 69 | + print("- Connected!") |
| 70 | + |
| 71 | + if not await client.load_bitstream("dual_tgen_detector"): |
| 72 | + print("Error: Failed to load bitstream") |
| 73 | + exit(1) |
| 74 | + |
| 75 | + print("- Bitstream loaded") |
| 76 | + |
| 77 | + # Get handle to the timer, eth0 traffic generator and eth0 stats collector |
| 78 | + |
| 79 | + timer = client.get_device(Devices.DEV_SIMPLE_TIMER) |
| 80 | + tgen0 = client.get_device(Devices.DEV_TRAFFIC_GENERATOR, {0}) |
| 81 | + fd0 = client.get_device(Devices.DEV_FRAME_DETECTOR, {2, 3}) |
| 82 | + |
| 83 | + # Set function to be called every time the server sends measurement data |
| 84 | + |
| 85 | + fd0.measurement_handler = write_fd_measurement |
| 86 | + |
| 87 | + # Tell the server to start the run, this will initialize the DMA core |
| 88 | + |
| 89 | + await client.start_run() |
| 90 | + |
| 91 | + # Configure tgen0, sc0 and the timer |
| 92 | + |
| 93 | + template_bytes, template_mask = TrafficGenerator.load_frame_template("arp_response.hex") |
| 94 | + script_bytes = fd0.load_script("arp_spoof_response.zbscr") |
| 95 | + |
| 96 | + await fd0.set_property(Properties.PROP_FRAME_SCRIPT, script_bytes, {"index": 0}) |
| 97 | + await fd0.set_property(Properties.PROP_ENABLE_SCRIPT, 1) |
| 98 | + await fd0.set_property(Properties.PROP_ENABLE_LOG, True) |
| 99 | + await fd0.set_property(Properties.PROP_ENABLE, True) |
| 100 | + |
| 101 | + await tgen0.set_property(Properties.PROP_FRAME_TEMPLATE, template_bytes) |
| 102 | + await tgen0.set_property(Properties.PROP_FRAME_TEMPLATE_MASK, template_mask) |
| 103 | + await tgen0.set_property(Properties.PROP_FRAME_SIZE, 64) |
| 104 | + await tgen0.set_property(Properties.PROP_FRAME_GAP, 12500000) |
| 105 | + await tgen0.set_property(Properties.PROP_ENABLE, True) |
| 106 | + |
| 107 | + await timer.set_property(Properties.PROP_TIMER_LIMIT, 10 * timer.freq) |
| 108 | + await timer.set_property(Properties.PROP_ENABLE, True) |
| 109 | + |
| 110 | + # Wait until all data has been sent and the server stops the run |
| 111 | + |
| 112 | + await client.wait_for_run_end() |
| 113 | + |
| 114 | + # Get overflow counters |
| 115 | + |
| 116 | + res, (overflow_a2b, overflow_b2a) = await fd0.get_property(Properties.PROP_OVERFLOW_COUNT) |
| 117 | + |
| 118 | + if res: |
| 119 | + print("- Overflow counters: {0}, {1}".format(overflow_a2b, overflow_b2a)) |
| 120 | + |
| 121 | +asyncio.run(main()) |
| 122 | + |
| 123 | +output_file.close() |
0 commit comments