def simplest_display_str(self, source_hash): trust_level = self.trust_level(source_hash) if trust_level == DirectoryEntry.WARNING or trust_level == DirectoryEntry.UNTRUSTED: return "<" + RNS.hexrep(source_hash, delimit=False) + ">" else: if source_hash in self.directory_entries: return self.directory_entries[source_hash].display_name else: return "<" + RNS.hexrep(source_hash, delimit=False) + ">"
def write_to_directory(self, directory_path): file_name = RNS.hexrep(self.hash, delimit=False) file_path = directory_path + "/" + file_name try: if not self.packed: self.pack() container = { "state": self.state, "lxmf_bytes": self.packed, "transport_encrypted": self.transport_encrypted, "transport_encryption": self.transport_encryption } packed_container = msgpack.packb(container) file = open(file_path, "wb") file.write(packed_container) file.close() return file_path except Exception as e: RNS.log( "Error while writing LXMF message to file \"" + str(file_path) + "\". The contained exception was: " + str(e), RNS.LOG_ERROR) return None
def received_announce(destination_hash, announced_identity, app_data): app = nomadnet.NomadNetworkApp.get_shared_instance() if not destination_hash in app.ignored_list: destination_hash_text = RNS.hexrep(destination_hash, delimit=False) # Check if the announced destination is in # our list of conversations if destination_hash_text in [ e[0] for e in Conversation.conversation_list(app) ]: if app.directory.find(destination_hash): if Conversation.created_callback != None: Conversation.created_callback() else: if Conversation.created_callback != None: Conversation.created_callback() # Add the announce to the directory announce # stream logger app.directory.lxmf_announce_received(destination_hash, app_data) else: RNS.log( "Ignored announce from " + RNS.prettyhexrep(destination_hash), RNS.LOG_DEBUG)
def cache_request_packet(packet): if len(packet.data) == RNS.Identity.HASHLENGTH / 8: packet_hash = RNS.hexrep(packet.data, delimit=False) path = RNS.Reticulum.cachepath + "/" + packet_hash if os.path.isfile(path): file = open(path, "r") raw = file.read() file.close() packet = RNS.Packet(None, raw)
def forward(self): target_ptr = self.history_ptr + 1 if not self.history_inc and not self.history_dec: if target_ptr <= len(self.history): self.history_dec = True entry = self.history[target_ptr - 1] url = RNS.hexrep(entry[0], delimit=False) + ":" + entry[1] self.history_ptr = target_ptr self.retrieve_url(url)
def current_url(self): if self.destination_hash == None: return "" else: if self.path == None: path = "" else: path = self.path return RNS.hexrep(self.destination_hash, delimit=False) + ":" + path
def cache_request_packet(packet): if len(packet.data) == RNS.Identity.HASHLENGTH / 8: packet_hash = RNS.hexrep(packet.data, delimit=False) # TODO: There's some pretty obvious file access # issues here. Make sure this can't happen path = RNS.Reticulum.cachepath + "/" + packet_hash if os.path.isfile(path): file = open(path, "r") raw = file.read() file.close() packet = RNS.Packet(None, raw)
def cache(packet): if RNS.Transport.shouldCache(packet): try: packet_hash = RNS.hexrep(packet.getHash(), delimit=False) file = open(RNS.Reticulum.cachepath + "/" + packet_hash, "w") file.write(packet.raw) file.close() RNS.log("Wrote packet " + packet_hash + " to cache", RNS.LOG_EXTREME) except Exception as e: RNS.log("Error writing packet to cache", RNS.LOG_ERROR) RNS.log("The contained exception was: " + str(e))
def ingest(lxmessage, app, originator=False, delegate=None): if originator: source_hash = lxmessage.destination_hash else: source_hash = lxmessage.source_hash source_hash_path = RNS.hexrep(source_hash, delimit=False) conversation_path = app.conversationpath + "/" + source_hash_path if not os.path.isdir(conversation_path): os.makedirs(conversation_path) if Conversation.created_callback != None: Conversation.created_callback() ingested_path = lxmessage.write_to_directory(conversation_path) if RNS.hexrep(source_hash, delimit=False) in Conversation.cached_conversations: conversation = Conversation.cached_conversations[RNS.hexrep( source_hash, delimit=False)] conversation.scan_storage() if not source_hash in Conversation.unread_conversations: Conversation.unread_conversations[source_hash] = True try: dirname = RNS.hexrep(source_hash, delimit=False) open(app.conversationpath + "/" + dirname + "/unread", 'a').close() except Exception as e: pass if Conversation.created_callback != None: Conversation.created_callback() return ingested_path
def cache_request(packet_hash): RNS.log("Cache request for " + RNS.prettyhexrep(packet_hash), RNS.LOG_EXTREME) path = RNS.Reticulum.cachepath + "/" + RNS.hexrep(packet_hash, delimit=False) if os.path.isfile(path): file = open(path, "r") raw = file.read() Transport.inbound(raw) file.close() else: cache_request_packet = RNS.Packet( Transport.transport_destination(), packet_hash, context=RNS.Packet.CACHE_REQUEST)
def received_announce(destination_hash, announced_identity, app_data): app = nomadnet.NomadNetworkApp.get_shared_instance() if not destination_hash in app.ignored_list: destination_hash_text = RNS.hexrep(destination_hash, delimit=False) associated_peer = RNS.Destination.hash_from_name_and_identity( "lxmf.delivery", announced_identity) app.directory.node_announce_received(destination_hash, app_data, associated_peer) app.autoselect_propagation_node() else: RNS.log( "Ignored announce from " + RNS.prettyhexrep(destination_hash), RNS.LOG_DEBUG)
def __str__(self): if self.hash != None: return "<LXMessage " + RNS.hexrep(self.hash, delimit=False) + ">" else: return "<LXMessage>"
def readLoop(self): try: in_frame = False escape = False command = KISS.CMD_UNKNOWN data_buffer = "" command_buffer = "" last_read_ms = int(time.time() * 1000) while self.serial.is_open: if self.serial.in_waiting: byte = self.serial.read(1) last_read_ms = int(time.time() * 1000) if (in_frame and byte == KISS.FEND and command == KISS.CMD_DATA): in_frame = False self.processIncoming(data_buffer) data_buffer = "" command_buffer = "" elif (byte == KISS.FEND): in_frame = True command = KISS.CMD_UNKNOWN data_buffer = "" command_buffer = "" elif (in_frame and len(data_buffer) < RNS.Reticulum.MTU): if (len(data_buffer) == 0 and command == KISS.CMD_UNKNOWN): command = byte elif (command == KISS.CMD_DATA): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False data_buffer = data_buffer + byte elif (command == KISS.CMD_FREQUENCY): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False command_buffer = command_buffer + byte if (len(command_buffer) == 4): self.r_frequency = ord( command_buffer[0]) << 24 | ord( command_buffer[1]) << 16 | ord( command_buffer[2]) << 8 | ord( command_buffer[3]) RNS.log( str(self) + " Radio reporting frequency is " + str(self.r_frequency / 1000000.0) + " MHz", RNS.LOG_DEBUG) self.updateBitrate() elif (command == KISS.CMD_BANDWIDTH): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False command_buffer = command_buffer + byte if (len(command_buffer) == 4): self.r_bandwidth = ord( command_buffer[0]) << 24 | ord( command_buffer[1]) << 16 | ord( command_buffer[2]) << 8 | ord( command_buffer[3]) RNS.log( str(self) + " Radio reporting bandwidth is " + str(self.r_bandwidth / 1000.0) + " KHz", RNS.LOG_DEBUG) self.updateBitrate() elif (command == KISS.CMD_TXPOWER): self.r_txpower = ord(byte) RNS.log( str(self) + " Radio reporting TX power is " + str(self.r_txpower) + " dBm", RNS.LOG_DEBUG) elif (command == KISS.CMD_SF): self.r_sf = ord(byte) RNS.log( str(self) + " Radio reporting spreading factor is " + str(self.r_sf), RNS.LOG_DEBUG) self.updateBitrate() elif (command == KISS.CMD_CR): self.r_cr = ord(byte) RNS.log( str(self) + " Radio reporting coding rate is " + str(self.r_cr), RNS.LOG_DEBUG) self.updateBitrate() elif (command == KISS.CMD_RADIO_STATE): self.r_state = ord(byte) elif (command == KISS.CMD_RADIO_LOCK): self.r_lock = ord(byte) elif (command == KISS.CMD_STAT_RX): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False command_buffer = command_buffer + byte if (len(command_buffer) == 4): self.r_stat_rx = ord( command_buffer[0]) << 24 | ord( command_buffer[1]) << 16 | ord( command_buffer[2]) << 8 | ord( command_buffer[3]) elif (command == KISS.CMD_STAT_TX): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False command_buffer = command_buffer + byte if (len(command_buffer) == 4): self.r_stat_tx = ord( command_buffer[0]) << 24 | ord( command_buffer[1]) << 16 | ord( command_buffer[2]) << 8 | ord( command_buffer[3]) elif (command == KISS.CMD_STAT_RSSI): self.r_stat_rssi = ord( byte) - RNodeInterface.RSSI_OFFSET elif (command == KISS.CMD_RANDOM): self.r_random = ord(byte) elif (command == KISS.CMD_ERROR): if (byte == KISS.ERROR_INITRADIO): RNS.log( str(self) + " hardware initialisation error (code " + RNS.hexrep(byte) + ")", RNS.LOG_ERROR) elif (byte == KISS.ERROR_INITRADIO): RNS.log( str(self) + " hardware TX error (code " + RNS.hexrep(byte) + ")", RNS.LOG_ERROR) else: RNS.log( str(self) + " hardware error (code " + RNS.hexrep(byte) + ")", RNS.LOG_ERROR) elif (command == KISS.CMD_READY): # TODO: add timeout and reset if ready # command never arrives self.process_queue() else: time_since_last = int(time.time() * 1000) - last_read_ms if len(data_buffer) > 0 and time_since_last > self.timeout: RNS.log( str(self) + " serial read timeout", RNS.LOG_DEBUG) data_buffer = "" in_frame = False command = KISS.CMD_UNKNOWN escape = False sleep(0.08) except Exception as e: self.online = False RNS.log( "A serial port error occurred, the contained exception was: " + str(e), RNS.LOG_ERROR) RNS.log( "The interface " + str(self.name) + " is now offline. Restart Reticulum to attempt reconnection.", RNS.LOG_ERROR)
def url_hash(self, url): if url == None: return None else: url = url.encode("utf-8") return RNS.hexrep(RNS.Identity.full_hash(url), delimit=False)
def readLoop(self): try: in_frame = False escape = False command = KISS.CMD_UNKNOWN data_buffer = b"" command_buffer = b"" last_read_ms = int(time.time() * 1000) while self.serial.is_open: if self.serial.in_waiting: byte = ord(self.serial.read(1)) last_read_ms = int(time.time() * 1000) if (in_frame and byte == KISS.FEND and command == KISS.CMD_DATA): in_frame = False self.processIncoming(data_buffer) data_buffer = b"" command_buffer = b"" elif (byte == KISS.FEND): in_frame = True command = KISS.CMD_UNKNOWN data_buffer = b"" command_buffer = b"" elif (in_frame and len(data_buffer) < RNS.Reticulum.MTU): if (len(data_buffer) == 0 and command == KISS.CMD_UNKNOWN): command = byte elif (command == KISS.CMD_DATA): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False data_buffer = data_buffer + bytes([byte]) elif (command == KISS.CMD_FREQUENCY): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False command_buffer = command_buffer + bytes([byte]) if (len(command_buffer) == 4): self.r_frequency = command_buffer[ 0] << 24 | command_buffer[ 1] << 16 | command_buffer[ 2] << 8 | command_buffer[3] RNS.log( str(self) + " Radio reporting frequency is " + str(self.r_frequency / 1000000.0) + " MHz", RNS.LOG_DEBUG) self.updateBitrate() elif (command == KISS.CMD_BANDWIDTH): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False command_buffer = command_buffer + bytes([byte]) if (len(command_buffer) == 4): self.r_bandwidth = command_buffer[ 0] << 24 | command_buffer[ 1] << 16 | command_buffer[ 2] << 8 | command_buffer[3] RNS.log( str(self) + " Radio reporting bandwidth is " + str(self.r_bandwidth / 1000.0) + " KHz", RNS.LOG_DEBUG) self.updateBitrate() elif (command == KISS.CMD_TXPOWER): self.r_txpower = byte RNS.log( str(self) + " Radio reporting TX power is " + str(self.r_txpower) + " dBm", RNS.LOG_DEBUG) elif (command == KISS.CMD_SF): self.r_sf = byte RNS.log( str(self) + " Radio reporting spreading factor is " + str(self.r_sf), RNS.LOG_DEBUG) self.updateBitrate() elif (command == KISS.CMD_CR): self.r_cr = byte RNS.log( str(self) + " Radio reporting coding rate is " + str(self.r_cr), RNS.LOG_DEBUG) self.updateBitrate() elif (command == KISS.CMD_RADIO_STATE): self.r_state = byte elif (command == KISS.CMD_RADIO_LOCK): self.r_lock = byte elif (command == KISS.CMD_STAT_RX): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False command_buffer = command_buffer + bytes([byte]) if (len(command_buffer) == 4): self.r_stat_rx = ord( command_buffer[0]) << 24 | ord( command_buffer[1]) << 16 | ord( command_buffer[2]) << 8 | ord( command_buffer[3]) elif (command == KISS.CMD_STAT_TX): if (byte == KISS.FESC): escape = True else: if (escape): if (byte == KISS.TFEND): byte = KISS.FEND if (byte == KISS.TFESC): byte = KISS.FESC escape = False command_buffer = command_buffer + bytes([byte]) if (len(command_buffer) == 4): self.r_stat_tx = ord( command_buffer[0]) << 24 | ord( command_buffer[1]) << 16 | ord( command_buffer[2]) << 8 | ord( command_buffer[3]) elif (command == KISS.CMD_STAT_RSSI): self.r_stat_rssi = byte - RNodeInterface.RSSI_OFFSET elif (command == KISS.CMD_STAT_SNR): self.r_stat_snr = int.from_bytes( bytes([byte ]), byteorder="big", signed=True) * 0.25 elif (command == KISS.CMD_RANDOM): self.r_random = byte elif (command == KISS.CMD_ERROR): if (byte == KISS.ERROR_INITRADIO): RNS.log( str(self) + " hardware initialisation error (code " + RNS.hexrep(byte) + ")", RNS.LOG_ERROR) elif (byte == KISS.ERROR_INITRADIO): RNS.log( str(self) + " hardware TX error (code " + RNS.hexrep(byte) + ")", RNS.LOG_ERROR) else: RNS.log( str(self) + " hardware error (code " + RNS.hexrep(byte) + ")", RNS.LOG_ERROR) elif (command == KISS.CMD_READY): self.process_queue() else: time_since_last = int(time.time() * 1000) - last_read_ms if len(data_buffer) > 0 and time_since_last > self.timeout: RNS.log( str(self) + " serial read timeout", RNS.LOG_DEBUG) data_buffer = b"" in_frame = False command = KISS.CMD_UNKNOWN escape = False if self.id_interval != None and self.id_callsign != None: if self.first_tx != None: if time.time() > self.first_tx + self.id_interval: RNS.log( "Interface " + str(self) + " is transmitting beacon data: " + str(self.id_callsign.decode("utf-8")), RNS.LOG_DEBUG) self.processOutgoing(self.id_callsign) sleep(0.08) except Exception as e: self.online = False RNS.log( "A serial port error occurred, the contained exception was: " + str(e), RNS.LOG_ERROR) RNS.log( "The interface " + str(self.name) + " is now offline. Restart Reticulum to attempt reconnection.", RNS.LOG_ERROR)