mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
Eliminate modem TX queues and change transmit() to a blocking call
This commit is contained in:
parent
1640f6c66e
commit
30996c03b6
|
@ -25,7 +25,7 @@ class ARQSession():
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, config: dict, tx_frame_queue: queue.Queue, dxcall: str):
|
def __init__(self, config: dict, modem, dxcall: str):
|
||||||
self.logger = structlog.get_logger(type(self).__name__)
|
self.logger = structlog.get_logger(type(self).__name__)
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class ARQSession():
|
||||||
self.dxcall = dxcall
|
self.dxcall = dxcall
|
||||||
self.dx_snr = []
|
self.dx_snr = []
|
||||||
|
|
||||||
self.tx_frame_queue = tx_frame_queue
|
self.modem = modem
|
||||||
self.speed_level = 0
|
self.speed_level = 0
|
||||||
self.frames_per_burst = 1
|
self.frames_per_burst = 1
|
||||||
|
|
||||||
|
@ -56,13 +56,7 @@ class ARQSession():
|
||||||
if mode in ['auto']:
|
if mode in ['auto']:
|
||||||
mode = self.get_mode_by_speed_level(self.speed_level)
|
mode = self.get_mode_by_speed_level(self.speed_level)
|
||||||
|
|
||||||
modem_queue_item = {
|
self.modem.transmit(mode, 1, 1, frame)
|
||||||
'mode': mode,
|
|
||||||
'repeat': 1,
|
|
||||||
'repeat_delay': 1,
|
|
||||||
'frame': frame,
|
|
||||||
}
|
|
||||||
self.tx_frame_queue.put(modem_queue_item)
|
|
||||||
|
|
||||||
def set_state(self, state):
|
def set_state(self, state):
|
||||||
self.log(f"{type(self).__name__} state change from {self.state} to {state}")
|
self.log(f"{type(self).__name__} state change from {self.state} to {state}")
|
||||||
|
|
|
@ -39,8 +39,8 @@ class ARQSessionIRS(arq_session.ARQSession):
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, config: dict, tx_frame_queue: queue.Queue, dxcall: str, session_id: int):
|
def __init__(self, config: dict, modem, dxcall: str, session_id: int):
|
||||||
super().__init__(config, tx_frame_queue, dxcall)
|
super().__init__(config, modem, dxcall)
|
||||||
|
|
||||||
self.id = session_id
|
self.id = session_id
|
||||||
self.dxcall = dxcall
|
self.dxcall = dxcall
|
||||||
|
|
|
@ -35,8 +35,8 @@ class ARQSessionISS(arq_session.ARQSession):
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, config: dict, tx_frame_queue: queue.Queue, dxcall: str, data: bytearray):
|
def __init__(self, config: dict, modem, dxcall: str, data: bytearray):
|
||||||
super().__init__(config, tx_frame_queue, dxcall)
|
super().__init__(config, modem, dxcall)
|
||||||
self.data = data
|
self.data = data
|
||||||
self.data_crc = ''
|
self.data_crc = ''
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,11 @@ class TxCommand():
|
||||||
'frame': frame,
|
'frame': frame,
|
||||||
}
|
}
|
||||||
|
|
||||||
def transmit(self, tx_frame_queue):
|
def transmit(self, modem):
|
||||||
frame = self.build_frame()
|
frame = self.build_frame()
|
||||||
tx_queue_item = self.make_modem_queue_item(self.get_tx_mode(), 1, 0, frame)
|
modem.transmit(self.get_tx_mode(), 1, 0, frame)
|
||||||
tx_frame_queue.put(tx_queue_item)
|
|
||||||
|
|
||||||
def run(self, event_queue: queue.Queue, tx_frame_queue: queue.Queue):
|
def run(self, event_queue: queue.Queue, modem):
|
||||||
self.emit_event(event_queue)
|
self.emit_event(event_queue)
|
||||||
self.logger.info(self.log_message())
|
self.logger.info(self.log_message())
|
||||||
self.transmit(tx_frame_queue)
|
self.transmit(modem)
|
||||||
|
|
|
@ -13,11 +13,11 @@ class ARQRawCommand(TxCommand):
|
||||||
|
|
||||||
self.data = base64.b64decode(apiParams['data'])
|
self.data = base64.b64decode(apiParams['data'])
|
||||||
|
|
||||||
def run(self, event_queue: Queue, tx_frame_queue: Queue):
|
def run(self, event_queue: Queue, modem):
|
||||||
self.emit_event(event_queue)
|
self.emit_event(event_queue)
|
||||||
self.logger.info(self.log_message())
|
self.logger.info(self.log_message())
|
||||||
|
|
||||||
iss = ARQSessionISS(self.config, tx_frame_queue, self.dxcall, self.data)
|
iss = ARQSessionISS(self.config, modem, self.dxcall, self.data)
|
||||||
self.state_manager.register_arq_iss_session(iss)
|
self.state_manager.register_arq_iss_session(iss)
|
||||||
iss.start()
|
iss.start()
|
||||||
return iss
|
return iss
|
||||||
|
|
|
@ -5,8 +5,8 @@ class BeaconCommand(TxCommand):
|
||||||
def build_frame(self):
|
def build_frame(self):
|
||||||
return self.frame_factory.build_beacon()
|
return self.frame_factory.build_beacon()
|
||||||
|
|
||||||
def transmit(self, tx_frame_queue):
|
def transmit(self, modem):
|
||||||
super().transmit(tx_frame_queue)
|
super().transmit(modem)
|
||||||
if self.config['MODEM']['enable_morse_identifier']:
|
if self.config['MODEM']['enable_morse_identifier']:
|
||||||
mycall = f"{self.config['STATION']['mycall']}-{self.config['STATION']['myssid']}"
|
mycall = f"{self.config['STATION']['mycall']}-{self.config['STATION']['myssid']}"
|
||||||
tx_frame_queue.put(["morse", 1, 0, mycall])
|
modem.transmit_morse("morse", 1, 0, mycall)
|
||||||
|
|
|
@ -39,7 +39,7 @@ class DISPATCHER():
|
||||||
FR_TYPE.FEC_WAKEUP.value: {"class": FrameHandler, "name": "FEC WAKEUP"},
|
FR_TYPE.FEC_WAKEUP.value: {"class": FrameHandler, "name": "FEC WAKEUP"},
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, config, event_queue, states, data_q_rx, modem_tx_q):
|
def __init__(self, config, event_queue, states, modem):
|
||||||
self.log = structlog.get_logger("frame_dispatcher")
|
self.log = structlog.get_logger("frame_dispatcher")
|
||||||
|
|
||||||
self.log.info("loading frame dispatcher.....\n")
|
self.log.info("loading frame dispatcher.....\n")
|
||||||
|
@ -49,8 +49,8 @@ class DISPATCHER():
|
||||||
|
|
||||||
self._initialize_handlers(config, event_queue, states)
|
self._initialize_handlers(config, event_queue, states)
|
||||||
|
|
||||||
self.data_queue_received = data_q_rx
|
self.modem = modem
|
||||||
self.modem_transmit_queue = modem_tx_q
|
self.data_queue_received = modem.data_queue_received
|
||||||
|
|
||||||
self.arq_sessions = []
|
self.arq_sessions = []
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ class DISPATCHER():
|
||||||
self.config,
|
self.config,
|
||||||
self.states,
|
self.states,
|
||||||
self.event_manager,
|
self.event_manager,
|
||||||
self.modem_transmit_queue)
|
self.modem)
|
||||||
|
|
||||||
handler.handle(deconstructed_frame, snr, frequency_offset, freedv, bytes_per_frame)
|
handler.handle(deconstructed_frame, snr, frequency_offset, freedv, bytes_per_frame)
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,13 @@ from codec2 import FREEDV_MODE
|
||||||
class FrameHandler():
|
class FrameHandler():
|
||||||
|
|
||||||
def __init__(self, name: str, config, states: StateManager, event_manager: EventManager,
|
def __init__(self, name: str, config, states: StateManager, event_manager: EventManager,
|
||||||
tx_frame_queue: Queue) -> None:
|
modem) -> None:
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.config = config
|
self.config = config
|
||||||
self.states = states
|
self.states = states
|
||||||
self.event_manager = event_manager
|
self.event_manager = event_manager
|
||||||
self.tx_frame_queue = tx_frame_queue
|
self.modem = modem
|
||||||
self.logger = structlog.get_logger("Frame Handler")
|
self.logger = structlog.get_logger("Frame Handler")
|
||||||
|
|
||||||
self.details = {
|
self.details = {
|
||||||
|
@ -86,14 +86,6 @@ class FrameHandler():
|
||||||
event_data = self.make_event()
|
event_data = self.make_event()
|
||||||
self.event_manager.broadcast(event_data)
|
self.event_manager.broadcast(event_data)
|
||||||
|
|
||||||
def make_modem_queue_item(self, mode, repeat, repeat_delay, frame):
|
|
||||||
return {
|
|
||||||
'mode': self.get_tx_mode(),
|
|
||||||
'repeat': repeat,
|
|
||||||
'repeat_delay': repeat_delay,
|
|
||||||
'frame': frame,
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_tx_mode(self):
|
def get_tx_mode(self):
|
||||||
return (
|
return (
|
||||||
FREEDV_MODE.fsk_ldpc_0.value
|
FREEDV_MODE.fsk_ldpc_0.value
|
||||||
|
@ -102,8 +94,7 @@ class FrameHandler():
|
||||||
)
|
)
|
||||||
|
|
||||||
def transmit(self, frame):
|
def transmit(self, frame):
|
||||||
tx_queue_item = self.make_modem_queue_item(self.get_tx_mode(), 1, 0, frame)
|
self.modem.transmit(self.get_tx_mode(), 1, 0, frame)
|
||||||
self.tx_frame_queue.put(tx_queue_item)
|
|
||||||
|
|
||||||
def follow_protocol(self):
|
def follow_protocol(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -22,8 +22,8 @@ class ARQFrameHandler(frame_handler.FrameHandler):
|
||||||
|
|
||||||
# Normal case when receiving a SESSION_OPEN for the first time
|
# Normal case when receiving a SESSION_OPEN for the first time
|
||||||
else:
|
else:
|
||||||
session = ARQSessionIRS(self.config,
|
session = ARQSessionIRS(self.config,
|
||||||
self.tx_frame_queue,
|
self.modem,
|
||||||
frame['origin'],
|
frame['origin'],
|
||||||
session_id)
|
session_id)
|
||||||
self.states.register_arq_irs_session(session)
|
self.states.register_arq_irs_session(session)
|
||||||
|
|
|
@ -87,7 +87,6 @@ class RF:
|
||||||
self.modem_received_queue = queue.Queue()
|
self.modem_received_queue = queue.Queue()
|
||||||
|
|
||||||
self.audio_received_queue = queue.Queue()
|
self.audio_received_queue = queue.Queue()
|
||||||
self.audio_transmit_queue = queue.Queue()
|
|
||||||
|
|
||||||
self.data_queue_received = queue.Queue()
|
self.data_queue_received = queue.Queue()
|
||||||
|
|
||||||
|
@ -105,7 +104,6 @@ class RF:
|
||||||
self.beacon = beacon.Beacon(self.config, self.states, event_queue,
|
self.beacon = beacon.Beacon(self.config, self.states, event_queue,
|
||||||
self.log, self.modem_transmit_queue)
|
self.log, self.modem_transmit_queue)
|
||||||
|
|
||||||
# --------------------------------------------------------------------------------------------------------
|
|
||||||
def tci_tx_callback(self, audio_48k) -> None:
|
def tci_tx_callback(self, audio_48k) -> None:
|
||||||
self.radio.set_ptt(True)
|
self.radio.set_ptt(True)
|
||||||
self.event_manager.send_ptt_change(True)
|
self.event_manager.send_ptt_change(True)
|
||||||
|
@ -212,7 +210,7 @@ class RF:
|
||||||
self.stream = Object()
|
self.stream = Object()
|
||||||
|
|
||||||
# lets init TCI module
|
# lets init TCI module
|
||||||
self.tci_module = tci.TCICtrl(self.audio_received_queue, self.audio_transmit_queue)
|
self.tci_module = tci.TCICtrl(self.audio_received_queue)
|
||||||
|
|
||||||
tci_rx_callback_thread = threading.Thread(
|
tci_rx_callback_thread = threading.Thread(
|
||||||
target=self.tci_rx_callback,
|
target=self.tci_rx_callback,
|
||||||
|
@ -230,7 +228,35 @@ class RF:
|
||||||
)
|
)
|
||||||
tci_tx_callback_thread.start()
|
tci_tx_callback_thread.start()
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
def audio_auto_tune(self):
|
||||||
|
# enable / disable AUDIO TUNE Feature / ALC correction
|
||||||
|
if self.enable_audio_auto_tune:
|
||||||
|
if self.radio_alc == 0.0:
|
||||||
|
self.tx_audio_level = self.tx_audio_level + 20
|
||||||
|
elif 0.0 < self.radio_alc <= 0.1:
|
||||||
|
print("0.0 < self.radio_alc <= 0.1")
|
||||||
|
self.tx_audio_level = self.tx_audio_level + 2
|
||||||
|
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
||||||
|
alc_level=str(self.radio_alc))
|
||||||
|
elif 0.1 < self.radio_alc < 0.2:
|
||||||
|
print("0.1 < self.radio_alc < 0.2")
|
||||||
|
self.tx_audio_level = self.tx_audio_level
|
||||||
|
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
||||||
|
alc_level=str(self.radio_alc))
|
||||||
|
elif 0.2 < self.radio_alc < 0.99:
|
||||||
|
print("0.2 < self.radio_alc < 0.99")
|
||||||
|
self.tx_audio_level = self.tx_audio_level - 20
|
||||||
|
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
||||||
|
alc_level=str(self.radio_alc))
|
||||||
|
elif 1.0 >= self.radio_alc:
|
||||||
|
print("1.0 >= self.radio_alc")
|
||||||
|
self.tx_audio_level = self.tx_audio_level - 40
|
||||||
|
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
||||||
|
alc_level=str(self.radio_alc))
|
||||||
|
else:
|
||||||
|
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
||||||
|
alc_level=str(self.radio_alc))
|
||||||
|
|
||||||
def transmit(
|
def transmit(
|
||||||
self, mode, repeats: int, repeat_delay: int, frames: bytearray
|
self, mode, repeats: int, repeat_delay: int, frames: bytearray
|
||||||
) -> bool:
|
) -> bool:
|
||||||
|
@ -310,6 +336,7 @@ class RF:
|
||||||
"[MDM] TRANSMIT", mode=self.MODE, payload=payload_bytes_per_frame, delay=self.tx_delay
|
"[MDM] TRANSMIT", mode=self.MODE, payload=payload_bytes_per_frame, delay=self.tx_delay
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not isinstance(frames, list): frames = [frames]
|
||||||
for _ in range(repeats):
|
for _ in range(repeats):
|
||||||
|
|
||||||
# Create modulation for all frames in the list
|
# Create modulation for all frames in the list
|
||||||
|
@ -419,42 +446,12 @@ class RF:
|
||||||
# After processing, set the locking state back to true to be prepared for next transmission
|
# After processing, set the locking state back to true to be prepared for next transmission
|
||||||
self.mod_out_locked = True
|
self.mod_out_locked = True
|
||||||
|
|
||||||
self.modem_transmit_queue.task_done()
|
|
||||||
self.states.setTransmitting(False)
|
self.states.setTransmitting(False)
|
||||||
|
|
||||||
end_of_transmission = time.time()
|
end_of_transmission = time.time()
|
||||||
transmission_time = end_of_transmission - start_of_transmission
|
transmission_time = end_of_transmission - start_of_transmission
|
||||||
self.log.debug("[MDM] ON AIR TIME", time=transmission_time)
|
self.log.debug("[MDM] ON AIR TIME", time=transmission_time)
|
||||||
|
|
||||||
def audio_auto_tune(self):
|
|
||||||
# enable / disable AUDIO TUNE Feature / ALC correction
|
|
||||||
if self.enable_audio_auto_tune:
|
|
||||||
if self.radio_alc == 0.0:
|
|
||||||
self.tx_audio_level = self.tx_audio_level + 20
|
|
||||||
elif 0.0 < self.radio_alc <= 0.1:
|
|
||||||
print("0.0 < self.radio_alc <= 0.1")
|
|
||||||
self.tx_audio_level = self.tx_audio_level + 2
|
|
||||||
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
|
||||||
alc_level=str(self.radio_alc))
|
|
||||||
elif 0.1 < self.radio_alc < 0.2:
|
|
||||||
print("0.1 < self.radio_alc < 0.2")
|
|
||||||
self.tx_audio_level = self.tx_audio_level
|
|
||||||
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
|
||||||
alc_level=str(self.radio_alc))
|
|
||||||
elif 0.2 < self.radio_alc < 0.99:
|
|
||||||
print("0.2 < self.radio_alc < 0.99")
|
|
||||||
self.tx_audio_level = self.tx_audio_level - 20
|
|
||||||
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
|
||||||
alc_level=str(self.radio_alc))
|
|
||||||
elif 1.0 >= self.radio_alc:
|
|
||||||
print("1.0 >= self.radio_alc")
|
|
||||||
self.tx_audio_level = self.tx_audio_level - 40
|
|
||||||
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
|
||||||
alc_level=str(self.radio_alc))
|
|
||||||
else:
|
|
||||||
self.log.debug("[MDM] AUDIO TUNE", audio_level=str(self.tx_audio_level),
|
|
||||||
alc_level=str(self.radio_alc))
|
|
||||||
|
|
||||||
def transmit_morse(self, repeats, repeat_delay, frames):
|
def transmit_morse(self, repeats, repeat_delay, frames):
|
||||||
self.states.waitForTransmission()
|
self.states.waitForTransmission()
|
||||||
self.states.setTransmitting(True)
|
self.states.setTransmitting(True)
|
||||||
|
@ -528,11 +525,6 @@ class RF:
|
||||||
)
|
)
|
||||||
worker_received.start()
|
worker_received.start()
|
||||||
|
|
||||||
worker_transmit = threading.Thread(
|
|
||||||
target=self.worker_transmit, name="WORKER_THREAD", daemon=True
|
|
||||||
)
|
|
||||||
worker_transmit.start()
|
|
||||||
|
|
||||||
# Low level modem audio transmit
|
# Low level modem audio transmit
|
||||||
def transmit_audio(self, audio_48k) -> None:
|
def transmit_audio(self, audio_48k) -> None:
|
||||||
self.radio.set_ptt(True)
|
self.radio.set_ptt(True)
|
||||||
|
@ -545,23 +537,6 @@ class RF:
|
||||||
sd.play(audio_48k, blocking=True)
|
sd.play(audio_48k, blocking=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
def worker_transmit(self) -> None:
|
|
||||||
"""Worker for FIFO queue for processing frames to be transmitted"""
|
|
||||||
while True:
|
|
||||||
# print queue size for debugging purposes
|
|
||||||
# TODO Lets check why we have several frames in our transmit queue which causes sometimes a double transmission
|
|
||||||
# we could do a cleanup after a transmission so theres no reason sending twice
|
|
||||||
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']])
|
|
||||||
else:
|
|
||||||
self.transmit(tx['mode'], tx['repeat'], tx['repeat_delay'], [tx['frame']])
|
|
||||||
# self.modem_transmit_queue.task_done()
|
|
||||||
|
|
||||||
def init_rig_control(self):
|
def init_rig_control(self):
|
||||||
# Check how we want to control the radio
|
# Check how we want to control the radio
|
||||||
if self.radiocontrol == "rigctld":
|
if self.radiocontrol == "rigctld":
|
||||||
|
|
|
@ -8,9 +8,5 @@ MESH_RECEIVED_QUEUE = queue.Queue()
|
||||||
MESH_QUEUE_TRANSMIT = queue.Queue()
|
MESH_QUEUE_TRANSMIT = queue.Queue()
|
||||||
MESH_SIGNALLING_TABLE = []
|
MESH_SIGNALLING_TABLE = []
|
||||||
|
|
||||||
# Initialize FIFO queue to finally store received data
|
|
||||||
# TODO Fix rx_buffer_size
|
|
||||||
RX_BUFFER = queue.Queue(maxsize=16)
|
|
||||||
|
|
||||||
# Commands we want to send to rigctld
|
# Commands we want to send to rigctld
|
||||||
RIGCTLD_COMMAND_QUEUE = queue.Queue()
|
RIGCTLD_COMMAND_QUEUE = queue.Queue()
|
|
@ -83,8 +83,8 @@ def validate(req, param, validator, isRequired = True):
|
||||||
# Takes a transmit command and puts it in the transmit command queue
|
# Takes a transmit command and puts it in the transmit command queue
|
||||||
def enqueue_tx_command(cmd_class, params = {}):
|
def enqueue_tx_command(cmd_class, params = {}):
|
||||||
command = cmd_class(app.config_manager.read(), app.state_manager, app.modem_events, params)
|
command = cmd_class(app.config_manager.read(), app.state_manager, app.modem_events, params)
|
||||||
command.run(app.modem_events, app.service_manager.modem.modem_transmit_queue)
|
app.logger.info(f"Command {command.get_name()} running...")
|
||||||
app.logger.info(f"Command {command.get_name()} enqueued.")
|
command.run(app.modem_events, app.service_manager.modem)
|
||||||
|
|
||||||
## REST API
|
## REST API
|
||||||
@app.route('/', methods=['GET'])
|
@app.route('/', methods=['GET'])
|
||||||
|
|
|
@ -84,8 +84,7 @@ class SM:
|
||||||
self.frame_dispatcher = frame_dispatcher.DISPATCHER(self.config,
|
self.frame_dispatcher = frame_dispatcher.DISPATCHER(self.config,
|
||||||
self.modem_events,
|
self.modem_events,
|
||||||
self.states,
|
self.states,
|
||||||
self.modem.data_queue_received,
|
self.modem)
|
||||||
self.modem.modem_transmit_queue)
|
|
||||||
self.frame_dispatcher.start()
|
self.frame_dispatcher.start()
|
||||||
|
|
||||||
self.states.set("is_modem_running", True)
|
self.states.set("is_modem_running", True)
|
||||||
|
|
|
@ -7,12 +7,11 @@ import websocket
|
||||||
import time
|
import time
|
||||||
|
|
||||||
class TCICtrl:
|
class TCICtrl:
|
||||||
def __init__(self, audio_rx_q, audio_tx_q, hostname='127.0.0.1', port=50001):
|
def __init__(self, audio_rx_q, hostname='127.0.0.1', port=50001):
|
||||||
# websocket.enableTrace(True)
|
# websocket.enableTrace(True)
|
||||||
self.log = structlog.get_logger("TCI")
|
self.log = structlog.get_logger("TCI")
|
||||||
|
|
||||||
self.audio_received_queue = audio_rx_q
|
self.audio_received_queue = audio_rx_q
|
||||||
self.audio_transmit_queue = audio_tx_q
|
|
||||||
|
|
||||||
self.hostname = str(hostname)
|
self.hostname = str(hostname)
|
||||||
self.port = str(port)
|
self.port = str(port)
|
||||||
|
|
|
@ -13,6 +13,13 @@ from frame_dispatcher import DISPATCHER
|
||||||
import random
|
import random
|
||||||
import structlog
|
import structlog
|
||||||
|
|
||||||
|
class TestModem:
|
||||||
|
def __init__(self):
|
||||||
|
self.data_queue_received = queue.Queue()
|
||||||
|
|
||||||
|
def transmit(self, mode, repeats: int, repeat_delay: int, frames: bytearray) -> bool:
|
||||||
|
self.data_queue_received.put(frames)
|
||||||
|
|
||||||
class TestARQSession(unittest.TestCase):
|
class TestARQSession(unittest.TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -23,24 +30,22 @@ class TestARQSession(unittest.TestCase):
|
||||||
cls.logger = structlog.get_logger("TESTS")
|
cls.logger = structlog.get_logger("TESTS")
|
||||||
|
|
||||||
# ISS
|
# ISS
|
||||||
cls.iss_modem_transmit_queue = queue.Queue()
|
cls.iss_modem = TestModem()
|
||||||
cls.iss_state_manager = StateManager(queue.Queue())
|
cls.iss_state_manager = StateManager(queue.Queue())
|
||||||
cls.iss_event_queue = queue.Queue()
|
cls.iss_event_queue = queue.Queue()
|
||||||
cls.iss_frame_dispatcher = DISPATCHER(cls.config,
|
cls.iss_frame_dispatcher = DISPATCHER(cls.config,
|
||||||
cls.iss_event_queue,
|
cls.iss_event_queue,
|
||||||
cls.iss_state_manager,
|
cls.iss_state_manager,
|
||||||
queue.Queue(),
|
cls.iss_modem)
|
||||||
cls.iss_modem_transmit_queue)
|
|
||||||
|
|
||||||
# IRS
|
# IRS
|
||||||
cls.irs_modem_transmit_queue = queue.Queue()
|
cls.irs_modem = TestModem()
|
||||||
cls.irs_state_manager = StateManager(queue.Queue())
|
cls.irs_state_manager = StateManager(queue.Queue())
|
||||||
cls.irs_event_queue = queue.Queue()
|
cls.irs_event_queue = queue.Queue()
|
||||||
cls.irs_frame_dispatcher = DISPATCHER(cls.config,
|
cls.irs_frame_dispatcher = DISPATCHER(cls.config,
|
||||||
cls.irs_event_queue,
|
cls.irs_event_queue,
|
||||||
cls.irs_state_manager,
|
cls.irs_state_manager,
|
||||||
queue.Queue(),
|
cls.irs_modem)
|
||||||
cls.irs_modem_transmit_queue)
|
|
||||||
|
|
||||||
# Frame loss probability in %
|
# Frame loss probability in %
|
||||||
cls.loss_probability = 50
|
cls.loss_probability = 50
|
||||||
|
@ -48,8 +53,7 @@ class TestARQSession(unittest.TestCase):
|
||||||
|
|
||||||
def channelWorker(self, modem_transmit_queue: queue, frame_dispatcher: DISPATCHER):
|
def channelWorker(self, modem_transmit_queue: queue, frame_dispatcher: DISPATCHER):
|
||||||
while True:
|
while True:
|
||||||
transmission_item = modem_transmit_queue.get()
|
frame_bytes = modem_transmit_queue.get()
|
||||||
frame_bytes = bytes(transmission_item['frame'])
|
|
||||||
if random.randint(0, 100) < self.loss_probability:
|
if random.randint(0, 100) < self.loss_probability:
|
||||||
self.logger.info(f"[{threading.current_thread().name}] Frame lost...")
|
self.logger.info(f"[{threading.current_thread().name}] Frame lost...")
|
||||||
continue
|
continue
|
||||||
|
@ -58,13 +62,13 @@ class TestARQSession(unittest.TestCase):
|
||||||
|
|
||||||
def establishChannels(self):
|
def establishChannels(self):
|
||||||
self.iss_to_irs_channel = threading.Thread(target=self.channelWorker,
|
self.iss_to_irs_channel = threading.Thread(target=self.channelWorker,
|
||||||
args=[self.iss_modem_transmit_queue,
|
args=[self.iss_modem.data_queue_received,
|
||||||
self.irs_frame_dispatcher],
|
self.irs_frame_dispatcher],
|
||||||
name = "ISS to IRS channel")
|
name = "ISS to IRS channel")
|
||||||
self.iss_to_irs_channel.start()
|
self.iss_to_irs_channel.start()
|
||||||
|
|
||||||
self.irs_to_iss_channel = threading.Thread(target=self.channelWorker,
|
self.irs_to_iss_channel = threading.Thread(target=self.channelWorker,
|
||||||
args=[self.irs_modem_transmit_queue,
|
args=[self.irs_modem.data_queue_received,
|
||||||
self.iss_frame_dispatcher],
|
self.iss_frame_dispatcher],
|
||||||
name = "IRS to ISS channel")
|
name = "IRS to ISS channel")
|
||||||
self.irs_to_iss_channel.start()
|
self.irs_to_iss_channel.start()
|
||||||
|
@ -80,7 +84,7 @@ class TestARQSession(unittest.TestCase):
|
||||||
'data': base64.b64encode(bytes("Hello world!", encoding="utf-8")),
|
'data': base64.b64encode(bytes("Hello world!", encoding="utf-8")),
|
||||||
}
|
}
|
||||||
cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params)
|
cmd = ARQRawCommand(self.config, self.iss_state_manager, self.iss_event_queue, params)
|
||||||
cmd.run(self.iss_event_queue, self.iss_modem_transmit_queue)
|
cmd.run(self.iss_event_queue, self.iss_modem)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in a new issue