def main(): parser = argparse.ArgumentParser( description="Read Cuckoo filter and check against contacts") parser.add_argument("-d", "--debug", help="Run in debug mode logging to stderr", action="store_true") parser.add_argument( "-D", "--database", help="Specify the database location", default="/var/lib/epidose/client-database.db", ) parser.add_argument("-o", "--observation", help="Observation hash to check") parser.add_argument("-v", "--verbose", help="Set verbose logging", action="store_true") parser.add_argument("filter", help="Cuckoo filter file") args = parser.parse_args() # Setup logging daemon = Daemon("check_infection", args) global logger logger = daemon.get_logger() with open(args.filter, "rb") as f: (capacity, ) = struct.unpack(">Q", f.read(8)) cuckoo_filter = TracingDataBatch(fh=f, capacity=capacity) if args.observation: if (bytes(bytearray.fromhex(args.observation)) in cuckoo_filter.infected_observations): print("Found") sys.exit(0) else: print("Not found") sys.exit(1) else: ct = ContactTracer(None, args.database, transmitter=False, receiver=False) matches = ct.matches_with_batch(cuckoo_filter) logger.info(f"{'Contact match' if matches else 'No contact match'}") setup_leds() if matches: red_led_set(True) exit_code = 0 else: red_led_set(False) exit_code = 1 cleanup() sys.exit(exit_code)
def initialize(args): """Initialize the server's database and logger. """ global daemon daemon = Daemon("ha_server", args) # Setup logging global logger logger = daemon.get_logger() # Connect to the database global db db = ServerDatabase(args.database)
def main(): parser = argparse.ArgumentParser( description="Contact tracing beacon receiver") parser.add_argument("-d", "--debug", help="Run in debug mode logging to stderr", action="store_true") parser.add_argument( "-D", "--database", help="Specify the database location", default="/var/lib/epidose/client-database.db", ) parser.add_argument("-v", "--verbose", help="Set verbose logging", action="store_true") args = parser.parse_args() daemon = Daemon("watchdog", args) # Setup logging global logger logger = daemon.get_logger() # Setup server connection proxy = client.ServerProxy( "http://localhost", transport=UnixStreamTransport("/run/supervisor.sock")) setup_leds() red_led_set(False) while True: if watchdog_check(proxy): # Signal heartbeat if no other signalling is active if led_change_age() > CHECK_INTERVAL * 2: green_led_set(True) sleep(FLASH_BLINK) green_led_set(False) sleep(FLASH_PAUSE) green_led_set(True) sleep(FLASH_BLINK) green_led_set(False) v = get_battery_voltage() logger.debug(f"Battery {v}") # Graceful shutdown when needed if v < SHUTDOWN_VOLTAGE: logger.debug("Battery exchausted; shutting down") schedule_power_off() system("shutdown now 'Battery exhausted (${v} V)'") exit(0) sleep(CHECK_INTERVAL)
def main(): parser = argparse.ArgumentParser( description="Contact tracing beacon receiver") parser.add_argument("-d", "--debug", help="Run in debug mode logging to stderr", action="store_true") parser.add_argument( "-D", "--database", help="Specify the database location", default="/var/lib/epidose/client-database.db", ) parser.add_argument( "-i", "--iface", help="Listen on the specified interface number, not [hci]0", type=int, default=0, ) parser.add_argument("-t", "--test", help="Test script", action="store_true") parser.add_argument("-v", "--verbose", help="Set verbose logging", action="store_true") args = parser.parse_args() if args.test: args.debug = True args.database = ":memory:" # Setup logging daemon = Daemon("beacon_rx", args) global logger logger = daemon.get_logger() # Receive and process beacon packets global receiver receiver = ContactTracer(None, args.database, transmitter=False) if args.test: sys.exit(0) socket = bluez.hci_open_dev(args.iface) set_receive(socket) setup_leds() while True: process_packet(socket)
def test_run_command(): args = types.SimpleNamespace() args.debug = True args.verbose = True daemon = Daemon("test_run_command", args) global logger logger = daemon.get_logger() result = daemon.run_command(["true"]) assert result.returncode == 0 try: result = daemon.run_command(["false"]) except Exception as e: logger.debug(f"{e}")
def main(): parser = argparse.ArgumentParser( description="Create Cuckoo filter with reported infections" ) parser.add_argument( "-d", "--debug", help="Run in debug mode logging to stderr", action="store_true" ) parser.add_argument( "-D", "--database", help="Specify the database location", default="/var/lib/epidose/server-database.db", ) parser.add_argument("-s", "--seeds-file", help="File containing epochs and seeds") parser.add_argument( "-v", "--verbose", help="Set verbose logging", action="store_true" ) parser.add_argument("filter", help="File where filter will be stored") args = parser.parse_args() # Setup logging daemon = Daemon("create_filter", args) global logger logger = daemon.get_logger() # Obtain seeds if args.seeds_file: tracing_seeds = read_seeds(args.seeds_file) else: db = ServerDatabase(args.database) tracing_seeds = [db.get_epoch_seeds_tuple()] # Create and save filter cuckoo_filter = TracingDataBatch(tracing_seeds) handle, name = mkstemp(dir=os.path.dirname(args.filter)) # Write filter to a temparary file with os.fdopen(handle, "wb") as f: f.write(cuckoo_filter.capacity.to_bytes(8, byteorder="big", signed=False)) cuckoo_filter.tofile(f) # Atomically replace any existing filter file with the new one logger.debug(f"Rename {name} to {args.filter}") os.rename(name, args.filter)
def main(): parser = argparse.ArgumentParser(description="Contact tracing device I/O") parser.add_argument("-b", "--battery", help="Display battery voltage", action="store_true") parser.add_argument("-c", "--clock-get", help="Display real time clock", action="store_true") parser.add_argument( "-C", "--clock-set", help="Set real time clock to the current time", action="store_true", ) parser.add_argument("-d", "--debug", help="Run in debug mode logging to stderr", action="store_true") parser.add_argument("-G", "--green-on", help="Turn red LED on", action="store_true") parser.add_argument("-g", "--green-off", help="Turn red LED off", action="store_true") parser.add_argument("-O", "--orange-on", help="Turn orange LED on", action="store_true") parser.add_argument("-o", "--orange-off", help="Turn orange LED off", action="store_true") parser.add_argument("-p", "--power-off", help="Schedule power to turn off", action="store_true") parser.add_argument("-R", "--red-on", help="Turn red LED on", action="store_true") parser.add_argument("-r", "--red-off", help="Turn red LED off", action="store_true") parser.add_argument("-s", "--share-wait", help="Wait for share key press", action="store_true") parser.add_argument("-t", "--test", help="Toggle LED with button", action="store_true") parser.add_argument("-v", "--verbose", help="Set verbose logging", action="store_true") parser.add_argument("-w", "--wifi-wait", help="Wait for WiFi key press", action="store_true") args = parser.parse_args() # Setup logging daemon = Daemon("device_io", args) global logger logger = daemon.get_logger() if args.battery: print(get_battery_voltage()) if args.test: print(get_real_time_clock()) setup_leds() setup_switch(SHARE_SWITCH_PORT) setup_switch(WIFI_SWITCH_PORT) led_state = True while True: try: print("Press the share button to toggle the LED.") led_state = toggle(led_state, SHARE_SWITCH_PORT) print("Press the WiFi button to toggle the LED.") led_state = toggle(led_state, WIFI_SWITCH_PORT) except KeyboardInterrupt: sys.exit(0) if args.clock_get: print(get_real_time_clock()) if args.clock_set: set_real_time_clock() print(get_real_time_clock()) if args.green_off: logger.debug("Turn green LED off") setup_leds() green_led_set(False) if args.green_on: logger.debug("Turn green LED on") setup_leds() green_led_set(True) if args.orange_off: logger.debug("Turn orange LED off") setup_leds() orange_led_set(False) if args.orange_on: logger.debug("Turn orange LED on") setup_leds() orange_led_set(True) if args.power_off: logger.debug("Schedule power off") schedule_power_off() if args.red_off: logger.debug("Turn red LED off") setup_leds() red_led_set(False) if args.red_on: logger.debug("Turn red LED on") setup_leds() red_led_set(True) if args.share_wait: logger.debug( "Waiting for share button press; press ^C and button to abort") setup() setup_switch(SHARE_SWITCH_PORT) wait_for_button_press(SHARE_SWITCH_PORT) logger.debug("Share button pressed") if args.wifi_wait: logger.debug( "Waiting for WiFi button press; press ^C and button to abort") setup() setup_switch(WIFI_SWITCH_PORT) wait_for_button_press(WIFI_SWITCH_PORT) logger.debug("WiFi button pressed")
def main(): parser = argparse.ArgumentParser( description="Contact tracing beacon trasmitter") parser.add_argument("-d", "--debug", help="Run in debug mode logging to stderr", action="store_true") parser.add_argument( "-D", "--database", help="Specify the database location", default="/var/lib/epidose/client-database.db", ) parser.add_argument( "-i", "--iface", help="Transmit on the specified interface, not [hci]0", type=int, default=0, ) parser.add_argument( "-n", "--dry-run", help="Do not execute the required command(s)", action="store_true", ) parser.add_argument( "-r", "--rssi", help="Specify the received signal strength indication", type=int, default=0xC0, ) parser.add_argument("-t", "--test", help="Test script", action="store_true") parser.add_argument("-v", "--verbose", help="Set verbose logging", action="store_true") args = parser.parse_args() if args.test: args.debug = True args.dry_run = True args.database = ":memory:" # Setup logging daemon = Daemon("beacon_tx", args) global logger logger = daemon.get_logger() global dry_run dry_run = args.dry_run interface = f"hci{args.iface}" # Transmit and store beacon packets current_ephid = None transmitter = ContactTracer(None, args.database, receiver=False) sleeper = InterruptibleSleep([signal.SIGTERM, signal.SIGINT]) while True: now = datetime.now() transmitter.check_advance_day(now) ephid = transmitter.get_ephid_for_time(now) if ephid != current_ephid: # Generate random bdaddr bdaddr = generate_random_bdaddr() bdaddr = bdaddr.split() # Change local device bdaddr run_command([ "hcitool", "-i", interface, "cmd", "0x3f", "0x001", bdaddr[5], bdaddr[4], bdaddr[3], bdaddr[2], bdaddr[1], bdaddr[0] ]) # Enable the bluetooth interface run_command(["hciconfig", interface, "up"]) # Enable LE advertising run_command( ["hcitool", "-i", interface, "cmd", "0x08", "0x000a", "01"]) set_transmit(interface, ephid, args.rssi) current_ephid = ephid logger.debug(f"Change ephid to {ephid.hex()}") # Wait for the current epoch (e.g. 15 minutes) to pass # The API can't tell us TTL, so sample every minute sleeper.sleep(EPOCH_LENGTH / 60) if sleeper.signaled: # Stop advertising run_command(["hciconfig", interface, "noleadv"]) exit(0) if args.test: break
def main(): parser = argparse.ArgumentParser( description="Contact tracing seed uploader") parser.add_argument("-a", "--authorization", help="Upload authorization code", default=":NONE:") parser.add_argument("-d", "--debug", help="Run in debug mode logging to stderr", action="store_true") parser.add_argument( "-D", "--database", help="Specify the database location", default="/var/lib/epidose/client-database.db", ) parser.add_argument("-t", "--test", help="Test script", action="store_true") parser.add_argument("-s", "--server", help="Server URL", default=SERVER_URL) parser.add_argument("-v", "--verbose", help="Set verbose logging", action="store_true") parser.add_argument( "start_time", help="The (ISO) time from which contact tracing should start") parser.add_argument( "end_time", help="The (ISO) time at which contact tracing should end") args = parser.parse_args() if args.test: args.debug = True args.database = ":memory:" # Setup logging daemon = Daemon("upload_seeds", args) global logger logger = daemon.get_logger() # Obtain the specified seeds ct = ContactTracer(None, args.database, transmitter=False, receiver=False) (epochs, seeds) = ct.get_tracing_information( datetime.fromisoformat(args.start_time), datetime.fromisoformat(args.end_time)) # Create dictionary for JSON logger.debug("Creating request") post = {"authorization": args.authorization, "data": []} i = 0 for e in epochs: post["data"].append({"epoch": e, "seed": seeds[i].hex()}) i += 1 # Send request and check response logger.debug("Sending request") res = requests.post(f"{args.server}/add_contagious", json=post) logger.debug("Request sent") if res.ok: exit(0) else: logger.error(f"Request failed: {res.status_code} {res.reason}") exit(1)
def main(): parser = argparse.ArgumentParser(description="Contact tracing device I/O") parser.add_argument( "-d", "--debug", help="Run in debug mode logging to stderr", action="store_true" ) parser.add_argument("-G", "--green-on", help="Turn red LED on", action="store_true") parser.add_argument( "-g", "--green-off", help="Turn red LED off", action="store_true" ) parser.add_argument( "-O", "--orange-on", help="Turn orange LED on", action="store_true" ) parser.add_argument( "-o", "--orange-off", help="Turn orange LED off", action="store_true" ) parser.add_argument("-R", "--red-on", help="Turn red LED on", action="store_true") parser.add_argument("-r", "--red-off", help="Turn red LED off", action="store_true") parser.add_argument( "-t", "--test", help="Toggle LED with button", action="store_true" ) parser.add_argument( "-v", "--verbose", help="Set verbose logging", action="store_true" ) parser.add_argument("-w", "--wait", help="Wait for key press", action="store_true") args = parser.parse_args() # Setup logging daemon = Daemon("device_io", args) global logger logger = daemon.get_logger() if args.test: setup_leds() setup_switch() try: toggle() except KeyboardInterrupt: pass if args.green_off: logger.debug("Turn green LED off") setup_leds() green_led_set(False) if args.green_on: logger.debug("Turn green LED on") setup_leds() green_led_set(True) if args.orange_off: logger.debug("Turn orange LED off") setup_leds() orange_led_set(False) if args.orange_on: logger.debug("Turn orange LED on") setup_leds() orange_led_set(True) if args.red_off: logger.debug("Turn red LED off") setup_leds() red_led_set(False) if args.red_on: logger.debug("Turn red LED on") setup_leds() red_led_set(True) if args.wait: logger.debug("Waiting for button press; press ^C and button to abort") setup_switch() wait_for_button_press() logger.debug("Button pressed")