WIP ARQ - cleanup and modem fix

This commit is contained in:
DJ2LS 2023-12-15 14:41:11 +01:00
parent 16f37677d5
commit c4dbe0caef
5 changed files with 32 additions and 82 deletions

View file

@ -51,10 +51,13 @@ class ARQSession():
def get_mode_by_speed_level(self, speed_level):
return self.SPEED_LEVEL_DICT[speed_level]["mode"]
def transmit_frame(self, frame: bytearray):
def transmit_frame(self, frame: bytearray, mode = False):
self.log("Transmitting frame")
if not mode:
self.get_mode_by_speed_level(self.speed_level)
modem_queue_item = {
'mode': self.get_mode_by_speed_level(self.speed_level),
'mode': mode,
'repeat': 1,
'repeat_delay': 1,
'frame': frame,

View file

@ -4,6 +4,8 @@ import queue
import arq_session
import helpers
from modem_frametypes import FRAME_TYPE
from codec2 import FREEDV_MODE
class ARQSessionIRS(arq_session.ARQSession):
@ -77,9 +79,9 @@ class ARQSessionIRS(arq_session.ARQSession):
self.log("Timeout waiting for ISS. Session failed.")
self.set_state(self.STATE_FAILED)
def launch_transmit_and_wait(self, frame, timeout):
def launch_transmit_and_wait(self, frame, timeout, mode):
thread_wait = threading.Thread(target = self.transmit_and_wait,
args = [frame, timeout])
args = [frame, timeout, mode])
thread_wait.start()
def send_open_ack(self, open_frame):
@ -88,7 +90,7 @@ class ARQSessionIRS(arq_session.ARQSession):
self.dxcall,
self.version,
self.snr[0])
self.launch_transmit_and_wait(ack_frame, self.TIMEOUT_CONNECT)
self.launch_transmit_and_wait(ack_frame, self.TIMEOUT_CONNECT, mode=FREEDV_MODE.datac13)
self.set_state(self.STATE_OPEN_ACK_SENT)
def send_info_ack(self, info_frame):
@ -97,10 +99,11 @@ class ARQSessionIRS(arq_session.ARQSession):
self.total_crc = info_frame['total_crc']
self.dx_snr.append(info_frame['snr'])
self.calibrate_speed_settings()
info_ack = self.frame_factory.build_arq_session_info_ack(
self.id, self.total_crc, self.snr[0],
self.speed_level, self.frames_per_burst)
self.launch_transmit_and_wait(info_ack, self.TIMEOUT_CONNECT)
self.launch_transmit_and_wait(info_ack, self.TIMEOUT_CONNECT, mode=FREEDV_MODE.datac13)
self.set_state(self.STATE_INFO_ACK_SENT)
def send_burst_nack(self):
@ -108,7 +111,6 @@ class ARQSessionIRS(arq_session.ARQSession):
nack = self.frame_factory.build_arq_burst_ack(self.id, self.received_bytes, self.speed_level, self.frames_per_burst, self.snr[0])
self.transmit_and_wait(nack)
def process_incoming_data(self, frame):
if frame['offset'] != self.received_bytes:
self.logger.info(f"Discarding data frame due to wrong offset", frame=self.frame_received)

View file

@ -52,12 +52,12 @@ class ARQSessionISS(arq_session.ARQSession):
def generate_id(self):
return random.randint(1,255)
def transmit_wait_and_retry(self, frame_or_burst, timeout, retries):
def transmit_wait_and_retry(self, frame_or_burst, timeout, retries, mode):
while retries > 0:
if isinstance(frame_or_burst, list): burst = frame_or_burst
else: burst = [frame_or_burst]
for f in burst:
self.transmit_frame(f)
self.transmit_frame(f, mode)
self.log(f"Waiting {timeout} seconds...")
if self.event_frame_received.wait(timeout):
return
@ -66,13 +66,13 @@ class ARQSessionISS(arq_session.ARQSession):
self.set_state(self.STATE_FAILED)
self.log("Session failed")
def launch_twr(self, frame_or_burst, timeout, retries):
twr = threading.Thread(target = self.transmit_wait_and_retry, args=[frame_or_burst, timeout, retries])
def launch_twr(self, frame_or_burst, timeout, retries, mode):
twr = threading.Thread(target = self.transmit_wait_and_retry, args=[frame_or_burst, timeout, retries, mode])
twr.start()
def start(self):
session_open_frame = self.frame_factory.build_arq_session_open(self.dxcall, self.id)
self.launch_twr(session_open_frame, self.TIMEOUT_CONNECT_ACK, self.RETRIES_CONNECT)
self.launch_twr(session_open_frame, self.TIMEOUT_CONNECT_ACK, self.RETRIES_CONNECT, mode=FREEDV_MODE.datac13)
self.set_state(self.STATE_OPEN_SENT)
def set_speed_and_frames_per_burst(self, frame):

View file

@ -7,7 +7,8 @@ from arq_session_iss import ARQSessionISS
class ARQRawCommand(TxCommand):
def set_params_from_api(self, apiParams):
self.dxcall = apiParams['dxcall']
print(apiParams)
self.dxcall = apiParams['dxcallsign']
if not api_validations.validate_freedata_callsign(self.dxcall):
self.dxcall = f"{self.dxcall}-0"

View file

@ -11,7 +11,6 @@ Created on Wed Dec 23 07:04:24 2020
import atexit
import ctypes
import os
import queue
import threading
import time
@ -25,13 +24,9 @@ import cw
from queues import RIGCTLD_COMMAND_QUEUE
import audio
import event_manager
from modem_frametypes import FRAME_TYPE
import beacon
import demodulator
TESTMODE = False
TXCHANNEL = ""
class RF:
"""Class to encapsulate interactions between the audio device and codec2"""
@ -132,16 +127,14 @@ class RF:
def start_modem(self):
result = False
if not TESTMODE and self.radiocontrol not in ["tci"]:
if self.radiocontrol not in ["tci"]:
result = self.init_audio()
if not result:
raise RuntimeError("Unable to init audio devices")
self.demodulator.start(self.stream)
elif not TESTMODE:
result = self.init_tci()
else:
result = self.init_mkfifo()
result = self.init_tci()
if result not in [False]:
# init codec2 instances
@ -245,34 +238,6 @@ class RF:
daemon=True,
)
tci_tx_callback_thread.start()
def init_mkfifo(self):
class Object:
"""An object for simulating audio stream"""
active = True
self.stream = Object()
# Create mkfifo buffers
try:
os.mkfifo(RXCHANNEL)
os.mkfifo(TXCHANNEL)
except Exception as err:
self.log.info(f"[MDM] init:mkfifo: Exception: {err}")
mkfifo_write_callback_thread = threading.Thread(
target=self.mkfifo_write_callback,
name="MKFIFO WRITE CALLBACK THREAD",
daemon=True,
)
mkfifo_write_callback_thread.start()
self.log.debug("[MDM] Starting mkfifo_read_callback")
mkfifo_read_callback_thread = threading.Thread(
target=self.mkfifo_read_callback,
name="MKFIFO READ CALLBACK THREAD",
daemon=True,
)
mkfifo_read_callback_thread.start()
def mkfifo_write_callback(self) -> None:
"""Support testing by writing the audio data to a pipe."""
@ -304,20 +269,16 @@ class RF:
"""
self.demodulator.reset_data_sync()
if mode == codec2.FREEDV_MODE.datac0.value:
freedv = self.freedv_datac0_tx
elif mode == codec2.FREEDV_MODE.datac1.value:
freedv = self.freedv_datac1_tx
elif mode == codec2.FREEDV_MODE.datac3.value:
freedv = self.freedv_datac3_tx
elif mode == codec2.FREEDV_MODE.datac4.value:
freedv = self.freedv_datac4_tx
elif mode == codec2.FREEDV_MODE.datac13.value:
freedv = self.freedv_datac13_tx
elif mode == codec2.FREEDV_MODE.fsk_ldpc_0.value:
freedv = self.freedv_ldpc0_tx
elif mode == codec2.FREEDV_MODE.fsk_ldpc_1.value:
freedv = self.freedv_ldpc1_tx
# get freedv instance by mode
mode_transition = {
codec2.FREEDV_MODE.datac0: self.freedv_datac0_tx,
codec2.FREEDV_MODE.datac1: self.freedv_datac1_tx,
codec2.FREEDV_MODE.datac3: self.freedv_datac3_tx,
codec2.FREEDV_MODE.datac4: self.freedv_datac4_tx,
codec2.FREEDV_MODE.datac13: self.freedv_datac13_tx,
}
if mode in mode_transition:
freedv = mode_transition[mode]
else:
return False
@ -659,7 +620,7 @@ class RF:
queuesize = self.modem_transmit_queue.qsize()
self.log.debug("[MDM] self.modem_transmit_queue", qsize=queuesize)
tx = self.modem_transmit_queue.get()
print(tx)
# TODO Why we is this taking an array instead of a single frame?
if tx['mode'] in ["morse"]:
self.transmit_morse(tx['repeat'], tx['repeat_delay'], [tx['frame']])
@ -870,20 +831,3 @@ class RF:
# Set config boolean regarding wheter it should sent FFT data to queue
self.enable_fft_stream = enable
def get_modem_error_state():
"""
get current state buffer and return True of contains 10
"""
if RECEIVE_DATAC1 and 10 in DAT0_DATAC1_STATE:
DAT0_DATAC1_STATE.clear()
return True
if RECEIVE_DATAC3 and 10 in DAT0_DATAC3_STATE:
DAT0_DATAC3_STATE.clear()
return True
if RECEIVE_DATAC4 and 10 in DAT0_DATAC4_STATE:
DAT0_DATAC4_STATE.clear()
return True
return False