mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
adjusted arq timeouts...
This commit is contained in:
parent
e445fbb3a3
commit
3f49b63930
|
@ -56,10 +56,16 @@ class DATA:
|
||||||
self.length_sig0_frame = 14
|
self.length_sig0_frame = 14
|
||||||
self.length_sig1_frame = 14
|
self.length_sig1_frame = 14
|
||||||
|
|
||||||
# duration of signalling frame
|
# duration of frames
|
||||||
self.duration_sig0_frame = 2.3
|
self.duration_datac4 = 5.17
|
||||||
self.duration_sig1_frame = 2.3
|
self.duration_datac13 = 2.0
|
||||||
self.longest_duration = 5.8 # datac5
|
self.duration_datac1 = 4.18
|
||||||
|
self.duration_datac3 = 3.19
|
||||||
|
self.duration_sig0_frame = self.duration_datac13
|
||||||
|
self.duration_sig1_frame = self.duration_datac13
|
||||||
|
self.longest_duration = self.duration_datac4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# hold session id
|
# hold session id
|
||||||
self.session_id = bytes(1)
|
self.session_id = bytes(1)
|
||||||
|
@ -123,7 +129,7 @@ class DATA:
|
||||||
# List for minimum SNR operating level for the corresponding mode in self.mode_list
|
# List for minimum SNR operating level for the corresponding mode in self.mode_list
|
||||||
self.snr_list_low_bw = [-100]
|
self.snr_list_low_bw = [-100]
|
||||||
# List for time to wait for corresponding mode in seconds
|
# List for time to wait for corresponding mode in seconds
|
||||||
self.time_list_low_bw = [6 + self.duration_sig0_frame + 1]
|
self.time_list_low_bw = [self.duration_datac4]
|
||||||
|
|
||||||
# --------------------- HIGH BANDWIDTH
|
# --------------------- HIGH BANDWIDTH
|
||||||
|
|
||||||
|
@ -139,7 +145,7 @@ class DATA:
|
||||||
# test with 6,7 --> caused sometimes a frame timeout if ack frame takes longer
|
# test with 6,7 --> caused sometimes a frame timeout if ack frame takes longer
|
||||||
# TODO Need to check why ACK frames needs more time
|
# TODO Need to check why ACK frames needs more time
|
||||||
# TODO Adjust these times
|
# TODO Adjust these times
|
||||||
self.time_list_high_bw = [6 + self.duration_sig0_frame + 1, 6 + self.duration_sig0_frame + 1, 6 + self.duration_sig0_frame + 1]
|
self.time_list_high_bw = [self.duration_datac4, self.duration_datac3, self.duration_datac1]
|
||||||
# -------------- AVAILABLE MODES END-----------
|
# -------------- AVAILABLE MODES END-----------
|
||||||
|
|
||||||
# Mode list for selecting between low bandwidth ( 500Hz ) and modes with higher bandwidth
|
# Mode list for selecting between low bandwidth ( 500Hz ) and modes with higher bandwidth
|
||||||
|
@ -566,11 +572,7 @@ class DATA:
|
||||||
if ModemParam.channel_busy:
|
if ModemParam.channel_busy:
|
||||||
self.channel_busy_handler()
|
self.channel_busy_handler()
|
||||||
|
|
||||||
# reset burst timeout in case we had to wait too long
|
|
||||||
self.burst_last_received = time.time() + self.channel_busy_timeout + 8
|
|
||||||
# Transmit frame
|
# Transmit frame
|
||||||
# TODO Do we have to send , self.send_ident_frame(False) ?
|
|
||||||
# self.enqueue_frame_for_tx([ack_frame, self.send_ident_frame(False)], c2_mode=FREEDV_MODE.sig1.value, copies=3, repeat_delay=0)
|
|
||||||
self.enqueue_frame_for_tx([ack_frame], c2_mode=FREEDV_MODE.sig1.value, copies=3, repeat_delay=0)
|
self.enqueue_frame_for_tx([ack_frame], c2_mode=FREEDV_MODE.sig1.value, copies=3, repeat_delay=0)
|
||||||
|
|
||||||
def send_retransmit_request_frame(self) -> None:
|
def send_retransmit_request_frame(self) -> None:
|
||||||
|
@ -614,7 +616,7 @@ class DATA:
|
||||||
# reset burst timeout in case we had to wait too long
|
# reset burst timeout in case we had to wait too long
|
||||||
self.burst_last_received = time.time()
|
self.burst_last_received = time.time()
|
||||||
|
|
||||||
def send_burst_nack_frame_watchdog(self, snr: bytes, tx_n_frames_per_burst) -> None:
|
def send_burst_nack_frame_watchdog(self, tx_n_frames_per_burst) -> None:
|
||||||
"""Build and send NACK frame for watchdog timeout"""
|
"""Build and send NACK frame for watchdog timeout"""
|
||||||
|
|
||||||
# increment nack counter for transmission stats
|
# increment nack counter for transmission stats
|
||||||
|
@ -628,7 +630,7 @@ class DATA:
|
||||||
nack_frame = bytearray(self.length_sig1_frame)
|
nack_frame = bytearray(self.length_sig1_frame)
|
||||||
nack_frame[:1] = bytes([FR_TYPE.BURST_NACK.value])
|
nack_frame[:1] = bytes([FR_TYPE.BURST_NACK.value])
|
||||||
nack_frame[1:2] = self.session_id
|
nack_frame[1:2] = self.session_id
|
||||||
nack_frame[2:3] = helpers.snr_to_bytes(snr)
|
nack_frame[2:3] = helpers.snr_to_bytes(0)
|
||||||
nack_frame[3:4] = bytes([int(self.speed_level)])
|
nack_frame[3:4] = bytes([int(self.speed_level)])
|
||||||
nack_frame[4:5] = bytes([int(tx_n_frames_per_burst)])
|
nack_frame[4:5] = bytes([int(tx_n_frames_per_burst)])
|
||||||
nack_frame[5:9] = len(ARQ.rx_frame_buffer).to_bytes(4, byteorder="big")
|
nack_frame[5:9] = len(ARQ.rx_frame_buffer).to_bytes(4, byteorder="big")
|
||||||
|
@ -649,11 +651,6 @@ class DATA:
|
||||||
disconnection_frame[:1] = bytes([FR_TYPE.ARQ_SESSION_CLOSE.value])
|
disconnection_frame[:1] = bytes([FR_TYPE.ARQ_SESSION_CLOSE.value])
|
||||||
disconnection_frame[1:2] = self.session_id
|
disconnection_frame[1:2] = self.session_id
|
||||||
disconnection_frame[2:5] = Station.dxcallsign_crc
|
disconnection_frame[2:5] = Station.dxcallsign_crc
|
||||||
# TODO Needed? disconnection_frame[7:13] = helpers.callsign_to_bytes(self.mycallsign)
|
|
||||||
# self.enqueue_frame_for_tx([disconnection_frame, self.send_ident_frame(False)], c2_mode=FREEDV_MODE.sig0.value, copies=5, repeat_delay=0)
|
|
||||||
# TODO We need to add the ident frame feature with a seperate PR after publishing latest protocol
|
|
||||||
# TODO We need to wait some time between last arq related signalling frame and ident frame
|
|
||||||
# TODO Maybe about 500ms - 1500ms to avoid confusion and too much PTT toggles
|
|
||||||
|
|
||||||
# wait if we have a channel busy condition
|
# wait if we have a channel busy condition
|
||||||
if ModemParam.channel_busy:
|
if ModemParam.channel_busy:
|
||||||
|
@ -809,8 +806,12 @@ class DATA:
|
||||||
):
|
):
|
||||||
self.arq_calculate_speed_level(snr)
|
self.arq_calculate_speed_level(snr)
|
||||||
|
|
||||||
self.data_channel_last_received = int(time.time()) + 6 + 6
|
# TIMING TEST
|
||||||
self.burst_last_received = int(time.time()) + 6 + 6
|
#self.data_channel_last_received = int(time.time()) + 6 + 6
|
||||||
|
#self.burst_last_received = int(time.time()) + 6 + 6
|
||||||
|
self.data_channel_last_received = int(time.time())
|
||||||
|
self.burst_last_received = int(time.time())
|
||||||
|
|
||||||
# Create and send ACK frame
|
# Create and send ACK frame
|
||||||
self.log.info("[Modem] ARQ | RX | SENDING ACK", finished=ARQ.arq_seconds_until_finish,
|
self.log.info("[Modem] ARQ | RX | SENDING ACK", finished=ARQ.arq_seconds_until_finish,
|
||||||
bytesperminute=ARQ.bytes_per_minute)
|
bytesperminute=ARQ.bytes_per_minute)
|
||||||
|
@ -2393,6 +2394,7 @@ class DATA:
|
||||||
)
|
)
|
||||||
|
|
||||||
# Reset data_channel/burst timestamps
|
# Reset data_channel/burst timestamps
|
||||||
|
# TIMING TEST
|
||||||
self.data_channel_last_received = int(time.time())
|
self.data_channel_last_received = int(time.time())
|
||||||
self.burst_last_received = int(time.time() + 10) # we might need some more time so lets increase this
|
self.burst_last_received = int(time.time() + 10) # we might need some more time so lets increase this
|
||||||
|
|
||||||
|
@ -2441,7 +2443,9 @@ class DATA:
|
||||||
# set start of transmission for our statistics
|
# set start of transmission for our statistics
|
||||||
self.rx_start_of_transmission = time.time()
|
self.rx_start_of_transmission = time.time()
|
||||||
|
|
||||||
|
# TIMING TEST
|
||||||
# Reset data_channel/burst timestamps once again for avoiding running into timeout
|
# Reset data_channel/burst timestamps once again for avoiding running into timeout
|
||||||
|
# and therefore sending a NACK
|
||||||
self.data_channel_last_received = int(time.time())
|
self.data_channel_last_received = int(time.time())
|
||||||
self.burst_last_received = int(time.time() + 10) # we might need some more time so lets increase this
|
self.burst_last_received = int(time.time() + 10) # we might need some more time so lets increase this
|
||||||
|
|
||||||
|
@ -2783,6 +2787,8 @@ class DATA:
|
||||||
else:
|
else:
|
||||||
self.enqueue_frame_for_tx([beacon_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1,
|
self.enqueue_frame_for_tx([beacon_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1,
|
||||||
repeat_delay=0)
|
repeat_delay=0)
|
||||||
|
if Modem.transmit_morse_identifier:
|
||||||
|
modem.MODEM_TRANSMIT_QUEUE.put(["morse", 1, 0, self.mycallsign])
|
||||||
|
|
||||||
self.beacon_interval_timer = time.time() + self.beacon_interval
|
self.beacon_interval_timer = time.time() + self.beacon_interval
|
||||||
while (
|
while (
|
||||||
|
@ -2860,8 +2866,7 @@ class DATA:
|
||||||
self.enqueue_frame_for_tx([cq_frame], c2_mode=FREEDV_MODE.fsk_ldpc_0.value)
|
self.enqueue_frame_for_tx([cq_frame], c2_mode=FREEDV_MODE.fsk_ldpc_0.value)
|
||||||
else:
|
else:
|
||||||
self.enqueue_frame_for_tx([cq_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0)
|
self.enqueue_frame_for_tx([cq_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0)
|
||||||
if Modem.transmit_morse_identifier:
|
|
||||||
modem.MODEM_TRANSMIT_QUEUE.put(["morse", 1, 0, self.mycallsign])
|
|
||||||
|
|
||||||
def received_cq(self, data_in: bytes) -> None:
|
def received_cq(self, data_in: bytes) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -3329,10 +3334,18 @@ class DATA:
|
||||||
if frames_left == 0:
|
if frames_left == 0:
|
||||||
frames_left = 1
|
frames_left = 1
|
||||||
|
|
||||||
timeout = self.burst_last_received + (self.time_list[self.speed_level] * frames_left)
|
# timeout is reached, if we didnt receive data, while we waited
|
||||||
|
# for the corresponding data frame + the transmitted signalling frame of ack/nack
|
||||||
|
# + a small offset of about 1 second
|
||||||
|
timeout = self.burst_last_received + (self.time_list[self.speed_level] * frames_left) + self.duration_sig0_frame + self.channel_busy_timeout + 1
|
||||||
|
|
||||||
# TODO Enable this for development
|
# TODO Enable this for development
|
||||||
# print(f"timeout expected in:{round(timeout - time.time())} | frames left: {frames_left} of {self.rx_n_frames_per_burst} | speed level: {self.speed_level}")
|
print(f"timeout expected in:{round(timeout - time.time())} | frames left: {frames_left} of {self.rx_n_frames_per_burst} | speed level: {self.speed_level}")
|
||||||
if timeout <= time.time() or modem_error_state:
|
# if timeout is expired, but we are receiving codec2 data,
|
||||||
|
# better wait some more time because data might be important for us
|
||||||
|
# reason for this situation can be delays on IRS and ISS, maybe because both had a busy channel condition.
|
||||||
|
# Nevertheless, we need to keep timeouts short for efficiency
|
||||||
|
if timeout <= time.time() or modem_error_state and not ModemParam.is_codec2_traffic and not Modem.transmitting:
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
"[Modem] Burst decoding error or timeout",
|
"[Modem] Burst decoding error or timeout",
|
||||||
attempt=self.n_retries_per_burst,
|
attempt=self.n_retries_per_burst,
|
||||||
|
@ -3343,7 +3356,7 @@ class DATA:
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"frames_per_burst {self.rx_n_frame_of_burst} / {self.rx_n_frames_per_burst}, Repeats: {self.burst_rpt_counter} Nones: {ARQ.rx_burst_buffer.count(None)}")
|
f"frames_per_burst {self.rx_n_frame_of_burst} / {self.rx_n_frames_per_burst}, Repeats: {self.burst_rpt_counter} Nones: {ARQ.rx_burst_buffer.count(None)}")
|
||||||
|
# check if we have N frames per burst > 1
|
||||||
if self.rx_n_frames_per_burst > 1 and self.burst_rpt_counter < 3 and ARQ.rx_burst_buffer.count(None) > 0:
|
if self.rx_n_frames_per_burst > 1 and self.burst_rpt_counter < 3 and ARQ.rx_burst_buffer.count(None) > 0:
|
||||||
# reset self.burst_last_received
|
# reset self.burst_last_received
|
||||||
self.burst_last_received = time.time() + self.time_list[self.speed_level] * frames_left
|
self.burst_last_received = time.time() + self.time_list[self.speed_level] * frames_left
|
||||||
|
@ -3352,8 +3365,8 @@ class DATA:
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# reset self.burst_last_received
|
# reset self.burst_last_received counter
|
||||||
self.burst_last_received = time.time() + self.time_list[self.speed_level]
|
self.burst_last_received = time.time()
|
||||||
|
|
||||||
# reduce speed level if nack counter increased
|
# reduce speed level if nack counter increased
|
||||||
self.frame_received_counter = 0
|
self.frame_received_counter = 0
|
||||||
|
@ -3374,13 +3387,14 @@ class DATA:
|
||||||
self.set_listening_modes(True, True, self.mode_list[self.speed_level])
|
self.set_listening_modes(True, True, self.mode_list[self.speed_level])
|
||||||
|
|
||||||
# TODO Does SNR make sense for NACK if we dont have an actual SNR information?
|
# TODO Does SNR make sense for NACK if we dont have an actual SNR information?
|
||||||
self.send_burst_nack_frame_watchdog(0, tx_n_frames_per_burst)
|
self.send_burst_nack_frame_watchdog(tx_n_frames_per_burst)
|
||||||
|
|
||||||
# Update data_channel timestamp
|
# Update data_channel timestamp
|
||||||
# TODO Disabled this one for testing.
|
# TODO Disabled this one for testing.
|
||||||
# self.data_channel_last_received = time.time()
|
# self.data_channel_last_received = time.time()
|
||||||
self.n_retries_per_burst += 1
|
self.n_retries_per_burst += 1
|
||||||
else:
|
else:
|
||||||
|
# debugging output
|
||||||
# print((self.data_channel_last_received + self.time_list[self.speed_level])-time.time())
|
# print((self.data_channel_last_received + self.time_list[self.speed_level])-time.time())
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -265,7 +265,7 @@ if __name__ == "__main__":
|
||||||
"--morse",
|
"--morse",
|
||||||
dest="transmit_morse_identifier",
|
dest="transmit_morse_identifier",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=True,
|
default=False,
|
||||||
help="Enable and send a morse identifier on disconnect an beacon",
|
help="Enable and send a morse identifier on disconnect an beacon",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,8 @@ class RF:
|
||||||
self.AUDIO_CHANNELS = 1
|
self.AUDIO_CHANNELS = 1
|
||||||
self.MODE = 0
|
self.MODE = 0
|
||||||
|
|
||||||
|
self.is_codec2_traffic_cooldown = 20
|
||||||
|
self.is_codec2_traffic_counter = 0
|
||||||
# Locking state for mod out so buffer will be filled before we can use it
|
# Locking state for mod out so buffer will be filled before we can use it
|
||||||
# https://github.com/DJ2LS/FreeDATA/issues/127
|
# https://github.com/DJ2LS/FreeDATA/issues/127
|
||||||
# https://github.com/DJ2LS/FreeDATA/issues/99
|
# https://github.com/DJ2LS/FreeDATA/issues/99
|
||||||
|
@ -845,6 +847,8 @@ class RF:
|
||||||
:return: NIN from freedv instance
|
:return: NIN from freedv instance
|
||||||
:rtype: int
|
:rtype: int
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
nbytes = 0
|
nbytes = 0
|
||||||
try:
|
try:
|
||||||
while self.stream.active:
|
while self.stream.active:
|
||||||
|
@ -862,10 +866,11 @@ class RF:
|
||||||
# 10 error decoding == NACK
|
# 10 error decoding == NACK
|
||||||
rx_status = codec2.api.freedv_get_rx_status(freedv)
|
rx_status = codec2.api.freedv_get_rx_status(freedv)
|
||||||
|
|
||||||
if rx_status != 0:
|
if rx_status not in [0]:
|
||||||
# we need to disable this if in testmode as its causing problems with FIFO it seems
|
# we need to disable this if in testmode as its causing problems with FIFO it seems
|
||||||
if not TESTMODE:
|
if not TESTMODE:
|
||||||
ModemParam.is_codec2_traffic = True
|
ModemParam.is_codec2_traffic = True
|
||||||
|
self.is_codec2_traffic_counter = self.is_codec2_traffic_cooldown
|
||||||
if not ModemParam.channel_busy:
|
if not ModemParam.channel_busy:
|
||||||
self.log.debug("[MDM] Setting channel_busy since codec2 data detected")
|
self.log.debug("[MDM] Setting channel_busy since codec2 data detected")
|
||||||
ModemParam.channel_busy=True
|
ModemParam.channel_busy=True
|
||||||
|
@ -877,6 +882,15 @@ class RF:
|
||||||
else:
|
else:
|
||||||
ModemParam.is_codec2_traffic = False
|
ModemParam.is_codec2_traffic = False
|
||||||
|
|
||||||
|
# decrement codec traffic counter for making state smoother
|
||||||
|
|
||||||
|
print(f"{mode_name}: {self.is_codec2_traffic_counter}")
|
||||||
|
if self.is_codec2_traffic_counter > 0:
|
||||||
|
self.is_codec2_traffic_counter -= 1
|
||||||
|
ModemParam.is_codec2_traffic = True
|
||||||
|
else:
|
||||||
|
ModemParam.is_codec2_traffic = False
|
||||||
|
|
||||||
if rx_status == 10:
|
if rx_status == 10:
|
||||||
state_buffer.append(rx_status)
|
state_buffer.append(rx_status)
|
||||||
|
|
||||||
|
@ -1357,7 +1371,7 @@ class RF:
|
||||||
ModemParam.channel_busy_slot[slot] = False
|
ModemParam.channel_busy_slot[slot] = False
|
||||||
# increment slot
|
# increment slot
|
||||||
slot += 1
|
slot += 1
|
||||||
if (addDelay):
|
if addDelay:
|
||||||
# Limit delay counter to a maximum of 200. The higher this value,
|
# Limit delay counter to a maximum of 200. The higher this value,
|
||||||
# the longer we will wait until releasing state
|
# the longer we will wait until releasing state
|
||||||
ModemParam.channel_busy = True
|
ModemParam.channel_busy = True
|
||||||
|
|
|
@ -136,7 +136,7 @@ class TCIParam:
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Modem:
|
class Modem:
|
||||||
version = "0.11.2-alpha.1"
|
version = "0.11.2-alpha.2"
|
||||||
host: str = "0.0.0.0"
|
host: str = "0.0.0.0"
|
||||||
port: int = 3000
|
port: int = 3000
|
||||||
SOCKET_TIMEOUT: int = 1 # seconds
|
SOCKET_TIMEOUT: int = 1 # seconds
|
||||||
|
|
Loading…
Reference in a new issue