mirror of https://github.com/DJ2LS/FreeDATA.git
ARQ progress
parent
c98b37db96
commit
9bbdaa055a
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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'])
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue