diff --git a/modem/arq_session.py b/modem/arq_session.py index 618cdec9..6563de95 100644 --- a/modem/arq_session.py +++ b/modem/arq_session.py @@ -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 diff --git a/modem/arq_session_irs.py b/modem/arq_session_irs.py index b45ada35..231c3cc5 100644 --- a/modem/arq_session_irs.py +++ b/modem/arq_session_irs.py @@ -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( diff --git a/modem/arq_session_iss.py b/modem/arq_session_iss.py index 1693c51c..43f584ba 100644 --- a/modem/arq_session_iss.py +++ b/modem/arq_session_iss.py @@ -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): diff --git a/modem/data_frame_factory.py b/modem/data_frame_factory.py index 5bed4ee1..96397066 100644 --- a/modem/data_frame_factory.py +++ b/modem/data_frame_factory.py @@ -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) diff --git a/tests/test_arq_session.py b/tests/test_arq_session.py index 4c71bffd..b0b50590 100644 --- a/tests/test_arq_session.py +++ b/tests/test_arq_session.py @@ -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 = {