Merge branch 'master' into master
This commit is contained in:
		
						commit
						0a15b4c6c1
					
				| @ -77,6 +77,15 @@ class AutoInterface(Interface): | ||||
|         ifas = self.netinfo.ifaddresses(ifname) | ||||
|         return ifas | ||||
| 
 | ||||
|     def interface_name_to_index(self, ifname): | ||||
| 
 | ||||
|         # socket.if_nametoindex doesn't work with uuid interface names on windows, it wants the ethernet_0 style | ||||
|         # we will just get the index from netinfo instead as it seems to work | ||||
|         if RNS.vendor.platformutils.is_windows(): | ||||
|             return self.netinfo.interface_names_to_indexes()[ifname] | ||||
| 
 | ||||
|         return socket.if_nametoindex(ifname) | ||||
| 
 | ||||
|     def __init__(self, owner, name, group_id=None, discovery_scope=None, discovery_port=None, multicast_address_type=None, data_port=None, allowed_interfaces=None, ignored_interfaces=None, configured_bitrate=None): | ||||
|         from RNS.vendor.ifaddr import niwrapper | ||||
|         super().__init__() | ||||
| @ -172,69 +181,90 @@ class AutoInterface(Interface): | ||||
| 
 | ||||
|         suitable_interfaces = 0 | ||||
|         for ifname in self.list_interfaces(): | ||||
|             if RNS.vendor.platformutils.is_darwin() and ifname in AutoInterface.DARWIN_IGNORE_IFS and not ifname in self.allowed_interfaces: | ||||
|                 RNS.log(str(self)+" skipping Darwin AWDL or tethering interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|             elif RNS.vendor.platformutils.is_darwin() and ifname == "lo0": | ||||
|                 RNS.log(str(self)+" skipping Darwin loopback interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|             elif RNS.vendor.platformutils.is_android() and ifname in AutoInterface.ANDROID_IGNORE_IFS and not ifname in self.allowed_interfaces: | ||||
|                 RNS.log(str(self)+" skipping Android system interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|             elif ifname in self.ignored_interfaces: | ||||
|                 RNS.log(str(self)+" ignoring disallowed interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|             elif ifname in AutoInterface.ALL_IGNORE_IFS: | ||||
|                 RNS.log(str(self)+" skipping interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|             else: | ||||
|                 if len(self.allowed_interfaces) > 0 and not ifname in self.allowed_interfaces: | ||||
|                     RNS.log(str(self)+" ignoring interface "+str(ifname)+" since it was not allowed", RNS.LOG_EXTREME) | ||||
|             try: | ||||
|                 if RNS.vendor.platformutils.is_darwin() and ifname in AutoInterface.DARWIN_IGNORE_IFS and not ifname in self.allowed_interfaces: | ||||
|                     RNS.log(str(self)+" skipping Darwin AWDL or tethering interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|                 elif RNS.vendor.platformutils.is_darwin() and ifname == "lo0": | ||||
|                     RNS.log(str(self)+" skipping Darwin loopback interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|                 elif RNS.vendor.platformutils.is_android() and ifname in AutoInterface.ANDROID_IGNORE_IFS and not ifname in self.allowed_interfaces: | ||||
|                     RNS.log(str(self)+" skipping Android system interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|                 elif ifname in self.ignored_interfaces: | ||||
|                     RNS.log(str(self)+" ignoring disallowed interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|                 elif ifname in AutoInterface.ALL_IGNORE_IFS: | ||||
|                     RNS.log(str(self)+" skipping interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|                 else: | ||||
|                     addresses = self.list_addresses(ifname) | ||||
|                     if self.netinfo.AF_INET6 in addresses: | ||||
|                         link_local_addr = None | ||||
|                         for address in addresses[self.netinfo.AF_INET6]: | ||||
|                             if "addr" in address: | ||||
|                                 if address["addr"].startswith("fe80:"): | ||||
|                                     link_local_addr = self.descope_linklocal(address["addr"]) | ||||
|                                     self.link_local_addresses.append(link_local_addr) | ||||
|                                     self.adopted_interfaces[ifname] = link_local_addr | ||||
|                                     self.multicast_echoes[ifname] = time.time() | ||||
|                                     RNS.log(str(self)+" Selecting link-local address "+str(link_local_addr)+" for interface "+str(ifname), RNS.LOG_EXTREME) | ||||
|                     if len(self.allowed_interfaces) > 0 and not ifname in self.allowed_interfaces: | ||||
|                         RNS.log(str(self)+" ignoring interface "+str(ifname)+" since it was not allowed", RNS.LOG_EXTREME) | ||||
|                     else: | ||||
|                         addresses = self.list_addresses(ifname) | ||||
|                         if self.netinfo.AF_INET6 in addresses: | ||||
|                             link_local_addr = None | ||||
|                             for address in addresses[self.netinfo.AF_INET6]: | ||||
|                                 if "addr" in address: | ||||
|                                     if address["addr"].startswith("fe80:"): | ||||
|                                         link_local_addr = self.descope_linklocal(address["addr"]) | ||||
|                                         self.link_local_addresses.append(link_local_addr) | ||||
|                                         self.adopted_interfaces[ifname] = link_local_addr | ||||
|                                         self.multicast_echoes[ifname] = time.time() | ||||
|                                         nice_name = self.netinfo.interface_name_to_nice_name(ifname) | ||||
|                                         if nice_name != None and nice_name != ifname: | ||||
|                                             RNS.log(f"{self} Selecting link-local address {link_local_addr} for interface {nice_name} / {ifname}", RNS.LOG_EXTREME) | ||||
|                                         else: | ||||
|                                             RNS.log(f"{self} Selecting link-local address {link_local_addr} for interface {ifname}", RNS.LOG_EXTREME) | ||||
| 
 | ||||
|                         if link_local_addr == None: | ||||
|                             RNS.log(str(self)+" No link-local IPv6 address configured for "+str(ifname)+", skipping interface", RNS.LOG_EXTREME) | ||||
|                         else: | ||||
|                             mcast_addr = self.mcast_discovery_address | ||||
|                             RNS.log(str(self)+" Creating multicast discovery listener on "+str(ifname)+" with address "+str(mcast_addr), RNS.LOG_EXTREME) | ||||
| 
 | ||||
|                             # Struct with interface index | ||||
|                             if_struct = struct.pack("I", socket.if_nametoindex(ifname)) | ||||
| 
 | ||||
|                             # Set up multicast socket | ||||
|                             discovery_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) | ||||
|                             discovery_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | ||||
|                             if hasattr(socket, "SO_REUSEPORT"): | ||||
|                                 discovery_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) | ||||
|                             discovery_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, if_struct) | ||||
| 
 | ||||
|                             # Join multicast group | ||||
|                             mcast_group = socket.inet_pton(socket.AF_INET6, mcast_addr) + if_struct | ||||
|                             discovery_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mcast_group) | ||||
| 
 | ||||
|                             # Bind socket | ||||
|                             if self.discovery_scope == AutoInterface.SCOPE_LINK: | ||||
|                                 addr_info = socket.getaddrinfo(mcast_addr+"%"+ifname, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM) | ||||
|                             if link_local_addr == None: | ||||
|                                 RNS.log(str(self)+" No link-local IPv6 address configured for "+str(ifname)+", skipping interface", RNS.LOG_EXTREME) | ||||
|                             else: | ||||
|                                 addr_info = socket.getaddrinfo(mcast_addr, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM) | ||||
|                                 mcast_addr = self.mcast_discovery_address | ||||
|                                 RNS.log(str(self)+" Creating multicast discovery listener on "+str(ifname)+" with address "+str(mcast_addr), RNS.LOG_EXTREME) | ||||
| 
 | ||||
|                             discovery_socket.bind(addr_info[0][4]) | ||||
|                                 # Struct with interface index | ||||
|                                 if_struct = struct.pack("I", self.interface_name_to_index(ifname)) | ||||
| 
 | ||||
|                             # Set up thread for discovery packets | ||||
|                             def discovery_loop(): | ||||
|                                 self.discovery_handler(discovery_socket, ifname) | ||||
|                                 # Set up multicast socket | ||||
|                                 discovery_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) | ||||
|                                 discovery_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | ||||
|                                 if hasattr(socket, "SO_REUSEPORT"): | ||||
|                                     discovery_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) | ||||
|                                 discovery_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, if_struct) | ||||
| 
 | ||||
|                             thread = threading.Thread(target=discovery_loop) | ||||
|                             thread.daemon = True | ||||
|                             thread.start() | ||||
|                                 # Join multicast group | ||||
|                                 mcast_group = socket.inet_pton(socket.AF_INET6, mcast_addr) + if_struct | ||||
|                                 discovery_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mcast_group) | ||||
| 
 | ||||
|                             suitable_interfaces += 1 | ||||
|                                 # Bind socket | ||||
|                                 if RNS.vendor.platformutils.is_windows(): | ||||
| 
 | ||||
|                                     # window throws "[WinError 10049] The requested address is not valid in its context" | ||||
|                                     # when trying to use the multicast address as host, or when providing interface index | ||||
|                                     # passing an empty host appears to work, but probably not exactly how we want it to... | ||||
|                                     discovery_socket.bind(('', self.discovery_port)) | ||||
| 
 | ||||
|                                 else: | ||||
| 
 | ||||
|                                     if self.discovery_scope == AutoInterface.SCOPE_LINK: | ||||
|                                         addr_info = socket.getaddrinfo(mcast_addr+"%"+ifname, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM) | ||||
|                                     else: | ||||
|                                         addr_info = socket.getaddrinfo(mcast_addr, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM) | ||||
| 
 | ||||
|                                     discovery_socket.bind(addr_info[0][4]) | ||||
| 
 | ||||
|                                 # Set up thread for discovery packets | ||||
|                                 def discovery_loop(): | ||||
|                                     self.discovery_handler(discovery_socket, ifname) | ||||
| 
 | ||||
|                                 thread = threading.Thread(target=discovery_loop) | ||||
|                                 thread.daemon = True | ||||
|                                 thread.start() | ||||
| 
 | ||||
|                                 suitable_interfaces += 1 | ||||
| 
 | ||||
|             except Exception as e: | ||||
|                 nice_name = self.netinfo.interface_name_to_nice_name(ifname) | ||||
|                 if nice_name != None and nice_name != ifname: | ||||
|                     RNS.log(f"Could not configure the system interface {nice_name} / {ifname} for use with {self}, skipping it. The contained exception was: {e}", RNS.LOG_ERROR) | ||||
|                 else: | ||||
|                     RNS.log(f"Could not configure the system interface {ifname} for use with {self}, skipping it. The contained exception was: {e}", RNS.LOG_ERROR) | ||||
| 
 | ||||
|         if suitable_interfaces == 0: | ||||
|             RNS.log(str(self)+" could not autoconfigure. This interface currently provides no connectivity.", RNS.LOG_WARNING) | ||||
| @ -253,7 +283,7 @@ class AutoInterface(Interface): | ||||
|             socketserver.UDPServer.address_family = socket.AF_INET6 | ||||
| 
 | ||||
|             for ifname in self.adopted_interfaces: | ||||
|                 local_addr = self.adopted_interfaces[ifname]+"%"+ifname | ||||
|                 local_addr = self.adopted_interfaces[ifname]+"%"+str(self.interface_name_to_index(ifname)) | ||||
|                 addr_info = socket.getaddrinfo(local_addr, self.data_port, socket.AF_INET6, socket.SOCK_DGRAM) | ||||
|                 address = addr_info[0][4] | ||||
| 
 | ||||
| @ -380,7 +410,7 @@ class AutoInterface(Interface): | ||||
|             announce_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) | ||||
|             addr_info = socket.getaddrinfo(self.mcast_discovery_address, self.discovery_port, socket.AF_INET6, socket.SOCK_DGRAM) | ||||
| 
 | ||||
|             ifis = struct.pack("I", socket.if_nametoindex(ifname)) | ||||
|             ifis = struct.pack("I", self.interface_name_to_index(ifname)) | ||||
|             announce_socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, ifis) | ||||
|             announce_socket.sendto(discovery_token, addr_info[0][4]) | ||||
|             announce_socket.close() | ||||
| @ -433,8 +463,8 @@ class AutoInterface(Interface): | ||||
|                 try: | ||||
|                     if self.outbound_udp_socket == None: | ||||
|                         self.outbound_udp_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) | ||||
|                      | ||||
|                     peer_addr = str(peer)+"%"+str(self.peers[peer][0]) | ||||
| 
 | ||||
|                     peer_addr = str(peer)+"%"+str(self.interface_name_to_index(self.peers[peer][0])) | ||||
|                     addr_info = socket.getaddrinfo(peer_addr, self.data_port, socket.AF_INET6, socket.SOCK_DGRAM) | ||||
|                     self.outbound_udp_socket.sendto(data, addr_info[0][4]) | ||||
| 
 | ||||
|  | ||||
| @ -536,46 +536,40 @@ class Reticulum: | ||||
| 
 | ||||
|                             if (("interface_enabled" in c) and c.as_bool("interface_enabled") == True) or (("enabled" in c) and c.as_bool("enabled") == True): | ||||
|                                 if c["type"] == "AutoInterface": | ||||
|                                     if not RNS.vendor.platformutils.is_windows(): | ||||
|                                         group_id        = c["group_id"] if "group_id" in c else None | ||||
|                                         discovery_scope = c["discovery_scope"] if "discovery_scope" in c else None | ||||
|                                         discovery_port  = int(c["discovery_port"]) if "discovery_port" in c else None | ||||
|                                         multicast_address_type = c["multicast_address_type"] if "multicast_address_type" in c else None | ||||
|                                         data_port  = int(c["data_port"]) if "data_port" in c else None | ||||
|                                         allowed_interfaces = c.as_list("devices") if "devices" in c else None | ||||
|                                         ignored_interfaces = c.as_list("ignored_devices") if "ignored_devices" in c else None | ||||
|                                     group_id        = c["group_id"] if "group_id" in c else None | ||||
|                                     discovery_scope = c["discovery_scope"] if "discovery_scope" in c else None | ||||
|                                     discovery_port  = int(c["discovery_port"]) if "discovery_port" in c else None | ||||
|                                     multicast_address_type = c["multicast_address_type"] if "multicast_address_type" in c else None | ||||
|                                     data_port  = int(c["data_port"]) if "data_port" in c else None | ||||
|                                     allowed_interfaces = c.as_list("devices") if "devices" in c else None | ||||
|                                     ignored_interfaces = c.as_list("ignored_devices") if "ignored_devices" in c else None | ||||
| 
 | ||||
|                                         interface = AutoInterface.AutoInterface( | ||||
|                                             RNS.Transport, | ||||
|                                             name, | ||||
|                                             group_id, | ||||
|                                             discovery_scope, | ||||
|                                             discovery_port, | ||||
|                                             multicast_address_type, | ||||
|                                             data_port, | ||||
|                                             allowed_interfaces, | ||||
|                                             ignored_interfaces | ||||
|                                         ) | ||||
| 
 | ||||
|                                         if "outgoing" in c and c.as_bool("outgoing") == False: | ||||
|                                             interface.OUT = False | ||||
|                                         else: | ||||
|                                             interface.OUT = True | ||||
| 
 | ||||
|                                         interface.mode = interface_mode | ||||
| 
 | ||||
|                                         interface.announce_cap = announce_cap | ||||
|                                         if configured_bitrate: | ||||
|                                             interface.bitrate = configured_bitrate | ||||
|                                         if ifac_size != None: | ||||
|                                             interface.ifac_size = ifac_size | ||||
|                                         else: | ||||
|                                             interface.ifac_size = 16 | ||||
|                                     interface = AutoInterface.AutoInterface( | ||||
|                                         RNS.Transport, | ||||
|                                         name, | ||||
|                                         group_id, | ||||
|                                         discovery_scope, | ||||
|                                         discovery_port, | ||||
|                                         multicast_address_type, | ||||
|                                         data_port, | ||||
|                                         allowed_interfaces, | ||||
|                                         ignored_interfaces | ||||
|                                     ) | ||||
| 
 | ||||
|                                     if "outgoing" in c and c.as_bool("outgoing") == False: | ||||
|                                         interface.OUT = False | ||||
|                                     else: | ||||
|                                         RNS.log("AutoInterface is not currently supported on Windows, disabling interface.", RNS.LOG_ERROR); | ||||
|                                         RNS.log("Please remove this AutoInterface instance from your configuration file.", RNS.LOG_ERROR); | ||||
|                                         RNS.log("You will have to manually configure other interfaces for connectivity.", RNS.LOG_ERROR); | ||||
|                                         interface.OUT = True | ||||
| 
 | ||||
|                                     interface.mode = interface_mode | ||||
| 
 | ||||
|                                     interface.announce_cap = announce_cap | ||||
|                                     if configured_bitrate: | ||||
|                                         interface.bitrate = configured_bitrate | ||||
|                                     if ifac_size != None: | ||||
|                                         interface.ifac_size = ifac_size | ||||
|                                     else: | ||||
|                                         interface.ifac_size = 16 | ||||
| 
 | ||||
|                                 if c["type"] == "UDPInterface": | ||||
|                                     device       = c["device"] if "device" in c else None | ||||
|  | ||||
| @ -290,7 +290,7 @@ except Exception as e: | ||||
|     print("No access to directory "+str(CNF_DIR)+". This utility needs file system access to store firmware and data files. Cannot continue.") | ||||
|     print("The contained exception was:") | ||||
|     print(str(e)) | ||||
|     exit(99) | ||||
|     graceful_exit(99) | ||||
| 
 | ||||
| squashvw = False | ||||
| 
 | ||||
| @ -332,6 +332,7 @@ class RNode(): | ||||
|         self.checksum = None | ||||
|         self.device_hash = None | ||||
|         self.firmware_hash = None | ||||
|         self.firmware_hash_target = None | ||||
|         self.signature = None | ||||
|         self.signature_valid = False | ||||
|         self.locally_signed = False | ||||
| @ -479,6 +480,8 @@ class RNode(): | ||||
|                                     escape = False | ||||
|                                 command_buffer = command_buffer+bytes([byte]) | ||||
|                                 if (len(command_buffer) == 33): | ||||
|                                     if command_buffer[0] == 0x01: | ||||
|                                         self.firmware_hash_target = command_buffer[1:] | ||||
|                                     if command_buffer[0] == 0x02: | ||||
|                                         self.firmware_hash = command_buffer[1:] | ||||
| 
 | ||||
| @ -580,7 +583,7 @@ class RNode(): | ||||
| 
 | ||||
|         except Exception as e: | ||||
|             raise e | ||||
|             exit() | ||||
|             graceful_exit() | ||||
| 
 | ||||
|     def updateBitrate(self): | ||||
|         try: | ||||
| @ -596,7 +599,7 @@ class RNode(): | ||||
|         self.version = str(self.major_version)+"."+minstr | ||||
| 
 | ||||
|     def detect(self): | ||||
|         kiss_command = bytes([KISS.FEND, KISS.CMD_DETECT, KISS.DETECT_REQ, KISS.FEND, KISS.CMD_FW_VERSION, 0x00, KISS.FEND, KISS.CMD_PLATFORM, 0x00, KISS.FEND, KISS.CMD_MCU, 0x00, KISS.FEND, KISS.CMD_BOARD, 0x00, KISS.FEND, KISS.CMD_DEV_HASH, 0x01, KISS.FEND, KISS.CMD_HASHES, 0x02, KISS.FEND]) | ||||
|         kiss_command = bytes([KISS.FEND, KISS.CMD_DETECT, KISS.DETECT_REQ, KISS.FEND, KISS.CMD_FW_VERSION, 0x00, KISS.FEND, KISS.CMD_PLATFORM, 0x00, KISS.FEND, KISS.CMD_MCU, 0x00, KISS.FEND, KISS.CMD_BOARD, 0x00, KISS.FEND, KISS.CMD_DEV_HASH, 0x01, KISS.FEND, KISS.CMD_HASHES, 0x01, KISS.FEND, KISS.CMD_HASHES, 0x02, KISS.FEND]) | ||||
|         written = self.serial.write(kiss_command) | ||||
|         if written != len(kiss_command): | ||||
|             raise IOError("An IO error occurred while detecting hardware for "+self(str)) | ||||
| @ -606,6 +609,7 @@ class RNode(): | ||||
|         written = self.serial.write(kiss_command) | ||||
|         if written != len(kiss_command): | ||||
|             raise IOError("An IO error occurred while sending host left command to device") | ||||
|         sleep(1) | ||||
| 
 | ||||
|     def set_display_intensity(self, intensity): | ||||
|         data = bytes([intensity & 0xFF]) | ||||
| @ -773,7 +777,7 @@ class RNode(): | ||||
|         sleep(0.6) | ||||
|         if self.eeprom == None: | ||||
|             RNS.log("Could not download EEPROM from device. Is a valid firmware installed?") | ||||
|             exit() | ||||
|             graceful_exit() | ||||
|         else: | ||||
|             self.parse_eeprom() | ||||
| 
 | ||||
| @ -819,7 +823,7 @@ class RNode(): | ||||
|                 if self.checksum != checksum: | ||||
|                     self.provisioned = False | ||||
|                     RNS.log("EEPROM checksum mismatch") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
|                 else: | ||||
|                     RNS.log("EEPROM checksum correct") | ||||
| 
 | ||||
| @ -1000,7 +1004,7 @@ def ensure_firmware_file(fw_filename): | ||||
|                 RNS.log("One or more required firmware files are missing from the extracted RNode") | ||||
|                 RNS.log("Firmware archive. Installation cannot continue. Please try extracting the") | ||||
|                 RNS.log("firmware again with the --extract-firmware option.") | ||||
|                 exit(184) | ||||
|                 graceful_exit(184) | ||||
| 
 | ||||
|             vf = open(vfpath, "rb") | ||||
|             release_info = vf.read().decode("utf-8").strip() | ||||
| @ -1010,7 +1014,7 @@ def ensure_firmware_file(fw_filename): | ||||
|         else: | ||||
|             RNS.log("No extracted firmware is available, cannot continue.") | ||||
|             RNS.log("Extract a firmware from an existing RNode first, using the --extract-firmware option.") | ||||
|             exit(183) | ||||
|             graceful_exit(183) | ||||
| 
 | ||||
|     else: | ||||
|         try: | ||||
| @ -1044,7 +1048,7 @@ def ensure_firmware_file(fw_filename): | ||||
|                             RNS.log("Check your internet connection and try again.") | ||||
|                             RNS.log("If you don't have Internet access currently, use the --fw-version option to manually specify a version.") | ||||
|                             RNS.log("You can also use --extract to copy the firmware from a known-good RNode of the same model.") | ||||
|                             exit() | ||||
|                             graceful_exit() | ||||
|                 except Exception as e: | ||||
|                     # if custom firmware url, don't fallback | ||||
|                     if fw_url != None: | ||||
| @ -1052,7 +1056,7 @@ def ensure_firmware_file(fw_filename): | ||||
|                         RNS.log("Check your internet connection and try again.") | ||||
|                         RNS.log("If you don't have Internet access currently, use the --fw-version option to manually specify a version.") | ||||
|                         RNS.log("You can also use --extract to copy the firmware from a known-good RNode of the same model.") | ||||
|                         exit() | ||||
|                         graceful_exit() | ||||
| 
 | ||||
|                     RNS.log("") | ||||
|                     RNS.log("WARNING!") | ||||
| @ -1081,7 +1085,7 @@ def ensure_firmware_file(fw_filename): | ||||
|                 selected_version = release_info.split()[0] | ||||
|                 if selected_version == "not": | ||||
|                     RNS.log("No valid version found for this board, exiting.") | ||||
|                     exit(199) | ||||
|                     graceful_exit(199) | ||||
| 
 | ||||
|                 selected_hash = release_info.split()[1] | ||||
|                 if not os.path.isdir(UPD_DIR+"/"+selected_version): | ||||
| @ -1092,7 +1096,7 @@ def ensure_firmware_file(fw_filename): | ||||
|             else: | ||||
|                 RNS.log("Online firmware version check was disabled, but no firmware version specified for install.") | ||||
|                 RNS.log("use the --fw-version option to manually specify a version.") | ||||
|                 exit(98) | ||||
|                 graceful_exit(98) | ||||
| 
 | ||||
|             # if custom firmware url, use it | ||||
|             if fw_url != None: | ||||
| @ -1126,7 +1130,7 @@ def ensure_firmware_file(fw_filename): | ||||
| 
 | ||||
|                         if selected_hash == None: | ||||
|                             RNS.log("No release hash found for "+fw_filename+". The firmware integrity could not be verified.") | ||||
|                             exit(97) | ||||
|                             graceful_exit(97) | ||||
| 
 | ||||
|                     RNS.log("Verifying firmware integrity...") | ||||
|                     fw_file = open(UPD_DIR+"/"+selected_version+"/"+fw_filename, "rb") | ||||
| @ -1137,24 +1141,24 @@ def ensure_firmware_file(fw_filename): | ||||
|                     else: | ||||
|                         RNS.log("") | ||||
|                         RNS.log("Firmware corrupt. Try clearing the local firmware cache with: rnodeconf --clear-cache") | ||||
|                         exit(96) | ||||
|                         graceful_exit(96) | ||||
| 
 | ||||
|                 except Exception as e: | ||||
|                     RNS.log("An error occurred while checking firmware file integrity. The contained exception was:") | ||||
|                     RNS.log(str(e)) | ||||
|                     exit(95) | ||||
|                     graceful_exit(95) | ||||
| 
 | ||||
|             except Exception as e: | ||||
|                 RNS.log("Could not download required firmware file: ") | ||||
|                 RNS.log(str(update_target_url)) | ||||
|                 RNS.log("The contained exception was:") | ||||
|                 RNS.log(str(e)) | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|         except Exception as e: | ||||
|             RNS.log("An error occurred while reading version information for "+str(fw_filename)+". The contained exception was:") | ||||
|             RNS.log(str(e)) | ||||
|             exit() | ||||
|             graceful_exit() | ||||
| 
 | ||||
| def rnode_open_serial(port): | ||||
|     import serial | ||||
| @ -1171,6 +1175,21 @@ def rnode_open_serial(port): | ||||
|         write_timeout = None, | ||||
|         dsrdtr = False | ||||
|     ) | ||||
|      | ||||
|      | ||||
| def graceful_exit(C=0): | ||||
|     if RNS.vendor.platformutils.is_windows(): | ||||
|         RNS.log("Windows detected; delaying DTR",RNS.LOG_VERBOSE)  | ||||
|         if rnode: | ||||
|             RNS.log("Sending \"Leave\" to Rnode",RNS.LOG_VERBOSE) | ||||
|             rnode.leave() # Leave has wait built in | ||||
|         elif rnode_serial: | ||||
|             RNS.log("Closing raw serial",RNS.LOG_VERBOSE) | ||||
|             sleep(1) # Wait for MCU to complete operation before DTR goes false | ||||
|             rnode_serial.close() | ||||
|     RNS.log("Exiting: Code "+str(C),RNS.LOG_INFO) | ||||
|     exit(C) | ||||
| 
 | ||||
| 
 | ||||
| device_signer = None | ||||
| force_update = False | ||||
| @ -1186,7 +1205,7 @@ def main(): | ||||
|         print("RNode Config Utility needs pyserial to work.") | ||||
|         print("You can install it with: pip3 install pyserial") | ||||
|         print("") | ||||
|         exit() | ||||
|         graceful_exit() | ||||
| 
 | ||||
|     try: | ||||
|         if not util.find_spec("cryptography"): | ||||
| @ -1196,7 +1215,7 @@ def main(): | ||||
|         print("RNode Config Utility needs the cryptography module to work.") | ||||
|         print("You can install it with: pip3 install cryptography") | ||||
|         print("") | ||||
|         exit() | ||||
|         graceful_exit() | ||||
| 
 | ||||
|     import serial | ||||
|     from serial.tools import list_ports | ||||
| @ -1245,6 +1264,8 @@ def main(): | ||||
|         parser.add_argument("-k", "--key", action="store_true", help="Generate a new signing key and exit") #  | ||||
|         parser.add_argument("-S", "--sign", action="store_true", help="Display public part of signing key") | ||||
|         parser.add_argument("-H", "--firmware-hash", action="store", help="Display installed firmware hash") | ||||
|         parser.add_argument("-K", "--get-target-firmware-hash", action="store_true", help=argparse.SUPPRESS) # Get target firmware hash from device | ||||
|         parser.add_argument("-L", "--get-firmware-hash", action="store_true", help=argparse.SUPPRESS) # Get calculated firmware hash from device | ||||
|         parser.add_argument("--platform", action="store", metavar="platform", type=str, default=None, help="Platform specification for device bootstrap") | ||||
|         parser.add_argument("--product", action="store", metavar="product", type=str, default=None, help="Product specification for device bootstrap") #  | ||||
|         parser.add_argument("--model", action="store", metavar="model", type=str, default=None, help="Model code for device bootstrap") | ||||
| @ -1264,14 +1285,14 @@ def main(): | ||||
| 
 | ||||
|         if args.version: | ||||
|             print("rnodeconf "+program_version) | ||||
|             exit(0) | ||||
|             graceful_exit(0) | ||||
| 
 | ||||
|         if args.clear_cache: | ||||
|             RNS.log("Clearing local firmware cache...") | ||||
|             import shutil | ||||
|             shutil.rmtree(UPD_DIR) | ||||
|             RNS.log("Done") | ||||
|             exit(0) | ||||
|             graceful_exit(0) | ||||
| 
 | ||||
|         if args.fw_version != None: | ||||
|             selected_version = args.fw_version | ||||
| @ -1279,7 +1300,7 @@ def main(): | ||||
|                 check_float = float(selected_version) | ||||
|             except ValueError: | ||||
|                 RNS.log("Selected version \""+selected_version+"\" does not appear to be a number.") | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|         if args.fw_url != None: | ||||
|             fw_url = args.fw_url | ||||
| @ -1318,7 +1339,7 @@ def main(): | ||||
| 
 | ||||
|             except Exception as e: | ||||
|                 RNS.log("Invalid key data supplied") | ||||
|             exit(0) | ||||
|             graceful_exit(0) | ||||
| 
 | ||||
|         if args.use_extracted and ((args.update and args.port != None) or args.autoinstall): | ||||
|             print("") | ||||
| @ -1357,11 +1378,11 @@ def main(): | ||||
|                     selected_port = portlist[c_port-1] | ||||
|                 except Exception as e: | ||||
|                     print("That port does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 if selected_port == None: | ||||
|                     print("Could not select port, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 port_path = selected_port.device | ||||
|                 port_product = selected_port.product | ||||
| @ -1378,7 +1399,7 @@ def main(): | ||||
| 
 | ||||
|                 if selected_port == None: | ||||
|                     print("Could not find specified port "+str(args.port)+", exiting now") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 port_path = selected_port.device | ||||
|                 port_product = selected_port.product | ||||
| @ -1393,7 +1414,7 @@ def main(): | ||||
|             except Exception as e: | ||||
|                 RNS.log("Could not open the specified serial port. The contained exception was:") | ||||
|                 RNS.log(str(e)) | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             rnode = RNode(rnode_serial) | ||||
|             rnode.usb_serial_id = port_serialno | ||||
| @ -1457,10 +1478,10 @@ def main(): | ||||
|                         print("Could not read firmware information from device") | ||||
| 
 | ||||
|                 print("\nRNode firmware extraction failed") | ||||
|                 exit(180) | ||||
|                 graceful_exit(180) | ||||
|             else: | ||||
|                 print("\nFirmware extraction is currently only supported on ESP32-based RNodes.") | ||||
|                 exit(170) | ||||
|                 graceful_exit(170) | ||||
| 
 | ||||
|         if args.autoinstall: | ||||
|             clear() | ||||
| @ -1494,11 +1515,11 @@ def main(): | ||||
|                     selected_port = portlist[c_port-1] | ||||
|                 except Exception as e: | ||||
|                     print("That port does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 if selected_port == None: | ||||
|                     print("Could not select port, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 port_path = selected_port.device | ||||
|                 port_product = selected_port.product | ||||
| @ -1516,7 +1537,7 @@ def main(): | ||||
| 
 | ||||
|                 if selected_port == None: | ||||
|                     print("Could not find specified port "+str(args.port)+", exiting now") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 port_path = selected_port.device | ||||
|                 port_product = selected_port.product | ||||
| @ -1531,7 +1552,7 @@ def main(): | ||||
|             except Exception as e: | ||||
|                 RNS.log("Could not open the specified serial port. The contained exception was:") | ||||
|                 RNS.log(str(e)) | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             rnode = RNode(rnode_serial) | ||||
|             rnode.usb_serial_id = port_serialno | ||||
| @ -1549,7 +1570,7 @@ def main(): | ||||
|                 print("\nThis device is already installed and provisioned. No further action will") | ||||
|                 print("be taken. If you wish to completely reinstall this device, you must first") | ||||
|                 print("wipe the current EEPROM. See the help for more info.\n\nExiting now.") | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             print("\n---------------------------------------------------------------------------") | ||||
|             print("                               Device Selection") | ||||
| @ -1735,7 +1756,7 @@ def main(): | ||||
|                     input() | ||||
|             except Exception as e: | ||||
|                 print("That device type does not exist, exiting now.") | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             selected_platform = None | ||||
|             selected_model = None | ||||
| @ -1764,7 +1785,7 @@ def main(): | ||||
| 
 | ||||
|                 except Exception as e: | ||||
|                     print("That MCU type does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 print("\nWhat transceiver module does your board use?\n") | ||||
|                 print("[1] SX1276/SX1278 with antenna port on PA_BOOST pin") | ||||
| @ -1781,7 +1802,7 @@ def main(): | ||||
| 
 | ||||
|                 except Exception as e: | ||||
|                     print("That transceiver type does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
| 
 | ||||
|             elif selected_product == ROM.PRODUCT_RNODE: | ||||
| @ -1833,7 +1854,7 @@ def main(): | ||||
|                         #     selected_platform = ROM.PLATFORM_ESP32 | ||||
|                     except Exception as e: | ||||
|                         print("That model does not exist, exiting now.") | ||||
|                         exit() | ||||
|                         graceful_exit() | ||||
|                 else: | ||||
|                     print("\nWhat model is this T3S3?\n") | ||||
|                     print("[1] 410 - 525 MHz (with SX1268 chip)") | ||||
| @ -1853,7 +1874,7 @@ def main(): | ||||
|                             selected_platform = ROM.PLATFORM_ESP32 | ||||
|                     except Exception as e: | ||||
|                         print("That model does not exist, exiting now.") | ||||
|                         exit() | ||||
|                         graceful_exit() | ||||
| 
 | ||||
|             elif selected_product == ROM.PRODUCT_TBEAM: | ||||
|                 selected_mcu = ROM.MCU_ESP32 | ||||
| @ -1882,7 +1903,7 @@ def main(): | ||||
|                         selected_platform = ROM.PLATFORM_ESP32 | ||||
|                 except Exception as e: | ||||
|                     print("That band does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|             elif selected_product == ROM.PRODUCT_T32_10: | ||||
|                 selected_mcu = ROM.MCU_ESP32 | ||||
| @ -1904,7 +1925,7 @@ def main(): | ||||
|                         selected_platform = ROM.PLATFORM_ESP32 | ||||
|                 except Exception as e: | ||||
|                     print("That band does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|             elif selected_product == ROM.PRODUCT_T32_20: | ||||
|                 selected_mcu = ROM.MCU_ESP32 | ||||
| @ -1926,7 +1947,7 @@ def main(): | ||||
|                         selected_platform = ROM.PLATFORM_ESP32 | ||||
|                 except Exception as e: | ||||
|                     print("That band does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|             elif selected_product == ROM.PRODUCT_T32_21: | ||||
|                 selected_mcu = ROM.MCU_ESP32 | ||||
| @ -1954,7 +1975,7 @@ def main(): | ||||
|                         selected_platform = ROM.PLATFORM_ESP32 | ||||
|                 except Exception as e: | ||||
|                     print("That band does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|             elif selected_product == ROM.PRODUCT_H32_V2: | ||||
|                 selected_mcu = ROM.MCU_ESP32 | ||||
| @ -1976,7 +1997,7 @@ def main(): | ||||
|                         selected_platform = ROM.PLATFORM_ESP32 | ||||
|                 except Exception as e: | ||||
|                     print("That band does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|             elif selected_product == ROM.PRODUCT_H32_V3: | ||||
|                 selected_mcu = ROM.MCU_ESP32 | ||||
| @ -2014,7 +2035,7 @@ def main(): | ||||
|                         selected_platform = ROM.PLATFORM_NRF52 | ||||
|                 except Exception as e: | ||||
|                     print("That band does not exist, exiting now.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|             if selected_model != ROM.MODEL_FF and selected_model != ROM.MODEL_FE: | ||||
|                 fw_filename = models[selected_model][4] | ||||
| @ -2042,7 +2063,7 @@ def main(): | ||||
|                             fw_filename = "rnode_firmware_esp32_generic.zip" | ||||
|                     except Exception as e: | ||||
|                         print("That ESP32 board does not exist, exiting now.") | ||||
|                         exit() | ||||
|                         graceful_exit() | ||||
| 
 | ||||
|             if fw_filename == None: | ||||
|                 print("") | ||||
| @ -2052,7 +2073,7 @@ def main(): | ||||
|                 print("") | ||||
|                 print_donation_block() | ||||
|                 print("") | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             if args.use_extracted: | ||||
|                 fw_filename = "extracted_rnode_firmware.zip" | ||||
| @ -2082,7 +2103,7 @@ def main(): | ||||
|                     raise ValueError() | ||||
|             except Exception as e: | ||||
|                 print("OK, aborting now.") | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             args.key = True | ||||
|             args.port = selected_port.device | ||||
| @ -2099,7 +2120,7 @@ def main(): | ||||
|             except Exception as e: | ||||
|                 RNS.log("Could not obain firmware package for your board") | ||||
|                 RNS.log("The contained exception was: "+str(e)) | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             rnode.disconnect() | ||||
| 
 | ||||
| @ -2140,7 +2161,7 @@ def main(): | ||||
|                 RNS.log("Could not load device signing key") | ||||
|                  | ||||
| 
 | ||||
|             exit() | ||||
|             graceful_exit() | ||||
| 
 | ||||
|         if args.key: | ||||
|             if not os.path.isfile(FWD_DIR+"/device.key"): | ||||
| @ -2153,7 +2174,7 @@ def main(): | ||||
|                     RNS.log("Could not create new device signing key at "+str(FWD_DIR+"/device.key")+". The contained exception was:") | ||||
|                     RNS.log(str(e)) | ||||
|                     RNS.log("Please ensure filesystem access and try again.") | ||||
|                     exit(81) | ||||
|                     graceful_exit(81) | ||||
|             else: | ||||
|                 try: | ||||
|                     device_signer = RNS.Identity.from_file(FWD_DIR+"/device.key") | ||||
| @ -2161,7 +2182,7 @@ def main(): | ||||
|                     RNS.log("Could not load device signing key from "+str(FWD_DIR+"/device.key")+". The contained exception was:") | ||||
|                     RNS.log(str(e)) | ||||
|                     RNS.log("Please restore or clear the key and try again.") | ||||
|                     exit(82) | ||||
|                     graceful_exit(82) | ||||
| 
 | ||||
|             if not os.path.isfile(FWD_DIR+"/signing.key"): | ||||
|                 RNS.log("Generating a new EEPROM signing key...") | ||||
| @ -2199,7 +2220,7 @@ def main(): | ||||
|                 RNS.log("The firmware directory does not exist, can't write key!") | ||||
| 
 | ||||
|             if not args.autoinstall: | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|         def get_partition_hash(platform, partition_file): | ||||
|             try: | ||||
| @ -2241,7 +2262,7 @@ def main(): | ||||
|                     RNS.log("  sudo apt install "+flasher) | ||||
|                     RNS.log("") | ||||
|                     RNS.log("Please install \""+flasher+"\" and try again.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
|             elif platform == ROM.PLATFORM_AVR: | ||||
|                 flasher = "avrdude" | ||||
|                 if which(flasher) is not None: | ||||
| @ -2260,7 +2281,7 @@ def main(): | ||||
|                     RNS.log("  sudo apt install avrdude") | ||||
|                     RNS.log("") | ||||
|                     RNS.log("Please install \""+flasher+"\" and try again.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
|             elif platform == ROM.PLATFORM_ESP32: | ||||
|                 numeric_version = float(selected_version) | ||||
|                 flasher_dir = UPD_DIR+"/"+selected_version | ||||
| @ -2720,7 +2741,8 @@ def main(): | ||||
|                     RNS.log("  sudo apt install esptool") | ||||
|                     RNS.log("") | ||||
|                     RNS.log("Please install \""+flasher+"\" and try again.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|             elif platform == ROM.PLATFORM_NRF52: | ||||
|                 flasher = "adafruit-nrfutil" | ||||
|                 if which(flasher) is not None: | ||||
| @ -2734,7 +2756,7 @@ def main(): | ||||
|                     RNS.log("  pip3 install --user adafruit-nrfutil") | ||||
|                     RNS.log("") | ||||
|                     RNS.log("Please install \""+flasher+"\" and try again.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|         if args.port: | ||||
|             wants_fw_provision = False | ||||
| @ -2749,7 +2771,7 @@ def main(): | ||||
| 
 | ||||
|                 if selected_version == None: | ||||
|                     RNS.log("Missing parameters, cannot continue") | ||||
|                     exit(68) | ||||
|                     graceful_exit(68) | ||||
| 
 | ||||
|                 if fw_filename == "extracted_rnode_firmware.zip": | ||||
|                     try: | ||||
| @ -2765,12 +2787,12 @@ def main(): | ||||
|                                 RNS.log("Waiting for ESP32 reset...") | ||||
|                                 time.sleep(7) | ||||
|                         else: | ||||
|                             exit() | ||||
|                             graceful_exit() | ||||
| 
 | ||||
|                     except Exception as e: | ||||
|                         RNS.log("Error while flashing") | ||||
|                         RNS.log(str(e)) | ||||
|                         exit(1) | ||||
|                         graceful_exit(1) | ||||
|                  | ||||
|                 else: | ||||
|                     fw_src = UPD_DIR+"/"+selected_version+"/" | ||||
| @ -2783,7 +2805,7 @@ def main(): | ||||
|                                         zip.extractall(fw_src) | ||||
|                                 except Exception as e: | ||||
|                                     RNS.log("Could not decompress firmware from downloaded zip file") | ||||
|                                     exit() | ||||
|                                     graceful_exit() | ||||
|                                 RNS.log("Firmware decompressed") | ||||
| 
 | ||||
|                             RNS.log("Flashing RNode firmware to device on "+args.port) | ||||
| @ -2807,15 +2829,15 @@ def main(): | ||||
|                                 RNS.log("Some boards have trouble flashing at high speeds, and you can") | ||||
|                                 RNS.log("try flashing with a lower baud rate, as in this example:") | ||||
|                                 RNS.log("rnodeconf --autoinstall --baud-flash 115200") | ||||
|                                 exit() | ||||
|                                 graceful_exit() | ||||
| 
 | ||||
|                         except Exception as e: | ||||
|                             RNS.log("Error while flashing") | ||||
|                             RNS.log(str(e)) | ||||
|                             exit(1) | ||||
|                             graceful_exit(1) | ||||
|                     else: | ||||
|                         RNS.log("Firmware file not found") | ||||
|                         exit() | ||||
|                         graceful_exit() | ||||
| 
 | ||||
|             RNS.log("Opening serial port "+args.port+"...") | ||||
|             try: | ||||
| @ -2824,7 +2846,7 @@ def main(): | ||||
|             except Exception as e: | ||||
|                 RNS.log("Could not open the specified serial port. The contained exception was:") | ||||
|                 RNS.log(str(e)) | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             rnode = RNode(rnode_serial) | ||||
|             ports = list_ports.comports() | ||||
| @ -2839,7 +2861,7 @@ def main(): | ||||
|             except Exception as e: | ||||
|                 RNS.log("Serial port opened, but RNode did not respond. Is a valid firmware installed?") | ||||
|                 print(e) | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             if rnode.detected: | ||||
|                 if rnode.platform == None or rnode.mcu == None: | ||||
| @ -2850,7 +2872,10 @@ def main(): | ||||
|             if args.eeprom_wipe: | ||||
|                 RNS.log("WARNING: EEPROM is being wiped! Power down device NOW if you do not want this!") | ||||
|                 rnode.wipe_eeprom() | ||||
|                 exit() | ||||
| 
 | ||||
|                 # TODO: Add conditional for avoiding this reset on nRF | ||||
|                 rnode.hard_reset() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             RNS.log("Reading EEPROM...") | ||||
|             rnode.download_eeprom() | ||||
| @ -2880,12 +2905,12 @@ def main(): | ||||
| 
 | ||||
|                                 if args.update: | ||||
|                                     RNS.log("ERROR: No firmware found for this board. Cannot update.") | ||||
|                                     exit() | ||||
|                                     graceful_exit() | ||||
| 
 | ||||
|             if args.update: | ||||
|                 if not rnode.provisioned: | ||||
|                     RNS.log("Device not provisioned. Cannot update device firmware.") | ||||
|                     exit(1) | ||||
|                     graceful_exit(1) | ||||
| 
 | ||||
|                 if args.use_extracted: | ||||
|                     fw_filename = "extracted_rnode_firmware.zip" | ||||
| @ -2904,21 +2929,21 @@ def main(): | ||||
|                             if args.fw_version != None: | ||||
|                                 RNS.log("Specified firmware version ("+selected_version+") is already installed on this device") | ||||
|                                 RNS.log("Override with -U option to install anyway") | ||||
|                                 exit(0) | ||||
|                                 graceful_exit(0) | ||||
|                             else: | ||||
|                                 RNS.log("Latest firmware version ("+selected_version+") is already installed on this device") | ||||
|                                 RNS.log("Override with -U option to install anyway") | ||||
|                                 exit(0) | ||||
|                                 graceful_exit(0) | ||||
| 
 | ||||
|                         if rnode.version > selected_version: | ||||
|                             if args.fw_version != None: | ||||
|                                 RNS.log("Specified firmware version ("+selected_version+") is older than firmware already installed on this device") | ||||
|                                 RNS.log("Override with -U option to install anyway") | ||||
|                                 exit(0) | ||||
|                                 graceful_exit(0) | ||||
|                             else: | ||||
|                                 RNS.log("Latest firmware version ("+selected_version+") is older than firmware already installed on this device") | ||||
|                                 RNS.log("Override with -U option to install anyway") | ||||
|                                 exit(0) | ||||
|                                 graceful_exit(0) | ||||
| 
 | ||||
|                     if not fw_file_ensured and selected_version != None: | ||||
|                         ensure_firmware_file(fw_filename) | ||||
| @ -2931,13 +2956,13 @@ def main(): | ||||
|                                 zip.extractall(fw_src) | ||||
|                         except Exception as e: | ||||
|                             RNS.log("Could not decompress firmware from downloaded zip file") | ||||
|                             exit() | ||||
|                             graceful_exit() | ||||
|                         RNS.log("Firmware decompressed") | ||||
| 
 | ||||
|                 except Exception as e: | ||||
|                     RNS.log("Could not obtain firmware package for your board") | ||||
|                     RNS.log("The contained exception was: "+str(e)) | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 if fw_filename == "extracted_rnode_firmware.zip": | ||||
|                     update_full_path = EXT_DIR+"/extracted_rnode_firmware.version" | ||||
| @ -2979,7 +3004,7 @@ def main(): | ||||
|                             except Exception as e: | ||||
|                                 RNS.log("Could not open the specified serial port. The contained exception was:") | ||||
|                                 RNS.log(str(e)) | ||||
|                                 exit() | ||||
|                                 graceful_exit() | ||||
| 
 | ||||
|                             rnode = RNode(rnode_serial) | ||||
|                             thread = threading.Thread(target=rnode.readLoop, daemon=True).start() | ||||
| @ -2989,7 +3014,7 @@ def main(): | ||||
|                             except Exception as e: | ||||
|                                 RNS.log("Serial port opened, but RNode did not respond. Is a valid firmware installed?") | ||||
|                                 print(e) | ||||
|                                 exit() | ||||
|                                 graceful_exit() | ||||
| 
 | ||||
|                             if rnode.detected: | ||||
|                                 if rnode.platform == None or rnode.mcu == None: | ||||
| @ -3013,19 +3038,19 @@ def main(): | ||||
|                                 RNS.log("Firmware update completed successfully") | ||||
|                         else: | ||||
|                             RNS.log("An error occurred while flashing the new firmware, exiting now.") | ||||
|                             exit() | ||||
|                             graceful_exit() | ||||
| 
 | ||||
|                     except Exception as e: | ||||
|                         RNS.log("Error while updating firmware") | ||||
|                         RNS.log(str(e)) | ||||
|                 else: | ||||
|                     RNS.log("Firmware update file not found") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|             if args.eeprom_dump: | ||||
|                 RNS.log("EEPROM contents:") | ||||
|                 RNS.log(RNS.hexrep(rnode.eeprom)) | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             if args.eeprom_backup: | ||||
|                 try: | ||||
| @ -3039,7 +3064,7 @@ def main(): | ||||
|                 except Exception as e: | ||||
|                     RNS.log("EEPROM was successfully downloaded from device,") | ||||
|                     RNS.log("but file could not be written to disk.") | ||||
|                 exit() | ||||
|                 graceful_exit() | ||||
| 
 | ||||
|             if isinstance(args.display, int): | ||||
|                 di = args.display | ||||
| @ -3064,7 +3089,7 @@ def main(): | ||||
|                     RNS.log("Setting display address to "+RNS.hexrep(da, delimit=False)) | ||||
|                     rnode.set_display_address(ord(da)) | ||||
|                     rnode.hard_reset() | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
|                 else: | ||||
|                     RNS.log("Invalid display address specified") | ||||
| 
 | ||||
| @ -3134,23 +3159,23 @@ def main(): | ||||
| 
 | ||||
|                     print("") | ||||
|                     rnode.disconnect() | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 else: | ||||
|                     RNS.log("EEPROM is invalid, no further information available") | ||||
|                     exit() | ||||
|                     egraceful_xit() | ||||
| 
 | ||||
|             if args.rom: | ||||
|                 if rnode.provisioned and not args.autoinstall: | ||||
|                     RNS.log("EEPROM bootstrap was requested, but a valid EEPROM was already present.") | ||||
|                     RNS.log("No changes are being made.") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
| 
 | ||||
|                 else: | ||||
|                     if rnode.signature_valid: | ||||
|                         RNS.log("EEPROM bootstrap was requested, but a valid EEPROM was already present.") | ||||
|                         RNS.log("No changes are being made.") | ||||
|                         exit() | ||||
|                         graceful_exit() | ||||
|                     else: | ||||
|                         if args.autoinstall: | ||||
|                             RNS.log("Clearing old EEPROM, this will take about 15 seconds...") | ||||
| @ -3196,7 +3221,7 @@ def main(): | ||||
|                     except Exception as e: | ||||
|                         RNS.log("Could not create device serial number, exiting") | ||||
|                         RNS.log(str(e)) | ||||
|                         exit() | ||||
|                         graceful_exit() | ||||
| 
 | ||||
|                     serialno = counter+1 | ||||
|                     model = None | ||||
| @ -3298,7 +3323,7 @@ def main(): | ||||
|                                     RNS.log(str(e)) | ||||
|                             else: | ||||
|                                 RNS.log("No signing key found") | ||||
|                                 exit() | ||||
|                                 graceful_exit() | ||||
| 
 | ||||
|                             if model == ROM.MODEL_A1 or model == ROM.MODEL_A6: | ||||
|                                 rnode.hard_reset() | ||||
| @ -3454,10 +3479,10 @@ def main(): | ||||
|                                     file.close() | ||||
|                                 except Exception as e: | ||||
|                                     RNS.log("WARNING: Could not backup device EEPROM to disk") | ||||
|                                 exit() | ||||
|                                 graceful_exit() | ||||
|                             else: | ||||
|                                 RNS.log("EEPROM was written, but validation failed. Check your settings.") | ||||
|                                 exit() | ||||
|                                 graceful_exit() | ||||
|                         except Exception as e: | ||||
|                             RNS.log("An error occurred while writing EEPROM. The contained exception was:") | ||||
|                             RNS.log(str(e)) | ||||
| @ -3465,7 +3490,7 @@ def main(): | ||||
| 
 | ||||
|                     else: | ||||
|                         RNS.log("Invalid data specified, cancelling EEPROM write") | ||||
|                         exit() | ||||
|                         graceful_exit() | ||||
| 
 | ||||
|             if args.sign: | ||||
|                 if rnode.provisioned: | ||||
| @ -3479,14 +3504,14 @@ def main(): | ||||
|                     else: | ||||
|                         if device_signer == None: | ||||
|                             RNS.log("No device signer loaded, cannot sign device") | ||||
|                             exit(78) | ||||
|                             graceful_exit(78) | ||||
|                         else: | ||||
|                             new_device_signature = device_signer.sign(rnode.device_hash) | ||||
|                             rnode.store_signature(new_device_signature) | ||||
|                             RNS.log("Device signed") | ||||
|                 else: | ||||
|                     RNS.log("This device has not been provisioned yet, cannot create device signature") | ||||
|                     exit(79) | ||||
|                     graceful_exit(79) | ||||
| 
 | ||||
|             if args.firmware_hash != None: | ||||
|                 if rnode.provisioned: | ||||
| @ -3499,17 +3524,33 @@ def main(): | ||||
|                         RNS.log("Firmware hash set") | ||||
|                     except Exception as e: | ||||
|                         RNS.log("The provided value was not a valid SHA256 hash") | ||||
|                         exit(78) | ||||
|                         graceful_exit(78) | ||||
| 
 | ||||
|                 else: | ||||
|                     RNS.log("This device has not been provisioned yet, cannot set firmware hash") | ||||
|                     graceful_exit(77) | ||||
| 
 | ||||
|             if args.get_target_firmware_hash: | ||||
|                 if rnode.provisioned: | ||||
|                     RNS.log(f"The target firmware hash is: {rnode.firmware_hash_target.hex()}") | ||||
| 
 | ||||
|                 else: | ||||
|                     RNS.log("This device has not been provisioned yet, cannot get firmware hash") | ||||
|                     exit(77) | ||||
|                  | ||||
|             if args.get_firmware_hash: | ||||
|                 if rnode.provisioned: | ||||
|                     RNS.log(f"The actual firmware hash is: {rnode.firmware_hash.hex()}") | ||||
| 
 | ||||
|                 else: | ||||
|                     RNS.log("This device has not been provisioned yet, cannot get firmware hash") | ||||
|                     exit(77) | ||||
| 
 | ||||
|             if rnode.provisioned: | ||||
|                 if args.normal: | ||||
|                     rnode.setNormalMode() | ||||
|                     RNS.log("Device set to normal (host-controlled) operating mode") | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
|                 if args.tnc: | ||||
|                     if not (args.freq and args.bw and args.txp and args.sf and args.cr): | ||||
|                         RNS.log("Please input startup configuration:") | ||||
| @ -3554,7 +3595,7 @@ def main(): | ||||
|                     RNS.log("Device set to TNC operating mode") | ||||
|                     sleep(1.0) | ||||
| 
 | ||||
|                     exit() | ||||
|                     graceful_exit() | ||||
|             else: | ||||
|                 RNS.log("This device contains a valid firmware, but EEPROM is invalid.") | ||||
|                 RNS.log("Probably the device has not been initialised, or the EEPROM has been erased.") | ||||
| @ -3564,12 +3605,14 @@ def main(): | ||||
|             print("") | ||||
|             parser.print_help() | ||||
|             print("") | ||||
|             exit() | ||||
|             graceful_exit() | ||||
| 
 | ||||
| 
 | ||||
|     except KeyboardInterrupt: | ||||
|         print("") | ||||
|         exit() | ||||
|         graceful_exit() | ||||
|          | ||||
|     graceful_exit() | ||||
| 
 | ||||
| def extract_recovery_esptool(): | ||||
|     if not os.path.isfile(RT_PATH): | ||||
| @ -3583,7 +3626,7 @@ def extract_recovery_esptool(): | ||||
|         except Exception as e: | ||||
|             RNS.log("Error: Could not extract recovery ESP-Tool. The contained exception was:") | ||||
|             RNS.log(str(e)) | ||||
|             exit(181) | ||||
|             graceful_exit(181) | ||||
| 
 | ||||
| if __name__ == "__main__": | ||||
|     main() | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| __version__ = "0.7.4" | ||||
| __version__ = "0.7.5" | ||||
|  | ||||
							
								
								
									
										19
									
								
								RNS/vendor/ifaddr/niwrapper.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								RNS/vendor/ifaddr/niwrapper.py
									
									
									
									
										vendored
									
									
								
							| @ -11,6 +11,25 @@ def interfaces() -> List[str]: | ||||
|     adapters = RNS.vendor.ifaddr.get_adapters(include_unconfigured=True) | ||||
|     return [a.name for a in adapters] | ||||
| 
 | ||||
| def interface_names_to_indexes() -> dict: | ||||
|     adapters = RNS.vendor.ifaddr.get_adapters(include_unconfigured=True) | ||||
|     results = {} | ||||
|     for adapter in adapters: | ||||
|         results[adapter.name] = adapter.index | ||||
|     return results | ||||
| 
 | ||||
| def interface_name_to_nice_name(ifname) -> str: | ||||
|     try: | ||||
|         adapters = RNS.vendor.ifaddr.get_adapters(include_unconfigured=True) | ||||
|         for adapter in adapters: | ||||
|             if adapter.name == ifname: | ||||
|                 if hasattr(adapter, "nice_name"): | ||||
|                     return adapter.nice_name | ||||
|     except: | ||||
|         return None | ||||
| 
 | ||||
|     return None | ||||
| 
 | ||||
| def ifaddresses(ifname) -> dict: | ||||
|     adapters = RNS.vendor.ifaddr.get_adapters(include_unconfigured=True) | ||||
|     ifa = {} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user