mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
WIP ARQ - cleanup and modem fix
This commit is contained in:
parent
16f37677d5
commit
c4dbe0caef
5 changed files with 32 additions and 82 deletions
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue