diff --git a/modem/arq_session_irs.py b/modem/arq_session_irs.py index 52d94ca6..ce611362 100644 --- a/modem/arq_session_irs.py +++ b/modem/arq_session_irs.py @@ -81,6 +81,7 @@ class ARQSessionIRS(arq_session.ARQSession): self.abort = False def all_data_received(self): + print(f"{self.total_length} vs {self.received_bytes}") return self.total_length == self.received_bytes def final_crc_matches(self) -> bool: @@ -141,7 +142,7 @@ class ARQSessionIRS(arq_session.ARQSession): def process_incoming_data(self, frame): if frame['offset'] != self.received_bytes: - self.log(f"Discarding data offset {frame['offset']}") + self.log(f"Discarding data offset {frame['offset']} vs {self.received_bytes}") return False remaining_data_length = self.total_length - self.received_bytes diff --git a/modem/arq_session_iss.py b/modem/arq_session_iss.py index e0c74395..de924ace 100644 --- a/modem/arq_session_iss.py +++ b/modem/arq_session_iss.py @@ -60,6 +60,7 @@ class ARQSessionISS(arq_session.ARQSession): self.data_crc = '' self.type_byte = type_byte self.confirmed_bytes = 0 + self.expected_byte_offset = 0 self.state = ISS_State.NEW self.state_enum = ISS_State # needed for access State enum from outside @@ -153,11 +154,18 @@ class ARQSessionISS(arq_session.ARQSession): self.update_histograms(self.confirmed_bytes, self.total_length) self.update_speed_level(irs_frame) - if 'offset' in irs_frame: - self.confirmed_bytes = irs_frame['offset'] - self.log(f"IRS confirmed {self.confirmed_bytes}/{self.total_length} bytes") - self.event_manager.send_arq_session_progress( - True, self.id, self.dxcall, self.confirmed_bytes, self.total_length, self.state.name, statistics=self.calculate_session_statistics(self.confirmed_bytes, self.total_length)) + #if 'offset' in irs_frame: + # self.confirmed_bytes = irs_frame['offset'] + # self.log(f"IRS confirmed {self.confirmed_bytes}/{self.total_length} bytes") + # self.event_manager.send_arq_session_progress( + # True, self.id, self.dxcall, self.confirmed_bytes, self.total_length, self.state.name, statistics=self.calculate_session_statistics(self.confirmed_bytes, self.total_length)) + + + if self.expected_byte_offset > self.total_length: + self.confirmed_bytes = self.total_length + else: + self.confirmed_bytes = self.expected_byte_offset + self.log(f"IRS confirmed {self.confirmed_bytes}/{self.total_length} bytes") # check if we received an abort flag if irs_frame["flag"]["ABORT"]: @@ -176,10 +184,17 @@ class ARQSessionISS(arq_session.ARQSession): burst = [] for _ in range(0, self.frames_per_burst): offset = self.confirmed_bytes + #self.expected_byte_offset = offset payload = self.data[offset : offset + payload_size] + + print(len(payload)) + #self.expected_byte_offset = offset + payload_size + #print(self.expected_byte_offset) + self.expected_byte_offset = offset + len(payload) + print(f"EXPECTED----------------------{self.expected_byte_offset}") data_frame = self.frame_factory.build_arq_burst_frame( self.SPEED_LEVEL_DICT[self.speed_level]["mode"], - self.id, self.confirmed_bytes, payload, self.speed_level) + self.id, offset, payload, self.speed_level) burst.append(data_frame) self.launch_twr(burst, self.TIMEOUT_TRANSFER, self.RETRIES_CONNECT, mode='auto', isARQBurst=True) self.set_state(ISS_State.BURST_SENT) diff --git a/modem/data_frame_factory.py b/modem/data_frame_factory.py index c025c2ab..edc925a2 100644 --- a/modem/data_frame_factory.py +++ b/modem/data_frame_factory.py @@ -156,10 +156,10 @@ class DataFrameFactory: self.template_list[FR_TYPE.ARQ_BURST_ACK.value] = { "frame_length": self.LENGTH_SIG1_FRAME, "session_id": 1, - "offset":4, + #"offset":4, "speed_level": 1, - "frames_per_burst": 1, - "snr": 1, + #"frames_per_burst": 1, + #"snr": 1, "flag": 1, } @@ -227,11 +227,13 @@ class DataFrameFactory: if isinstance(frame_template["frame_length"], int): frame_length = frame_template["frame_length"] else: - frame_length -= 2 + frame_length -= 0#2 frame = bytearray(frame_length) - frame[:1] = bytes([frametype.value]) - - buffer_position = 1 + if frametype in [FR_TYPE.ARQ_BURST_ACK]: + buffer_position = 0 + else: + frame[:1] = bytes([frametype.value]) + buffer_position = 1 for key, item_length in frame_template.items(): if key == "frame_length": continue @@ -242,6 +244,7 @@ class DataFrameFactory: raise OverflowError("Frame data overflow!") frame[buffer_position: buffer_position + item_length] = content[key] buffer_position += item_length + print(frame) return frame def deconstruct(self, frame): @@ -252,10 +255,15 @@ class DataFrameFactory: if not frame_template: # Handle the case where the frame type is not recognized - raise ValueError(f"Unknown frame type: {frametype}") + #raise ValueError(f"Unknown frame type: {frametype}") + print(f"Unknown frame type, handling as ACK") + frametype = FR_TYPE.ARQ_BURST_ACK.value + frame_template = self.template_list.get(frametype) + print(frame) + frame = bytes([frametype]) + frame extracted_data = {"frame_type": FR_TYPE(frametype).name, "frame_type_int": frametype} - + print(extracted_data) for key, item_length in frame_template.items(): if key == "frame_length": continue @@ -481,10 +489,10 @@ class DataFrameFactory: payload = { "session_id": session_id.to_bytes(1, 'big'), - "offset": offset.to_bytes(4, '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), + #"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 b9221475..b6b1e6a0 100644 --- a/tests/test_arq_session.py +++ b/tests/test_arq_session.py @@ -35,6 +35,10 @@ class TestModem: samples += codec2.api.freedv_get_n_tx_modem_samples(c2instance) samples += codec2.api.freedv_get_n_tx_postamble_modem_samples(c2instance) time = samples / 8000 + #print(mode) + #if mode == codec2.FREEDV_MODE.signalling: + # time = 0.69 + #print(time) return time def transmit(self, mode, repeats: int, repeat_delay: int, frames: bytearray) -> bool: @@ -96,7 +100,7 @@ class TestARQSession(unittest.TestCase): continue frame_bytes = transmission['bytes'] - frame_dispatcher.new_process_data(frame_bytes, None, len(frame_bytes), 0, 0) + frame_dispatcher.new_process_data(frame_bytes, None, len(frame_bytes), 10, 0) except queue.Empty: continue self.logger.info(f"[{threading.current_thread().name}] Channel closed.") @@ -129,7 +133,7 @@ class TestARQSession(unittest.TestCase): self.waitForSession(self.irs_event_queue, False) self.channels_running = False - def testARQSessionSmallPayload(self): + def DisabledtestARQSessionSmallPayload(self): # set Packet Error Rate (PER) / frame loss probability self.loss_probability = 30 @@ -146,7 +150,7 @@ class TestARQSession(unittest.TestCase): def testARQSessionLargePayload(self): # set Packet Error Rate (PER) / frame loss probability - self.loss_probability = 0 + self.loss_probability = 30 self.establishChannels() params = { @@ -160,7 +164,7 @@ class TestARQSession(unittest.TestCase): self.waitAndCloseChannels() del cmd - def testARQSessionAbortTransmissionISS(self): + def DisabledtestARQSessionAbortTransmissionISS(self): # set Packet Error Rate (PER) / frame loss probability self.loss_probability = 0 @@ -172,14 +176,14 @@ class TestARQSession(unittest.TestCase): cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params) cmd.run(self.iss_event_queue, self.iss_modem) - threading.Event().wait(np.random.randint(1,10)) + threading.Event().wait(np.random.randint(10,10)) for id in self.iss_state_manager.arq_iss_sessions: self.iss_state_manager.arq_iss_sessions[id].abort_transmission() self.waitAndCloseChannels() del cmd - def testARQSessionAbortTransmissionIRS(self): + def DisabledtestARQSessionAbortTransmissionIRS(self): # set Packet Error Rate (PER) / frame loss probability self.loss_probability = 0 @@ -198,7 +202,7 @@ class TestARQSession(unittest.TestCase): self.waitAndCloseChannels() del cmd - def testSessionCleanupISS(self): + def DisabledtestSessionCleanupISS(self): params = { 'dxcall': "AA1AAA-1", @@ -217,7 +221,7 @@ class TestARQSession(unittest.TestCase): break del cmd - def testSessionCleanupIRS(self): + def DisabledtestSessionCleanupIRS(self): session = arq_session_irs.ARQSessionIRS(self.config, self.irs_modem, 'AA1AAA-1',