WIP ARQ - speed level

This commit is contained in:
DJ2LS 2023-12-14 22:53:32 +01:00
parent b42c40dd78
commit 16f37677d5
3 changed files with 46 additions and 21 deletions

View file

@ -6,11 +6,24 @@ from modem_frametypes import FRAME_TYPE
class ARQSession():
MODE_BY_SPEED = [
codec2.FREEDV_MODE.datac4,
codec2.FREEDV_MODE.datac3,
codec2.FREEDV_MODE.datac1,
]
SPEED_LEVEL_DICT = {
0: {
'mode': codec2.FREEDV_MODE.datac4,
'min_snr': -10,
'duration_per_frame': 5.17,
},
1: {
'mode': codec2.FREEDV_MODE.datac3,
'min_snr': 0,
'duration_per_frame': 3.19,
},
2: {
'mode': codec2.FREEDV_MODE.datac1,
'min_snr': 3,
'duration_per_frame': 4.18,
},
}
def __init__(self, config: dict, tx_frame_queue: queue.Queue, dxcall: str):
self.logger = structlog.get_logger(type(self).__name__)
@ -36,7 +49,7 @@ class ARQSession():
logger(msg)
def get_mode_by_speed_level(self, speed_level):
return self.MODE_BY_SPEED[speed_level]
return self.SPEED_LEVEL_DICT[speed_level]["mode"]
def transmit_frame(self, frame: bytearray):
self.log("Transmitting frame")
@ -55,7 +68,7 @@ class ARQSession():
def get_data_payload_size(self):
return self.frame_factory.get_available_data_payload_for_mode(
FRAME_TYPE.ARQ_BURST_FRAME,
self.MODE_BY_SPEED[self.speed_level]
self.SPEED_LEVEL_DICT[self.speed_level]["mode"]
)
def set_details(self, snr, frequency_offset):

View file

@ -52,6 +52,8 @@ class ARQSessionIRS(arq_session.ARQSession):
self.received_bytes = 0
self.received_crc = None
self.transmitted_acks = 0
def set_modem_decode_modes(self, modes):
pass
@ -65,6 +67,13 @@ class ARQSessionIRS(arq_session.ARQSession):
self.transmit_frame(frame)
self.log(f"Waiting {timeout} seconds...")
if not self.event_frame_received.wait(timeout):
# use case: data burst got lost, we want to send a NACK with updated speed level
if self.state in [self.STATE_BURST_REPLY_SENT, self.STATE_INFO_ACK_SENT]:
self.transmitted_acks = 0
self.calibrate_speed_settings()
self.send_burst_nack()
return
self.log("Timeout waiting for ISS. Session failed.")
self.set_state(self.STATE_FAILED)
@ -94,6 +103,12 @@ class ARQSessionIRS(arq_session.ARQSession):
self.launch_transmit_and_wait(info_ack, self.TIMEOUT_CONNECT)
self.set_state(self.STATE_INFO_ACK_SENT)
def send_burst_nack(self):
self.calibrate_speed_settings()
nack = self.frame_factory.build_arq_burst_ack(self.id, self.received_bytes, self.speed_level, self.frames_per_burst, self.snr[0])
self.transmit_and_wait(nack)
def process_incoming_data(self, frame):
if frame['offset'] != self.received_bytes:
self.logger.info(f"Discarding data frame due to wrong offset", frame=self.frame_received)
@ -116,12 +131,14 @@ class ARQSessionIRS(arq_session.ARQSession):
def receive_data(self, burst_frame):
self.process_incoming_data(burst_frame)
self.calibrate_speed_settings()
ack = self.frame_factory.build_arq_burst_ack(
self.id, self.received_bytes,
self.speed_level, self.frames_per_burst, self.snr[0])
if not self.all_data_received():
# increase ack counter
self.transmitted_acks += 1
self.transmit_and_wait(ack)
self.set_state(self.STATE_BURST_REPLY_SENT)
return
@ -136,17 +153,12 @@ class ARQSessionIRS(arq_session.ARQSession):
self.set_state(self.STATE_FAILED)
def calibrate_speed_settings(self):
return
# decrement speed level after the 2nd retry
if self.RETRIES_TRANSFER - self.retries >= 2:
self.speed -= 1
self.speed = max(self.speed, 0)
return
# if we have two ACKS, then consider increasing speed level
if self.transmitted_acks >= 2:
self.transmitted_acks = 0
new_speed_level = min(self.speed_level + 1, len(self.SPEED_LEVEL_DICT) - 1)
# increment speed level after 2 successfully sent bursts and fitting snr
# TODO
# check first if the next mode supports the actual snr
if self.snr >= self.SPEED_LEVEL_DICT[new_speed_level]["min_snr"]:
self.speed_level = new_speed_level
self.speed = self.speed
self.frames_per_burst = self.frames_per_burst

View file

@ -105,7 +105,7 @@ class ARQSessionISS(arq_session.ARQSession):
offset = self.confirmed_bytes
payload = self.data[offset : offset + payload_size]
data_frame = self.frame_factory.build_arq_burst_frame(
self.MODE_BY_SPEED[self.speed_level],
self.SPEED_LEVEL_DICT[self.speed_level]["mode"],
self.id, self.confirmed_bytes, payload)
burst.append(data_frame)