diff --git a/modem/arq_session_irs.py b/modem/arq_session_irs.py index 0f619a68..b711d1f1 100644 --- a/modem/arq_session_irs.py +++ b/modem/arq_session_irs.py @@ -72,10 +72,11 @@ class ARQSessionIRS(arq_session.ARQSession): self.thread.start() def send_session_ack(self): - ack_frame = self.frame_factory.build_arq_session_connect_ack( - self.id, - self.speed, - self.version) + ack_frame = self.frame_factory.build_arq_session_open_ack( + self.id, + self.dxcall, + self.version, + self.snr) self.transmit_frame(ack_frame) def send_data_nack(self): @@ -89,11 +90,11 @@ class ARQSessionIRS(arq_session.ARQSession): raise RuntimeError(f"ARQ Session: Received data while in state {self.state}, expected {self.STATE_WAITING_DATA}") self.event_data_received.set() - def on_transfer_ack_received(self, ack): + def on_burst_ack_received(self, ack): self.event_transfer_ack_received.set() self.speed_level = ack['speed_level'] - def on_transfer_nack_received(self, nack): + def on_burst_nack_received(self, nack): self.speed_level = nack['speed_level'] def on_disconnect_received(self): diff --git a/modem/arq_session_iss.py b/modem/arq_session_iss.py index 9dfaa4e2..bbc7f7d4 100644 --- a/modem/arq_session_iss.py +++ b/modem/arq_session_iss.py @@ -4,6 +4,7 @@ import queue import random from codec2 import FREEDV_MODE import arq_session +import helpers class ARQSessionISS(arq_session.ARQSession): @@ -27,7 +28,8 @@ class ARQSessionISS(arq_session.ARQSession): self.state = self.STATE_DISCONNECTED self.id = self.generate_id() - self.event_connection_ack_received = threading.Event() + self.event_open_ack_received = threading.Event() + self.event_info_ack_received = threading.Event() self.event_transfer_ack_received = threading.Event() self.frame_factory = data_frame_factory.DataFrameFactory(self.config) @@ -39,39 +41,53 @@ class ARQSessionISS(arq_session.ARQSession): self.state = state def runner(self): - if not self.connect(): + self.state = self.STATE_CONNECTING + + if not self.session_open(): return False - + + if not self.session_info(): + return False + return self.send_data() def run(self): self.thread = threading.Thread(target=self.runner, name=f"ARQ ISS Session {self.id}", daemon=True) self.thread.run() - def connect(self): - self.state = self.STATE_CONNECTING - - connect_frame = self.frame_factory.build_arq_session_connect(self.dxcall, self.id) - + def handshake(self, frame, event): retries = self.RETRIES_CONNECT while retries > 0: - self.transmit_frame(connect_frame) - self.logger.info("Waiting for CONN ACK...") - if self.event_connection_ack_received.wait(self.TIMEOUT_CONNECT_ACK): - self.setState(self.STATE_CONNECTED) + self.transmit_frame(frame) + self.logger.info("Waiting...") + if event.wait(self.TIMEOUT_CONNECT_ACK): return True retries = retries - 1 self.setState(self.STATE_DISCONNECTED) return False - def on_connection_ack_received(self, ack): + def session_open(self): + open_frame = self.frame_factory.build_arq_session_open(self.dxcall, self.id) + return self.handshake(open_frame, self.event_open_ack_received) + + def session_info(self): + info_frame = self.frame_factory.build_arq_session_info(self.id, len(self.data), + helpers.get_crc_32(self.data), + self.snr) + return self.handshake(info_frame, self.event_info_ack_received) + + def on_open_ack_received(self, ack): if self.state != self.STATE_CONNECTING: - raise RuntimeError(f"ARQ Session: Received connection ACK while in state {self.state}") + raise RuntimeError(f"ARQ Session: Received OPEN ACK while in state {self.state}") - self.build_arq_data_framespeed_level = ack['speed_level'] - self.event_connection_ack_received.set() + self.event_open_ack_received.set() + def on_info_ack_received(self, ack): + if self.state != self.STATE_CONNECTING: + raise RuntimeError(f"ARQ Session: Received INFO ACK while in state {self.state}") + + self.event_info_ack_received.set() # Sends the full payload in multiple frames def send_data(self): diff --git a/modem/data_frame_factory.py b/modem/data_frame_factory.py index 99f056fb..42124009 100644 --- a/modem/data_frame_factory.py +++ b/modem/data_frame_factory.py @@ -216,7 +216,9 @@ class DataFrameFactory: elif key == "gridsquare": extracted_data[key] = helpers.decode_grid(data) - elif key in ["session_id", "speed_level", "frames_per_burst", "version"]: + elif key in ["session_id", "speed_level", + "frames_per_burst", "version", + "snr"]: extracted_data[key] = int.from_bytes(data, 'big') else: diff --git a/modem/frame_handler_arq_session.py b/modem/frame_handler_arq_session.py index 8f54128b..97e843f6 100644 --- a/modem/frame_handler_arq_session.py +++ b/modem/frame_handler_arq_session.py @@ -14,7 +14,6 @@ class ARQFrameHandler(frame_handler.FrameHandler): snr = self.details["snr"] frequency_offset = self.details["frequency_offset"] - # ARQ session open received if frame['frame_type_int'] == FR.ARQ_SESSION_OPEN.value: session = ARQSessionIRS(self.config, self.tx_frame_queue, @@ -23,16 +22,22 @@ class ARQFrameHandler(frame_handler.FrameHandler): self.states.register_arq_irs_session(session) session.run() - # ARQ session open ack received elif frame['frame_type_int'] == FR.ARQ_SESSION_OPEN_ACK.value: - iss_session:ARQSessionISS = self.states.get_arq_iss_session(frame['session_id']) - iss_session.on_connection_ack_received(frame) + session:ARQSessionISS = self.states.get_arq_iss_session(frame['session_id']) + session.on_open_ack_received(frame) + + elif frame['frame_type_int'] == FR.ARQ_SESSION_INFO_ACK.value: + session:ARQSessionISS = self.states.get_arq_iss_session(frame['session_id']) + session.on_info_ack_received(frame) - # ARQ session data frame received elif frame['frame_type_int'] == FR.BURST_FRAME.value: - print("received data frame....") - print(frame) + session:ARQSessionIRS = self.states.get_arq_irs_session(frame['session_id']) + session.on_data_received(frame) - irs_session:ARQSessionIRS = self.states.get_arq_irs_session(frame['session_id']) - irs_session.on_data_received(frame) - irs_session.rx_data_chain(frame, snr, frequency_offset) + elif frame['frame_type_int'] == FR.BURST_ACK.value: + session:ARQSessionISS = self.states.get_arq_iss_session(frame['session_id']) + session.on_burst_ack_received(frame) + + elif frame['frame_type_int'] == FR.BURST_NACK.value: + session:ARQSessionISS = self.states.get_arq_iss_session(frame['session_id']) + session.on_burst_nack_received(frame)