ARQ progress

This commit is contained in:
Pedro 2023-12-13 18:27:55 +01:00
parent c98b37db96
commit 9bbdaa055a
5 changed files with 30 additions and 21 deletions

View file

@ -24,11 +24,6 @@ class ARQSession():
self.id = None
# 3 bytes for the BOF Beginning of File indicator in a data frame
self.data_frame_bof = b"BOF"
# 3 bytes for the EOF End of File indicator in a data frame
self.data_frame_eof = b"EOF"
def log(self, message, isWarning = False):
msg = f"[{type(self).__name__}]: {message}"
logger = self.logger.warn if isWarning else self.logger.info

View file

@ -94,7 +94,8 @@ class ARQSessionIRS(arq_session.ARQSession):
def run(self):
self.set_state(self.STATE_WAITING_DATA)
self.thread = threading.Thread(target=self.runner, name=f"ARQ IRS Session {self.id}", daemon=False)
self.thread = threading.Thread(target=self.runner,
name=f"ARQ IRS Session {self.id}", daemon=False)
self.thread.start()
def send_open_ack(self):
@ -123,6 +124,10 @@ class ARQSessionIRS(arq_session.ARQSession):
self.frames_per_burst = self.frames_per_burst
def on_info_received(self, frame):
if self.state != self.STATE_CONN_REQ_RECEIVED:
self.logger.warning("Discarding received INFO.")
return
self.received_data = bytearray(frame['total_length'])
self.received_crc = frame['total_crc']
self.dx_snr = frame['snr']
@ -134,7 +139,8 @@ class ARQSessionIRS(arq_session.ARQSession):
def on_data_received(self, frame):
if self.state != self.STATE_WAITING_DATA:
raise RuntimeError(f"ARQ Session: Received data while in state {self.state}, expected {self.STATE_WAITING_DATA}")
self.logger.warning(f"ARQ Session: Received data while in state {self.state}. Ignoring.")
return
self.received_frame = frame
self.event_data_received.set()
@ -144,10 +150,10 @@ class ARQSessionIRS(arq_session.ARQSession):
self.logger.info(f"Discarding data frame due to wrong offset", frame=self.frame_received)
return False
remaining_data_length = len(self.receive_data) - self.received_bytes
remaining_data_length = len(self.received_data) - self.received_bytes
# Is this the last data part?
if len(self.received_frame['data']) <= remaining_data_length:
if remaining_data_length <= len(self.received_frame['data']):
# we only want the remaining length, not the entire frame data
data_part = self.received_frame['data'][:remaining_data_length]
else:

View file

@ -199,7 +199,7 @@ class DataFrameFactory:
if key in ["origin", "destination"]:
extracted_data[key] = helpers.bytes_to_callsign(data).decode()
elif key in ["origin_crc", "destination_crc"]:
elif key in ["origin_crc", "destination_crc", "total_crc"]:
extracted_data[key] = data.hex()
elif key == "gridsquare":
@ -207,7 +207,7 @@ class DataFrameFactory:
elif key in ["session_id", "speed_level",
"frames_per_burst", "version",
"snr", "offset"]:
"snr", "offset", "total_length"]:
extracted_data[key] = int.from_bytes(data, 'big')
else:
@ -333,7 +333,7 @@ class DataFrameFactory:
payload = {
"frame_length": self.LENGTH_SIG0_FRAME,
"session_id": session_id.to_bytes(1, 'big'),
"total_crc": total_crc,
"total_crc": bytes.fromhex(total_crc),
"snr": snr.to_bytes(1, 'big'),
"speed_level": speed_level.to_bytes(1, 'big'),
"frames_per_burst": frames_per_burst.to_bytes(1, 'big'),

View file

@ -9,19 +9,27 @@ from arq_session_iss import ARQSessionISS
class ARQFrameHandler(frame_handler.FrameHandler):
def follow_protocol(self):
# self.details == {'frame': {'frame_type': 'BURST_01', 'frame_type_int': 1, 'n_frames_per_burst': 1, 'session_id': 31, 'data': b'Hello world!'}, 'snr': 0, 'frequency_offset': 0, 'freedv_inst': None, 'bytes_per_frame': 15}
frame = self.details['frame']
snr = self.details["snr"]
frequency_offset = self.details["frequency_offset"]
if frame['frame_type_int'] == FR.ARQ_SESSION_OPEN.value:
session = ARQSessionIRS(self.config,
self.tx_frame_queue,
frame['origin'],
frame['session_id'])
self.states.register_arq_irs_session(session)
session.set_details(snr, frequency_offset)
session.run()
# Lost OPEN_ACK case .. ISS will retry opening a session
if frame['session_id'] in self.states.arq_irs_sessions:
session = self.states.arq_irs_sessions[frame['session_id']]
if session.state == ARQSessionIRS.STATE_CONN_REQ_RECEIVED:
session.set_details(snr, frequency_offset)
else:
self.logger.warning(f"IRS Session conflict for session {session.id}")
# Normal case when receiving a SESSION_OPEN for the first time
else:
session = ARQSessionIRS(self.config,
self.tx_frame_queue,
frame['origin'],
frame['session_id'])
self.states.register_arq_irs_session(session)
session.set_details(snr, frequency_offset)
session.run()
elif frame['frame_type_int'] == FR.ARQ_SESSION_OPEN_ACK.value:
session:ARQSessionISS = self.states.get_arq_iss_session(frame['session_id'])

View file

@ -72,7 +72,7 @@ class TestARQSession(unittest.TestCase):
def testARQSession(self):
# set Packet Error Rate (PER) / frame loss probability
self.loss_probability = 50
self.loss_probability = 20
self.establishChannels()
params = {