ARQ WIP - introduced flags

This commit is contained in:
DJ2LS 2023-12-20 16:43:08 +01:00
parent 674dd2e383
commit 0fffe86f05
5 changed files with 57 additions and 20 deletions

View file

@ -25,15 +25,6 @@ class ARQSession():
},
}
"""
helpers.set_flag(byte, 'DATA-ACK-NACK', True, FLAG_POSITIONS)
helpers.get_flag(byte, 'DATA-ACK-NACK', FLAG_POSITIONS)
"""
FLAG_POSITIONS = {
'DATA-ACK-NACK': 0, # Bit position for DATA-ACK-NACK
}
def __init__(self, config: dict, modem, dxcall: str):
self.logger = structlog.get_logger(type(self).__name__)
self.config = config

View file

@ -144,11 +144,12 @@ 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():
ack = self.frame_factory.build_arq_burst_ack(
self.id, self.received_bytes,
self.speed_level, self.frames_per_burst, self.snr[0])
# increase ack counter
self.transmitted_acks += 1
self.set_state(IRS_State.BURST_REPLY_SENT)
@ -157,6 +158,13 @@ class ARQSessionIRS(arq_session.ARQSession):
if self.final_crc_matches():
self.log("All data received successfully!")
ack = self.frame_factory.build_arq_burst_ack(self.id,
self.received_bytes,
self.speed_level,
self.frames_per_burst,
self.snr[0],
flag_final=True,
flag_checksum=True)
self.transmit_frame(ack, mode=FREEDV_MODE.signalling)
self.log("ACK sent")
self.set_state(IRS_State.ENDED)
@ -164,6 +172,15 @@ class ARQSessionIRS(arq_session.ARQSession):
False, self.id, self.dxcall, self.total_length, True)
else:
ack = self.frame_factory.build_arq_burst_ack(self.id,
self.received_bytes,
self.speed_level,
self.frames_per_burst,
self.snr[0],
flag_final=True,
flag_checksum=False)
self.transmit_frame(ack, mode=FREEDV_MODE.signalling)
self.log("CRC fail at the end of transmission!")
self.set_state(IRS_State.FAILED)
self.event_manager.send_arq_session_finished(

View file

@ -102,11 +102,12 @@ class ARQSessionISS(arq_session.ARQSession):
self.event_manager.send_arq_session_progress(
True, self.id, self.dxcall, self.confirmed_bytes, len(self.data))
if self.confirmed_bytes == len(self.data):
if self.confirmed_bytes == len(self.data) and irs_frame["flag"]["FINAL"]:
self.set_state(ISS_State.ENDED)
self.log("All data transfered!")
self.event_manager.send_arq_session_finished(True, self.id, self.dxcall, len(self.data), True)
self.event_manager.send_arq_session_finished(True, self.id, self.dxcall, len(self.data), irs_frame["flag"]["CHECKSUM"])
return
payload_size = self.get_data_payload_size()
burst = []
for f in range(0, self.frames_per_burst):

View file

@ -7,6 +7,16 @@ class DataFrameFactory:
LENGTH_SIG0_FRAME = 14
LENGTH_SIG1_FRAME = 14
"""
helpers.set_flag(byte, 'DATA-ACK-NACK', True, FLAG_POSITIONS)
helpers.get_flag(byte, 'DATA-ACK-NACK', FLAG_POSITIONS)
"""
ARQ_FLAGS = {
'FINAL': 0, # Bit position for indicating the FINAL state
'CHECKSUM': 1, # Bit position for indicating the CHECKSUM is correct or not
}
def __init__(self, config):
self.myfullcall = f"{config['STATION']['mycall']}-{config['STATION']['myssid']}"
self.mygrid = config['STATION']['mygrid']
@ -132,6 +142,7 @@ class DataFrameFactory:
"speed_level": 1,
"frames_per_burst": 1,
"snr": 1,
"flag": 1,
}
# arq burst nack
@ -171,7 +182,6 @@ class DataFrameFactory:
item_length = len(content[key])
if buffer_position + item_length > frame_length:
raise OverflowError("Frame data overflow!")
frame[buffer_position: buffer_position + item_length] = content[key]
buffer_position += item_length
return frame
@ -214,6 +224,16 @@ class DataFrameFactory:
"snr", "offset", "total_length", "state"]:
extracted_data[key] = int.from_bytes(data, 'big')
elif key == "flag":
data = int.from_bytes(data, "big")
extracted_data[key] = {}
if frametype == FR_TYPE.ARQ_BURST_ACK.value:
flag_dict = self.ARQ_FLAGS
for flag in flag_dict:
# Update extracted_data with the status of each flag
# get_flag returns True or False based on the bit value at the flag's position
extracted_data[key][flag] = helpers.get_flag(data, flag, flag_dict)
else:
extracted_data[key] = data
@ -315,13 +335,13 @@ class DataFrameFactory:
return self.construct(FR_TYPE.ARQ_SESSION_OPEN, payload)
def build_arq_session_open_ack(self, session_id, destination, version, snr):
payload = {
"session_id": session_id.to_bytes(1, 'big'),
"origin": helpers.callsign_to_bytes(self.myfullcall),
"destination_crc": helpers.get_crc_24(destination),
"version": bytes([version]),
"snr": snr.to_bytes(1, 'big'),
}
"snr": snr.to_bytes(1, 'big'), }
return self.construct(FR_TYPE.ARQ_SESSION_OPEN_ACK, payload)
def build_arq_session_info(self, session_id: int, total_length: int, total_crc: bytes, snr):
@ -354,13 +374,21 @@ class DataFrameFactory:
return frame
def build_arq_burst_ack(self, session_id: bytes, offset, speed_level: int,
frames_per_burst: int, snr: int):
frames_per_burst: int, snr: int, flag_final=False, flag_checksum=False):
flag = 0b00000000
if flag_final:
flag = helpers.set_flag(flag, 'FINAL', True, self.ARQ_FLAGS)
if flag_checksum:
flag = helpers.set_flag(flag, 'CHECKSUM', True, self.ARQ_FLAGS)
payload = {
"session_id": session_id.to_bytes(1, 'big'),
"offset": offset.to_bytes(4, 'big'),
"speed_level": speed_level.to_bytes(1, 'big'),
"frames_per_burst": frames_per_burst.to_bytes(1, 'big'),
"snr": helpers.snr_to_bytes(snr),
"flag": flag.to_bytes(1, 'big'),
}
return self.construct(FR_TYPE.ARQ_BURST_ACK, payload)

View file

@ -98,7 +98,7 @@ class TestARQSession(unittest.TestCase):
def testARQSessionSmallPayload(self):
# set Packet Error Rate (PER) / frame loss probability
self.loss_probability = 30
self.loss_probability = 0
self.establishChannels()
params = {
@ -111,7 +111,7 @@ class TestARQSession(unittest.TestCase):
def testARQSessionLargePayload(self):
# set Packet Error Rate (PER) / frame loss probability
self.loss_probability = 50
self.loss_probability = 0
self.establishChannels()
params = {