2021-06-13 15:21:37 +00:00
|
|
|
#!/usr/bin/python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
2022-01-07 10:25:28 +00:00
|
|
|
daemon.py
|
2021-06-13 15:21:37 +00:00
|
|
|
|
2022-01-07 10:25:28 +00:00
|
|
|
Author: DJ2LS, January 2022
|
2021-06-13 15:21:37 +00:00
|
|
|
|
2022-03-04 15:50:32 +00:00
|
|
|
daemon for providing basic information for the tnc like audio or serial devices
|
|
|
|
|
2021-06-13 15:21:37 +00:00
|
|
|
"""
|
2022-05-11 22:10:59 +00:00
|
|
|
# pylint: disable=invalid-name, line-too-long, c-extension-no-member
|
|
|
|
# pylint: disable=import-outside-toplevel
|
|
|
|
|
2021-06-13 15:21:37 +00:00
|
|
|
import argparse
|
2022-05-11 22:10:59 +00:00
|
|
|
import atexit
|
|
|
|
import multiprocessing
|
|
|
|
import os
|
|
|
|
import signal
|
2021-06-13 15:21:37 +00:00
|
|
|
import socketserver
|
2021-09-25 13:24:25 +00:00
|
|
|
import subprocess
|
2022-05-11 22:10:59 +00:00
|
|
|
import sys
|
|
|
|
import threading
|
|
|
|
import time
|
2022-01-20 19:38:56 +00:00
|
|
|
import audio
|
2022-05-26 01:23:30 +00:00
|
|
|
import crcengine
|
2022-05-11 22:10:59 +00:00
|
|
|
import log_handler
|
2022-05-26 01:23:30 +00:00
|
|
|
import serial.tools.list_ports
|
2022-01-22 19:39:37 +00:00
|
|
|
import sock
|
2023-04-27 19:43:56 +00:00
|
|
|
from static import ARQ, AudioParam, Beacon, Channel, Daemon, HamlibParam, ModemParam, Station, Statistics, TCIParam, TNC
|
2023-04-26 17:54:53 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
import structlog
|
|
|
|
import ujson as json
|
2022-09-20 09:34:28 +00:00
|
|
|
import config
|
|
|
|
|
2022-05-11 22:10:59 +00:00
|
|
|
|
2022-09-05 09:54:50 +00:00
|
|
|
# signal handler for closing application
|
2022-02-16 08:11:32 +00:00
|
|
|
def signal_handler(sig, frame):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
2022-05-11 22:10:59 +00:00
|
|
|
Signal handler for closing the network socket on app exit
|
2022-03-04 15:50:32 +00:00
|
|
|
Args:
|
2022-05-09 00:41:49 +00:00
|
|
|
sig:
|
|
|
|
frame:
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Returns: system exit
|
|
|
|
"""
|
2022-05-26 01:23:30 +00:00
|
|
|
print("Closing daemon...")
|
2022-02-16 08:11:32 +00:00
|
|
|
sock.CLOSE_SIGNAL = True
|
|
|
|
sys.exit(0)
|
2022-04-11 09:03:54 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
|
2022-05-11 22:10:59 +00:00
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
2022-01-22 19:39:37 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
|
|
|
|
class DAEMON:
|
2022-05-09 00:41:49 +00:00
|
|
|
"""
|
2022-05-11 22:10:59 +00:00
|
|
|
Daemon class
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
2022-05-30 17:47:51 +00:00
|
|
|
|
2022-05-28 02:17:15 +00:00
|
|
|
log = structlog.get_logger("DAEMON")
|
2022-05-26 01:23:30 +00:00
|
|
|
|
2022-01-22 19:39:37 +00:00
|
|
|
def __init__(self):
|
2022-05-09 00:41:49 +00:00
|
|
|
# load crc engine
|
2022-05-26 01:23:30 +00:00
|
|
|
self.crc_algorithm = crcengine.new("crc16-ccitt-false") # load crc8 library
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-01-22 19:39:37 +00:00
|
|
|
self.daemon_queue = sock.DAEMON_QUEUE
|
2022-05-26 01:23:30 +00:00
|
|
|
update_audio_devices = threading.Thread(
|
|
|
|
target=self.update_audio_devices, name="UPDATE_AUDIO_DEVICES", daemon=True
|
|
|
|
)
|
2022-01-22 19:39:37 +00:00
|
|
|
update_audio_devices.start()
|
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
update_serial_devices = threading.Thread(
|
|
|
|
target=self.update_serial_devices, name="UPDATE_SERIAL_DEVICES", daemon=True
|
|
|
|
)
|
2022-01-22 19:39:37 +00:00
|
|
|
update_serial_devices.start()
|
|
|
|
|
2022-02-16 08:11:32 +00:00
|
|
|
worker = threading.Thread(target=self.worker, name="WORKER", daemon=True)
|
2022-01-22 19:39:37 +00:00
|
|
|
worker.start()
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-01-22 19:39:37 +00:00
|
|
|
def update_audio_devices(self):
|
2022-05-09 00:41:49 +00:00
|
|
|
"""
|
2022-05-11 22:10:59 +00:00
|
|
|
Update audio devices and set to static
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
2022-05-28 02:17:15 +00:00
|
|
|
while True:
|
2022-02-15 17:10:14 +00:00
|
|
|
try:
|
2023-04-27 19:43:56 +00:00
|
|
|
if not Daemon.tncstarted:
|
2022-05-26 01:23:30 +00:00
|
|
|
(
|
2023-04-27 19:43:56 +00:00
|
|
|
AudioParam.audio_input_devices,
|
|
|
|
AudioParam.audio_output_devices,
|
2022-05-26 01:23:30 +00:00
|
|
|
) = audio.get_audio_devices()
|
|
|
|
except Exception as err1:
|
|
|
|
self.log.error(
|
|
|
|
"[DMN] update_audio_devices: Exception gathering audio devices:",
|
|
|
|
e=err1,
|
|
|
|
)
|
2022-12-12 11:28:52 +00:00
|
|
|
threading.Event().wait(1)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-01-22 19:39:37 +00:00
|
|
|
def update_serial_devices(self):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
2022-05-11 22:10:59 +00:00
|
|
|
Update serial devices and set to static
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
2022-05-28 02:17:15 +00:00
|
|
|
while True:
|
2022-02-15 17:10:14 +00:00
|
|
|
try:
|
|
|
|
serial_devices = []
|
|
|
|
ports = serial.tools.list_ports.comports()
|
|
|
|
for port, desc, hwid in ports:
|
|
|
|
# calculate hex of hwid if we have unique names
|
2022-05-26 01:23:30 +00:00
|
|
|
crc_hwid = self.crc_algorithm(bytes(hwid, encoding="utf-8"))
|
|
|
|
crc_hwid = crc_hwid.to_bytes(2, byteorder="big")
|
2022-02-15 17:10:14 +00:00
|
|
|
crc_hwid = crc_hwid.hex()
|
2022-05-11 22:10:59 +00:00
|
|
|
description = f"{desc} [{crc_hwid}]"
|
2022-05-26 01:23:30 +00:00
|
|
|
serial_devices.append(
|
|
|
|
{"port": str(port), "description": str(description)}
|
|
|
|
)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-04-27 19:43:56 +00:00
|
|
|
Daemon.serial_devices = serial_devices
|
2022-12-12 11:28:52 +00:00
|
|
|
threading.Event().wait(1)
|
2022-05-26 01:23:30 +00:00
|
|
|
except Exception as err1:
|
|
|
|
self.log.error(
|
|
|
|
"[DMN] update_serial_devices: Exception gathering serial devices:",
|
|
|
|
e=err1,
|
|
|
|
)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-01-22 19:39:37 +00:00
|
|
|
def worker(self):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
2022-05-11 22:10:59 +00:00
|
|
|
Worker to handle the received commands
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
2022-05-28 02:17:15 +00:00
|
|
|
while True:
|
2022-02-15 17:10:14 +00:00
|
|
|
try:
|
|
|
|
data = self.daemon_queue.get()
|
2022-09-20 10:23:28 +00:00
|
|
|
# increase length of list for storing additional
|
|
|
|
# parameters starting at entry 64
|
|
|
|
data = data[:64] + [None] * (64 - len(data))
|
2022-02-15 17:10:14 +00:00
|
|
|
# data[1] mycall
|
|
|
|
# data[2] mygrid
|
|
|
|
# data[3] rx_audio
|
|
|
|
# data[4] tx_audio
|
2023-02-09 20:56:20 +00:00
|
|
|
# data[5] radiocontrol
|
|
|
|
# data[6] rigctld_ip
|
|
|
|
# data[7] rigctld_port
|
|
|
|
# data[8] send_scatter
|
|
|
|
# data[9] send_fft
|
|
|
|
# data[10] low_bandwidth_mode
|
|
|
|
# data[11] tuning_range_fmin
|
|
|
|
# data[12] tuning_range_fmax
|
|
|
|
# data[13] enable FSK
|
|
|
|
# data[14] tx-audio-level
|
|
|
|
# data[15] respond_to_cq
|
|
|
|
# data[16] rx_buffer_size
|
|
|
|
# data[17] explorer
|
|
|
|
# data[18] ssid_list
|
|
|
|
# data[19] auto_tune
|
|
|
|
# data[20] stats
|
2023-03-06 11:48:27 +00:00
|
|
|
# data[21] tx_delay
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
if data[0] == "STARTTNC":
|
2023-02-09 20:56:20 +00:00
|
|
|
self.start_tnc(data)
|
2022-02-15 17:10:14 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if data[0] == "TEST_HAMLIB":
|
|
|
|
# data[9] radiocontrol
|
|
|
|
# data[10] rigctld_ip
|
|
|
|
# data[11] rigctld_port
|
|
|
|
self.test_hamlib_ptt(data)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-10-08 19:09:30 +00:00
|
|
|
if data[0] == "START_RIGCTLD":
|
|
|
|
"""
|
|
|
|
data[0] START_RIGCTLD,
|
|
|
|
data[1] hamlib_deviceid,
|
|
|
|
data[2] hamlib_deviceport,
|
|
|
|
data[3] hamlib_stop_bits,
|
|
|
|
data[4] hamlib_data_bits,
|
|
|
|
data[5] hamlib_handshake,
|
|
|
|
data[6] hamlib_serialspeed,
|
|
|
|
data[7] hamlib_dtrstate,
|
|
|
|
data[8] hamlib_pttprotocol,
|
|
|
|
data[9] hamlib_ptt_port,
|
|
|
|
data[10] hamlib_dcd,
|
|
|
|
data[11] hamlbib_serialspeed_ptt,
|
|
|
|
data[12] hamlib_rigctld_port,
|
|
|
|
data[13] hamlib_rigctld_ip,
|
|
|
|
data[14] hamlib_rigctld_path,
|
|
|
|
data[15] hamlib_rigctld_server_port,
|
|
|
|
data[16] hamlib_rigctld_custom_args
|
|
|
|
"""
|
|
|
|
self.start_rigctld(data)
|
|
|
|
|
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
except Exception as err1:
|
|
|
|
self.log.error("[DMN] worker: Exception: ", e=err1)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
def test_hamlib_ptt(self, data):
|
|
|
|
radiocontrol = data[1]
|
|
|
|
|
|
|
|
# check how we want to control the radio
|
|
|
|
if radiocontrol == "direct":
|
|
|
|
print("direct hamlib support deprecated - not usable anymore")
|
|
|
|
sys.exit(1)
|
|
|
|
elif radiocontrol == "rigctl":
|
|
|
|
print("rigctl support deprecated - not usable anymore")
|
|
|
|
sys.exit(1)
|
|
|
|
elif radiocontrol == "rigctld":
|
|
|
|
import rigctld as rig
|
2023-05-24 13:29:12 +00:00
|
|
|
rigctld_ip = data[2]
|
|
|
|
rigctld_port = data[3]
|
|
|
|
|
|
|
|
elif radiocontrol == "tci":
|
|
|
|
import tci as rig
|
|
|
|
rigctld_ip = data[22]
|
|
|
|
rigctld_port = data[23]
|
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
else:
|
|
|
|
import rigdummy as rig
|
2023-05-24 13:29:12 +00:00
|
|
|
rigctld_ip = '127.0.0.1'
|
|
|
|
rigctld_port = '0'
|
2023-02-09 20:56:20 +00:00
|
|
|
|
|
|
|
hamlib = rig.radio()
|
|
|
|
hamlib.open_rig(
|
|
|
|
rigctld_ip=rigctld_ip,
|
|
|
|
rigctld_port=rigctld_port,
|
|
|
|
)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
# hamlib_version = rig.hamlib_version
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
hamlib.set_ptt(True)
|
2023-02-12 21:42:23 +00:00
|
|
|
#Allow a little time for network based rig to register PTT is active
|
2023-05-24 13:29:12 +00:00
|
|
|
time.sleep(.250)
|
2023-02-09 20:56:20 +00:00
|
|
|
if hamlib.get_ptt():
|
|
|
|
self.log.info("[DMN] Hamlib PTT", status="SUCCESS")
|
|
|
|
response = {"command": "test_hamlib", "result": "SUCCESS"}
|
|
|
|
else:
|
|
|
|
self.log.warning("[DMN] Hamlib PTT", status="NO SUCCESS")
|
|
|
|
response = {"command": "test_hamlib", "result": "NOSUCCESS"}
|
2022-04-11 09:10:32 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
hamlib.set_ptt(False)
|
|
|
|
hamlib.close_rig()
|
2022-04-11 09:10:32 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
jsondata = json.dumps(response)
|
|
|
|
sock.SOCKET_QUEUE.put(jsondata)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-10-08 19:09:30 +00:00
|
|
|
def start_rigctld(self, data):
|
2023-10-15 07:32:44 +00:00
|
|
|
# Seems to be working on Win
|
2023-10-08 21:11:07 +00:00
|
|
|
"""
|
|
|
|
data[0] START_RIGCTLD,
|
|
|
|
data[1] hamlib_deviceid,
|
|
|
|
data[2] hamlib_deviceport,
|
|
|
|
data[3] hamlib_stop_bits,
|
|
|
|
data[4] hamlib_data_bits,
|
|
|
|
data[5] hamlib_handshake,
|
|
|
|
data[6] hamlib_serialspeed,
|
|
|
|
data[7] hamlib_dtrstate,
|
|
|
|
data[8] hamlib_pttprotocol,
|
|
|
|
data[9] hamlib_ptt_port,
|
|
|
|
data[10] hamlib_dcd,
|
|
|
|
data[11] hamlbib_serialspeed_ptt,
|
|
|
|
data[12] hamlib_rigctld_port,
|
|
|
|
data[13] hamlib_rigctld_ip,
|
|
|
|
data[14] hamlib_rigctld_path,
|
|
|
|
data[15] hamlib_rigctld_server_port,
|
|
|
|
data[16] hamlib_rigctld_custom_args
|
|
|
|
"""
|
2023-10-08 19:09:30 +00:00
|
|
|
try:
|
|
|
|
command = []
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2023-10-08 19:09:30 +00:00
|
|
|
if sys.platform in ["darwin"]:
|
2023-10-08 21:11:07 +00:00
|
|
|
if data[14] not in [""]:
|
|
|
|
# hamlib_rigctld_path
|
|
|
|
application_path = data[14]
|
|
|
|
else:
|
|
|
|
application_path = "rigctld"
|
|
|
|
|
|
|
|
command.append(f'{application_path}')
|
2023-10-08 19:09:30 +00:00
|
|
|
|
|
|
|
elif sys.platform in ["linux", "darwin"]:
|
2023-10-08 21:11:07 +00:00
|
|
|
if data[14] not in [""]:
|
|
|
|
# hamlib_rigctld_path
|
|
|
|
application_path = data[14]
|
|
|
|
else:
|
|
|
|
application_path = "rigctld"
|
|
|
|
command.append(f'{application_path}')
|
2023-10-08 19:09:30 +00:00
|
|
|
elif sys.platform in ["win32", "win64"]:
|
2023-10-15 07:56:26 +00:00
|
|
|
if data[13].lower() == "localhost":
|
2023-10-15 07:32:44 +00:00
|
|
|
data[13]="127.0.0.1"
|
2023-10-08 21:11:07 +00:00
|
|
|
if data[14] not in [""]:
|
|
|
|
# hamlib_rigctld_path
|
|
|
|
application_path = data[14]
|
|
|
|
else:
|
|
|
|
application_path = "rigctld.exe"
|
|
|
|
command.append(f'{application_path}')
|
|
|
|
|
|
|
|
|
|
|
|
options = []
|
|
|
|
|
|
|
|
# hamlib_deviceid
|
|
|
|
if data[1] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--model=" + data[1] ))
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_deviceport
|
|
|
|
if data[2] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--rig-file="+ data[2]))
|
2023-10-08 21:11:07 +00:00
|
|
|
# hamlib_stop_bits
|
|
|
|
if data[3] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--set-conf=stop_bits=" + data[3]))
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_data_bits
|
|
|
|
if data[4] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--set-conf=data_bits=" + data[4]))
|
2023-10-08 21:24:06 +00:00
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_handshake
|
|
|
|
if data[5] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--set-conf=serial_handshake=" + data[5]))
|
2023-10-08 21:24:06 +00:00
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_serialspeed
|
|
|
|
if data[6] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--serial-speed=" + data[6]))
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_dtrstate
|
|
|
|
if data[7] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--set-conf=dtr_state=" + data[7]))
|
2023-10-08 21:24:06 +00:00
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_pttprotocol
|
|
|
|
if data[8] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--ptt-type=" + data[8]))
|
2023-10-08 21:24:06 +00:00
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_ptt_port
|
|
|
|
if data[9] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--ptt-file=" + data[9]))
|
2023-10-08 21:24:06 +00:00
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_dcd
|
|
|
|
if data[10] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--dcd-type=" + data[10]))
|
2023-10-08 21:24:06 +00:00
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlbib_serialspeed_ptt
|
|
|
|
if data[11] not in [None, "None", "ignore"]:
|
|
|
|
# options.extend(("-m", data[11]))
|
|
|
|
pass
|
|
|
|
|
|
|
|
# hamlib_rigctld_port
|
2023-10-15 07:32:44 +00:00
|
|
|
# Using this ensures rigctld starts on port configured in GUI
|
2023-10-08 21:11:07 +00:00
|
|
|
if data[12] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--port="+ data[12]))
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_rigctld_ip
|
|
|
|
if data[13] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
options.append(("--listen-addr="+ data[13]))
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# data[14] == hamlib_rigctld_path
|
|
|
|
# maybe at wrong place in list...
|
2023-10-15 07:32:44 +00:00
|
|
|
#Not needed for setting command line arguments
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_rigctld_server_port
|
2023-10-15 07:32:44 +00:00
|
|
|
# Ignore configured value and use value configured in GUI
|
|
|
|
#if data[15] not in [None, "None", "ignore"]:
|
2023-10-08 21:11:07 +00:00
|
|
|
# options.extend(("-m", data[15]))
|
2023-10-15 07:32:44 +00:00
|
|
|
# pass
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
# hamlib_rigctld_custom_args
|
|
|
|
if data[16] not in [None, "None", "ignore"]:
|
2023-10-15 07:32:44 +00:00
|
|
|
for o in data[16].split(" "):
|
|
|
|
options.append(o)
|
2023-10-08 19:09:30 +00:00
|
|
|
|
2023-10-15 07:32:44 +00:00
|
|
|
command += options
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
print(command)
|
2023-10-08 19:09:30 +00:00
|
|
|
proc = subprocess.Popen(command)
|
|
|
|
atexit.register(proc.kill)
|
2023-10-08 21:11:07 +00:00
|
|
|
|
|
|
|
Daemon.rigctldstarted = True
|
2023-10-11 18:26:50 +00:00
|
|
|
Daemon.rigctldprocess = proc
|
|
|
|
|
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
|
2023-10-08 19:09:30 +00:00
|
|
|
except Exception as err:
|
|
|
|
self.log.info("[DMN] starting rigctld: ", e=err)
|
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
|
2023-10-08 19:09:30 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
def start_tnc(self, data):
|
|
|
|
self.log.warning("[DMN] Starting TNC", rig=data[5], port=data[6])
|
2022-04-18 15:17:53 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
# list of parameters, necessary for running subprocess command as a list
|
2023-04-26 17:54:53 +00:00
|
|
|
options = ["--port", str(DAEMON.port - 1)]
|
2022-09-05 09:54:50 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
# create an additional list entry for parameters not covered by gui
|
2023-04-26 17:54:53 +00:00
|
|
|
data[50] = int(DAEMON.port - 1)
|
2022-11-05 21:27:33 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
options.append("--mycall")
|
|
|
|
options.extend((data[1], "--mygrid"))
|
|
|
|
options.extend((data[2], "--rx"))
|
|
|
|
options.extend((data[3], "--tx"))
|
|
|
|
options.append(data[4])
|
2022-12-08 15:14:59 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
# if radiocontrol != disabled
|
|
|
|
# this should hopefully avoid a ton of problems if we are just running in
|
|
|
|
# disabled mode
|
2023-02-02 17:03:22 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if data[5] != "disabled":
|
2023-01-22 20:47:14 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
options.append("--radiocontrol")
|
|
|
|
options.append(data[5])
|
2023-01-22 20:47:14 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if data[5] == "rigctld":
|
|
|
|
options.append("--rigctld_ip")
|
|
|
|
options.extend((data[6], "--rigctld_port"))
|
|
|
|
options.append(data[7])
|
2023-01-22 20:47:14 +00:00
|
|
|
|
2023-05-20 07:53:57 +00:00
|
|
|
if data[5] == "tci":
|
2023-05-24 13:29:12 +00:00
|
|
|
options.append("--tci-ip")
|
|
|
|
options.extend((data[22], "--tci-port"))
|
2023-05-20 07:53:57 +00:00
|
|
|
options.append(data[23])
|
|
|
|
|
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if data[8] == "True":
|
|
|
|
options.append("--scatter")
|
2022-09-20 09:34:28 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if data[9] == "True":
|
|
|
|
options.append("--fft")
|
2023-01-22 20:47:14 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if data[10] == "True":
|
|
|
|
options.append("--500hz")
|
2023-01-22 20:47:14 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
options.append("--tuning_range_fmin")
|
|
|
|
options.extend((data[11], "--tuning_range_fmax"))
|
|
|
|
options.extend((data[12], "--tx-audio-level"))
|
|
|
|
options.append(data[14])
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if data[15] == "True":
|
|
|
|
options.append("--qrv")
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
options.append("--rx-buffer-size")
|
|
|
|
options.append(data[16])
|
2022-02-08 14:27:34 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if data[17] == "True":
|
|
|
|
options.append("--explorer")
|
2023-01-22 20:47:14 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
options.append("--ssid")
|
|
|
|
options.extend(str(i) for i in data[18])
|
|
|
|
if data[19] == "True":
|
|
|
|
options.append("--tune")
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if data[20] == "True":
|
|
|
|
options.append("--stats")
|
2022-02-16 08:11:32 +00:00
|
|
|
|
2023-03-04 09:59:43 +00:00
|
|
|
if data[13] == "True":
|
|
|
|
options.append("--fsk")
|
|
|
|
|
2023-03-06 11:48:27 +00:00
|
|
|
options.append("--tx-delay")
|
|
|
|
options.append(data[21])
|
|
|
|
|
2023-07-03 04:32:46 +00:00
|
|
|
#Mesh
|
2023-07-03 15:54:24 +00:00
|
|
|
print(data[24])
|
2023-07-03 04:32:46 +00:00
|
|
|
if data[24] == "True":
|
|
|
|
options.append("--mesh")
|
2023-07-03 15:54:24 +00:00
|
|
|
print(options)
|
2023-02-09 20:56:20 +00:00
|
|
|
# safe data to config file
|
|
|
|
config.write_entire_config(data)
|
2022-01-22 19:39:37 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
# Try running tnc from binary, else run from source
|
|
|
|
# This helps running the tnc in a developer environment
|
|
|
|
try:
|
|
|
|
command = []
|
2023-02-02 22:06:47 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
if (getattr(sys, 'frozen', False) or hasattr(sys, "_MEIPASS")) and sys.platform in ["darwin"]:
|
|
|
|
# If the application is run as a bundle, the PyInstaller bootloader
|
|
|
|
# extends the sys module by a flag frozen=True and sets the app
|
|
|
|
# path into variable _MEIPASS'.
|
|
|
|
application_path = sys._MEIPASS
|
|
|
|
command.append(f'{application_path}/freedata-tnc')
|
2023-02-02 22:06:47 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
elif sys.platform in ["linux", "darwin"]:
|
|
|
|
command.append("./freedata-tnc")
|
|
|
|
elif sys.platform in ["win32", "win64"]:
|
|
|
|
command.append("freedata-tnc.exe")
|
2022-01-18 18:38:05 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
command += options
|
2023-05-24 13:29:12 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
proc = subprocess.Popen(command)
|
2021-10-17 13:57:41 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
atexit.register(proc.kill)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
Daemon.tncprocess = proc
|
|
|
|
Daemon.tncstarted = True
|
|
|
|
|
2023-10-11 18:26:50 +00:00
|
|
|
|
2023-02-09 20:56:20 +00:00
|
|
|
self.log.info("[DMN] TNC started", path="binary")
|
|
|
|
except FileNotFoundError as err1:
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-10-11 18:26:50 +00:00
|
|
|
try:
|
|
|
|
self.log.info("[DMN] worker: ", e=err1)
|
|
|
|
command = []
|
|
|
|
|
|
|
|
if sys.platform in ["linux", "darwin"]:
|
|
|
|
command.append("python3")
|
|
|
|
elif sys.platform in ["win32", "win64"]:
|
|
|
|
command.append("python")
|
|
|
|
|
|
|
|
command.append("main.py")
|
|
|
|
command += options
|
|
|
|
proc = subprocess.Popen(command)
|
|
|
|
atexit.register(proc.kill)
|
|
|
|
|
|
|
|
self.log.info("[DMN] TNC started", path="source")
|
|
|
|
|
|
|
|
Daemon.tncprocess = proc
|
|
|
|
Daemon.tncstarted = True
|
|
|
|
except Exception as e:
|
|
|
|
self.log.error("[DMN] TNC not started", error=e)
|
|
|
|
Daemon.tncstarted = False
|
2022-05-26 01:23:30 +00:00
|
|
|
|
2023-10-08 21:11:07 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
if __name__ == "__main__":
|
|
|
|
mainlog = structlog.get_logger(__file__)
|
2022-05-23 07:37:24 +00:00
|
|
|
# we need to run this on Windows for multiprocessing support
|
2022-02-17 13:25:22 +00:00
|
|
|
multiprocessing.freeze_support()
|
2022-02-17 15:52:11 +00:00
|
|
|
|
2021-06-13 15:21:37 +00:00
|
|
|
# --------------------------------------------GET PARAMETER INPUTS
|
2022-05-26 01:23:30 +00:00
|
|
|
PARSER = argparse.ArgumentParser(description="FreeDATA Daemon")
|
|
|
|
PARSER.add_argument(
|
|
|
|
"--port",
|
|
|
|
dest="socket_port",
|
|
|
|
default=3001,
|
2022-05-28 15:52:05 +00:00
|
|
|
help="Socket port in the range of 1024-65535",
|
2022-05-26 01:23:30 +00:00
|
|
|
type=int,
|
|
|
|
)
|
2021-06-13 15:21:37 +00:00
|
|
|
ARGS = PARSER.parse_args()
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2023-04-26 17:54:53 +00:00
|
|
|
DAEMON.port = ARGS.socket_port
|
2022-03-04 15:50:32 +00:00
|
|
|
|
2022-02-21 16:58:44 +00:00
|
|
|
try:
|
2022-05-26 01:23:30 +00:00
|
|
|
if sys.platform == "linux":
|
|
|
|
logging_path = os.getenv("HOME") + "/.config/" + "FreeDATA/" + "daemon"
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
if sys.platform == "darwin":
|
|
|
|
logging_path = (
|
|
|
|
os.getenv("HOME")
|
|
|
|
+ "/Library/"
|
|
|
|
+ "Application Support/"
|
|
|
|
+ "FreeDATA/"
|
|
|
|
+ "daemon"
|
|
|
|
)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
if sys.platform in ["win32", "win64"]:
|
|
|
|
logging_path = os.getenv("APPDATA") + "/" + "FreeDATA/" + "daemon"
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-02-21 16:58:44 +00:00
|
|
|
if not os.path.exists(logging_path):
|
|
|
|
os.makedirs(logging_path)
|
|
|
|
log_handler.setup_logging(logging_path)
|
2022-05-26 01:23:30 +00:00
|
|
|
except Exception as err:
|
|
|
|
mainlog.error("[DMN] logger init error", exception=err)
|
2022-01-22 19:39:37 +00:00
|
|
|
|
2022-09-20 09:34:28 +00:00
|
|
|
# init config
|
2022-12-10 12:34:26 +00:00
|
|
|
config = config.CONFIG("config.ini")
|
2022-09-20 09:34:28 +00:00
|
|
|
|
2022-01-22 19:39:37 +00:00
|
|
|
try:
|
2023-04-26 17:54:53 +00:00
|
|
|
mainlog.info("[DMN] Starting TCP/IP socket", port=DAEMON.port)
|
2022-01-22 19:39:37 +00:00
|
|
|
# https://stackoverflow.com/a/16641793
|
|
|
|
socketserver.TCPServer.allow_reuse_address = True
|
2022-05-26 01:23:30 +00:00
|
|
|
cmdserver = sock.ThreadedTCPServer(
|
2023-04-27 19:43:56 +00:00
|
|
|
(TNC.host, DAEMON.port), sock.ThreadedTCPRequestHandler
|
2022-05-26 01:23:30 +00:00
|
|
|
)
|
2022-01-22 19:39:37 +00:00
|
|
|
server_thread = threading.Thread(target=cmdserver.serve_forever)
|
|
|
|
server_thread.daemon = True
|
|
|
|
server_thread.start()
|
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
except Exception as err:
|
|
|
|
mainlog.error(
|
2023-04-26 17:54:53 +00:00
|
|
|
"[DMN] Starting TCP/IP socket failed", port=DAEMON.port, e=err
|
2022-05-26 01:23:30 +00:00
|
|
|
)
|
2022-05-11 22:10:59 +00:00
|
|
|
sys.exit(1)
|
2022-05-09 01:27:24 +00:00
|
|
|
daemon = DAEMON()
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
mainlog.info(
|
|
|
|
"[DMN] Starting FreeDATA Daemon",
|
|
|
|
author="DJ2LS",
|
2023-03-05 06:35:41 +00:00
|
|
|
year="2023",
|
2023-04-26 17:54:53 +00:00
|
|
|
version=TNC.version,
|
2022-05-26 01:23:30 +00:00
|
|
|
)
|
2022-01-22 19:39:37 +00:00
|
|
|
while True:
|
2022-12-12 11:28:52 +00:00
|
|
|
threading.Event().wait(1)
|