diff --git a/freedata_server/demodulator.py b/freedata_server/demodulator.py index 7ce0994d..b72973e1 100644 --- a/freedata_server/demodulator.py +++ b/freedata_server/demodulator.py @@ -42,6 +42,9 @@ class Demodulator(): self.fft_queue = fft_queue + # Audio Stream object + self.stream = None + # init codec2 resampler self.resampler = codec2.resampler() @@ -50,9 +53,6 @@ class Demodulator(): # enable decoding of signalling modes self.MODE_DICT[codec2.FREEDV_MODE.signalling.value]["decode"] = True self.MODE_DICT[codec2.FREEDV_MODE.signalling_ack.value]["decode"] = True - self.MODE_DICT[codec2.FREEDV_MODE.data_ofdm_2438.value]["decode"] = True - #self.MODE_DICT[codec2.FREEDV_MODE.qam16c2.value]["decode"] = True - tci_rx_callback_thread = threading.Thread( target=self.tci_rx_callback, @@ -114,7 +114,6 @@ class Demodulator(): self.MODE_DICT[mode]["nin"] = nin def start(self, stream): - self.stream = stream for mode in self.MODE_DICT: @@ -153,7 +152,7 @@ class Demodulator(): state_buffer = self.MODE_DICT[mode]["state_buffer"] mode_name = self.MODE_DICT[mode]["name"] try: - while self.stream.active: + while self.stream and self.stream.active: threading.Event().wait(0.01) while audiobuffer.nbuffer >= nin: # demodulate audio @@ -209,11 +208,13 @@ class Demodulator(): except Exception as e: error_message = str(e) # we expect this error when shutdown - if "PortAudio not initialized" in error_message: - e = None - self.log.debug( - "[MDM] [demod_audio] demod loop ended", mode=mode_name, e=e - ) + if error_message in ["PortAudio not initialized [PaErrorCode -10000]", "Invalid stream pointer [PaErrorCode -9988]"]: + return + else: + self.log.warning( + "[MDM] [demod_audio] demod loop ended", mode=mode_name, e=e + ) + audio.sd._terminate() def tci_rx_callback(self) -> None: """ diff --git a/freedata_server/modem.py b/freedata_server/modem.py index 45ea698a..21855f39 100644 --- a/freedata_server/modem.py +++ b/freedata_server/modem.py @@ -115,9 +115,10 @@ class RF: # self.stream = lambda: None # self.stream.active = False # self.stream.stop - - except Exception: - self.log.error("[MDM] Error stopping freedata_server") + self.sd_input_stream.close() + self.sd_output_stream.close() + except Exception as e: + self.log.error("[MDM] Error stopping freedata_server", e=e) def init_audio(self): self.log.info(f"[MDM] init: get audio devices", input_device=self.audio_input_device, diff --git a/freedata_server/server.py b/freedata_server/server.py index 5e50e9de..d9115948 100644 --- a/freedata_server/server.py +++ b/freedata_server/server.py @@ -339,10 +339,7 @@ def stop_server(): # if app.service_manager.modem: # app.service_manager.modem.sd_input_stream.stop - audio.sd._terminate() #time.sleep(1) - print('Server shutdown...') - print("------------------------------------------") def main(): app.config['SOCK_SERVER_OPTIONS'] = {'ping_interval': 10} diff --git a/freedata_server/service_manager.py b/freedata_server/service_manager.py index d2a5a386..43b21515 100644 --- a/freedata_server/service_manager.py +++ b/freedata_server/service_manager.py @@ -36,6 +36,8 @@ class SM: if self.config['SOCKET_INTERFACE']['enable']: self.socket_interface_manager = SocketInterfaceHandler(self.modem, self.app.config_manager, self.state_manager, self.event_manager).start_servers() + else: + self.socket_interface_manager = None elif cmd in ['stop'] and self.modem: self.stop_modem() @@ -49,9 +51,9 @@ class SM: self.stop_modem() self.stop_radio_manager() if self.config['SOCKET_INTERFACE']['enable'] and self.socket_interface_manager: - self.socket_interface_manager.stop_servers() - + del self.socket_interface_manager + self.socket_interface_manager = SocketInterfaceHandler(self.modem, self.app.config_manager, self.state_manager, self.event_manager).start_servers() # we need to wait a bit for avoiding a portaudio crash threading.Event().wait(0.5) @@ -64,7 +66,6 @@ class SM: else: self.log.warning("[SVC] freedata_server command processing failed", cmd=cmd, state=self.state_manager.is_modem_running) - def start_modem(self): if self.config['STATION']['mycall'] in ['XX1XXX']: @@ -103,6 +104,7 @@ class SM: def stop_modem(self): self.log.info("stopping freedata_server....") + self.modem.stop_modem() del self.modem self.modem = False self.state_manager.set("is_modem_running", False) diff --git a/freedata_server/socket_interface.py b/freedata_server/socket_interface.py index 0bb5620d..88d39ccb 100644 --- a/freedata_server/socket_interface.py +++ b/freedata_server/socket_interface.py @@ -7,7 +7,6 @@ import select from queue import Queue from socket_interface_commands import SocketCommandHandler - class CommandSocket(socketserver.BaseRequestHandler): #def __init__(self, request, client_address, server): def __init__(self, request, client_address, server, modem=None, state_manager=None, event_manager=None, config_manager=None): @@ -88,7 +87,6 @@ class DataSocket(socketserver.BaseRequestHandler): def handle(self): self.log(f"Data connection established with {self.client_address}") - try: while True: @@ -171,23 +169,28 @@ class SocketInterfaceHandler: self.log(f"Interfaces started") def run_server(self, port, handler): - with CustomThreadedTCPServer(('127.0.0.1', port), handler, modem=self.modem, state_manager=self.state_manager, event_manager=self.event_manager, config_manager=self.config_manager) as server: - self.log(f"Server started on port {port}") - if port == self.command_port: - self.command_server = server - else: - self.data_server = server - server.serve_forever() + try: + with CustomThreadedTCPServer(('127.0.0.1', port), handler, modem=self.modem, state_manager=self.state_manager, event_manager=self.event_manager, config_manager=self.config_manager) as server: + self.log(f"Server starting on port {port}") + if port == self.command_port: + self.command_server = server + else: + self.data_server = server + server.serve_forever() + self.log(f"Server started on port {port}") + except Exception as e: + self.log(f"Error starting server on port {port} | {e}", isWarning=True) def stop_servers(self): # Gracefully shutdown the server if self.command_server: self.command_server.shutdown() + self.command_server_thread.join() + + del self.command_server if self.data_server: self.data_server.shutdown() - self.log(f"Interfaces stopped") + self.data_server_thread.join() + del self.data_server - def wait_for_server_threads(self): - # Wait for both server threads to finish - self.command_server_thread.join() - self.data_server_thread.join() + self.log(f"Interfaces stopped")