Skip to content

Commit

Permalink
improve flow
Browse files Browse the repository at this point in the history
* add support for FB 3390
* improve transfer visualization through tftp
* remove ip argument as it is probably never needed?
* isort, remove unused imports
  • Loading branch information
maurerle committed Jul 30, 2023
1 parent 7ed24a6 commit bea55de
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 63 deletions.
102 changes: 46 additions & 56 deletions fritzflash.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
#! /usr/bin/env python3
import argparse
import ipaddress
from ipaddress import (
IPv4Interface,
IPv4Address,
IPv6Interface,
IPv6Address,
AddressValueError,
)
import platform
import socket
import time
from contextlib import contextmanager
from ftplib import FTP
from ipaddress import (
IPv4Address,
IPv4Interface,
IPv6Address,
IPv6Interface,
)
from pathlib import Path
from subprocess import run
from contextlib import contextmanager

from typing import List, ContextManager, Union
from typing import ContextManager, List, Union

from simple_tftp import serve_file

Expand Down Expand Up @@ -52,7 +50,7 @@ def __init__(
break
except socket.timeout:
i += 1
except OSError as e:
except OSError:
time.sleep(1)
i += 1
if i > max_retry:
Expand Down Expand Up @@ -115,8 +113,7 @@ def set_ip(ipinterface: IPInterface, network_device: str) -> ContextManager[None
ipinterface.with_prefixlen,
"dev",
network_device,
],
capture_output=True,
]
)
else:
output = run(
Expand All @@ -126,7 +123,7 @@ def set_ip(ipinterface: IPInterface, network_device: str) -> ContextManager[None
"ipv4",
"add",
"address",
f'"{network_device}"',
f"{network_device}",
f"{ipinterface.ip}",
f"{ipinterface.netmask}",
],
Expand All @@ -143,10 +140,9 @@ def set_ip(ipinterface: IPInterface, network_device: str) -> ContextManager[None
"ipv4",
"delete",
"address",
f'"{network_device}"',
f"{network_device}",
f"{ipinterface.ip}",
],
capture_output=True,
]
)


Expand Down Expand Up @@ -203,17 +199,7 @@ def start_message(ip_address):
"You can always find the most current version of this script at https://www.github.com/freifunk-darmstadt/fritz-tools\n\n"
"It is strongly recommended to only connect your computer to the device you want to flash.\n"
"Try to disable all other connections (Ethernet, WiFi/WLAN, VMs) if detection fails.\n"
"Sometimes an unmanaged switch between your AVM device and your computer is helpful.\n\n"
"If you run this program with according permission, it will configure IPs on your host automatically.\n"
"Otherwise, make sure you have assigned your PC a static IP Address in the Subnet of the device you want to flash.\n"
"The following example would be a completely fine option:\n"
)
print("IP-Address: %s" % str(ipaddress.ip_address(ip_address) + 1))
print("Subnet: 255.255.255.0")
print("Gateway: %s" % str(ipaddress.ip_address(ip_address)))
print("DNS Servers: Leave blank\n")
print(
"Once you're ready to flash, press enter, disconnect power from your AVM device and reconnect the power-supply."
"Sometimes an unmanaged switch between your AVM device and your computer is helpful."
)


Expand Down Expand Up @@ -278,7 +264,7 @@ def autodiscover_avm_ip():
bytearray.fromhex("0000120101000000c0a8b20100000000"),
("255.255.255.255", 5035),
)
while 1:
while True:
data, addr = receiver.recvfrom(64)
if addr[0] == "192.168.178.1":
print("\rFritzBox found at %s" % addr[0])
Expand Down Expand Up @@ -325,6 +311,9 @@ def determine_image_name(env_string):
"gluon": ["avm-fritz-box-7312-sysupgrade.bin"],
"openwrt": ["avm_fritz7312-squashfs-sysupgrade.bin"],
},
"193": {
"openwrt": ["avm_fritz3390-squashfs-sysupgrade.bin"],
},
"196": {
"gluon": ["avm-fritz-box-7360-v2-sysupgrade.bin"],
"openwrt": ["avm_fritz7360sl-squashfs-sysupgrade.bin"],
Expand All @@ -345,9 +334,7 @@ def determine_image_name(env_string):
"openwrt": ["avm_fritzbox-4040-squashfs-eva.bin"],
},
"203": {
"openwrt": [
"openwrt-lantiq-xrx200-avm_fritz7362sl-initramfs-kernel.bin"
]
"openwrt": ["openwrt-lantiq-xrx200-avm_fritz7362sl-initramfs-kernel.bin"]
},
"209": {
"openwrt": ["openwrt-lantiq-xrx200-avm_fritz7412-initramfs-kernel.bin"]
Expand Down Expand Up @@ -566,9 +553,6 @@ def perform_tftp_flash(initramfsfile: Path, sysupgradefile: Path):
parser = argparse.ArgumentParser(
description="Flash Gluon image to AVM devices using EVA or/and TFTP."
)
parser.add_argument(
"--ip", type=str, help="IP Address of device. Autodiscovery if not specified."
)
parser.add_argument(
"--image",
type=str,
Expand Down Expand Up @@ -606,32 +590,38 @@ def perform_tftp_flash(initramfsfile: Path, sysupgradefile: Path):
flash_tftp = input().lower().startswith("y")

start_message("192.168.178.1")
input()

with set_ip(ipaddress.ip_interface("192.168.178.2/24"), args.device) as can_set_ip:
client_intf = ipaddress.ip_interface("192.168.178.2/24")
with set_ip(client_intf, args.device) as can_set_ip:
if can_set_ip:
print("did set ip to 192.168.178.2/24")
print(f"did set ip to {client_intf}")
else:
print("could not set ip to 192.168.178.2/24")
print(f"could not set ip to {client_intf}")
print(
"If you run this program with according permission, it will configure IPs on your host automatically.\n"
"Otherwise, make sure you have assigned your PC a static IP Address in the Subnet of the device you want to flash.\n"
"The following example would be a completely fine option:\n"
)
print(f"IP-Address: {client_intf.ip}")
print(f"Subnet: {client_intf.netmask}")
print("Gateway: 192.168.178.1")
print("DNS Servers: Leave blank\n")
print(
"Once you're ready to flash, press enter, disconnect power from your AVM device and reconnect the power-supply."
)
input()

if args.ip:
try:
ip = ipaddress.ip_address(args.ip)
except AddressValueError:
print(f"{args.ip} is not a valid IPv4 address!")
exit(1)
else:
print("Trying to autodiscover! Abort via Ctrl-c.")
ip = autodiscover_avm_ip()
print("Trying to autodiscover! Abort via Ctrl-c.")
ip = autodiscover_avm_ip()

if ip is None:
print("\nAutodiscovery failed!")
print("Press any key to exit.")
input()
exit(1)
if ip is None:
print("\nAutodiscovery failed!")
print("Press any key to exit.")
input()
exit(1)

print("\nAutodiscovery succesful!")
print(f"-> Device detected at {ip}.")
print("\nAutodiscovery succesful!")
print(f"-> Device detected at {ip}.")

if args.image is None:
# Try to automatically locate an image to use
Expand Down Expand Up @@ -664,4 +654,4 @@ def perform_tftp_flash(initramfsfile: Path, sysupgradefile: Path):
time.sleep(30)
perform_bootloader_flash(sysupgradefile, imagefile, flash_tftp)
print("Finished flash procedure")
finish_message()
finish_message()
16 changes: 9 additions & 7 deletions simple_tftp.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import os.path, random, sys
from socket import socket, AF_INET, AF_INET6, SOCK_DGRAM, timeout
from pathlib import Path
#! /usr/bin/env python3
import random
import sys
from contextlib import contextmanager
from typing import Tuple, Generator, Literal
from pathlib import Path
from socket import AF_INET, SOCK_DGRAM, socket, timeout
from typing import Generator, Literal, Tuple

UDP_IP = "0.0.0.0"
UDP_PORT = 69 # TFTP Protocol Port (69)
Expand Down Expand Up @@ -160,7 +162,7 @@ def serve(port: int, file: Path, mode: TRANSFER_MODES_T) -> Tuple[bool, str]:
return True, addr
block += 1
if block % 256 == 0:
print(f"{block} / {size}")
print(f"{block} / {size}", end="")

packet = create_data_packet(block, file, mode)
sock.sendto(packet, addr)
Expand Down Expand Up @@ -212,15 +214,15 @@ def serve_file(
yield serve(port, file, mode)


if __name__ == "__main__":
def main_tftp():
for success, host in serve_file(sys.argv[1]):
if success:
print(f"Successfully served file {sys.argv[1]} to Host {host}")
try:
input(
"Press any key to serve to another Host, CTRL-c or CTRL-d to stop TFTP server."
)
except (KeyboardInterrupt, EOFError) as interrupt:
except (KeyboardInterrupt, EOFError):
break
else:
print(f"Timeout serving file to Host {host}")

0 comments on commit bea55de

Please sign in to comment.