diff --git a/tnc/data_handler.py b/tnc/data_handler.py index 18b66378..6b52c6e7 100644 --- a/tnc/data_handler.py +++ b/tnc/data_handler.py @@ -418,8 +418,8 @@ class DATA: # ack_frame[1:4] = static.DXCALLSIGN_CRC # ack_frame[4:7] = static.MYCALLSIGN_CRC ack_frame[1:2] = self.session_id - ack_frame[7:8] = bytes([int(snr)]) - ack_frame[8:9] = bytes([int(self.speed_level)]) + ack_frame[2:3] = bytes([int(snr)]) + ack_frame[3:4] = bytes([int(self.speed_level)]) # Transmit frame self.enqueue_frame_for_tx(ack_frame) @@ -431,8 +431,8 @@ class DATA: ack_frame[1:2] = self.session_id # ack_frame[1:4] = static.DXCALLSIGN_CRC # ack_frame[4:7] = static.MYCALLSIGN_CRC - ack_frame[7:8] = bytes([int(snr)]) - ack_frame[8:9] = bytes([int(self.speed_level)]) + # ack_frame[7:8] = bytes([int(snr)]) + # ack_frame[8:9] = bytes([int(self.speed_level)]) # Transmit frame self.enqueue_frame_for_tx(ack_frame, copies=3, repeat_delay=0) @@ -452,14 +452,14 @@ class DATA: codec2.api.freedv_set_frames_per_burst(freedv, len(missing_frames)) # TODO: Trim `missing_frames` bytesarray to [7:13] (6) frames, if it's larger. - + # TODO: Instead of using int we could use a binary flag # then create a repeat frame rpt_frame = bytearray(self.length_sig_frame) rpt_frame[:1] = bytes([FR_TYPE.FR_REPEAT.value]) rpt_frame[1:2] = self.session_id # rpt_frame[1:4] = static.DXCALLSIGN_CRC # rpt_frame[4:7] = static.MYCALLSIGN_CRC - rpt_frame[7:13] = missing_frames + # rpt_frame[7:13] = missing_frames self.log.info("[TNC] ARQ | RX | Requesting", frames=missing_frames) # Transmit frame @@ -472,8 +472,8 @@ class DATA: nack_frame[1:2] = self.session_id # nack_frame[1:4] = static.DXCALLSIGN_CRC # nack_frame[4:7] = static.MYCALLSIGN_CRC - nack_frame[7:8] = bytes([int(snr)]) - nack_frame[8:9] = bytes([int(self.speed_level)]) + nack_frame[2:3] = bytes([int(snr)]) + nack_frame[3:4] = bytes([int(self.speed_level)]) # TRANSMIT NACK FRAME FOR BURST self.enqueue_frame_for_tx(nack_frame) @@ -485,8 +485,8 @@ class DATA: nack_frame[1:2] = self.session_id # nack_frame[1:4] = static.DXCALLSIGN_CRC # nack_frame[4:7] = static.MYCALLSIGN_CRC - nack_frame[7:8] = bytes([int(snr)]) - nack_frame[8:9] = bytes([int(self.speed_level)]) + nack_frame[2:3] = bytes([int(snr)]) + nack_frame[3:4] = bytes([int(self.speed_level)]) # TRANSMIT NACK FRAME FOR BURST self.enqueue_frame_for_tx(nack_frame) @@ -498,7 +498,7 @@ class DATA: disconnection_frame[1:2] = self.session_id # disconnection_frame[1:4] = static.DXCALLSIGN_CRC # disconnection_frame[4:7] = static.MYCALLSIGN_CRC - disconnection_frame[7:13] = helpers.callsign_to_bytes(self.mycallsign) + # TODO: Needed? disconnection_frame[7:13] = helpers.callsign_to_bytes(self.mycallsign) self.enqueue_frame_for_tx(disconnection_frame, copies=5, repeat_delay=0) @@ -553,7 +553,7 @@ class DATA: # Append data to rx burst buffer # [frame_type][n_frames_per_burst][CRC24][CRC24] - #static.RX_BURST_BUFFER[rx_n_frame_of_burst] = data_in[8:] # type: ignore + # static.RX_BURST_BUFFER[rx_n_frame_of_burst] = data_in[8:] # type: ignore static.RX_BURST_BUFFER[rx_n_frame_of_burst] = data_in[3:] # type: ignore self.log.debug("[TNC] static.RX_BURST_BUFFER", buffer=static.RX_BURST_BUFFER) @@ -635,7 +635,7 @@ class DATA: static.ARQ_SPEED_LEVEL = self.speed_level # Update modes we are listening to - self.set_listening_modes(self.mode_list[self.speed_level]) + self.set_listening_modes(False, True, self.mode_list[self.speed_level]) # Create and send ACK frame self.log.info("[TNC] ARQ | RX | SENDING ACK") @@ -838,6 +838,11 @@ class DATA: """ self.arq_file_transfer = True + # set signalling modes we want to listen to + # we are in an ongoing arq transmission, so we don't need sig0 actually + modem.RECEIVE_SIG0 = False + modem.RECEIVE_SIG1 = True + self.tx_n_retry_of_burst = 0 # retries we already sent data # Maximum number of retries to send before declaring a frame is lost @@ -1143,8 +1148,8 @@ class DATA: # Update data_channel timestamp self.data_channel_last_received = int(time.time()) - self.burst_ack_snr = int.from_bytes(bytes(data_in[7:8]), "big") - self.speed_level = int.from_bytes(bytes(data_in[8:9]), "big") + self.burst_ack_snr = int.from_bytes(bytes(data_in[2:3]), "big") + self.speed_level = int.from_bytes(bytes(data_in[3:4]), "big") static.ARQ_SPEED_LEVEL = self.speed_level self.log.debug( @@ -1747,7 +1752,7 @@ class DATA: ) # Update modes we are listening to - self.set_listening_modes(self.mode_list[self.speed_level]) + self.set_listening_modes(True, True, self.mode_list[self.speed_level]) helpers.add_to_heard_stations( static.DXCALLSIGN, @@ -2417,6 +2422,8 @@ class DATA: self.burst_ack_snr = 255 # reset modem receiving state to reduce cpu load + modem.RECEIVE_SIG0 = True + modem.RECEIVE_SIG1 = False modem.RECEIVE_DATAC1 = False modem.RECEIVE_DATAC3 = False # modem.RECEIVE_FSK_LDPC_0 = False @@ -2457,15 +2464,20 @@ class DATA: self.rpt_request_received = state self.data_frame_ack_received = state - def set_listening_modes(self, mode: int) -> None: + def set_listening_modes(self, enable_sig0: bool, enable_sig1: bool, mode: int) -> None: """ Function for setting the data modes we are listening to for saving cpu power Args: + enable_sig0:int: Enable/Disable signalling mode 0 + enable_sig1:int: Enable/Disable signalling mode 1 mode:int: Codec2 mode to listen for """ # set modes we want to listen to + modem.RECEIVE_SIG0 = enable_sig0 + modem.RECEIVE_SIG1 = enable_sig1 + if mode == FREEDV_MODE.datac1.value: modem.RECEIVE_DATAC1 = True self.log.debug("[TNC] Changing listening data mode", mode="datac1") @@ -2530,7 +2542,7 @@ class DATA: static.ARQ_SPEED_LEVEL = self.speed_level # Update modes we are listening to - self.set_listening_modes(self.mode_list[self.speed_level]) + self.set_listening_modes(True, True, self.mode_list[self.speed_level]) # Why not pass `snr` or `static.SNR`? self.send_burst_nack_frame_watchdog(0) diff --git a/tnc/modem.py b/tnc/modem.py index 53105ba7..34656e92 100644 --- a/tnc/modem.py +++ b/tnc/modem.py @@ -32,6 +32,8 @@ TXCHANNEL = "" static.TRANSMITTING = False # Receive only specific modes to reduce CPU load +RECEIVE_SIG0 = False +RECEIVE_SIG1 = False RECEIVE_DATAC1 = False RECEIVE_DATAC3 = False RECEIVE_FSK_LDPC_1 = False @@ -83,27 +85,38 @@ class RF: # Open codec2 instances # DATAC0 - self.datac0_freedv, \ - self.datac0_bytes_per_frame, \ - self.datac0_bytes_out, \ - self.datac0_buffer, \ - self.datac0_nin = \ + # SIGNALLING MODE 0 - Used for Connecting - Payload 14 Bytes + self.sig0_datac0_freedv, \ + self.sig0_datac0_bytes_per_frame, \ + self.sig0_datac0_bytes_out, \ + self.sig0_datac0_buffer, \ + self.sig0_datac0_nin = \ self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC0, None) + # DATAC0 + # SIGNALLING MODE 1 - Used for ACK/NACK - Payload 5 Bytes + self.sig1_datac0_freedv, \ + self.sig1_datac0_bytes_per_frame, \ + self.sig1_datac0_bytes_out, \ + self.sig1_datac0_buffer, \ + self.sig1_datac0_nin = \ + self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC0, None) + + # DATAC1 - self.datac1_freedv, \ - self.datac1_bytes_per_frame, \ - self.datac1_bytes_out, \ - self.datac1_buffer, \ - self.datac1_nin = \ + self.dat0_datac1_freedv, \ + self.dat0_datac1_bytes_per_frame, \ + self.dat0_datac1_bytes_out, \ + self.dat0_datac1_buffer, \ + self.dat0_datac1_nin = \ self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC1, None) # DATAC3 - self.datac3_freedv, \ - self.datac3_bytes_per_frame, \ - self.datac3_bytes_out, \ - self.datac3_buffer, \ - self.datac3_nin = \ + self.dat0_datac3_freedv, \ + self.dat0_datac3_bytes_per_frame, \ + self.dat0_datac3_bytes_out, \ + self.dat0_datac3_buffer, \ + self.dat0_datac3_nin = \ self.init_codec2_mode(codec2.api.FREEDV_MODE_DATAC3, None) # FSK LDPC - 0 @@ -215,20 +228,25 @@ class RF: ) fft_thread.start() - audio_thread_datac0 = threading.Thread( - target=self.audio_datac0, name="AUDIO_THREAD DATAC0", daemon=True + audio_thread_sig0_datac0 = threading.Thread( + target=self.audio_sig0_datac0, name="AUDIO_THREAD DATAC0 - 0", daemon=True ) - audio_thread_datac0.start() + audio_thread_sig0_datac0.start() - audio_thread_datac1 = threading.Thread( - target=self.audio_datac1, name="AUDIO_THREAD DATAC1", daemon=True + audio_thread_sig1_datac0 = threading.Thread( + target=self.audio_sig1_datac0, name="AUDIO_THREAD DATAC0 - 1", daemon=True ) - audio_thread_datac1.start() + audio_thread_sig1_datac0.start() - audio_thread_datac3 = threading.Thread( - target=self.audio_datac3, name="AUDIO_THREAD DATAC3", daemon=True + audio_thread_dat0_datac1 = threading.Thread( + target=self.audio_dat0_datac1, name="AUDIO_THREAD DATAC1", daemon=True ) - audio_thread_datac3.start() + audio_thread_dat0_datac1.start() + + audio_thread_dat0_datac3 = threading.Thread( + target=self.audio_dat0_datac3, name="AUDIO_THREAD DATAC3", daemon=True + ) + audio_thread_dat0_datac3.start() if static.ENABLE_FSK: audio_thread_fsk_ldpc0 = threading.Thread( @@ -278,9 +296,10 @@ class RF: length_x = len(x) for data_buffer, receive in [ - (self.datac0_buffer, True), - (self.datac1_buffer, RECEIVE_DATAC1), - (self.datac3_buffer, RECEIVE_DATAC3), + (self.sig0_datac0_buffer, RECEIVE_SIG0), + (self.sig1_datac0_buffer, RECEIVE_SIG1), + (self.dat0_datac1_buffer, RECEIVE_DATAC1), + (self.dat0_datac3_buffer, RECEIVE_DATAC3), # Not enabled yet. # (self.fsk_ldpc_buffer_0, static.ENABLE_FSK), # (self.fsk_ldpc_buffer_1, static.ENABLE_FSK), @@ -334,11 +353,12 @@ class RF: # Avoid buffer overflow by filling only if buffer for # selected datachannel mode is not full for audiobuffer, receive, index in [ - (self.datac0_buffer, True, 0), - (self.datac1_buffer, RECEIVE_DATAC1, 1), - (self.datac3_buffer, RECEIVE_DATAC3, 2), - (self.fsk_ldpc_buffer_0, static.ENABLE_FSK, 3), - (self.fsk_ldpc_buffer_1, static.ENABLE_FSK, 4), + (self.sig0_datac0_buffer, True, 0), + (self.sig1_datac0_buffer, True, 1), + (self.dat0_datac1_buffer, RECEIVE_DATAC1, 2), + (self.dat0_datac3_buffer, RECEIVE_DATAC3, 3), + (self.fsk_ldpc_buffer_0, static.ENABLE_FSK, 4), + (self.fsk_ldpc_buffer_1, static.ENABLE_FSK, 5), ]: if audiobuffer.nbuffer + length_x > audiobuffer.size: static.BUFFER_OVERFLOW_COUNTER[index] += 1 @@ -618,51 +638,62 @@ class RF: nin = codec2.api.freedv_nin(c2instance) # Additional Datac0-specific information - these are not referenced anywhere else. - # self.datac0_payload_per_frame = self.datac0_bytes_per_frame - 2 - # self.datac0_n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples( - # self.datac0_freedv + # self.sig0_datac0_payload_per_frame = self.sig0_datac0_bytes_per_frame - 2 + # self.sig0_datac0_n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples( + # self.sig0_datac0_freedv # ) - # self.datac0_n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples( - # self.datac0_freedv + # self.sig0_datac0_n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples( + # self.sig0_datac0_freedv # ) - # self.datac0_n_tx_preamble_modem_samples = ( - # self.c_lib.freedv_get_n_tx_preamble_modem_samples(self.datac0_freedv) + # self.sig0_datac0_n_tx_preamble_modem_samples = ( + # self.c_lib.freedv_get_n_tx_preamble_modem_samples(self.sig0_datac0_freedv) # ) - # self.datac0_n_tx_postamble_modem_samples = ( - # self.c_lib.freedv_get_n_tx_postamble_modem_samples(self.datac0_freedv) + # self.sig0_datac0_n_tx_postamble_modem_samples = ( + # self.c_lib.freedv_get_n_tx_postamble_modem_samples(self.sig0_datac0_freedv) # ) # return values return c2instance, bytes_per_frame, bytes_out, audio_buffer, nin - def audio_datac0(self) -> None: - """Receive data encoded with datac0""" - self.datac0_nin = self.demodulate_audio( - self.datac0_buffer, - self.datac0_nin, - self.datac0_freedv, - self.datac0_bytes_out, - self.datac0_bytes_per_frame, + def audio_sig0_datac0(self) -> None: + """Receive data encoded with datac0 - 0""" + self.sig0_datac0_nin = self.demodulate_audio( + self.sig0_datac0_buffer, + self.sig0_datac0_nin, + self.sig0_datac0_freedv, + self.sig0_datac0_bytes_out, + self.sig0_datac0_bytes_per_frame, ) - def audio_datac1(self) -> None: + def audio_sig1_datac0(self) -> None: + """Receive data encoded with datac0 - 1""" + self.sig1_datac0_nin = self.demodulate_audio( + self.sig1_datac0_buffer, + self.sig1_datac0_nin, + self.sig1_datac0_freedv, + self.sig1_datac0_bytes_out, + self.sig1_datac0_bytes_per_frame, + ) + + + def audio_dat0_datac1(self) -> None: """Receive data encoded with datac1""" - self.datac1_nin = self.demodulate_audio( - self.datac1_buffer, - self.datac1_nin, - self.datac1_freedv, - self.datac1_bytes_out, - self.datac1_bytes_per_frame, + self.dat0_datac1_nin = self.demodulate_audio( + self.dat0_datac1_buffer, + self.dat0_datac1_nin, + self.dat0_datac1_freedv, + self.dat0_datac1_bytes_out, + self.dat0_datac1_bytes_per_frame, ) - def audio_datac3(self) -> None: + def audio_dat0_datac3(self) -> None: """Receive data encoded with datac3""" - self.datac3_nin = self.demodulate_audio( - self.datac3_buffer, - self.datac3_nin, - self.datac3_freedv, - self.datac3_bytes_out, - self.datac3_bytes_per_frame, + self.dat0_datac3_nin = self.demodulate_audio( + self.dat0_datac3_buffer, + self.dat0_datac3_nin, + self.dat0_datac3_freedv, + self.dat0_datac3_bytes_out, + self.dat0_datac3_bytes_per_frame, ) def audio_fsk_ldpc_0(self) -> None: @@ -883,8 +914,8 @@ class RF: frames_per_burst = min(frames_per_burst, 1) frames_per_burst = max(frames_per_burst, 5) - codec2.api.freedv_set_frames_per_burst(self.datac1_freedv, frames_per_burst) - codec2.api.freedv_set_frames_per_burst(self.datac3_freedv, frames_per_burst) + codec2.api.freedv_set_frames_per_burst(self.dat0_datac1_freedv, frames_per_burst) + codec2.api.freedv_set_frames_per_burst(self.dat0_datac3_freedv, frames_per_burst) codec2.api.freedv_set_frames_per_burst(self.fsk_ldpc_freedv_0, frames_per_burst)