mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 10:04:33 +02:00
ARQ WIP - channel busy detection
This commit is contained in:
parent
ca46949653
commit
7549e34d45
|
@ -50,6 +50,9 @@ class ARQSessionIRS(arq_session.ARQSession):
|
|||
FRAME_TYPE.ARQ_BURST_FRAME.value: 'receive_data',
|
||||
FRAME_TYPE.ARQ_STOP.value: 'send_stop_ack'
|
||||
},
|
||||
IRS_State.ABORTED: {
|
||||
FRAME_TYPE.ARQ_STOP.value: 'send_stop_ack'
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, config: dict, modem, dxcall: str, session_id: int):
|
||||
|
|
|
@ -24,14 +24,14 @@ class ARQSessionISS(arq_session.ARQSession):
|
|||
|
||||
# DJ2LS: 3 seconds seems to be too small for radios with a too slow PTT toggle time
|
||||
# DJ2LS: 3.5 seconds is working well WITHOUT a channel busy detection delay
|
||||
TIMEOUT_CONNECT_ACK = 3.5
|
||||
TIMEOUT_TRANSFER = 3.5
|
||||
TIMEOUT_STOP_ACK = 3.5
|
||||
TIMEOUT_CHANNEL_BUSY = 2
|
||||
TIMEOUT_CONNECT_ACK = 3.5 + TIMEOUT_CHANNEL_BUSY
|
||||
TIMEOUT_TRANSFER = 3.5 + TIMEOUT_CHANNEL_BUSY
|
||||
TIMEOUT_STOP_ACK = 3.5 + TIMEOUT_CHANNEL_BUSY
|
||||
|
||||
STATE_TRANSITION = {
|
||||
ISS_State.OPEN_SENT: {
|
||||
FRAME_TYPE.ARQ_SESSION_OPEN_ACK.value: 'send_info',
|
||||
|
||||
},
|
||||
ISS_State.INFO_SENT: {
|
||||
FRAME_TYPE.ARQ_SESSION_OPEN_ACK.value: 'send_info',
|
||||
|
@ -167,8 +167,6 @@ class ARQSessionISS(arq_session.ARQSession):
|
|||
self.event_frame_received.set()
|
||||
|
||||
# start with abort sequence
|
||||
# TODO: We have to wait some time here for avoiding collisions with actual transmissions...
|
||||
# This could be done by the channel busy detection, for example, if part of def transmit() in modem.py
|
||||
self.send_stop()
|
||||
|
||||
def send_stop(self):
|
||||
|
|
|
@ -8,6 +8,7 @@ import sounddevice as sd
|
|||
import structlog
|
||||
import numpy as np
|
||||
import queue
|
||||
import threading
|
||||
|
||||
atexit.register(sd._terminate)
|
||||
|
||||
|
@ -313,19 +314,17 @@ def calculate_fft(data, fft_queue, states) -> None:
|
|||
if addDelay:
|
||||
# Limit delay counter to a maximum of 200. The higher this value,
|
||||
# the longer we will wait until releasing state
|
||||
states.set("channel_busy", True)
|
||||
states.set_channel_busy_condition_traffic(True)
|
||||
CHANNEL_BUSY_DELAY = min(CHANNEL_BUSY_DELAY + 10, 200)
|
||||
else:
|
||||
# Decrement channel busy counter if no signal has been detected.
|
||||
CHANNEL_BUSY_DELAY = max(CHANNEL_BUSY_DELAY - 1, 0)
|
||||
# When our channel busy counter reaches 0, toggle state to False
|
||||
if CHANNEL_BUSY_DELAY == 0:
|
||||
states.set("channel_busy", False)
|
||||
# erase queue if greater than 10
|
||||
if fft_queue.qsize() >= 10:
|
||||
states.set_channel_busy_condition_traffic(False)
|
||||
# erase queue if greater than 3
|
||||
if fft_queue.qsize() >= 1:
|
||||
fft_queue = queue.Queue()
|
||||
fft_queue.put(dfftlist[:315]) # 315 --> bandwidth 3200
|
||||
except Exception as err:
|
||||
print(f"[MDM] calculate_fft: Exception: {err}")
|
||||
print("[MDM] Setting fft=0")
|
||||
fft_queue.put([0])
|
||||
|
|
|
@ -101,7 +101,7 @@ for file in files:
|
|||
#log.info("[C2 ] Libcodec2 loaded", path=file)
|
||||
break
|
||||
except OSError as err:
|
||||
log.warning("[C2 ] Error: Libcodec2 found but not loaded", path=file, e=err)
|
||||
log.info("[C2 ] Error: Libcodec2 found but not loaded", path=file, e=err)
|
||||
|
||||
# Quit module if codec2 cant be loaded
|
||||
if api is None or "api" not in locals():
|
||||
|
|
|
@ -37,7 +37,7 @@ class Demodulator():
|
|||
self.AUDIO_FRAMES_PER_BUFFER_RX = 4800
|
||||
self.buffer_overflow_counter = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
self.is_codec2_traffic_counter = 0
|
||||
self.is_codec2_traffic_cooldown = 20
|
||||
self.is_codec2_traffic_cooldown = 10
|
||||
|
||||
self.audio_received_queue = audio_rx_q
|
||||
self.modem_received_queue = modem_rx_q
|
||||
|
@ -224,25 +224,18 @@ class Demodulator():
|
|||
|
||||
if rx_status not in [0]:
|
||||
# we need to disable this if in testmode as its causing problems with FIFO it seems
|
||||
self.states.set("is_codec2_traffic", True)
|
||||
self.is_codec2_traffic_counter = self.is_codec2_traffic_cooldown
|
||||
if not self.states.channel_busy:
|
||||
self.log.debug("[MDM] Setting channel_busy since codec2 data detected")
|
||||
self.states.set("channel_busy", True)
|
||||
#self.channel_busy_delay += 10
|
||||
self.log.debug(
|
||||
"[MDM] [demod_audio] modem state", mode=mode_name, rx_status=rx_status,
|
||||
sync_flag=codec2.api.rx_sync_flags_to_text[rx_status]
|
||||
)
|
||||
else:
|
||||
self.states.set("is_codec2_traffic", False)
|
||||
|
||||
# decrement codec traffic counter for making state smoother
|
||||
if self.is_codec2_traffic_counter > 0:
|
||||
self.is_codec2_traffic_counter -= 1
|
||||
self.states.set("is_codec2_traffic", True)
|
||||
self.states.set_channel_busy_condition_codec2(True)
|
||||
else:
|
||||
self.states.set("is_codec2_traffic", False)
|
||||
self.states.set_channel_busy_condition_codec2(False)
|
||||
|
||||
if rx_status == 10:
|
||||
state_buffer.append(rx_status)
|
||||
|
|
|
@ -221,7 +221,7 @@ class RF:
|
|||
alc_level=str(self.radio_alc))
|
||||
|
||||
def transmit(
|
||||
self, mode, repeats: int, repeat_delay: int, frames: bytearray
|
||||
self, mode, repeats: int, repeat_delay: int, frames: bytearray, timeout_channel_busy=5
|
||||
) -> bool:
|
||||
"""
|
||||
|
||||
|
@ -256,8 +256,7 @@ class RF:
|
|||
# Wait for some other thread that might be transmitting
|
||||
self.states.waitForTransmission()
|
||||
self.states.setTransmitting(True)
|
||||
# if we're transmitting FreeDATA signals, reset channel busy state
|
||||
self.states.set("channel_busy", False)
|
||||
self.states.channel_busy_event.wait(timeout_channel_busy)
|
||||
|
||||
start_of_transmission = time.time()
|
||||
# TODO Moved ptt toggle some steps before audio is ready for testing
|
||||
|
@ -307,7 +306,6 @@ class RF:
|
|||
# transmit audio
|
||||
self.transmit_audio(txbuffer_out)
|
||||
|
||||
self.states.set("channel_busy", False)
|
||||
self.radio.set_ptt(False)
|
||||
self.event_manager.send_ptt_change(False)
|
||||
self.states.setTransmitting(False)
|
||||
|
|
|
@ -13,9 +13,11 @@ class StateManager:
|
|||
# modem related states
|
||||
# not every state is needed to publish, yet
|
||||
# TODO can we reduce them?
|
||||
self.channel_busy = False
|
||||
self.channel_busy_slot = [False, False, False, False, False]
|
||||
self.is_codec2_traffic = False
|
||||
self.channel_busy_event = threading.Event()
|
||||
self.channel_busy_condition_traffic = threading.Event()
|
||||
self.channel_busy_condition_codec2 = threading.Event()
|
||||
|
||||
self.is_modem_running = False
|
||||
self.is_modem_busy = False
|
||||
self.is_beacon_running = False
|
||||
|
@ -35,16 +37,6 @@ class StateManager:
|
|||
|
||||
self.arq_iss_sessions = {}
|
||||
self.arq_irs_sessions = {}
|
||||
|
||||
self.arq_session_state = 'disconnected'
|
||||
self.arq_speed_level = 0
|
||||
self.arq_total_bytes = 0
|
||||
self.arq_bits_per_second = 0
|
||||
self.arq_bytes_per_minute = 0
|
||||
self.arq_transmission_percent = 0
|
||||
self.arq_compression_factor = 0
|
||||
self.arq_speed_list = []
|
||||
self.arq_seconds_until_timeout = 0
|
||||
|
||||
self.mesh_routing_table = []
|
||||
|
||||
|
@ -89,7 +81,6 @@ class StateManager:
|
|||
return {
|
||||
"freedata-message": msgtype,
|
||||
"channel_busy": self.channel_busy,
|
||||
"is_codec2_traffic": self.is_codec2_traffic,
|
||||
"is_modem_running": self.is_modem_running,
|
||||
"is_beacon_running": self.is_beacon_running,
|
||||
"radio_status": self.radio_status,
|
||||
|
@ -162,3 +153,23 @@ class StateManager:
|
|||
|
||||
self.activities_list[activity_id] = activity_data
|
||||
self.sendStateUpdate()
|
||||
|
||||
def calculate_channel_busy_state(self):
|
||||
if self.channel_busy_condition_traffic.is_set() and self.channel_busy_condition_codec2.is_set():
|
||||
self.channel_busy_event.set()
|
||||
else:
|
||||
self.channel_busy_event = threading.Event()
|
||||
|
||||
def set_channel_busy_condition_traffic(self, busy):
|
||||
if not busy:
|
||||
self.channel_busy_condition_traffic.set()
|
||||
else:
|
||||
self.channel_busy_condition_traffic = threading.Event()
|
||||
self.calculate_channel_busy_state()
|
||||
|
||||
def set_channel_busy_condition_codec2(self, traffic):
|
||||
if not traffic:
|
||||
self.channel_busy_condition_codec2.set()
|
||||
else:
|
||||
self.channel_busy_condition_codec2 = threading.Event()
|
||||
self.calculate_channel_busy_state()
|
||||
|
|
Loading…
Reference in a new issue