adjustments to modem tests - still not working yet. but we have first benefits of new modem structure

pull/978/head
DJ2LS 2025-05-19 08:54:24 +02:00
parent feaaa699e8
commit e5208cffff
6 changed files with 74 additions and 62 deletions

View File

@ -30,6 +30,8 @@ class AppContext:
self.message_system_db_manager = DatabaseManager(self)
self.message_system_db_attachments = DatabaseManagerAttachments(self)
self.TESTMODE = False
def startup(self):
# initially read config

View File

@ -120,7 +120,10 @@ class Demodulator():
self.MODE_DICT[mode]["nin"] = nin
def start(self, stream):
self.stream = stream
if self.ctx.TESTMODE:
self.stream = None
else:
self.stream = stream
for mode in self.MODE_DICT:
# Start decoder threads
@ -160,7 +163,7 @@ class Demodulator():
last_rx_status = 0
try:
while self.stream and self.stream.active and not self.shutdown_flag.is_set():
while self.stream and self.stream.active and not self.shutdown_flag.is_set() or self.ctx.TESTMODE:
threading.Event().wait(0.01)
if audiobuffer.nbuffer >= nin and not self.shutdown_flag.is_set():
# demodulate audio

View File

@ -20,7 +20,6 @@ import audio
import demodulator
import modulator
TESTMODE = False
class RF:
"""Handles FreeDATA modem functionality.
@ -44,7 +43,7 @@ class RF:
states (StateManager): State manager instance.
radio_manager (RadioManager): Radio manager instance.
"""
self.ctx = ctx
self.sampler_avg = 0
self.buffer_avg = 0
@ -99,7 +98,10 @@ class RF:
Raises:
RuntimeError: If audio device initialization fails.
"""
if TESTMODE:
if self.ctx.TESTMODE:
self.log.warning("RUNNING IN TEST MODE")
self.resampler = codec2.resampler() # we need a resampler in test mode
self.demodulator.start(None)
return True
else:
if not self.init_audio():
@ -324,7 +326,11 @@ class RF:
self.ctx.event_manager.send_ptt_change(True)
# slice audio data to needed blocklength
block_size = self.sd_output_stream.blocksize
if self.ctx.TESTMODE:
block_size = 2400
else:
block_size = self.sd_output_stream.blocksize
pad_length = -len(audio_48k) % block_size
padded_data = np.pad(audio_48k, (0, pad_length), mode='constant')
sliced_audio_data = padded_data.reshape(-1, block_size)

View File

@ -129,13 +129,14 @@ class SM:
self.log.warning("freedata_server already running")
return False
# test audio devices
audio_test = self.test_audio()
if False in audio_test or None in audio_test or self.ctx.state_manager.is_modem_running:
self.log.warning("starting freedata_server failed", input_test=audio_test[0], output_test=audio_test[1])
self.ctx.state_manager.set("is_modem_running", False)
self.ctx.event_manager.modem_failed()
return False
if not self.ctx.TESTMODE:
# test audio devices
audio_test = self.test_audio()
if False in audio_test or None in audio_test or self.ctx.state_manager.is_modem_running:
self.log.warning("starting freedata_server failed", input_test=audio_test[0], output_test=audio_test[1])
self.ctx.state_manager.set("is_modem_running", False)
self.ctx.event_manager.modem_failed()
return False
self.log.info("starting freedata_server....")
self.ctx.rf_modem = modem.RF(self.ctx)

View File

@ -4,7 +4,9 @@ sys.path.append('freedata_server')
import unittest
import unittest.mock
from config import CONFIG
import config
from context import AppContext
import helpers
import queue
import threading
@ -20,6 +22,8 @@ from state_manager import StateManager
from data_frame_factory import DataFrameFactory
import codec2
import arq_session_irs
import os
class TestModem:
def __init__(self, event_q, state_q):
self.data_queue_received = queue.Queue()
@ -54,47 +58,45 @@ class TestModem:
}
self.data_queue_received.put(transmission)
class DummyCtx:
def __init__(self):
pass
class TestARQSession(unittest.TestCase):
@classmethod
def setUpClass(cls):
config_manager = CONFIG('freedata_server/config.ini.example')
cls.config = config_manager.read()
# TODO:
# ESTABLISH MODEM CHANNELS CORRECTLY SO WE ARE GETTING THE CORRESPINDING BURSTS
cls.logger = structlog.get_logger("TESTS")
cls.frame_factory = DataFrameFactory(cls.config)
# ISS
cls.iss_state_manager = StateManager(queue.Queue())
cls.iss_state_manager.set_channel_busy_condition_codec2(False)
cls.iss_event_manager = EventManager([queue.Queue()])
cls.iss_event_queue = queue.Queue()
cls.iss_state_queue = queue.Queue()
cls.iss_modem = TestModem(cls.iss_event_queue, cls.iss_state_queue)
cls.iss_frame_dispatcher = DISPATCHER(cls.config,
cls.iss_event_manager,
cls.iss_state_manager,
cls.iss_modem, None)
cls.ctx_ISS = AppContext('freedata_server/config.ini.example')
cls.ctx_ISS.TESTMODE = True
cls.ctx_ISS.startup()
# IRS
cls.irs_state_manager = StateManager(queue.Queue())
cls.iss_state_manager.set_channel_busy_condition_codec2(False)
cls.irs_event_manager = EventManager([queue.Queue()])
cls.irs_event_queue = queue.Queue()
cls.irs_state_queue = queue.Queue()
cls.irs_modem = TestModem(cls.irs_event_queue, cls.irs_state_queue)
cls.irs_frame_dispatcher = DISPATCHER(cls.config,
cls.irs_event_manager,
cls.irs_state_manager,
cls.irs_modem, None)
cls.ctx_IRS = AppContext('freedata_server/config.ini.example')
cls.ctx_IRS.TESTMODE = True
cls.ctx_IRS.startup()
# simulate a busy condition
cls.irs_state_manager.channel_busy_slot = [True, False, False, False, False]
cls.ctx_IRS.state_manager.channel_busy_slot = [True, False, False, False, False]
# Frame loss probability in %
cls.loss_probability = 0
cls.channels_running = True
cls.channels_running = False
def channelWorker(self, modem_transmit_queue: queue.Queue, frame_dispatcher: DISPATCHER):
while self.channels_running:
@ -126,23 +128,22 @@ class TestARQSession(unittest.TestCase):
break
def establishChannels(self):
self.channels_running = True
self.iss_to_irs_channel = threading.Thread(target=self.channelWorker,
args=[self.iss_modem.data_queue_received,
self.irs_frame_dispatcher],
self.iss_to_irs_channel = threading.Thread(target=self.channelWorker,
args=[self.ctx_ISS.rf_modem.data_queue_received,
self.ctx_IRS.service_manager.frame_dispatcher],
name = "ISS to IRS channel")
self.iss_to_irs_channel.start()
self.irs_to_iss_channel = threading.Thread(target=self.channelWorker,
args=[self.irs_modem.data_queue_received,
self.iss_frame_dispatcher],
args=[self.ctx_IRS.rf_modem.data_queue_received,
self.ctx_ISS.service_manager.frame_dispatcher],
name = "IRS to ISS channel")
self.irs_to_iss_channel.start()
self.channels_running = True
def waitAndCloseChannels(self):
self.waitForSession(self.iss_event_queue, True)
self.waitForSession(self.ctx_ISS.modem_events, True)
self.channels_running = False
self.waitForSession(self.irs_event_queue, False)
self.waitForSession(self.ctx_IRS.modem_events, False)
self.channels_running = False
def DisabledtestARQSessionSmallPayload(self):
@ -155,8 +156,8 @@ class TestARQSession(unittest.TestCase):
'data': base64.b64encode(bytes("Hello world!", encoding="utf-8")),
'type': "raw_lzma"
}
cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params)
cmd.run(self.iss_event_queue, self.iss_modem)
cmd = ARQRawCommand(self.ctx_ISS, params)
cmd.run()
self.waitAndCloseChannels()
del cmd
@ -170,8 +171,8 @@ class TestARQSession(unittest.TestCase):
'data': base64.b64encode(np.random.bytes(1000)),
'type': "raw_lzma"
}
cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params)
cmd.run(self.iss_event_queue, self.iss_modem)
cmd = ARQRawCommand(self.ctx_ISS, params)
cmd.run()
self.waitAndCloseChannels()
del cmd
@ -185,12 +186,12 @@ class TestARQSession(unittest.TestCase):
'dxcall': "AA1AAA-1",
'data': base64.b64encode(np.random.bytes(100)),
}
cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params)
cmd.run(self.iss_event_queue, self.iss_modem)
cmd = ARQRawCommand(self.ctx_ISS, params)
cmd.run()
threading.Event().wait(np.random.randint(10,10))
for id in self.iss_state_manager.arq_iss_sessions:
self.iss_state_manager.arq_iss_sessions[id].abort_transmission()
for id in self.ctx_ISS.state_manager.arq_iss_sessions:
self.ctx_ISS.state_manager.arq_iss_sessions[id].abort_transmission()
self.waitAndCloseChannels()
del cmd
@ -204,12 +205,12 @@ class TestARQSession(unittest.TestCase):
'dxcall': "AA1AAA-1",
'data': base64.b64encode(np.random.bytes(100)),
}
cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params)
cmd.run(self.iss_event_queue, self.iss_modem)
cmd = ARQRawCommand(self.ctx_ISS, params)
cmd.run()
threading.Event().wait(np.random.randint(1,10))
for id in self.irs_state_manager.arq_irs_sessions:
self.irs_state_manager.arq_irs_sessions[id].abort_transmission()
for id in self.ctx_IRS.state_manager.arq_irs_sessions:
self.ctx_IRS.state_manager.arq_irs_sessions[id].abort_transmission()
self.waitAndCloseChannels()
del cmd

View File

@ -17,7 +17,6 @@ class TestMessageP2P(unittest.TestCase):
@classmethod
def setUpClass(cls):
# Starte echten Context
cls.ctx = AppContext('freedata_server/config.ini.example')
cls.ctx.config_manager.read()