From cd6d9dddca6758c29a1c35d9c8363749daab2b9a Mon Sep 17 00:00:00 2001 From: DJ2LS <75909252+DJ2LS@users.noreply.github.com> Date: Sun, 4 May 2025 14:10:45 +0200 Subject: [PATCH] work on heartbeat --- freedata_server/data_frame_factory.py | 10 +++++++++- freedata_server/p2p_connection.py | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/freedata_server/data_frame_factory.py b/freedata_server/data_frame_factory.py index 58128508..4bae10f6 100644 --- a/freedata_server/data_frame_factory.py +++ b/freedata_server/data_frame_factory.py @@ -184,6 +184,7 @@ class DataFrameFactory: self.template_list[FR_TYPE.P2P_CONNECTION_HEARTBEAT_ACK.value] = { "frame_length": self.LENGTH_SIG1_FRAME, "session_id": 1, + "flag": 1, } # p2p payload frames @@ -554,9 +555,16 @@ class DataFrameFactory: } return self.construct(FR_TYPE.P2P_CONNECTION_HEARTBEAT, payload) - def build_p2p_connection_heartbeat_ack(self, session_id): + def build_p2p_connection_heartbeat_ack(self, session_id, flag_buffer_empty=False, flag_announce_arq=False): + flag = 0b00000000 + if flag_buffer_empty: + flag = helpers.set_flag(flag, 'BUFFER_EMPTY', True, self.P2P_FLAGS) + if flag_announce_arq: + flag = helpers.set_flag(flag, 'ANNOUNCE_ARQ', True, self.P2P_FLAGS) + payload = { "session_id": session_id.to_bytes(1, 'big'), + "flag": flag.to_bytes(1, 'big'), } return self.construct(FR_TYPE.P2P_CONNECTION_HEARTBEAT_ACK, payload) diff --git a/freedata_server/p2p_connection.py b/freedata_server/p2p_connection.py index 238523d4..3d764b0f 100644 --- a/freedata_server/p2p_connection.py +++ b/freedata_server/p2p_connection.py @@ -112,12 +112,16 @@ class P2PConnection: self.is_ISS = False # Indicator, if we are ISS or IRS self.is_Master = False # Indicator, if we are Maste or Not + self.announce_arq = False + self.buffer_empty = False + self.last_data_timestamp= time.time() self.start_data_processing_worker() self.flag_buffer_empty = False self.flag_announce_arq = False + self.transmission_in_progress = False # indicatews, if we are waiting for an ongoing transmission def start_data_processing_worker(self): """Starts a worker thread to monitor the transmit data queue and process data.""" @@ -129,7 +133,7 @@ class P2PConnection: return # thats our heartbeat logic, only ISS will run it - if time.time() > self.last_data_timestamp + 15 and self.state is States.CONNECTED and self.is_ISS and self.state is not States.ARQ_SESSION: + if time.time() > self.last_data_timestamp + 15 and self.state is States.CONNECTED and self.is_ISS and not self.transmission_in_progress: print("no data within last 15s. Sending heartbeat") self.transmit_heartbeat() @@ -194,6 +198,7 @@ class P2PConnection: def transmit_wait_and_retry(self, frame_or_burst, timeout, retries, mode): while retries > 0: self.event_frame_received = threading.Event() + self.transmission_in_progress = True if isinstance(frame_or_burst, list): burst = frame_or_burst else: burst = [frame_or_burst] for f in burst: @@ -201,6 +206,7 @@ class P2PConnection: self.event_frame_received.clear() self.log(f"Waiting {timeout} seconds...") if self.event_frame_received.wait(timeout): + self.transmission_in_progress = False return self.log("Timeout!") retries = retries - 1 @@ -324,15 +330,16 @@ class P2PConnection: self.launch_twr(heartbeat, 6, 10, mode=FREEDV_MODE.signalling) def transmit_heartbeat_ack(self): + print("transmit heartbeat ack") self.last_data_timestamp = time.time() - heartbeat_ack = self.frame_factory.build_p2p_connection_heartbeat(self.session_id, flag_buffer_empty=self.buffer_empty, - flag_announce_arq=self.announce_arq) - self.transmit_frame([heartbeat_ack], FREEDV_MODE.signalling) + heartbeat_ack = self.frame_factory.build_p2p_connection_heartbeat_ack(self.session_id, flag_buffer_empty=self.buffer_empty,flag_announce_arq=self.announce_arq) + print(heartbeat_ack) + self.launch_twr_irs(heartbeat_ack, self.ENTIRE_CONNECTION_TIMEOUT, mode=FREEDV_MODE.signalling) + def received_heartbeat(self, frame): print("received heartbeat...") self.last_data_timestamp = time.time() - print(frame) if bool(frame.get('flag', {}).get('BUFFER_EMPTY', False)) and self.buffer_empty: print("other stations buffer is empty as well. We wont become data master now") self.is_Master = False