mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 10:04:33 +02:00
Prefer double- over single-quote.
Other minor fixes.
This commit is contained in:
parent
e05bc262ad
commit
08202bbaec
19
tnc/audio.py
19
tnc/audio.py
|
@ -1,6 +1,9 @@
|
|||
|
||||
"""
|
||||
Gather information about audio devices.
|
||||
"""
|
||||
import atexit
|
||||
import multiprocessing
|
||||
|
||||
import sounddevice as sd
|
||||
|
||||
atexit.register(sd._terminate)
|
||||
|
@ -14,7 +17,7 @@ def get_audio_devices():
|
|||
"""
|
||||
# we need to run this on Windows for multiprocessing support
|
||||
# multiprocessing.freeze_support()
|
||||
# multiprocessing.get_context('spawn')
|
||||
# multiprocessing.get_context("spawn")
|
||||
|
||||
# we need to reset and initialize sounddevice before running the multiprocessing part.
|
||||
# If we are not doing this at this early point, not all devices will be displayed
|
||||
|
@ -25,9 +28,9 @@ def get_audio_devices():
|
|||
proxy_input_devices = manager.list()
|
||||
proxy_output_devices = manager.list()
|
||||
# print(multiprocessing.get_start_method())
|
||||
p = multiprocessing.Process(target=fetch_audio_devices, args=(proxy_input_devices, proxy_output_devices))
|
||||
p.start()
|
||||
p.join()
|
||||
proc = multiprocessing.Process(target=fetch_audio_devices, args=(proxy_input_devices, proxy_output_devices))
|
||||
proc.start()
|
||||
proc.join()
|
||||
|
||||
return list(proxy_input_devices), list(proxy_output_devices)
|
||||
|
||||
|
@ -52,11 +55,11 @@ def fetch_audio_devices(input_devices, output_devices):
|
|||
max_output_channels = device["max_output_channels"]
|
||||
max_input_channels = device["max_input_channels"]
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
except Exception as err:
|
||||
print(err)
|
||||
max_input_channels = 0
|
||||
max_output_channels = 0
|
||||
name = ''
|
||||
name = ""
|
||||
|
||||
if max_input_channels > 0:
|
||||
input_devices.append({"id": index, "name": name})
|
||||
|
|
|
@ -63,13 +63,13 @@ else:
|
|||
sys.path.append(os.path.abspath("."))
|
||||
|
||||
structlog.get_logger("structlog").info("[C2 ] Searching for libcodec2...")
|
||||
if sys.platform == 'linux':
|
||||
files = glob.glob(r'**/*libcodec2*', recursive=True)
|
||||
files.append('libcodec2.so')
|
||||
elif sys.platform == 'darwin':
|
||||
files = glob.glob(r'**/*libcodec2*.dylib', recursive=True)
|
||||
elif sys.platform in ['win32', 'win64']:
|
||||
files = glob.glob(r'**\*libcodec2*.dll', recursive=True)
|
||||
if sys.platform == "linux":
|
||||
files = glob.glob(r"**/*libcodec2*", recursive=True)
|
||||
files.append("libcodec2.so")
|
||||
elif sys.platform == "darwin":
|
||||
files = glob.glob(r"**/*libcodec2*.dylib", recursive=True)
|
||||
elif sys.platform in ["win32", "win64"]:
|
||||
files = glob.glob(r"**\*libcodec2*.dll", recursive=True)
|
||||
else:
|
||||
files = []
|
||||
|
||||
|
@ -79,11 +79,11 @@ for file in files:
|
|||
api = ctypes.CDLL(file)
|
||||
structlog.get_logger("structlog").info("[C2 ] Libcodec2 loaded", path=file)
|
||||
break
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").warning("[C2 ] Libcodec2 found but not loaded", path=file, e=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").warning("[C2 ] Libcodec2 found but not loaded", path=file, e=err)
|
||||
|
||||
# Quit module if codec2 cant be loaded
|
||||
if api is None or 'api' not in locals():
|
||||
if api is None or "api" not in locals():
|
||||
structlog.get_logger("structlog").critical("[C2 ] Libcodec2 not loaded")
|
||||
sys.exit(1)
|
||||
|
||||
|
@ -163,14 +163,14 @@ class ADVANCED(ctypes.Structure):
|
|||
]
|
||||
|
||||
|
||||
'''
|
||||
"""
|
||||
adv.interleave_frames = 0 # max amplitude
|
||||
adv.M = 2 # number of fsk tones 2/4
|
||||
adv.Rs = 100 # symbol rate
|
||||
adv.Fs = 8000 # sample rate
|
||||
adv.first_tone = 1500 # first tone freq
|
||||
adv.tone_spacing = 200 # shift between tones
|
||||
adv.codename = 'H_128_256_5'.encode('utf-8') # code word
|
||||
adv.codename = "H_128_256_5".encode("utf-8") # code word
|
||||
|
||||
HRA_112_112 rate 0.50 (224,112) BPF: 14 not working
|
||||
HRA_56_56 rate 0.50 (112,56) BPF: 7 not working
|
||||
|
@ -183,7 +183,7 @@ H_128_256_5 rate 0.50 (256,128) BPF: 16 working
|
|||
H_4096_8192_3d rate 0.50 (8192,4096) BPF: 512 not working
|
||||
H_16200_9720 rate 0.60 (16200,9720) BPF: 1215 not working
|
||||
H_1024_2048_4f rate 0.50 (2048,1024) BPF: 128 working
|
||||
'''
|
||||
"""
|
||||
# --------------- 2 FSK H_128_256_5, 16 bytes
|
||||
api.FREEDV_MODE_FSK_LDPC_0_ADV = ADVANCED()
|
||||
api.FREEDV_MODE_FSK_LDPC_0_ADV.interleave_frames = 0
|
||||
|
@ -192,7 +192,7 @@ api.FREEDV_MODE_FSK_LDPC_0_ADV.Rs = 100
|
|||
api.FREEDV_MODE_FSK_LDPC_0_ADV.Fs = 8000
|
||||
api.FREEDV_MODE_FSK_LDPC_0_ADV.first_tone = 1400 # 1150 4fsk, 1500 2fsk
|
||||
api.FREEDV_MODE_FSK_LDPC_0_ADV.tone_spacing = 120 # 200
|
||||
api.FREEDV_MODE_FSK_LDPC_0_ADV.codename = 'H_128_256_5'.encode('utf-8') # code word
|
||||
api.FREEDV_MODE_FSK_LDPC_0_ADV.codename = "H_128_256_5".encode("utf-8") # code word
|
||||
|
||||
# --------------- 4 H_256_512_4, 7 bytes
|
||||
api.FREEDV_MODE_FSK_LDPC_1_ADV = ADVANCED()
|
||||
|
@ -202,7 +202,7 @@ api.FREEDV_MODE_FSK_LDPC_1_ADV.Rs = 100
|
|||
api.FREEDV_MODE_FSK_LDPC_1_ADV.Fs = 8000
|
||||
api.FREEDV_MODE_FSK_LDPC_1_ADV.first_tone = 1250 # 1250 4fsk, 1500 2fsk
|
||||
api.FREEDV_MODE_FSK_LDPC_1_ADV.tone_spacing = 200
|
||||
api.FREEDV_MODE_FSK_LDPC_1_ADV.codename = 'H_256_512_4'.encode('utf-8') # code word
|
||||
api.FREEDV_MODE_FSK_LDPC_1_ADV.codename = "H_256_512_4".encode("utf-8") # code word
|
||||
|
||||
# ------- MODEM STATS STRUCTURES
|
||||
MODEM_STATS_NC_MAX = 50 + 1
|
||||
|
|
167
tnc/daemon.py
167
tnc/daemon.py
|
@ -22,15 +22,14 @@ import sys
|
|||
import threading
|
||||
import time
|
||||
|
||||
import crcengine
|
||||
import serial.tools.list_ports
|
||||
import structlog
|
||||
import ujson as json
|
||||
|
||||
import audio
|
||||
import crcengine
|
||||
import log_handler
|
||||
import serial.tools.list_ports
|
||||
import sock
|
||||
import static
|
||||
import structlog
|
||||
import ujson as json
|
||||
|
||||
|
||||
# signal handler for closing aplication
|
||||
|
@ -43,7 +42,7 @@ def signal_handler(sig, frame):
|
|||
|
||||
Returns: system exit
|
||||
"""
|
||||
print('Closing daemon...')
|
||||
print("Closing daemon...")
|
||||
sock.CLOSE_SIGNAL = True
|
||||
sys.exit(0)
|
||||
|
||||
|
@ -58,7 +57,7 @@ class DAEMON:
|
|||
"""
|
||||
def __init__(self):
|
||||
# load crc engine
|
||||
self.crc_algorithm = crcengine.new('crc16-ccitt-false') # load crc8 library
|
||||
self.crc_algorithm = crcengine.new("crc16-ccitt-false") # load crc8 library
|
||||
|
||||
self.daemon_queue = sock.DAEMON_QUEUE
|
||||
update_audio_devices = threading.Thread(target=self.update_audio_devices, name="UPDATE_AUDIO_DEVICES", daemon=True)
|
||||
|
@ -78,8 +77,8 @@ class DAEMON:
|
|||
try:
|
||||
if not static.TNCSTARTED:
|
||||
static.AUDIO_INPUT_DEVICES, static.AUDIO_OUTPUT_DEVICES = audio.get_audio_devices()
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[DMN] update_audio_devices: Exception gathering audio devices:", e=e)
|
||||
except Exception as err1:
|
||||
structlog.get_logger("structlog").error("[DMN] update_audio_devices: Exception gathering audio devices:", e=err1)
|
||||
# print(e)
|
||||
time.sleep(1)
|
||||
|
||||
|
@ -93,16 +92,16 @@ class DAEMON:
|
|||
ports = serial.tools.list_ports.comports()
|
||||
for port, desc, hwid in ports:
|
||||
# calculate hex of hwid if we have unique names
|
||||
crc_hwid = self.crc_algorithm(bytes(hwid, encoding='utf-8'))
|
||||
crc_hwid = crc_hwid.to_bytes(2, byteorder='big')
|
||||
crc_hwid = self.crc_algorithm(bytes(hwid, encoding="utf-8"))
|
||||
crc_hwid = crc_hwid.to_bytes(2, byteorder="big")
|
||||
crc_hwid = crc_hwid.hex()
|
||||
description = f"{desc} [{crc_hwid}]"
|
||||
serial_devices.append({"port": str(port), "description": str(description)})
|
||||
|
||||
static.SERIAL_DEVICES = serial_devices
|
||||
time.sleep(1)
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[DMN] update_serial_devices: Exception gathering serial devices:", e=e)
|
||||
except Exception as err1:
|
||||
structlog.get_logger("structlog").error("[DMN] update_serial_devices: Exception gathering serial devices:", e=err1)
|
||||
# print(e)
|
||||
|
||||
def worker(self):
|
||||
|
@ -137,99 +136,99 @@ class DAEMON:
|
|||
# data[22] tx-audio-level
|
||||
# data[23] respond_to_cq
|
||||
|
||||
if data[0] == 'STARTTNC':
|
||||
if data[0] == "STARTTNC":
|
||||
structlog.get_logger("structlog").warning("[DMN] Starting TNC", rig=data[5], port=data[6])
|
||||
|
||||
# list of parameters, necessary for running subprocess command as a list
|
||||
options = []
|
||||
|
||||
options.append('--port')
|
||||
options.append("--port")
|
||||
options.append(str(static.DAEMONPORT - 1))
|
||||
|
||||
options.append('--mycall')
|
||||
options.append("--mycall")
|
||||
options.append(data[1])
|
||||
|
||||
options.append('--mygrid')
|
||||
options.append("--mygrid")
|
||||
options.append(data[2])
|
||||
|
||||
options.append('--rx')
|
||||
options.append("--rx")
|
||||
options.append(data[3])
|
||||
|
||||
options.append('--tx')
|
||||
options.append("--tx")
|
||||
options.append(data[4])
|
||||
|
||||
# if radiocontrol != disabled
|
||||
# this should hopefully avoid a ton of problems if we are just running in
|
||||
# disabled mode
|
||||
|
||||
if data[13] != 'disabled':
|
||||
options.append('--devicename')
|
||||
if data[13] != "disabled":
|
||||
options.append("--devicename")
|
||||
options.append(data[5])
|
||||
|
||||
options.append('--deviceport')
|
||||
options.append("--deviceport")
|
||||
options.append(data[6])
|
||||
|
||||
options.append('--serialspeed')
|
||||
options.append("--serialspeed")
|
||||
options.append(data[7])
|
||||
|
||||
options.append('--pttprotocol')
|
||||
options.append("--pttprotocol")
|
||||
options.append(data[8])
|
||||
|
||||
options.append('--pttport')
|
||||
options.append("--pttport")
|
||||
options.append(data[9])
|
||||
|
||||
options.append('--data_bits')
|
||||
options.append("--data_bits")
|
||||
options.append(data[10])
|
||||
|
||||
options.append('--stop_bits')
|
||||
options.append("--stop_bits")
|
||||
options.append(data[11])
|
||||
|
||||
options.append('--handshake')
|
||||
options.append("--handshake")
|
||||
options.append(data[12])
|
||||
|
||||
options.append('--radiocontrol')
|
||||
options.append("--radiocontrol")
|
||||
options.append(data[13])
|
||||
|
||||
if data[13] == 'rigctld':
|
||||
options.append('--rigctld_ip')
|
||||
if data[13] == "rigctld":
|
||||
options.append("--rigctld_ip")
|
||||
options.append(data[14])
|
||||
|
||||
options.append('--rigctld_port')
|
||||
options.append("--rigctld_port")
|
||||
options.append(data[15])
|
||||
|
||||
if data[16] == 'True':
|
||||
options.append('--scatter')
|
||||
if data[16] == "True":
|
||||
options.append("--scatter")
|
||||
|
||||
if data[17] == 'True':
|
||||
options.append('--fft')
|
||||
if data[17] == "True":
|
||||
options.append("--fft")
|
||||
|
||||
if data[18] == 'True':
|
||||
options.append('--500hz')
|
||||
if data[18] == "True":
|
||||
options.append("--500hz")
|
||||
|
||||
options.append('--tuning_range_fmin')
|
||||
options.append("--tuning_range_fmin")
|
||||
options.append(data[19])
|
||||
|
||||
options.append('--tuning_range_fmax')
|
||||
options.append("--tuning_range_fmax")
|
||||
options.append(data[20])
|
||||
|
||||
# overriding FSK mode
|
||||
# if data[21] == 'True':
|
||||
# options.append('--fsk')
|
||||
# if data[21] == "True":
|
||||
# options.append("--fsk")
|
||||
|
||||
options.append('--tx-audio-level')
|
||||
options.append("--tx-audio-level")
|
||||
options.append(data[22])
|
||||
|
||||
if data[23] == 'True':
|
||||
options.append('--qrv')
|
||||
if data[23] == "True":
|
||||
options.append("--qrv")
|
||||
|
||||
# Try running tnc from binary, else run from source
|
||||
# This helps running the tnc in a developer environment
|
||||
try:
|
||||
command = []
|
||||
if sys.platform in ['linux', 'darwin']:
|
||||
command.append('./freedata-tnc')
|
||||
elif sys.platform in ['win32', 'win64']:
|
||||
command.append('freedata-tnc.exe')
|
||||
if sys.platform in ["linux", "darwin"]:
|
||||
command.append("./freedata-tnc")
|
||||
elif sys.platform in ["win32", "win64"]:
|
||||
command.append("freedata-tnc.exe")
|
||||
|
||||
command += options
|
||||
p = subprocess.Popen(command)
|
||||
|
@ -237,15 +236,15 @@ class DAEMON:
|
|||
atexit.register(p.kill)
|
||||
|
||||
structlog.get_logger("structlog").info("[DMN] TNC started", path="binary")
|
||||
except FileNotFoundError as e:
|
||||
structlog.get_logger("structlog").error("[DMN] worker: Exception:", e=e)
|
||||
except FileNotFoundError as err1:
|
||||
structlog.get_logger("structlog").error("[DMN] worker: Exception:", e=err1)
|
||||
command = []
|
||||
if sys.platform in ['linux', 'darwin']:
|
||||
command.append('python3')
|
||||
elif sys.platform in ['win32', 'win64']:
|
||||
command.append('python')
|
||||
if sys.platform in ["linux", "darwin"]:
|
||||
command.append("python3")
|
||||
elif sys.platform in ["win32", "win64"]:
|
||||
command.append("python")
|
||||
|
||||
command.append('main.py')
|
||||
command.append("main.py")
|
||||
command += options
|
||||
p = subprocess.Popen(command)
|
||||
atexit.register(p.kill)
|
||||
|
@ -254,14 +253,14 @@ class DAEMON:
|
|||
|
||||
static.TNCPROCESS = p # .pid
|
||||
static.TNCSTARTED = True
|
||||
'''
|
||||
"""
|
||||
# WE HAVE THIS PART in SOCKET
|
||||
if data[0] == 'STOPTNC':
|
||||
if data[0] == "STOPTNC":
|
||||
static.TNCPROCESS.kill()
|
||||
structlog.get_logger("structlog").warning("[DMN] Stopping TNC")
|
||||
#os.kill(static.TNCPROCESS, signal.SIGKILL)
|
||||
static.TNCSTARTED = False
|
||||
'''
|
||||
"""
|
||||
# data[1] devicename
|
||||
# data[2] deviceport
|
||||
# data[3] serialspeed
|
||||
|
@ -273,7 +272,7 @@ class DAEMON:
|
|||
# data[9] radiocontrol
|
||||
# data[10] rigctld_ip
|
||||
# data[11] rigctld_port
|
||||
if data[0] == 'TEST_HAMLIB':
|
||||
if data[0] == "TEST_HAMLIB":
|
||||
devicename = data[1]
|
||||
deviceport = data[2]
|
||||
serialspeed = data[3]
|
||||
|
@ -287,11 +286,11 @@ class DAEMON:
|
|||
rigctld_port = data[11]
|
||||
|
||||
# check how we want to control the radio
|
||||
if radiocontrol == 'direct':
|
||||
if radiocontrol == "direct":
|
||||
import rig
|
||||
elif radiocontrol == 'rigctl':
|
||||
elif radiocontrol == "rigctl":
|
||||
import rigctl as rig
|
||||
elif radiocontrol == 'rigctld':
|
||||
elif radiocontrol == "rigctld":
|
||||
import rigctld as rig
|
||||
else:
|
||||
import rigdummy as rig
|
||||
|
@ -307,14 +306,14 @@ class DAEMON:
|
|||
pttstate = hamlib.get_ptt()
|
||||
|
||||
if pttstate:
|
||||
structlog.get_logger("structlog").info("[DMN] Hamlib PTT", status='SUCCESS')
|
||||
response = {'command': 'test_hamlib', 'result': 'SUCCESS'}
|
||||
structlog.get_logger("structlog").info("[DMN] Hamlib PTT", status="SUCCESS")
|
||||
response = {"command": "test_hamlib", "result": "SUCCESS"}
|
||||
elif not pttstate:
|
||||
structlog.get_logger("structlog").warning("[DMN] Hamlib PTT", status='NO SUCCESS')
|
||||
response = {'command': 'test_hamlib', 'result': 'NOSUCCESS'}
|
||||
structlog.get_logger("structlog").warning("[DMN] Hamlib PTT", status="NO SUCCESS")
|
||||
response = {"command": "test_hamlib", "result": "NOSUCCESS"}
|
||||
else:
|
||||
structlog.get_logger("structlog").error("[DMN] Hamlib PTT", status='FAILED')
|
||||
response = {'command': 'test_hamlib', 'result': 'FAILED'}
|
||||
structlog.get_logger("structlog").error("[DMN] Hamlib PTT", status="FAILED")
|
||||
response = {"command": "test_hamlib", "result": "FAILED"}
|
||||
|
||||
hamlib.set_ptt(False)
|
||||
hamlib.close_rig()
|
||||
|
@ -322,36 +321,36 @@ class DAEMON:
|
|||
jsondata = json.dumps(response)
|
||||
sock.SOCKET_QUEUE.put(jsondata)
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[DMN] worker: Exception: ", e=e)
|
||||
except Exception as err1:
|
||||
structlog.get_logger("structlog").error("[DMN] worker: Exception: ", e=err1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
# we need to run this on Windows for multiprocessing support
|
||||
multiprocessing.freeze_support()
|
||||
|
||||
# --------------------------------------------GET PARAMETER INPUTS
|
||||
PARSER = argparse.ArgumentParser(description='FreeDATA Daemon')
|
||||
PARSER.add_argument('--port', dest="socket_port", default=3001, help="Socket port in the range of 1024-65536", type=int)
|
||||
PARSER = argparse.ArgumentParser(description="FreeDATA Daemon")
|
||||
PARSER.add_argument("--port", dest="socket_port", default=3001, help="Socket port in the range of 1024-65536", type=int)
|
||||
ARGS = PARSER.parse_args()
|
||||
|
||||
static.DAEMONPORT = ARGS.socket_port
|
||||
|
||||
try:
|
||||
if sys.platform == 'linux':
|
||||
logging_path = os.getenv("HOME") + '/.config/' + 'FreeDATA/' + 'daemon'
|
||||
if sys.platform == "linux":
|
||||
logging_path = os.getenv("HOME") + "/.config/" + "FreeDATA/" + "daemon"
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
logging_path = os.getenv("HOME") + '/Library/' + 'Application Support/' + 'FreeDATA/' + 'daemon'
|
||||
if sys.platform == "darwin":
|
||||
logging_path = os.getenv("HOME") + "/Library/" + "Application Support/" + "FreeDATA/" + "daemon"
|
||||
|
||||
if sys.platform in ['win32', 'win64']:
|
||||
logging_path = os.getenv('APPDATA') + '/' + 'FreeDATA/' + 'daemon'
|
||||
if sys.platform in ["win32", "win64"]:
|
||||
logging_path = os.getenv("APPDATA") + "/" + "FreeDATA/" + "daemon"
|
||||
|
||||
if not os.path.exists(logging_path):
|
||||
os.makedirs(logging_path)
|
||||
log_handler.setup_logging(logging_path)
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[DMN] logger init error", exception=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error("[DMN] logger init error", exception=err)
|
||||
|
||||
try:
|
||||
structlog.get_logger("structlog").info("[DMN] Starting TCP/IP socket", port=static.DAEMONPORT)
|
||||
|
@ -362,8 +361,8 @@ if __name__ == '__main__':
|
|||
server_thread.daemon = True
|
||||
server_thread.start()
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[DMN] Starting TCP/IP socket failed", port=static.DAEMONPORT, e=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error("[DMN] Starting TCP/IP socket failed", port=static.DAEMONPORT, e=err)
|
||||
sys.exit(1)
|
||||
daemon = DAEMON()
|
||||
|
||||
|
|
|
@ -17,15 +17,14 @@ import uuid
|
|||
import zlib
|
||||
from random import randrange
|
||||
|
||||
import numpy as np
|
||||
import structlog
|
||||
import ujson as json
|
||||
|
||||
import codec2
|
||||
import helpers
|
||||
import modem
|
||||
import numpy as np
|
||||
import sock
|
||||
import static
|
||||
import structlog
|
||||
import ujson as json
|
||||
|
||||
TESTMODE = False
|
||||
|
||||
|
@ -49,9 +48,9 @@ class DATA:
|
|||
self.arq_session_timeout = 30
|
||||
self.session_connect_max_retries = 3
|
||||
|
||||
self.transmission_uuid = ''
|
||||
self.transmission_uuid = ""
|
||||
|
||||
self.received_mycall_crc = b'' # Received my callsign crc if we received a crc for another ssid
|
||||
self.received_mycall_crc = b"" # Received my callsign crc if we received a crc for another ssid
|
||||
|
||||
self.data_channel_last_received = 0.0 # time of last "live sign" of a frame
|
||||
self.burst_ack_snr = 0 # SNR from received ack frames
|
||||
|
@ -61,8 +60,8 @@ class DATA:
|
|||
self.rpt_request_buffer = [] # requested frames, saved in a list
|
||||
self.rx_start_of_transmission = 0 # time of transmission start
|
||||
|
||||
self.data_frame_bof = b'BOF' # 2 bytes for the BOF End of File indicator in a data frame
|
||||
self.data_frame_eof = b'EOF' # 2 bytes for the EOF End of File indicator in a data frame
|
||||
self.data_frame_bof = b"BOF" # 2 bytes for the BOF End of File indicator in a data frame
|
||||
self.data_frame_eof = b"EOF" # 2 bytes for the EOF End of File indicator in a data frame
|
||||
|
||||
self.rx_n_max_retries_per_burst = 50
|
||||
self.n_retries_per_burst = 0
|
||||
|
@ -125,17 +124,17 @@ class DATA:
|
|||
data = self.data_queue_transmit.get()
|
||||
|
||||
# [0] == Command
|
||||
if data[0] == 'CQ':
|
||||
if data[0] == "CQ":
|
||||
self.transmit_cq()
|
||||
|
||||
elif data[0] == 'STOP':
|
||||
elif data[0] == "STOP":
|
||||
self.stop_transmission()
|
||||
|
||||
elif data[0] == 'PING':
|
||||
elif data[0] == "PING":
|
||||
# [1] dxcallsign
|
||||
self.transmit_ping(data[1])
|
||||
|
||||
elif data[0] == 'BEACON':
|
||||
elif data[0] == "BEACON":
|
||||
# [1] INTERVAL int
|
||||
# [2] STATE bool
|
||||
if data[2]:
|
||||
|
@ -144,7 +143,7 @@ class DATA:
|
|||
else:
|
||||
static.BEACON_STATE = False
|
||||
|
||||
elif data[0] == 'ARQ_RAW':
|
||||
elif data[0] == "ARQ_RAW":
|
||||
# [1] DATA_OUT bytes
|
||||
# [2] MODE int
|
||||
# [3] N_FRAMES_PER_BURST int
|
||||
|
@ -152,15 +151,15 @@ class DATA:
|
|||
# [5] mycallsign with ssid
|
||||
self.open_dc_and_transmit(data[1], data[2], data[3], data[4], data[5])
|
||||
|
||||
elif data[0] == 'CONNECT':
|
||||
elif data[0] == "CONNECT":
|
||||
# [1] DX CALLSIGN
|
||||
self.arq_session_handler(data[1])
|
||||
|
||||
elif data[0] == 'DISCONNECT':
|
||||
elif data[0] == "DISCONNECT":
|
||||
# [1] DX CALLSIGN
|
||||
self.close_session()
|
||||
|
||||
elif data[0] == 'SEND_TEST_FRAME':
|
||||
elif data[0] == "SEND_TEST_FRAME":
|
||||
# [1] DX CALLSIGN
|
||||
self.send_test_frame()
|
||||
else:
|
||||
|
@ -442,12 +441,12 @@ class DATA:
|
|||
return
|
||||
|
||||
# only process data if we are in ARQ and BUSY state else return to quit
|
||||
if not static.ARQ_STATE and static.TNC_STATE != 'BUSY':
|
||||
if not static.ARQ_STATE and static.TNC_STATE != "BUSY":
|
||||
return
|
||||
|
||||
self.arq_file_transfer = True
|
||||
|
||||
static.TNC_STATE = 'BUSY'
|
||||
static.TNC_STATE = "BUSY"
|
||||
static.ARQ_STATE = True
|
||||
static.INFO.append("ARQ;RECEIVING")
|
||||
self.data_channel_last_received = int(time.time())
|
||||
|
@ -467,7 +466,7 @@ class DATA:
|
|||
|
||||
structlog.get_logger("structlog").debug("[TNC] static.RX_BURST_BUFFER", buffer=static.RX_BURST_BUFFER)
|
||||
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', snr, static.FREQ_OFFSET,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", snr, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
|
||||
# Check if we received all frames in the burst by checking if burst buffer has no more "Nones"
|
||||
|
@ -475,7 +474,7 @@ class DATA:
|
|||
if None not in static.RX_BURST_BUFFER:
|
||||
# then iterate through burst buffer and stick the burst together
|
||||
# the temp burst buffer is needed for checking, if we already recevied data
|
||||
temp_burst_buffer = b''
|
||||
temp_burst_buffer = b""
|
||||
for value in static.RX_BURST_BUFFER:
|
||||
# static.RX_FRAME_BUFFER += static.RX_BURST_BUFFER[i]
|
||||
temp_burst_buffer += bytes(value)
|
||||
|
@ -612,8 +611,8 @@ class DATA:
|
|||
base64_data = base64.b64encode(data_frame).decode("utf-8")
|
||||
static.RX_BUFFER.append([uniqueid, timestamp, static.DXCALLSIGN, static.DXGRID, base64_data])
|
||||
jsondata = {"arq": "received", "uuid": uniqueid, "timestamp": timestamp,
|
||||
"mycallsign": str(mycallsign, 'utf-8'), "dxcallsign": str(static.DXCALLSIGN, 'utf-8'),
|
||||
"dxgrid": str(static.DXGRID, 'utf-8'), "data": base64_data}
|
||||
"mycallsign": str(mycallsign, "utf-8"), "dxcallsign": str(static.DXCALLSIGN, "utf-8"),
|
||||
"dxgrid": str(static.DXGRID, "utf-8"), "data": base64_data}
|
||||
json_data_out = json.dumps(jsondata)
|
||||
structlog.get_logger("structlog").debug("[TNC] arq_data_received:", jsondata=jsondata)
|
||||
sock.SOCKET_QUEUE.put(json_data_out)
|
||||
|
@ -626,8 +625,8 @@ class DATA:
|
|||
self.calculate_transfer_rate_rx(self.rx_start_of_transmission, len(static.RX_FRAME_BUFFER))
|
||||
|
||||
structlog.get_logger("structlog").info("[TNC] | RX | DATACHANNEL [" +
|
||||
str(self.mycallsign, 'utf-8') + "]<< >>[" + str(
|
||||
static.DXCALLSIGN, 'utf-8') + "]", snr=snr)
|
||||
str(self.mycallsign, "utf-8") + "]<< >>[" + str(
|
||||
static.DXCALLSIGN, "utf-8") + "]", snr=snr)
|
||||
|
||||
else:
|
||||
static.INFO.append("ARQ;RECEIVING;FAILED")
|
||||
|
@ -677,7 +676,7 @@ class DATA:
|
|||
# save len of data_out to TOTAL_BYTES for our statistics --> kBytes
|
||||
# static.TOTAL_BYTES = round(len(data_out) / 1024, 2)
|
||||
static.TOTAL_BYTES = len(data_out)
|
||||
frame_total_size = len(data_out).to_bytes(4, byteorder='big')
|
||||
frame_total_size = len(data_out).to_bytes(4, byteorder="big")
|
||||
static.INFO.append("ARQ;TRANSMITTING")
|
||||
|
||||
jsondata = {"arq": "transmission", "status": "transmitting", "uuid": self.transmission_uuid,
|
||||
|
@ -827,7 +826,7 @@ class DATA:
|
|||
break # break retry loop
|
||||
|
||||
# we need this part for leaving the repeat loop
|
||||
# static.ARQ_STATE == 'DATA' --> when stopping transmission manually
|
||||
# static.ARQ_STATE == "DATA" --> when stopping transmission manually
|
||||
if not static.ARQ_STATE:
|
||||
# print("not ready for data...leaving loop....")
|
||||
break
|
||||
|
@ -899,7 +898,7 @@ class DATA:
|
|||
|
||||
# only process data if we are in ARQ and BUSY state
|
||||
if static.ARQ_STATE:
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR,
|
||||
static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
|
||||
self.burst_ack = True # Force data loops of TNC to stop and continue with next frame
|
||||
self.data_channel_last_received = int(time.time()) # we need to update our timeout timestamp
|
||||
|
@ -930,7 +929,7 @@ class DATA:
|
|||
|
||||
# only process data if we are in ARQ and BUSY state
|
||||
if static.ARQ_STATE:
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR,
|
||||
static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
|
||||
self.burst_nack = True # Force data loops of TNC to stop and continue with next frame
|
||||
self.data_channel_last_received = int(time.time()) # we need to update our timeout timestamp
|
||||
|
@ -945,7 +944,7 @@ class DATA:
|
|||
""" """
|
||||
# only process data if we are in ARQ and BUSY state
|
||||
if static.ARQ_STATE:
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR,
|
||||
static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
|
||||
self.data_frame_ack_received = True # Force data loops of TNC to stop and continue with next frame
|
||||
self.data_channel_last_received = int(time.time()) # we need to update our timeout timestamp
|
||||
|
@ -960,7 +959,7 @@ class DATA:
|
|||
Returns:
|
||||
|
||||
"""
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR, static.FREQ_OFFSET,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
static.INFO.append("ARQ;TRANSMITTING;FAILED")
|
||||
jsondata = {"arq": "transmission", "status": "failed", "uuid": self.transmission_uuid,
|
||||
|
@ -982,8 +981,8 @@ class DATA:
|
|||
|
||||
"""
|
||||
# only process data if we are in ARQ and BUSY state
|
||||
if static.ARQ_STATE and static.TNC_STATE == 'BUSY':
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR,
|
||||
if static.ARQ_STATE and static.TNC_STATE == "BUSY":
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR,
|
||||
static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
|
||||
|
||||
self.rpt_request_received = True
|
||||
|
@ -993,7 +992,7 @@ class DATA:
|
|||
missing_area = bytes(data_in[3:12]) # 1:9
|
||||
|
||||
for i in range(0, 6, 2):
|
||||
if not missing_area[i:i + 2].endswith(b'\x00\x00'):
|
||||
if not missing_area[i:i + 2].endswith(b"\x00\x00"):
|
||||
missing = missing_area[i:i + 2]
|
||||
self.rpt_request_buffer.insert(0, missing)
|
||||
|
||||
|
@ -1012,7 +1011,7 @@ class DATA:
|
|||
# TODO: we need to check this, maybe placing it to class init
|
||||
self.datachannel_timeout = False
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] SESSION [" + str(self.mycallsign, 'utf-8') + "]>> <<[" + str(static.DXCALLSIGN, 'utf-8') + "]",
|
||||
"[TNC] SESSION [" + str(self.mycallsign, "utf-8") + "]>> <<[" + str(static.DXCALLSIGN, "utf-8") + "]",
|
||||
state=static.ARQ_SESSION_STATE)
|
||||
|
||||
self.open_session(callsign)
|
||||
|
@ -1020,13 +1019,13 @@ class DATA:
|
|||
# wait until data channel is open
|
||||
while not static.ARQ_SESSION and not self.arq_session_timeout:
|
||||
time.sleep(0.01)
|
||||
static.ARQ_SESSION_STATE = 'connecting'
|
||||
static.ARQ_SESSION_STATE = "connecting"
|
||||
|
||||
if static.ARQ_SESSION and static.ARQ_SESSION_STATE == 'connected':
|
||||
# static.ARQ_SESSION_STATE = 'connected'
|
||||
if static.ARQ_SESSION and static.ARQ_SESSION_STATE == "connected":
|
||||
# static.ARQ_SESSION_STATE = "connected"
|
||||
return True
|
||||
|
||||
static.ARQ_SESSION_STATE = 'failed'
|
||||
static.ARQ_SESSION_STATE = "failed"
|
||||
return False
|
||||
|
||||
def open_session(self, callsign):
|
||||
|
@ -1039,7 +1038,7 @@ class DATA:
|
|||
|
||||
"""
|
||||
self.IS_ARQ_SESSION_MASTER = True
|
||||
static.ARQ_SESSION_STATE = 'connecting'
|
||||
static.ARQ_SESSION_STATE = "connecting"
|
||||
|
||||
connection_frame = bytearray(14)
|
||||
connection_frame[:1] = bytes([221])
|
||||
|
@ -1051,8 +1050,8 @@ class DATA:
|
|||
time.sleep(0.01)
|
||||
for attempt in range(1, self.session_connect_max_retries + 1):
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] SESSION [" + str(self.mycallsign, 'utf-8') + "]>>?<<[" + str(static.DXCALLSIGN,
|
||||
'utf-8') + "]", a=attempt,
|
||||
"[TNC] SESSION [" + str(self.mycallsign, "utf-8") + "]>>?<<[" + str(static.DXCALLSIGN,
|
||||
"utf-8") + "]", a=attempt,
|
||||
state=static.ARQ_SESSION_STATE)
|
||||
|
||||
self.enqueue_frame_for_tx(connection_frame)
|
||||
|
@ -1083,30 +1082,30 @@ class DATA:
|
|||
|
||||
"""
|
||||
self.IS_ARQ_SESSION_MASTER = False
|
||||
static.ARQ_SESSION_STATE = 'connecting'
|
||||
static.ARQ_SESSION_STATE = "connecting"
|
||||
|
||||
self.arq_session_last_received = int(time.time())
|
||||
|
||||
static.DXCALLSIGN_CRC = bytes(data_in[4:7])
|
||||
static.DXCALLSIGN = helpers.bytes_to_callsign(bytes(data_in[7:13]))
|
||||
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR, static.FREQ_OFFSET,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] SESSION [" + str(self.mycallsign, 'utf-8') + "]>>|<<[" + str(static.DXCALLSIGN, 'utf-8') + "]",
|
||||
"[TNC] SESSION [" + str(self.mycallsign, "utf-8") + "]>>|<<[" + str(static.DXCALLSIGN, "utf-8") + "]",
|
||||
state=static.ARQ_SESSION_STATE)
|
||||
static.ARQ_SESSION = True
|
||||
static.TNC_STATE = 'BUSY'
|
||||
static.TNC_STATE = "BUSY"
|
||||
|
||||
self.transmit_session_heartbeat()
|
||||
|
||||
def close_session(self):
|
||||
""" Close the ARQ session """
|
||||
static.ARQ_SESSION_STATE = 'disconnecting'
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR, static.FREQ_OFFSET,
|
||||
static.ARQ_SESSION_STATE = "disconnecting"
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] SESSION [" + str(self.mycallsign, 'utf-8') + "]<<X>>[" + str(static.DXCALLSIGN, 'utf-8') + "]",
|
||||
"[TNC] SESSION [" + str(self.mycallsign, "utf-8") + "]<<X>>[" + str(static.DXCALLSIGN, "utf-8") + "]",
|
||||
state=static.ARQ_SESSION_STATE)
|
||||
static.INFO.append("ARQ;SESSION;CLOSE")
|
||||
self.IS_ARQ_SESSION_MASTER = False
|
||||
|
@ -1129,11 +1128,11 @@ class DATA:
|
|||
# Close the session if the DXCALLSIGN_CRC matches the station in static.
|
||||
_valid_crc, _ = helpers.check_callsign(static.DXCALLSIGN, bytes(data_in[4:7]))
|
||||
if _valid_crc:
|
||||
static.ARQ_SESSION_STATE = 'disconnected'
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR,
|
||||
static.ARQ_SESSION_STATE = "disconnected"
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR,
|
||||
static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] SESSION [" + str(self.mycallsign, 'utf-8') + "]<<X>>[" + str(static.DXCALLSIGN, 'utf-8') + "]",
|
||||
"[TNC] SESSION [" + str(self.mycallsign, "utf-8") + "]<<X>>[" + str(static.DXCALLSIGN, "utf-8") + "]",
|
||||
state=static.ARQ_SESSION_STATE)
|
||||
static.INFO.append("ARQ;SESSION;CLOSE")
|
||||
|
||||
|
@ -1144,8 +1143,8 @@ class DATA:
|
|||
def transmit_session_heartbeat(self):
|
||||
""" """
|
||||
# static.ARQ_SESSION = True
|
||||
# static.TNC_STATE = 'BUSY'
|
||||
# static.ARQ_SESSION_STATE = 'connected'
|
||||
# static.TNC_STATE = "BUSY"
|
||||
# static.ARQ_SESSION_STATE = "connected"
|
||||
|
||||
connection_frame = bytearray(14)
|
||||
connection_frame[:1] = bytes([222])
|
||||
|
@ -1167,14 +1166,14 @@ class DATA:
|
|||
_valid_crc, _ = helpers.check_callsign(static.DXCALLSIGN, bytes(data_in[4:7]))
|
||||
if _valid_crc:
|
||||
structlog.get_logger("structlog").debug("[TNC] Received session heartbeat")
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'SESSION-HB', static.SNR,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "SESSION-HB", static.SNR,
|
||||
static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
|
||||
|
||||
self.arq_session_last_received = int(time.time()) # we need to update our timeout timestamp
|
||||
|
||||
static.ARQ_SESSION = True
|
||||
static.ARQ_SESSION_STATE = 'connected'
|
||||
static.TNC_STATE = 'BUSY'
|
||||
static.ARQ_SESSION_STATE = "connected"
|
||||
static.TNC_STATE = "BUSY"
|
||||
self.data_channel_last_received = int(time.time())
|
||||
if not self.IS_ARQ_SESSION_MASTER and not self.arq_file_transfer:
|
||||
self.transmit_session_heartbeat()
|
||||
|
@ -1197,7 +1196,7 @@ class DATA:
|
|||
# overwrite mycallsign in case of different SSID
|
||||
self.mycallsign = mycallsign
|
||||
|
||||
static.TNC_STATE = 'BUSY'
|
||||
static.TNC_STATE = "BUSY"
|
||||
self.arq_file_transfer = True
|
||||
|
||||
self.transmission_uuid = transmission_uuid
|
||||
|
@ -1261,8 +1260,8 @@ class DATA:
|
|||
for attempt in range(1, self.data_channel_max_retries + 1):
|
||||
static.INFO.append("DATACHANNEL;OPENING")
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] ARQ | DATA | TX | [" + str(mycallsign, 'utf-8') + "]>> <<[" + str(static.DXCALLSIGN,
|
||||
'utf-8') + "]",
|
||||
"[TNC] ARQ | DATA | TX | [" + str(mycallsign, "utf-8") + "]>> <<[" + str(static.DXCALLSIGN,
|
||||
"utf-8") + "]",
|
||||
attempt=f"{str(attempt)}/{str(self.data_channel_max_retries)}")
|
||||
|
||||
self.enqueue_frame_for_tx(connection_frame)
|
||||
|
@ -1290,8 +1289,8 @@ class DATA:
|
|||
sock.SOCKET_QUEUE.put(json_data_out)
|
||||
|
||||
structlog.get_logger("structlog").warning(
|
||||
"[TNC] ARQ | TX | DATA [" + str(mycallsign, 'utf-8') + "]>>X<<[" + str(static.DXCALLSIGN,
|
||||
'utf-8') + "]")
|
||||
"[TNC] ARQ | TX | DATA [" + str(mycallsign, "utf-8") + "]>>X<<[" + str(static.DXCALLSIGN,
|
||||
"utf-8") + "]")
|
||||
self.datachannel_timeout = True
|
||||
if not TESTMODE:
|
||||
self.arq_cleanup()
|
||||
|
@ -1337,7 +1336,7 @@ class DATA:
|
|||
# updated modes we are listening to
|
||||
self.set_listening_modes(self.mode_list[self.speed_level])
|
||||
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR, static.FREQ_OFFSET,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
|
||||
# check if callsign ssid override
|
||||
|
@ -1349,11 +1348,11 @@ class DATA:
|
|||
return
|
||||
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] ARQ | DATA | RX | [" + str(mycallsign, 'utf-8') + "]>> <<[" + str(static.DXCALLSIGN, 'utf-8') + "]",
|
||||
"[TNC] ARQ | DATA | RX | [" + str(mycallsign, "utf-8") + "]>> <<[" + str(static.DXCALLSIGN, "utf-8") + "]",
|
||||
bandwith="wide")
|
||||
|
||||
static.ARQ_STATE = True
|
||||
static.TNC_STATE = 'BUSY'
|
||||
static.TNC_STATE = "BUSY"
|
||||
|
||||
self.reset_statistics()
|
||||
|
||||
|
@ -1375,7 +1374,7 @@ class DATA:
|
|||
self.enqueue_frame_for_tx(connection_frame)
|
||||
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] ARQ | DATA | RX | [" + str(mycallsign, 'utf-8') + "]>>|<<[" + str(static.DXCALLSIGN, 'utf-8') + "]",
|
||||
"[TNC] ARQ | DATA | RX | [" + str(mycallsign, "utf-8") + "]>>|<<[" + str(static.DXCALLSIGN, "utf-8") + "]",
|
||||
bandwith="wide", snr=static.SNR)
|
||||
|
||||
# set start of transmission for our statistics
|
||||
|
@ -1411,19 +1410,19 @@ class DATA:
|
|||
self.speed_level = len(self.mode_list) - 1
|
||||
structlog.get_logger("structlog").debug("[TNC] high bandwidth mode", modes=self.mode_list)
|
||||
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'DATA-CHANNEL', static.SNR,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "DATA-CHANNEL", static.SNR,
|
||||
static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
|
||||
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] ARQ | DATA | TX | [" + str(self.mycallsign, 'utf-8') + "]>>|<<[" + str(static.DXCALLSIGN,
|
||||
'utf-8') + "]",
|
||||
"[TNC] ARQ | DATA | TX | [" + str(self.mycallsign, "utf-8") + "]>>|<<[" + str(static.DXCALLSIGN,
|
||||
"utf-8") + "]",
|
||||
snr=static.SNR)
|
||||
|
||||
# as soon as we set ARQ_STATE to DATA, transmission starts
|
||||
static.ARQ_STATE = True
|
||||
self.data_channel_last_received = int(time.time())
|
||||
else:
|
||||
static.TNC_STATE = 'IDLE'
|
||||
static.TNC_STATE = "IDLE"
|
||||
static.ARQ_STATE = False
|
||||
static.INFO.append("PROTOCOL;VERSION_MISMATCH")
|
||||
structlog.get_logger("structlog").warning("[TNC] protocol version mismatch:", received=protocol_version,
|
||||
|
@ -1445,7 +1444,7 @@ class DATA:
|
|||
|
||||
static.INFO.append("PING;SENDING")
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] PING REQ [" + str(self.mycallsign, 'utf-8') + "] >>> [" + str(static.DXCALLSIGN, 'utf-8') + "]")
|
||||
"[TNC] PING REQ [" + str(self.mycallsign, "utf-8") + "] >>> [" + str(static.DXCALLSIGN, "utf-8") + "]")
|
||||
|
||||
ping_frame = bytearray(14)
|
||||
ping_frame[:1] = bytes([210])
|
||||
|
@ -1455,7 +1454,7 @@ class DATA:
|
|||
|
||||
structlog.get_logger("structlog").info("[TNC] ENABLE FSK", state=static.ENABLE_FSK)
|
||||
if static.ENABLE_FSK:
|
||||
self.enqueue_frame_for_tx(ping_frame, c2_mode='FSK_LDPC_0')
|
||||
self.enqueue_frame_for_tx(ping_frame, c2_mode=codec2.freedv_get_mode_value_by_name("FSK_LDPC_0"))
|
||||
else:
|
||||
self.enqueue_frame_for_tx(ping_frame)
|
||||
|
||||
|
@ -1471,7 +1470,7 @@ class DATA:
|
|||
"""
|
||||
static.DXCALLSIGN_CRC = bytes(data_in[4:7])
|
||||
static.DXCALLSIGN = helpers.bytes_to_callsign(bytes(data_in[7:13]))
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'PING', static.SNR, static.FREQ_OFFSET,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "PING", static.SNR, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
|
||||
static.INFO.append("PING;RECEIVING")
|
||||
|
@ -1485,7 +1484,7 @@ class DATA:
|
|||
return
|
||||
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] PING REQ [" + str(mycallsign, 'utf-8') + "] <<< [" + str(static.DXCALLSIGN, 'utf-8') + "]",
|
||||
"[TNC] PING REQ [" + str(mycallsign, "utf-8") + "] <<< [" + str(static.DXCALLSIGN, "utf-8") + "]",
|
||||
snr=static.SNR)
|
||||
|
||||
ping_frame = bytearray(14)
|
||||
|
@ -1496,7 +1495,7 @@ class DATA:
|
|||
|
||||
structlog.get_logger("structlog").info("[TNC] ENABLE FSK", state=static.ENABLE_FSK)
|
||||
if static.ENABLE_FSK:
|
||||
self.enqueue_frame_for_tx(ping_frame, c2_mode='FSK_LDPC_0')
|
||||
self.enqueue_frame_for_tx(ping_frame, c2_mode=codec2.freedv_get_mode_value_by_name("FSK_LDPC_0"))
|
||||
else:
|
||||
self.enqueue_frame_for_tx(ping_frame)
|
||||
|
||||
|
@ -1510,23 +1509,23 @@ class DATA:
|
|||
|
||||
"""
|
||||
static.DXCALLSIGN_CRC = bytes(data_in[4:7])
|
||||
static.DXGRID = bytes(data_in[7:13]).rstrip(b'\x00')
|
||||
static.DXGRID = bytes(data_in[7:13]).rstrip(b"\x00")
|
||||
|
||||
jsondata = {"type": "ping", "status": "ack", "uuid": str(uuid.uuid4()), "timestamp": int(time.time()),
|
||||
"mycallsign": str(self.mycallsign, 'utf-8'), "dxcallsign": str(static.DXCALLSIGN, 'utf-8'),
|
||||
"dxgrid": str(static.DXGRID, 'utf-8'), "snr": str(static.SNR)}
|
||||
"mycallsign": str(self.mycallsign, "utf-8"), "dxcallsign": str(static.DXCALLSIGN, "utf-8"),
|
||||
"dxgrid": str(static.DXGRID, "utf-8"), "snr": str(static.SNR)}
|
||||
json_data_out = json.dumps(jsondata)
|
||||
sock.SOCKET_QUEUE.put(json_data_out)
|
||||
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, 'PING-ACK', static.SNR, static.FREQ_OFFSET,
|
||||
helpers.add_to_heard_stations(static.DXCALLSIGN, static.DXGRID, "PING-ACK", static.SNR, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
|
||||
static.INFO.append("PING;RECEIVEDACK")
|
||||
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] PING ACK [" + str(self.mycallsign, 'utf-8') + "] >|< [" + str(static.DXCALLSIGN, 'utf-8') + "]",
|
||||
"[TNC] PING ACK [" + str(self.mycallsign, "utf-8") + "] >|< [" + str(static.DXCALLSIGN, "utf-8") + "]",
|
||||
snr=static.SNR)
|
||||
static.TNC_STATE = 'IDLE'
|
||||
static.TNC_STATE = "IDLE"
|
||||
|
||||
def stop_transmission(self):
|
||||
"""
|
||||
|
@ -1541,7 +1540,7 @@ class DATA:
|
|||
|
||||
self.enqueue_frame_for_tx(stop_frame, copies=2, repeat_delay=250)
|
||||
|
||||
static.TNC_STATE = 'IDLE'
|
||||
static.TNC_STATE = "IDLE"
|
||||
static.ARQ_STATE = False
|
||||
static.INFO.append("TRANSMISSION;STOPPED")
|
||||
self.arq_cleanup()
|
||||
|
@ -1551,7 +1550,7 @@ class DATA:
|
|||
Received a transmission stop
|
||||
"""
|
||||
structlog.get_logger("structlog").warning("[TNC] Stopping transmission!")
|
||||
static.TNC_STATE = 'IDLE'
|
||||
static.TNC_STATE = "IDLE"
|
||||
static.ARQ_STATE = False
|
||||
static.INFO.append("TRANSMISSION;STOPPED")
|
||||
self.arq_cleanup()
|
||||
|
@ -1582,7 +1581,7 @@ class DATA:
|
|||
structlog.get_logger("structlog").info("[TNC] ENABLE FSK", state=static.ENABLE_FSK)
|
||||
|
||||
if static.ENABLE_FSK:
|
||||
self.enqueue_frame_for_tx(beacon_frame, c2_mode='FSK_LDPC_0')
|
||||
self.enqueue_frame_for_tx(beacon_frame, c2_mode=codec2.freedv_get_mode_value_by_name("FSK_LDPC_0"))
|
||||
else:
|
||||
self.enqueue_frame_for_tx(beacon_frame)
|
||||
|
||||
|
@ -1590,8 +1589,8 @@ class DATA:
|
|||
while time.time() < interval_timer and static.BEACON_STATE and not static.BEACON_PAUSE:
|
||||
time.sleep(0.01)
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").debug("[TNC] run_beacon: ", exception=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").debug("[TNC] run_beacon: ", exception=err)
|
||||
# print(e)
|
||||
|
||||
def received_beacon(self, data_in: bytes):
|
||||
|
@ -1605,18 +1604,18 @@ class DATA:
|
|||
"""
|
||||
# here we add the received station to the heard stations buffer
|
||||
dxcallsign = helpers.bytes_to_callsign(bytes(data_in[1:7]))
|
||||
dxgrid = bytes(data_in[9:13]).rstrip(b'\x00')
|
||||
dxgrid = bytes(data_in[9:13]).rstrip(b"\x00")
|
||||
|
||||
jsondata = {"type": "beacon", "status": "received", "uuid": str(uuid.uuid4()), "timestamp": int(time.time()),
|
||||
"mycallsign": str(self.mycallsign, 'utf-8'), "dxcallsign": str(dxcallsign, 'utf-8'),
|
||||
"dxgrid": str(dxgrid, 'utf-8'), "snr": str(static.SNR)}
|
||||
"mycallsign": str(self.mycallsign, "utf-8"), "dxcallsign": str(dxcallsign, "utf-8"),
|
||||
"dxgrid": str(dxgrid, "utf-8"), "snr": str(static.SNR)}
|
||||
json_data_out = json.dumps(jsondata)
|
||||
sock.SOCKET_QUEUE.put(json_data_out)
|
||||
|
||||
static.INFO.append("BEACON;RECEIVING")
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] BEACON RCVD [" + str(dxcallsign, 'utf-8') + "][" + str(dxgrid, 'utf-8') + "] ", snr=static.SNR)
|
||||
helpers.add_to_heard_stations(dxcallsign, dxgrid, 'BEACON', static.SNR, static.FREQ_OFFSET,
|
||||
"[TNC] BEACON RCVD [" + str(dxcallsign, "utf-8") + "][" + str(dxgrid, "utf-8") + "] ", snr=static.SNR)
|
||||
helpers.add_to_heard_stations(dxcallsign, dxgrid, "BEACON", static.SNR, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
|
||||
def transmit_cq(self):
|
||||
|
@ -1640,7 +1639,7 @@ class DATA:
|
|||
structlog.get_logger("structlog").debug("[TNC] CQ Frame:", data=[cq_frame])
|
||||
|
||||
if static.ENABLE_FSK:
|
||||
self.enqueue_frame_for_tx(cq_frame, c2_mode='FSK_LDPC_0')
|
||||
self.enqueue_frame_for_tx(cq_frame, c2_mode=codec2.freedv_get_mode_value_by_name("FSK_LDPC_0"))
|
||||
else:
|
||||
self.enqueue_frame_for_tx(cq_frame)
|
||||
|
||||
|
@ -1660,8 +1659,8 @@ class DATA:
|
|||
dxgrid = bytes(helpers.decode_grid(data_in[7:11]), "utf-8")
|
||||
static.INFO.append("CQ;RECEIVING")
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] CQ RCVD [" + str(dxcallsign, 'utf-8') + "][" + str(dxgrid, 'utf-8') + "] ", snr=static.SNR)
|
||||
helpers.add_to_heard_stations(dxcallsign, dxgrid, 'CQ CQ CQ', static.SNR, static.FREQ_OFFSET,
|
||||
"[TNC] CQ RCVD [" + str(dxcallsign, "utf-8") + "][" + str(dxgrid, "utf-8") + "] ", snr=static.SNR)
|
||||
helpers.add_to_heard_stations(dxcallsign, dxgrid, "CQ CQ CQ", static.SNR, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
|
||||
if static.RESPOND_TO_CQ:
|
||||
|
@ -1692,7 +1691,7 @@ class DATA:
|
|||
structlog.get_logger("structlog").info("[TNC] ENABLE FSK", state=static.ENABLE_FSK)
|
||||
|
||||
if static.ENABLE_FSK:
|
||||
self.enqueue_frame_for_tx(qrv_frame, c2_mode='FSK_LDPC_0')
|
||||
self.enqueue_frame_for_tx(qrv_frame, c2_mode=codec2.freedv_get_mode_value_by_name("FSK_LDPC_0"))
|
||||
else:
|
||||
self.enqueue_frame_for_tx(qrv_frame)
|
||||
|
||||
|
@ -1710,15 +1709,15 @@ class DATA:
|
|||
dxgrid = bytes(helpers.decode_grid(data_in[7:11]), "utf-8")
|
||||
|
||||
jsondata = {"type": "qrv", "status": "received", "uuid": str(uuid.uuid4()), "timestamp": int(time.time()),
|
||||
"mycallsign": str(self.mycallsign, 'utf-8'), "dxcallsign": str(dxcallsign, 'utf-8'),
|
||||
"dxgrid": str(dxgrid, 'utf-8'), "snr": str(static.SNR)}
|
||||
"mycallsign": str(self.mycallsign, "utf-8"), "dxcallsign": str(dxcallsign, "utf-8"),
|
||||
"dxgrid": str(dxgrid, "utf-8"), "snr": str(static.SNR)}
|
||||
json_data_out = json.dumps(jsondata)
|
||||
sock.SOCKET_QUEUE.put(json_data_out)
|
||||
|
||||
static.INFO.append("QRV;RECEIVING")
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] QRV RCVD [" + str(dxcallsign, 'utf-8') + "][" + str(dxgrid, 'utf-8') + "] ", snr=static.SNR)
|
||||
helpers.add_to_heard_stations(dxcallsign, dxgrid, 'QRV', static.SNR, static.FREQ_OFFSET,
|
||||
"[TNC] QRV RCVD [" + str(dxcallsign, "utf-8") + "][" + str(dxgrid, "utf-8") + "] ", snr=static.SNR)
|
||||
helpers.add_to_heard_stations(dxcallsign, dxgrid, "QRV", static.SNR, static.FREQ_OFFSET,
|
||||
static.HAMLIB_FREQUENCY)
|
||||
|
||||
# ------------ CALUCLATE TRANSFER RATES
|
||||
|
@ -1749,8 +1748,8 @@ class DATA:
|
|||
else:
|
||||
static.ARQ_BITS_PER_SECOND = 0
|
||||
static.ARQ_BYTES_PER_MINUTE = 0
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error(f"[TNC] calculate_transfer_rate_rx: Exception: {e}")
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error(f"[TNC] calculate_transfer_rate_rx: Exception: {err}")
|
||||
static.ARQ_TRANSMISSION_PERCENT = 0.0
|
||||
static.ARQ_BITS_PER_SECOND = 0
|
||||
static.ARQ_BYTES_PER_MINUTE = 0
|
||||
|
@ -1796,8 +1795,8 @@ class DATA:
|
|||
static.ARQ_BITS_PER_SECOND = 0
|
||||
static.ARQ_BYTES_PER_MINUTE = 0
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error(f"[TNC] calculate_transfer_rate_tx: Exception: {e}")
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error(f"[TNC] calculate_transfer_rate_tx: Exception: {err}")
|
||||
static.ARQ_TRANSMISSION_PERCENT = 0.0
|
||||
static.ARQ_BITS_PER_SECOND = 0
|
||||
static.ARQ_BYTES_PER_MINUTE = 0
|
||||
|
@ -1813,7 +1812,7 @@ class DATA:
|
|||
"""
|
||||
structlog.get_logger("structlog").debug("[TNC] arq_cleanup")
|
||||
|
||||
self.received_mycall_crc = b''
|
||||
self.received_mycall_crc = b""
|
||||
|
||||
self.rx_frame_bof_received = False
|
||||
self.rx_frame_eof_received = False
|
||||
|
@ -1821,7 +1820,7 @@ class DATA:
|
|||
self.rpt_request_received = False
|
||||
self.data_frame_ack_received = False
|
||||
static.RX_BURST_BUFFER = []
|
||||
static.RX_FRAME_BUFFER = b''
|
||||
static.RX_FRAME_BUFFER = b""
|
||||
self.burst_ack_snr = 255
|
||||
|
||||
# reset modem receiving state to reduce cpu load
|
||||
|
@ -1847,7 +1846,7 @@ class DATA:
|
|||
self.n_retries_per_burst = 0
|
||||
|
||||
if not static.ARQ_SESSION:
|
||||
static.TNC_STATE = 'IDLE'
|
||||
static.TNC_STATE = "IDLE"
|
||||
|
||||
static.ARQ_STATE = False
|
||||
self.arq_file_transfer = False
|
||||
|
@ -1880,16 +1879,16 @@ class DATA:
|
|||
# set modes we want to listen to
|
||||
mode_name = codec2.freedv_get_mode_name_by_value(mode)
|
||||
|
||||
if mode_name == 'datac1':
|
||||
if mode_name == "datac1":
|
||||
modem.RECEIVE_DATAC1 = True
|
||||
structlog.get_logger("structlog").debug("[TNC] Changing listening data mode", mode="datac1")
|
||||
elif mode_name == 'datac3':
|
||||
elif mode_name == "datac3":
|
||||
modem.RECEIVE_DATAC3 = True
|
||||
structlog.get_logger("structlog").debug("[TNC] Changing listening data mode", mode="datac3")
|
||||
elif mode_name == 'fsk_ldpc_1':
|
||||
elif mode_name == "fsk_ldpc_1":
|
||||
modem.RECEIVE_FSK_LDPC_1 = True
|
||||
structlog.get_logger("structlog").debug("[TNC] Changing listening data mode", mode="fsk_ldpc_1")
|
||||
elif mode_name == 'allmodes':
|
||||
elif mode_name == "allmodes":
|
||||
modem.RECEIVE_DATAC1 = True
|
||||
modem.RECEIVE_DATAC3 = True
|
||||
modem.RECEIVE_FSK_LDPC_1 = True
|
||||
|
@ -1920,7 +1919,7 @@ class DATA:
|
|||
# IRS SIDE
|
||||
# TODO: We need to redesign this part for cleaner state handling
|
||||
# return only if not ARQ STATE and not ARQ SESSION STATE as they are different use cases
|
||||
if not static.ARQ_STATE and static.ARQ_SESSION_STATE != 'connected' or not self.is_IRS:
|
||||
if not static.ARQ_STATE and static.ARQ_SESSION_STATE != "connected" or not self.is_IRS:
|
||||
return
|
||||
# we want to reach this state only if connected ( == return above not called )
|
||||
if self.data_channel_last_received + self.time_list[self.speed_level] > time.time():
|
||||
|
@ -1960,7 +1959,7 @@ class DATA:
|
|||
DATA CHANNEL
|
||||
"""
|
||||
# and not static.ARQ_SEND_KEEP_ALIVE:
|
||||
if static.ARQ_STATE and static.TNC_STATE == 'BUSY':
|
||||
if static.ARQ_STATE and static.TNC_STATE == "BUSY":
|
||||
time.sleep(0.01)
|
||||
if self.data_channel_last_received + self.transmission_timeout > time.time():
|
||||
time.sleep(0.01)
|
||||
|
@ -1969,7 +1968,7 @@ class DATA:
|
|||
else:
|
||||
self.data_channel_last_received = 0
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] DATA [" + str(self.mycallsign, 'utf-8') + "]<<T>>[" + str(static.DXCALLSIGN, 'utf-8') + "]")
|
||||
"[TNC] DATA [" + str(self.mycallsign, "utf-8") + "]<<T>>[" + str(static.DXCALLSIGN, "utf-8") + "]")
|
||||
static.INFO.append("ARQ;RECEIVING;FAILED")
|
||||
if not TESTMODE:
|
||||
self.arq_cleanup()
|
||||
|
@ -1979,13 +1978,13 @@ class DATA:
|
|||
watchdog which checks if we are running into a connection timeout
|
||||
ARQ SESSION
|
||||
"""
|
||||
if static.ARQ_SESSION and static.TNC_STATE == 'BUSY' and not self.arq_file_transfer:
|
||||
if static.ARQ_SESSION and static.TNC_STATE == "BUSY" and not self.arq_file_transfer:
|
||||
if self.arq_session_last_received + self.arq_session_timeout > time.time():
|
||||
time.sleep(0.01)
|
||||
else:
|
||||
structlog.get_logger("structlog").info(
|
||||
"[TNC] SESSION [" + str(self.mycallsign, 'utf-8') + "]<<T>>[" + str(static.DXCALLSIGN,
|
||||
'utf-8') + "]")
|
||||
"[TNC] SESSION [" + str(self.mycallsign, "utf-8") + "]<<T>>[" + str(static.DXCALLSIGN,
|
||||
"utf-8") + "]")
|
||||
static.INFO.append("ARQ;SESSION;TIMEOUT")
|
||||
self.close_session()
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Fri Dec 25 21:25:14 2020
|
||||
|
@ -8,9 +7,8 @@ Created on Fri Dec 25 21:25:14 2020
|
|||
import time
|
||||
|
||||
import crcengine
|
||||
import structlog
|
||||
|
||||
import static
|
||||
import structlog
|
||||
|
||||
|
||||
def wait(seconds: float) -> bool:
|
||||
|
@ -41,9 +39,9 @@ def get_crc_8(data) -> bytes:
|
|||
Returns:
|
||||
CRC-8 (CCITT) of the provided data as bytes
|
||||
"""
|
||||
crc_algorithm = crcengine.new('crc8-ccitt') # load crc8 library
|
||||
crc_algorithm = crcengine.new("crc8-ccitt") # load crc8 library
|
||||
crc_data = crc_algorithm(data)
|
||||
crc_data = crc_data.to_bytes(1, byteorder='big')
|
||||
crc_data = crc_data.to_bytes(1, byteorder="big")
|
||||
return crc_data
|
||||
|
||||
|
||||
|
@ -60,9 +58,9 @@ def get_crc_16(data) -> bytes:
|
|||
Returns:
|
||||
CRC-16 (CCITT) of the provided data as bytes
|
||||
"""
|
||||
crc_algorithm = crcengine.new('crc16-ccitt-false') # load crc16 library
|
||||
crc_algorithm = crcengine.new("crc16-ccitt-false") # load crc16 library
|
||||
crc_data = crc_algorithm(data)
|
||||
crc_data = crc_data.to_bytes(2, byteorder='big')
|
||||
crc_data = crc_data.to_bytes(2, byteorder="big")
|
||||
return crc_data
|
||||
|
||||
|
||||
|
@ -86,9 +84,9 @@ def get_crc_24(data) -> bytes:
|
|||
ref_in=False,
|
||||
ref_out=False,
|
||||
xor_out=0,
|
||||
name='crc-24-openpgp')
|
||||
name="crc-24-openpgp")
|
||||
crc_data = crc_algorithm(data)
|
||||
crc_data = crc_data.to_bytes(3, byteorder='big')
|
||||
crc_data = crc_data.to_bytes(3, byteorder="big")
|
||||
return crc_data
|
||||
|
||||
|
||||
|
@ -105,9 +103,9 @@ def get_crc_32(data: bytes) -> bytes:
|
|||
Returns:
|
||||
CRC-32 of the provided data as bytes
|
||||
"""
|
||||
crc_algorithm = crcengine.new('crc32') # load crc32 library
|
||||
crc_algorithm = crcengine.new("crc32") # load crc32 library
|
||||
crc_data = crc_algorithm(data)
|
||||
crc_data = crc_data.to_bytes(4, byteorder='big')
|
||||
crc_data = crc_data.to_bytes(4, byteorder="big")
|
||||
return crc_data
|
||||
|
||||
|
||||
|
@ -176,17 +174,17 @@ def callsign_to_bytes(callsign) -> bytes:
|
|||
|
||||
# Try converting to bytestring if possible type string
|
||||
try:
|
||||
callsign = bytes(callsign, 'utf-8')
|
||||
except TypeError as e:
|
||||
structlog.get_logger("structlog").debug("[HLP] callsign_to_bytes: Exception converting callsign to bytes:", e=e)
|
||||
callsign = bytes(callsign, "utf-8")
|
||||
except TypeError as err:
|
||||
structlog.get_logger("structlog").debug("[HLP] callsign_to_bytes: Exception converting callsign to bytes:", e=err)
|
||||
|
||||
# Need this step to reduce the needed payload by the callsign (stripping "-" out of the callsign)
|
||||
callsign = callsign.split(b'-')
|
||||
callsign = callsign.split(b"-")
|
||||
ssid = 0
|
||||
try:
|
||||
ssid = int(callsign[1])
|
||||
except IndexError as e:
|
||||
structlog.get_logger("structlog").debug("[HLP] callsign_to_bytes: Error callsign SSID to integer:", e=e)
|
||||
except IndexError as err:
|
||||
structlog.get_logger("structlog").debug("[HLP] callsign_to_bytes: Error callsign SSID to integer:", e=err)
|
||||
|
||||
# callsign = callsign[0]
|
||||
# bytestring = bytearray(8)
|
||||
|
@ -229,18 +227,18 @@ def bytes_to_callsign(bytestring: bytes) -> bytes:
|
|||
# -15 generic additional station, digi, mobile, wx, etc
|
||||
|
||||
# we need to do this step to reduce the needed paypload by the callsign ( stripping "-" out of the callsign )
|
||||
'''
|
||||
"""
|
||||
callsign = bytes(bytestring[:7])
|
||||
callsign = callsign.rstrip(b'\x00')
|
||||
callsign = callsign.rstrip(b"\x00")
|
||||
ssid = int.from_bytes(bytes(bytestring[7:8]), "big")
|
||||
|
||||
callsign = callsign + b'-'
|
||||
callsign = callsign.decode('utf-8')
|
||||
callsign = callsign + b"-"
|
||||
callsign = callsign.decode("utf-8")
|
||||
callsign = callsign + str(ssid)
|
||||
callsign = callsign.encode('utf-8')
|
||||
callsign = callsign.encode("utf-8")
|
||||
|
||||
return bytes(callsign)
|
||||
'''
|
||||
"""
|
||||
decoded = decode_call(bytestring)
|
||||
callsign = decoded[:-1]
|
||||
ssid = ord(bytes(decoded[-1], "utf-8"))
|
||||
|
@ -260,19 +258,18 @@ def check_callsign(callsign: bytes, crc_to_check: bytes):
|
|||
False
|
||||
"""
|
||||
|
||||
# print(callsign)
|
||||
structlog.get_logger("structlog").debug("[HLP] check_callsign: Checking:", callsign=callsign)
|
||||
try:
|
||||
# We want the callsign without SSID
|
||||
callsign = callsign.split(b'-')[0]
|
||||
callsign = callsign.split(b"-")[0]
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").debug("[HLP] check_callsign: Error callsign SSIG to integer:", e=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").debug("[HLP] check_callsign: Error callsign SSIG to integer:", e=err)
|
||||
|
||||
for ssid in static.SSID_LIST:
|
||||
call_with_ssid = bytearray(callsign)
|
||||
call_with_ssid.extend('-'.encode('utf-8'))
|
||||
call_with_ssid.extend(str(ssid).encode('utf-8'))
|
||||
call_with_ssid.extend("-".encode("utf-8"))
|
||||
call_with_ssid.extend(str(ssid).encode("utf-8"))
|
||||
|
||||
callsign_crc = get_crc_24(call_with_ssid)
|
||||
|
||||
|
@ -295,8 +292,8 @@ def encode_grid(grid):
|
|||
|
||||
grid = grid.upper() # upper case to be save
|
||||
|
||||
int_first = ord(grid[0]) - 65 # -65 offset for 'A' become zero, utf8 table
|
||||
int_sec = ord(grid[1]) - 65 # -65 offset for 'A' become zero, utf8 table
|
||||
int_first = ord(grid[0]) - 65 # -65 offset for "A" become zero, utf8 table
|
||||
int_sec = ord(grid[1]) - 65 # -65 offset for "A" become zero, utf8 table
|
||||
|
||||
int_val = (int_first * 18) + int_sec # encode for modulo devision, 2 numbers in 1
|
||||
|
||||
|
@ -307,14 +304,14 @@ def encode_grid(grid):
|
|||
out_code_word |= (int_val & 0b1111111) # using bit OR to add new value
|
||||
out_code_word <<= 7 # shift 7 bit left having space next bits, letter A-X
|
||||
|
||||
int_val = ord(grid[4]) - 65 # -65 offset for 'A' become zero, utf8 table
|
||||
int_val = ord(grid[4]) - 65 # -65 offset for "A" become zero, utf8 table
|
||||
out_code_word |= (int_val & 0b11111) # using bit OR to add new value
|
||||
out_code_word <<= 5 # shift 5 bit left having space next bits, letter A-X
|
||||
|
||||
int_val = ord(grid[5]) - 65 # -65 offset for 'A' become zero, utf8 table
|
||||
int_val = ord(grid[5]) - 65 # -65 offset for "A" become zero, utf8 table
|
||||
out_code_word |= (int_val & 0b11111) # using bit OR to add new value
|
||||
|
||||
return out_code_word.to_bytes(length=4, byteorder='big')
|
||||
return out_code_word.to_bytes(length=4, byteorder="big")
|
||||
|
||||
|
||||
def decode_grid(b_code_word: bytes):
|
||||
|
@ -325,7 +322,7 @@ def decode_grid(b_code_word: bytes):
|
|||
Returns:
|
||||
grid:str: upper case maidenhead QTH locater [A-R][A-R][0-9][0-9][A-X][A-X]
|
||||
"""
|
||||
code_word = int.from_bytes(b_code_word, byteorder='big', signed=False)
|
||||
code_word = int.from_bytes(b_code_word, byteorder="big", signed=False)
|
||||
|
||||
grid = chr((code_word & 0b11111) + 65)
|
||||
code_word >>= 5
|
||||
|
@ -335,7 +332,7 @@ def decode_grid(b_code_word: bytes):
|
|||
|
||||
grid = str(int(code_word & 0b1111111)) + grid
|
||||
if (code_word & 0b1111111) < 10:
|
||||
grid = f'0{grid}'
|
||||
grid = f"0{grid}"
|
||||
code_word >>= 9
|
||||
|
||||
int_val = int(code_word & 0b111111111)
|
||||
|
@ -364,11 +361,12 @@ def encode_call(call):
|
|||
int_val = ord(x) - 48 # -48 reduce bits, begin with first number utf8 table
|
||||
out_code_word <<= 6 # shift left 6 bit, making space for a new char
|
||||
out_code_word |= (int_val & 0b111111) # bit OR adds the new char, masked with AND 0b111111
|
||||
|
||||
out_code_word >>= 6 # clean last char
|
||||
out_code_word <<= 6 # make clean space
|
||||
out_code_word |= (ord(call[-1]) & 0b111111) # add the SSID uncoded only 0 - 63
|
||||
|
||||
return out_code_word.to_bytes(length=6, byteorder='big')
|
||||
return out_code_word.to_bytes(length=6, byteorder="big")
|
||||
|
||||
|
||||
def decode_call(b_code_word: bytes):
|
||||
|
@ -380,7 +378,7 @@ def decode_call(b_code_word: bytes):
|
|||
Returns:
|
||||
call:str: upper case ham radio call sign [A-Z,0-9] + binary SSID
|
||||
"""
|
||||
code_word = int.from_bytes(b_code_word, byteorder='big', signed=False)
|
||||
code_word = int.from_bytes(b_code_word, byteorder="big", signed=False)
|
||||
ssid = chr(code_word & 0b111111) # save the uncoded binary SSID
|
||||
|
||||
call = str()
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
import logging.config
|
||||
|
||||
import structlog
|
||||
|
||||
|
||||
# https://www.structlog.org/en/stable/standard-library.html
|
||||
def setup_logging(filename):
|
||||
"""
|
||||
|
@ -8,8 +13,6 @@ def setup_logging(filename):
|
|||
Returns:
|
||||
|
||||
"""
|
||||
import logging.config
|
||||
import structlog
|
||||
|
||||
timestamper = structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S")
|
||||
pre_chain = [
|
||||
|
@ -19,7 +22,8 @@ def setup_logging(filename):
|
|||
timestamper,
|
||||
]
|
||||
|
||||
logging.config.dictConfig({
|
||||
logging.config.dictConfig(
|
||||
{
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"formatters": {
|
||||
|
@ -43,7 +47,7 @@ def setup_logging(filename):
|
|||
"file": {
|
||||
"level": "DEBUG",
|
||||
"class": "logging.handlers.WatchedFileHandler",
|
||||
"filename": filename + '.log',
|
||||
"filename": f"{filename}.log",
|
||||
"formatter": "plain",
|
||||
},
|
||||
},
|
||||
|
@ -53,8 +57,9 @@ def setup_logging(filename):
|
|||
"level": "DEBUG",
|
||||
"propagate": True,
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
structlog.configure(
|
||||
processors=[
|
||||
structlog.stdlib.add_log_level,
|
||||
|
|
83
tnc/main.py
83
tnc/main.py
|
@ -16,13 +16,12 @@ import sys
|
|||
import threading
|
||||
import time
|
||||
|
||||
import structlog
|
||||
|
||||
import data_handler
|
||||
import helpers
|
||||
import log_handler
|
||||
import modem
|
||||
import static
|
||||
import structlog
|
||||
|
||||
|
||||
def signal_handler(sig, frame):
|
||||
|
@ -35,57 +34,57 @@ def signal_handler(sig, frame):
|
|||
Returns: system exit
|
||||
|
||||
"""
|
||||
print('Closing TNC...')
|
||||
print("Closing TNC...")
|
||||
sock.CLOSE_SIGNAL = True
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
# we need to run this on Windows for multiprocessing support
|
||||
multiprocessing.freeze_support()
|
||||
# --------------------------------------------GET PARAMETER INPUTS
|
||||
PARSER = argparse.ArgumentParser(description='FreeDATA TNC')
|
||||
PARSER.add_argument('--mycall', dest="mycall", default="AA0AA", help="My callsign", type=str)
|
||||
PARSER.add_argument('--ssid', dest="ssid_list", nargs='*', default=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], help="SSID list we are responding to", type=str)
|
||||
PARSER.add_argument('--mygrid', dest="mygrid", default="JN12AA", help="My gridsquare", type=str)
|
||||
PARSER.add_argument('--rx', dest="audio_input_device", default=0, help="listening sound card", type=int)
|
||||
PARSER.add_argument('--tx', dest="audio_output_device", default=0, help="transmitting sound card", type=int)
|
||||
PARSER.add_argument('--port', dest="socket_port", default=3000, help="Socket port in the range of 1024-65536", type=int)
|
||||
PARSER.add_argument('--deviceport', dest="hamlib_device_port", default="/dev/ttyUSB0", help="Hamlib device port", type=str)
|
||||
PARSER.add_argument('--devicename', dest="hamlib_device_name", default="2028", help="Hamlib device name", type=str)
|
||||
PARSER.add_argument('--serialspeed', dest="hamlib_serialspeed", choices=[1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200], default=9600, help="Serialspeed", type=int)
|
||||
PARSER.add_argument('--pttprotocol', dest="hamlib_ptt_type", choices=['USB', 'RIG', 'RTS', 'DTR', 'CM108', 'MICDATA', 'PARALLEL', 'DTR-H', 'DTR-L', 'NONE'], default='USB', help="PTT Type", type=str)
|
||||
PARSER.add_argument('--pttport', dest="hamlib_ptt_port", default="/dev/ttyUSB0", help="PTT Port", type=str)
|
||||
PARSER.add_argument('--data_bits', dest="hamlib_data_bits", choices=[7, 8], default=8, help="Hamlib data bits", type=int)
|
||||
PARSER.add_argument('--stop_bits', dest="hamlib_stop_bits", choices=[1, 2], default=1, help="Hamlib stop bits", type=int)
|
||||
PARSER.add_argument('--handshake', dest="hamlib_handshake", default="None", help="Hamlib handshake", type=str)
|
||||
PARSER.add_argument('--radiocontrol', dest="hamlib_radiocontrol", choices=['disabled', 'direct', 'rigctl', 'rigctld'], default="disabled", help="Set how you want to control your radio")
|
||||
PARSER.add_argument('--rigctld_port', dest="rigctld_port", default=4532, type=int, help="Set rigctld port")
|
||||
PARSER.add_argument('--rigctld_ip', dest="rigctld_ip", default="localhost", help="Set rigctld ip")
|
||||
PARSER.add_argument('--scatter', dest="send_scatter", action="store_true", help="Send scatter information via network")
|
||||
PARSER.add_argument('--fft', dest="send_fft", action="store_true", help="Send fft information via network")
|
||||
PARSER.add_argument('--500hz', dest="low_bandwith_mode", action="store_true", help="Enable low bandwith mode ( 500 Hz only )")
|
||||
PARSER.add_argument('--fsk', dest="enable_fsk", action="store_true", help="Enable FSK mode for ping, beacon and CQ")
|
||||
PARSER.add_argument('--qrv', dest="enable_respond_to_cq", action="store_true", help="Enable sending a QRV frame if CQ received")
|
||||
PARSER.add_argument('--tuning_range_fmin', dest="tuning_range_fmin", choices=[-50.0, -100.0, -150.0, -200.0, -250.0], default=-50.0, help="Tuning range fmin", type=float)
|
||||
PARSER.add_argument('--tuning_range_fmax', dest="tuning_range_fmax", choices=[50.0, 100.0, 150.0, 200.0, 250.0], default=50.0, help="Tuning range fmax", type=float)
|
||||
PARSER.add_argument('--tx-audio-level', dest="tx_audio_level", default=50, help="Set the tx audio level at an early stage", type=int)
|
||||
PARSER = argparse.ArgumentParser(description="FreeDATA TNC")
|
||||
PARSER.add_argument("--mycall", dest="mycall", default="AA0AA", help="My callsign", type=str)
|
||||
PARSER.add_argument("--ssid", dest="ssid_list", nargs="*", default=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], help="SSID list we are responding to", type=str)
|
||||
PARSER.add_argument("--mygrid", dest="mygrid", default="JN12AA", help="My gridsquare", type=str)
|
||||
PARSER.add_argument("--rx", dest="audio_input_device", default=0, help="listening sound card", type=int)
|
||||
PARSER.add_argument("--tx", dest="audio_output_device", default=0, help="transmitting sound card", type=int)
|
||||
PARSER.add_argument("--port", dest="socket_port", default=3000, help="Socket port in the range of 1024-65536", type=int)
|
||||
PARSER.add_argument("--deviceport", dest="hamlib_device_port", default="/dev/ttyUSB0", help="Hamlib device port", type=str)
|
||||
PARSER.add_argument("--devicename", dest="hamlib_device_name", default="2028", help="Hamlib device name", type=str)
|
||||
PARSER.add_argument("--serialspeed", dest="hamlib_serialspeed", choices=[1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200], default=9600, help="Serialspeed", type=int)
|
||||
PARSER.add_argument("--pttprotocol", dest="hamlib_ptt_type", choices=["USB", "RIG", "RTS", "DTR", "CM108", "MICDATA", "PARALLEL", "DTR-H", "DTR-L", "NONE"], default="USB", help="PTT Type", type=str)
|
||||
PARSER.add_argument("--pttport", dest="hamlib_ptt_port", default="/dev/ttyUSB0", help="PTT Port", type=str)
|
||||
PARSER.add_argument("--data_bits", dest="hamlib_data_bits", choices=[7, 8], default=8, help="Hamlib data bits", type=int)
|
||||
PARSER.add_argument("--stop_bits", dest="hamlib_stop_bits", choices=[1, 2], default=1, help="Hamlib stop bits", type=int)
|
||||
PARSER.add_argument("--handshake", dest="hamlib_handshake", default="None", help="Hamlib handshake", type=str)
|
||||
PARSER.add_argument("--radiocontrol", dest="hamlib_radiocontrol", choices=["disabled", "direct", "rigctl", "rigctld"], default="disabled", help="Set how you want to control your radio")
|
||||
PARSER.add_argument("--rigctld_port", dest="rigctld_port", default=4532, type=int, help="Set rigctld port")
|
||||
PARSER.add_argument("--rigctld_ip", dest="rigctld_ip", default="localhost", help="Set rigctld ip")
|
||||
PARSER.add_argument("--scatter", dest="send_scatter", action="store_true", help="Send scatter information via network")
|
||||
PARSER.add_argument("--fft", dest="send_fft", action="store_true", help="Send fft information via network")
|
||||
PARSER.add_argument("--500hz", dest="low_bandwith_mode", action="store_true", help="Enable low bandwith mode ( 500 Hz only )")
|
||||
PARSER.add_argument("--fsk", dest="enable_fsk", action="store_true", help="Enable FSK mode for ping, beacon and CQ")
|
||||
PARSER.add_argument("--qrv", dest="enable_respond_to_cq", action="store_true", help="Enable sending a QRV frame if CQ received")
|
||||
PARSER.add_argument("--tuning_range_fmin", dest="tuning_range_fmin", choices=[-50.0, -100.0, -150.0, -200.0, -250.0], default=-50.0, help="Tuning range fmin", type=float)
|
||||
PARSER.add_argument("--tuning_range_fmax", dest="tuning_range_fmax", choices=[50.0, 100.0, 150.0, 200.0, 250.0], default=50.0, help="Tuning range fmax", type=float)
|
||||
PARSER.add_argument("--tx-audio-level", dest="tx_audio_level", default=50, help="Set the tx audio level at an early stage", type=int)
|
||||
|
||||
ARGS = PARSER.parse_args()
|
||||
|
||||
# additional step for beeing sure our callsign is correctly
|
||||
# in case we are not getting a station ssid
|
||||
# then we are forcing a station ssid = 0
|
||||
mycallsign = bytes(ARGS.mycall.upper(), 'utf-8')
|
||||
mycallsign = bytes(ARGS.mycall.upper(), "utf-8")
|
||||
mycallsign = helpers.callsign_to_bytes(mycallsign)
|
||||
static.MYCALLSIGN = helpers.bytes_to_callsign(mycallsign)
|
||||
static.MYCALLSIGN_CRC = helpers.get_crc_24(static.MYCALLSIGN)
|
||||
|
||||
static.SSID_LIST = ARGS.ssid_list
|
||||
|
||||
static.MYGRID = bytes(ARGS.mygrid, 'utf-8')
|
||||
static.MYGRID = bytes(ARGS.mygrid, "utf-8")
|
||||
static.AUDIO_INPUT_DEVICE = ARGS.audio_input_device
|
||||
static.AUDIO_OUTPUT_DEVICE = ARGS.audio_output_device
|
||||
static.PORT = ARGS.socket_port
|
||||
|
@ -114,20 +113,20 @@ if __name__ == '__main__':
|
|||
|
||||
# config logging
|
||||
try:
|
||||
if sys.platform == 'linux':
|
||||
logging_path = os.getenv("HOME") + '/.config/' + 'FreeDATA/' + 'tnc'
|
||||
if sys.platform == "linux":
|
||||
logging_path = os.getenv("HOME") + "/.config/" + "FreeDATA/" + "tnc"
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
logging_path = os.getenv("HOME") + '/Library/' + 'Application Support/' + 'FreeDATA/' + 'tnc'
|
||||
if sys.platform == "darwin":
|
||||
logging_path = os.getenv("HOME") + "/Library/" + "Application Support/" + "FreeDATA/" + "tnc"
|
||||
|
||||
if sys.platform in ['win32', 'win64']:
|
||||
logging_path = os.getenv('APPDATA') + '/' + 'FreeDATA/' + 'tnc'
|
||||
if sys.platform in ["win32", "win64"]:
|
||||
logging_path = os.getenv("APPDATA") + "/" + "FreeDATA/" + "tnc"
|
||||
|
||||
if not os.path.exists(logging_path):
|
||||
os.makedirs(logging_path)
|
||||
log_handler.setup_logging(logging_path)
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[DMN] logger init error", exception=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error("[DMN] logger init error", exception=err)
|
||||
|
||||
structlog.get_logger("structlog").info("[TNC] Starting FreeDATA", author="DJ2LS", year="2022", version=static.VERSION)
|
||||
|
||||
|
@ -148,8 +147,8 @@ if __name__ == '__main__':
|
|||
server_thread.daemon = True
|
||||
server_thread.start()
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[TNC] Starting TCP/IP socket failed", port=static.PORT, e=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error("[TNC] Starting TCP/IP socket failed", port=static.PORT, e=err)
|
||||
sys.exit(1)
|
||||
while 1:
|
||||
time.sleep(1)
|
||||
|
|
61
tnc/modem.py
61
tnc/modem.py
|
@ -17,20 +17,19 @@ import threading
|
|||
import time
|
||||
from collections import deque
|
||||
|
||||
import numpy as np
|
||||
import sounddevice as sd
|
||||
import structlog
|
||||
import ujson as json
|
||||
|
||||
# import audio
|
||||
import codec2
|
||||
import data_handler
|
||||
import numpy as np
|
||||
import sock
|
||||
import sounddevice as sd
|
||||
import static
|
||||
import structlog
|
||||
import ujson as json
|
||||
|
||||
TESTMODE = False
|
||||
RXCHANNEL = ''
|
||||
TXCHANNEL = ''
|
||||
RXCHANNEL = ""
|
||||
TXCHANNEL = ""
|
||||
|
||||
# Initialize FIFO queue to store received frames
|
||||
MODEM_RECEIVED_QUEUE = queue.Queue()
|
||||
|
@ -114,7 +113,7 @@ class RF:
|
|||
|
||||
self.fsk_ldpc_freedv_0 = ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC,
|
||||
ctypes.byref(
|
||||
codec2.api.FREEDV_MODE_FSK_LDPC_0_ADV)),
|
||||
codec2.api.FREEDV_MODE_FSK_LDPC_0_ADV)),
|
||||
ctypes.c_void_p)
|
||||
self.fsk_ldpc_bytes_per_frame_0 = int(codec2.api.freedv_get_bits_per_modem_frame(self.fsk_ldpc_freedv_0) / 8)
|
||||
self.fsk_ldpc_bytes_out_0 = ctypes.create_string_buffer(self.fsk_ldpc_bytes_per_frame_0)
|
||||
|
@ -123,7 +122,7 @@ class RF:
|
|||
|
||||
self.fsk_ldpc_freedv_1 = ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC,
|
||||
ctypes.byref(
|
||||
codec2.api.FREEDV_MODE_FSK_LDPC_1_ADV)),
|
||||
codec2.api.FREEDV_MODE_FSK_LDPC_1_ADV)),
|
||||
ctypes.c_void_p)
|
||||
self.fsk_ldpc_bytes_per_frame_1 = int(codec2.api.freedv_get_bits_per_modem_frame(self.fsk_ldpc_freedv_1) / 8)
|
||||
self.fsk_ldpc_bytes_out_1 = ctypes.create_string_buffer(self.fsk_ldpc_bytes_per_frame_1)
|
||||
|
@ -139,14 +138,14 @@ class RF:
|
|||
# --------------------------------------------CREATE PYAUDIO INSTANCE
|
||||
if not TESTMODE:
|
||||
try:
|
||||
self.stream = sd.RawStream(channels=1, dtype='int16', callback=self.callback,
|
||||
self.stream = sd.RawStream(channels=1, dtype="int16", callback=self.callback,
|
||||
device=(static.AUDIO_INPUT_DEVICE, static.AUDIO_OUTPUT_DEVICE),
|
||||
samplerate=self.AUDIO_SAMPLE_RATE_RX, blocksize=4800)
|
||||
atexit.register(self.stream.stop)
|
||||
structlog.get_logger("structlog").info("[MDM] init: opened audio devices")
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[MDM] init: can't open audio device. Exit", e=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error("[MDM] init: can't open audio device. Exit", e=err)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
|
@ -154,8 +153,8 @@ class RF:
|
|||
# self.audio_stream.start_stream()
|
||||
self.stream.start()
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[MDM] init: starting pyaudio callback failed", e=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error("[MDM] init: starting pyaudio callback failed", e=err)
|
||||
|
||||
else:
|
||||
# create a stream object for simulating audio stream
|
||||
|
@ -169,8 +168,8 @@ class RF:
|
|||
try:
|
||||
os.mkfifo(RXCHANNEL)
|
||||
os.mkfifo(TXCHANNEL)
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error(f"[MDM] init:mkfifo: Exception: {e}")
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error(f"[MDM] init:mkfifo: Exception: {err}")
|
||||
|
||||
mkfifo_write_callback_thread = threading.Thread(target=self.mkfifo_write_callback,
|
||||
name="MKFIFO WRITE CALLBACK THREAD", daemon=True)
|
||||
|
@ -182,13 +181,13 @@ class RF:
|
|||
|
||||
# --------------------------------------------INIT AND OPEN HAMLIB
|
||||
# Check how we want to control the radio
|
||||
if static.HAMLIB_RADIOCONTROL == 'direct':
|
||||
if static.HAMLIB_RADIOCONTROL == "direct":
|
||||
import rig
|
||||
elif static.HAMLIB_RADIOCONTROL == 'rigctl':
|
||||
elif static.HAMLIB_RADIOCONTROL == "rigctl":
|
||||
import rigctl as rig
|
||||
elif static.HAMLIB_RADIOCONTROL == 'rigctld':
|
||||
elif static.HAMLIB_RADIOCONTROL == "rigctld":
|
||||
import rigctld as rig
|
||||
elif static.HAMLIB_RADIOCONTROL == 'disabled':
|
||||
elif static.HAMLIB_RADIOCONTROL == "disabled":
|
||||
import rigdummy as rig
|
||||
else:
|
||||
import rigdummy as rig
|
||||
|
@ -238,7 +237,7 @@ class RF:
|
|||
time.sleep(0.01)
|
||||
# -----read
|
||||
data_in48k = bytes()
|
||||
with open(RXCHANNEL, 'rb') as fifo:
|
||||
with open(RXCHANNEL, "rb") as fifo:
|
||||
for line in fifo:
|
||||
data_in48k += line
|
||||
|
||||
|
@ -269,7 +268,7 @@ class RF:
|
|||
else:
|
||||
data_out48k = self.modoutqueue.popleft()
|
||||
|
||||
fifo_write = open(TXCHANNEL, 'wb')
|
||||
fifo_write = open(TXCHANNEL, "wb")
|
||||
fifo_write.write(data_out48k)
|
||||
fifo_write.flush()
|
||||
|
||||
|
@ -389,7 +388,7 @@ class RF:
|
|||
|
||||
for _ in range(repeats):
|
||||
# codec2 fsk preamble may be broken - at least it sounds like that so we are disabling it for testing
|
||||
if self.MODE not in ['FSK_LDPC_0', 'FSK_LDPC_1', 200, 201]:
|
||||
if self.MODE not in ["FSK_LDPC_0", "FSK_LDPC_1", 200, 201]:
|
||||
# Write preamble to txbuffer
|
||||
codec2.api.freedv_rawdatapreambletx(freedv, mod_out_preamble)
|
||||
txbuffer += bytes(mod_out_preamble)
|
||||
|
@ -404,7 +403,7 @@ class RF:
|
|||
# CRC algorithm incompatibilities
|
||||
crc = ctypes.c_ushort(
|
||||
codec2.api.freedv_gen_crc16(bytes(buffer), payload_bytes_per_frame)) # Generate CRC16
|
||||
crc = crc.value.to_bytes(2, byteorder='big') # Convert crc to 2 byte hex string
|
||||
crc = crc.value.to_bytes(2, byteorder="big") # Convert crc to 2 byte hex string
|
||||
buffer += crc # Append crc16 to buffer
|
||||
|
||||
data = (ctypes.c_ubyte * bytes_per_frame).from_buffer_copy(buffer)
|
||||
|
@ -412,7 +411,7 @@ class RF:
|
|||
txbuffer += bytes(mod_out)
|
||||
|
||||
# codec2 fsk postamble may be broken - at least it sounds like that so we are disabling it for testing
|
||||
if self.MODE not in ['FSK_LDPC_0', 'FSK_LDPC_1', 200, 201]:
|
||||
if self.MODE not in ["FSK_LDPC_0", "FSK_LDPC_1", 200, 201]:
|
||||
# Write postamble to txbuffer
|
||||
codec2.api.freedv_rawdatapostambletx(freedv, mod_out_postamble)
|
||||
# Append postamble to txbuffer
|
||||
|
@ -646,8 +645,8 @@ class RF:
|
|||
# static.SNR = np.clip(snr, 0, 255) # limit to max value of 255
|
||||
static.SNR = np.clip(snr, -128, 128) # limit to max value of -128/128 as a possible fix of #188
|
||||
return static.SNR
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error(f"[MDM] calculate_snr: Exception: {e}")
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error(f"[MDM] calculate_snr: Exception: {err}")
|
||||
static.SNR = 0
|
||||
return static.SNR
|
||||
|
||||
|
@ -712,8 +711,8 @@ class RF:
|
|||
dfftlist = dfft.tolist()
|
||||
|
||||
static.FFT = dfftlist[:320] # 320 --> bandwidth 3000
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error(f"[MDM] calculate_fft: Exception: {e}")
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error(f"[MDM] calculate_fft: Exception: {err}")
|
||||
structlog.get_logger("structlog").debug("[MDM] Setting fft=0")
|
||||
# else 0
|
||||
static.FFT = [0]
|
||||
|
@ -734,12 +733,12 @@ class RF:
|
|||
|
||||
def open_codec2_instance(mode):
|
||||
""" Return a codec2 instance """
|
||||
if mode in ['FSK_LDPC_0', 200]:
|
||||
if mode in ["FSK_LDPC_0", 200]:
|
||||
return ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC,
|
||||
ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_0_ADV)),
|
||||
ctypes.c_void_p)
|
||||
|
||||
if mode in ['FSK_LDPC_1', 201]:
|
||||
if mode in ["FSK_LDPC_1", 201]:
|
||||
return ctypes.cast(codec2.api.freedv_open_advanced(codec2.api.FREEDV_MODE_FSK_LDPC,
|
||||
ctypes.byref(codec2.api.FREEDV_MODE_FSK_LDPC_1_ADV)),
|
||||
ctypes.c_void_p)
|
||||
|
|
105
tnc/rig.py
105
tnc/rig.py
|
@ -1,11 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import re
|
||||
import structlog
|
||||
import atexit
|
||||
import subprocess
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import structlog
|
||||
|
||||
# set global hamlib version
|
||||
hamlib_version = 0
|
||||
|
@ -23,23 +24,23 @@ try:
|
|||
python_version = f"{str(sys.version_info[0])}.{str(sys.version_info[1])}"
|
||||
|
||||
# installation path for Ubuntu 20.04 LTS python modules
|
||||
# sys.path.append('/usr/local/lib/python'+ python_version +'/site-packages')
|
||||
# sys.path.append("/usr/local/lib/python"+ python_version +"/site-packages")
|
||||
|
||||
# installation path for Ubuntu 20.10 +
|
||||
sys.path.append('/usr/local/lib/')
|
||||
sys.path.append("/usr/local/lib/")
|
||||
|
||||
# installation path for Suse
|
||||
sys.path.append(f'/usr/local/lib64/python{python_version}/site-packages')
|
||||
sys.path.append(f"/usr/local/lib64/python{python_version}/site-packages")
|
||||
|
||||
# everything else... not nice, but an attempt to see how it's running within app bundle
|
||||
# this is not needed as python will be shipped with app bundle
|
||||
sys.path.append('/usr/local/lib/python3.6/site-packages')
|
||||
sys.path.append('/usr/local/lib/python3.7/site-packages')
|
||||
sys.path.append('/usr/local/lib/python3.8/site-packages')
|
||||
sys.path.append('/usr/local/lib/python3.9/site-packages')
|
||||
sys.path.append('/usr/local/lib/python3.10/site-packages')
|
||||
sys.path.append("/usr/local/lib/python3.6/site-packages")
|
||||
sys.path.append("/usr/local/lib/python3.7/site-packages")
|
||||
sys.path.append("/usr/local/lib/python3.8/site-packages")
|
||||
sys.path.append("/usr/local/lib/python3.9/site-packages")
|
||||
sys.path.append("/usr/local/lib/python3.10/site-packages")
|
||||
|
||||
sys.path.append('lib/hamlib/linux/python3.8/site-packages')
|
||||
sys.path.append("lib/hamlib/linux/python3.8/site-packages")
|
||||
import Hamlib
|
||||
|
||||
# https://stackoverflow.com/a/4703409
|
||||
|
@ -51,22 +52,22 @@ try:
|
|||
structlog.get_logger("structlog").info("[RIG] Hamlib found", version=hamlib_version)
|
||||
else:
|
||||
structlog.get_logger("structlog").warning("[RIG] Hamlib outdated", found=hamlib_version, recommend=min_hamlib_version)
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").warning("[RIG] Python Hamlib binding not found", error=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").warning("[RIG] Python Hamlib binding not found", error=err)
|
||||
|
||||
try:
|
||||
structlog.get_logger("structlog").warning("[RIG] Trying to open rigctl")
|
||||
rigctl = subprocess.Popen("rigctl -V", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
|
||||
|
||||
hamlib_version = rigctl.stdout.readline()
|
||||
hamlib_version = hamlib_version.split(' ')
|
||||
if hamlib_version[1] != 'Hamlib':
|
||||
raise Exception from e
|
||||
hamlib_version = hamlib_version.split(" ")
|
||||
if hamlib_version[1] != "Hamlib":
|
||||
raise Exception from err
|
||||
structlog.get_logger("structlog").warning("[RIG] Rigctl found! Please try using this", version=hamlib_version[2])
|
||||
|
||||
sys.exit()
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").critical("[RIG] HAMLIB NOT INSTALLED", error=e)
|
||||
except Exception as err1:
|
||||
structlog.get_logger("structlog").critical("[RIG] HAMLIB NOT INSTALLED", error=err1)
|
||||
|
||||
hamlib_version = 0
|
||||
sys.exit()
|
||||
|
@ -75,16 +76,16 @@ except Exception as e:
|
|||
class radio:
|
||||
""" """
|
||||
def __init__(self):
|
||||
self.devicename = ''
|
||||
self.devicenumber = ''
|
||||
self.deviceport = ''
|
||||
self.serialspeed = ''
|
||||
self.hamlib_ptt_type = ''
|
||||
self.my_rig = ''
|
||||
self.pttport = ''
|
||||
self.data_bits = ''
|
||||
self.stop_bits = ''
|
||||
self.handshake = ''
|
||||
self.devicename = ""
|
||||
self.devicenumber = ""
|
||||
self.deviceport = ""
|
||||
self.serialspeed = ""
|
||||
self.hamlib_ptt_type = ""
|
||||
self.my_rig = ""
|
||||
self.pttport = ""
|
||||
self.data_bits = ""
|
||||
self.stop_bits = ""
|
||||
self.handshake = ""
|
||||
|
||||
def open_rig(self, devicename, deviceport, hamlib_ptt_type, serialspeed, pttport, data_bits, stop_bits, handshake, rigctld_port, rigctld_ip):
|
||||
"""
|
||||
|
@ -133,42 +134,42 @@ class radio:
|
|||
self.my_rig.set_conf("data_bits", self.data_bits)
|
||||
self.my_rig.set_conf("ptt_pathname", self.pttport)
|
||||
|
||||
if self.hamlib_ptt_type == 'RIG':
|
||||
if self.hamlib_ptt_type == "RIG":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_RIG
|
||||
self.my_rig.set_conf("ptt_type", 'RIG')
|
||||
self.my_rig.set_conf("ptt_type", "RIG")
|
||||
|
||||
elif self.hamlib_ptt_type == 'USB':
|
||||
elif self.hamlib_ptt_type == "USB":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PORT_USB
|
||||
self.my_rig.set_conf("ptt_type", 'USB')
|
||||
self.my_rig.set_conf("ptt_type", "USB")
|
||||
|
||||
elif self.hamlib_ptt_type == 'DTR-H':
|
||||
elif self.hamlib_ptt_type == "DTR-H":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_SERIAL_DTR
|
||||
self.my_rig.set_conf("dtr_state", "HIGH")
|
||||
self.my_rig.set_conf("ptt_type", "DTR")
|
||||
|
||||
elif self.hamlib_ptt_type == 'DTR-L':
|
||||
elif self.hamlib_ptt_type == "DTR-L":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_SERIAL_DTR
|
||||
self.my_rig.set_conf("dtr_state", "LOW")
|
||||
self.my_rig.set_conf("ptt_type", "DTR")
|
||||
|
||||
elif self.hamlib_ptt_type == 'RTS':
|
||||
elif self.hamlib_ptt_type == "RTS":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_SERIAL_RTS
|
||||
self.my_rig.set_conf("dtr_state", "OFF")
|
||||
self.my_rig.set_conf("ptt_type", "RTS")
|
||||
|
||||
elif self.hamlib_ptt_type == 'PARALLEL':
|
||||
elif self.hamlib_ptt_type == "PARALLEL":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_PARALLEL
|
||||
|
||||
elif self.hamlib_ptt_type == 'MICDATA':
|
||||
elif self.hamlib_ptt_type == "MICDATA":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_RIG_MICDATA
|
||||
|
||||
elif self.hamlib_ptt_type == 'CM108':
|
||||
elif self.hamlib_ptt_type == "CM108":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_CM108
|
||||
|
||||
elif self.hamlib_ptt_type == 'RIG_PTT_NONE':
|
||||
elif self.hamlib_ptt_type == "RIG_PTT_NONE":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_NONE
|
||||
|
||||
else: # self.hamlib_ptt_type == 'RIG_PTT_NONE':
|
||||
else: # self.hamlib_ptt_type == "RIG_PTT_NONE":
|
||||
self.hamlib_ptt_type = Hamlib.RIG_PTT_NONE
|
||||
|
||||
structlog.get_logger("structlog").info("[RIG] Opening...", device=self.devicenumber, path=self.my_rig.get_conf("rig_pathname"), serial_speed=self.my_rig.get_conf("serial_speed"), serial_handshake=self.my_rig.get_conf("serial_handshake"), stop_bits=self.my_rig.get_conf("stop_bits"), data_bits=self.my_rig.get_conf("data_bits"), ptt_pathname=self.my_rig.get_conf("ptt_pathname"))
|
||||
|
@ -178,16 +179,16 @@ class radio:
|
|||
|
||||
try:
|
||||
# lets determine the error message when opening rig
|
||||
error = str(Hamlib.rigerror(my_rig.error_status)).splitlines()
|
||||
error = error[1].split('err=')
|
||||
error = str(Hamlib.rigerror(self.my_rig.error_status)).splitlines()
|
||||
error = error[1].split("err=")
|
||||
error = error[1]
|
||||
|
||||
if error == 'Permission denied':
|
||||
if error == "Permission denied":
|
||||
structlog.get_logger("structlog").error("[RIG] Hamlib has no permissions", e = error)
|
||||
help_url = 'https://github.com/DJ2LS/FreeDATA/wiki/UBUNTU-Manual-installation#1-permissions'
|
||||
help_url = "https://github.com/DJ2LS/FreeDATA/wiki/UBUNTU-Manual-installation#1-permissions"
|
||||
structlog.get_logger("structlog").error("[RIG] HELP:", check = help_url)
|
||||
except Exception:
|
||||
structlog.get_logger("structlog").info("[RIG] Hamlib device opened", status='SUCCESS')
|
||||
structlog.get_logger("structlog").info("[RIG] Hamlib device opened", status="SUCCESS")
|
||||
|
||||
# set ptt to false if ptt is stuck for some reason
|
||||
self.set_ptt(False)
|
||||
|
@ -198,8 +199,8 @@ class radio:
|
|||
# self.my_rig.set_mode(Hamlib.RIG_MODE_PKTUSB)
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[RIG] Hamlib - can't open rig", error=e, e=sys.exc_info()[0])
|
||||
except Exception as err2:
|
||||
structlog.get_logger("structlog").error("[RIG] Hamlib - can't open rig", error=err2, e=sys.exc_info()[0])
|
||||
return False
|
||||
|
||||
def get_frequency(self):
|
||||
|
@ -208,13 +209,13 @@ class radio:
|
|||
|
||||
def get_mode(self):
|
||||
""" """
|
||||
(hamlib_mode, bandwith) = self.my_rig.get_mode()
|
||||
(hamlib_mode, bandwidth) = self.my_rig.get_mode()
|
||||
return Hamlib.rig_strrmode(hamlib_mode)
|
||||
|
||||
def get_bandwith(self):
|
||||
""" """
|
||||
(hamlib_mode, bandwith) = self.my_rig.get_mode()
|
||||
return bandwith
|
||||
(hamlib_mode, bandwidth) = self.my_rig.get_mode()
|
||||
return bandwidth
|
||||
|
||||
# not needed yet beacuse of some possible problems
|
||||
# def set_mode(self, mode):
|
||||
|
|
|
@ -23,16 +23,17 @@ hamlib_version = 0
|
|||
class radio:
|
||||
""" """
|
||||
def __init__(self):
|
||||
self.devicename = ''
|
||||
self.devicenumber = ''
|
||||
self.deviceport = ''
|
||||
self.serialspeed = ''
|
||||
self.hamlib_ptt_type = ''
|
||||
self.my_rig = ''
|
||||
self.pttport = ''
|
||||
self.data_bits = ''
|
||||
self.stop_bits = ''
|
||||
self.handshake = ''
|
||||
self.devicename = ""
|
||||
self.devicenumber = ""
|
||||
self.deviceport = ""
|
||||
self.serialspeed = ""
|
||||
self.hamlib_ptt_type = ""
|
||||
self.my_rig = ""
|
||||
self.pttport = ""
|
||||
self.data_bits = ""
|
||||
self.stop_bits = ""
|
||||
self.handshake = ""
|
||||
self.cmd = ""
|
||||
|
||||
def open_rig(self, devicename, deviceport, hamlib_ptt_type, serialspeed, pttport, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port):
|
||||
"""
|
||||
|
@ -71,26 +72,26 @@ class radio:
|
|||
try:
|
||||
import Hamlib
|
||||
self.devicenumber = int(getattr(Hamlib, self.devicename))
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
if int(self.devicename):
|
||||
self.devicenumber = int(self.devicename)
|
||||
else:
|
||||
self.devicenumber = 6 # dummy
|
||||
structlog.get_logger("structlog").warning("[RIGCTL] Radio not found. Using DUMMY!", error=e)
|
||||
structlog.get_logger("structlog").warning("[RIGCTL] Radio not found. Using DUMMY!", error=err)
|
||||
|
||||
# set deviceport to dummy port, if we selected dummy model
|
||||
if self.devicenumber in {1, 6}:
|
||||
self.deviceport = '/dev/ttyUSB0'
|
||||
self.deviceport = "/dev/ttyUSB0"
|
||||
|
||||
print(self.devicenumber, self.deviceport, self.serialspeed)
|
||||
|
||||
# select precompiled executable for win32/win64 rigctl
|
||||
# this is really a hack...somewhen we need a native hamlib integration for windows
|
||||
if sys.platform in ['win32', 'win64']:
|
||||
self.cmd = app_path + 'lib\\hamlib\\'+sys.platform+'\\rigctl -m %d -r %s -s %d ' % (int(self.devicenumber), self.deviceport, int(self.serialspeed))
|
||||
if sys.platform in ["win32", "win64"]:
|
||||
self.cmd = app_path + "lib\\hamlib\\" + sys.platform + "\\rigctl -m %d -r %s -s %d " % (int(self.devicenumber), self.deviceport, int(self.serialspeed))
|
||||
|
||||
else:
|
||||
self.cmd = 'rigctl -m %d -r %s -s %d ' % (int(self.devicenumber), self.deviceport, int(self.serialspeed))
|
||||
self.cmd = "rigctl -m %d -r %s -s %d " % (int(self.devicenumber), self.deviceport, int(self.serialspeed))
|
||||
|
||||
# eseguo semplicemente rigctl con il solo comando T 1 o T 0 per
|
||||
# il set e t per il get
|
||||
|
@ -101,11 +102,11 @@ class radio:
|
|||
|
||||
def get_frequency(self):
|
||||
""" """
|
||||
cmd = f'{self.cmd} f'
|
||||
cmd = f"{self.cmd} f"
|
||||
sw_proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
|
||||
time.sleep(0.5)
|
||||
freq = sw_proc.communicate()[0]
|
||||
# print('get_frequency', freq, sw_proc.communicate())
|
||||
# print("get_frequency", freq, sw_proc.communicate())
|
||||
try:
|
||||
return int(freq)
|
||||
except Exception:
|
||||
|
@ -116,17 +117,17 @@ class radio:
|
|||
# (hamlib_mode, bandwith) = self.my_rig.get_mode()
|
||||
# return Hamlib.rig_strrmode(hamlib_mode)
|
||||
try:
|
||||
return 'PKTUSB'
|
||||
return "PKTUSB"
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def get_bandwith(self):
|
||||
""" """
|
||||
# (hamlib_mode, bandwith) = self.my_rig.get_mode()
|
||||
bandwith = 2700
|
||||
bandwidth = 2700
|
||||
|
||||
try:
|
||||
return bandwith
|
||||
return bandwidth
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
@ -144,7 +145,7 @@ class radio:
|
|||
|
||||
def get_ptt(self):
|
||||
""" """
|
||||
cmd = f'{self.cmd} t'
|
||||
cmd = f"{self.cmd} t"
|
||||
sw_proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
|
||||
time.sleep(0.5)
|
||||
status = sw_proc.communicate()[0]
|
||||
|
@ -163,10 +164,10 @@ class radio:
|
|||
Returns:
|
||||
|
||||
"""
|
||||
cmd = f'{self.cmd} T '
|
||||
print('set_ptt', state)
|
||||
cmd = f'{cmd}1' if state else f'{cmd}0'
|
||||
print('set_ptt', cmd)
|
||||
cmd = f"{self.cmd} T "
|
||||
print("set_ptt", state)
|
||||
cmd = f"{cmd}1" if state else f"{cmd}0"
|
||||
print("set_ptt", cmd)
|
||||
|
||||
sw_proc = subprocess.Popen(cmd, shell=True, text=True)
|
||||
try:
|
||||
|
|
|
@ -8,10 +8,9 @@ import logging
|
|||
import socket
|
||||
import time
|
||||
|
||||
import structlog
|
||||
|
||||
import log_handler
|
||||
import static
|
||||
import structlog
|
||||
|
||||
# set global hamlib version
|
||||
hamlib_version = 0
|
||||
|
@ -22,7 +21,7 @@ class radio():
|
|||
# Note: This is a massive hack.
|
||||
|
||||
def __init__(self, hostname="localhost", port=4532, poll_rate=5, timeout=5):
|
||||
""" Open a connection to rotctld, and test it for validity """
|
||||
""" Open a connection to rigctld, and test it for validity """
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
# self.sock.settimeout(timeout)
|
||||
|
||||
|
@ -51,7 +50,7 @@ class radio():
|
|||
"""
|
||||
self.hostname = rigctld_ip
|
||||
self.port = int(rigctld_port)
|
||||
|
||||
|
||||
if self.connect():
|
||||
logging.debug("Rigctl intialized")
|
||||
return True
|
||||
|
@ -67,10 +66,10 @@ class radio():
|
|||
self.connected = True
|
||||
structlog.get_logger("structlog").info("[RIGCTLD] Connected to rigctld!", ip=self.hostname, port=self.port)
|
||||
return True
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
# ConnectionRefusedError: [Errno 111] Connection refused
|
||||
self.close_rig()
|
||||
structlog.get_logger("structlog").warning("[RIGCTLD] Connection to rigctld refused! Reconnect...", ip=self.hostname, port=self.port, e=e)
|
||||
structlog.get_logger("structlog").warning("[RIGCTLD] Connection to rigctld refused! Reconnect...", ip=self.hostname, port=self.port, e=err)
|
||||
return False
|
||||
|
||||
def close_rig(self):
|
||||
|
@ -78,7 +77,7 @@ class radio():
|
|||
self.sock.close()
|
||||
self.connected = False
|
||||
|
||||
def send_command(self, command):
|
||||
def send_command(self, command) -> bytes:
|
||||
"""Send a command to the connected rotctld instance,
|
||||
and return the return value.
|
||||
|
||||
|
@ -90,7 +89,7 @@ class radio():
|
|||
"""
|
||||
if self.connected:
|
||||
try:
|
||||
self.connection.sendall(command+b'\n')
|
||||
self.connection.sendall(command + b"\n")
|
||||
except Exception:
|
||||
structlog.get_logger("structlog").warning("[RIGCTLD] Command not executed!", command=command, ip=self.hostname, port=self.port)
|
||||
self.connected = False
|
||||
|
@ -106,11 +105,13 @@ class radio():
|
|||
time.sleep(0.5)
|
||||
self.connect()
|
||||
|
||||
return b""
|
||||
|
||||
def get_mode(self):
|
||||
""" """
|
||||
try:
|
||||
data = self.send_command(b"m")
|
||||
data = data.split(b'\n')
|
||||
data = data.split(b"\n")
|
||||
mode = data[0]
|
||||
return mode.decode("utf-8")
|
||||
except Exception:
|
||||
|
@ -120,7 +121,7 @@ class radio():
|
|||
""" """
|
||||
try:
|
||||
data = self.send_command(b"m")
|
||||
data = data.split(b'\n')
|
||||
data = data.split(b"\n")
|
||||
bandwith = data[1]
|
||||
return bandwith.decode("utf-8")
|
||||
except Exception:
|
||||
|
|
|
@ -7,6 +7,7 @@ hamlib_version = 0
|
|||
|
||||
class radio:
|
||||
""" """
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
|
222
tnc/sock.py
222
tnc/sock.py
|
@ -6,35 +6,31 @@ Created on Fri Dec 25 21:25:14 2020
|
|||
@author: DJ2LS
|
||||
|
||||
# GET COMMANDS
|
||||
# "command" : "..."
|
||||
# "command" : "..."
|
||||
|
||||
# SET COMMANDS
|
||||
# "command" : "..."
|
||||
# "parameter" : " ..."
|
||||
|
||||
# DATA COMMANDS
|
||||
# "command" : "..."
|
||||
# "type" : "..."
|
||||
# "dxcallsign" : "..."
|
||||
# "data" : "..."
|
||||
# SET COMMANDS
|
||||
# "command" : "..."
|
||||
# "parameter" : " ..."
|
||||
|
||||
# DATA COMMANDS
|
||||
# "command" : "..."
|
||||
# "type" : "..."
|
||||
# "dxcallsign" : "..."
|
||||
# "data" : "..."
|
||||
"""
|
||||
import atexit
|
||||
import base64
|
||||
|
||||
import queue
|
||||
import socketserver
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
import structlog
|
||||
import ujson as json
|
||||
|
||||
import data_handler
|
||||
import helpers
|
||||
|
||||
import static
|
||||
import structlog
|
||||
import ujson as json
|
||||
|
||||
SOCKET_QUEUE = queue.Queue()
|
||||
DAEMON_QUEUE = queue.Queue()
|
||||
|
@ -59,7 +55,7 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
|
|||
function called by socket handler
|
||||
send data to a network client if available
|
||||
"""
|
||||
tempdata = b''
|
||||
tempdata = b""
|
||||
while self.connection_alive and not CLOSE_SIGNAL:
|
||||
# send tnc state as network stream
|
||||
# check server port against daemon port and send corresponding data
|
||||
|
@ -77,17 +73,17 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
|
|||
|
||||
while not SOCKET_QUEUE.empty():
|
||||
data = SOCKET_QUEUE.get()
|
||||
sock_data = bytes(data, 'utf-8')
|
||||
sock_data += b'\n' # append line limiter
|
||||
sock_data = bytes(data, "utf-8")
|
||||
sock_data += b"\n" # append line limiter
|
||||
|
||||
# send data to all clients
|
||||
# try:
|
||||
for client in CONNECTED_CLIENTS:
|
||||
try:
|
||||
client.send(sock_data)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
# print("connection lost...")
|
||||
structlog.get_logger("structlog").info("[SCK] Connection lost", e=e)
|
||||
structlog.get_logger("structlog").info("[SCK] Connection lost", e=err)
|
||||
self.connection_alive = False
|
||||
|
||||
# we want to transmit scatter data only once to reduce network traffic
|
||||
|
@ -108,15 +104,15 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
|
|||
chunk = self.request.recv(1024)
|
||||
data += chunk
|
||||
|
||||
if chunk == b'':
|
||||
if chunk == b"":
|
||||
# print("connection broken. Closing...")
|
||||
self.connection_alive = False
|
||||
|
||||
if data.startswith(b'{') and data.endswith(b'}\n'):
|
||||
if data.startswith(b"{") and data.endswith(b"}\n"):
|
||||
# split data by \n if we have multiple commands in socket buffer
|
||||
data = data.split(b'\n')
|
||||
data = data.split(b"\n")
|
||||
# remove empty data
|
||||
data.remove(b'')
|
||||
data.remove(b"")
|
||||
|
||||
# iterate thorugh data list
|
||||
for commands in data:
|
||||
|
@ -134,9 +130,9 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
|
|||
|
||||
# finally delete our rx buffer to be ready for new commands
|
||||
data = bytes()
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").info("[SCK] Connection closed", ip=self.client_address[0],
|
||||
port=self.client_address[1], e=e)
|
||||
port=self.client_address[1], e=err)
|
||||
self.connection_alive = False
|
||||
|
||||
def handle(self):
|
||||
|
@ -162,9 +158,9 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
|
|||
port=self.client_address[1])
|
||||
try:
|
||||
CONNECTED_CLIENTS.remove(self.request)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").warning("[SCK] client connection already removed from client list",
|
||||
client=self.request, e=e)
|
||||
client=self.request, e=err)
|
||||
|
||||
|
||||
def process_tnc_commands(data):
|
||||
|
@ -188,53 +184,53 @@ def process_tnc_commands(data):
|
|||
static.TX_AUDIO_LEVEL = int(received_json["value"])
|
||||
command_response("tx_audio_level", True)
|
||||
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("tx_audio_level", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# TRANSMIT SINE WAVE -----------------------------------------------------
|
||||
if received_json["type"] == "set" and received_json["command"] == "send_test_frame":
|
||||
try:
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(['SEND_TEST_FRAME'])
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(["SEND_TEST_FRAME"])
|
||||
command_response("send_test_frame", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("send_test_frame", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# CQ CQ CQ -----------------------------------------------------
|
||||
if received_json["command"] == "cqcqcq":
|
||||
try:
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(['CQ'])
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(["CQ"])
|
||||
command_response("cqcqcq", True)
|
||||
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("cqcqcq", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# START_BEACON -----------------------------------------------------
|
||||
if received_json["command"] == "start_beacon":
|
||||
try:
|
||||
static.BEACON_STATE = True
|
||||
interval = int(received_json["parameter"])
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(['BEACON', interval, True])
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(["BEACON", interval, True])
|
||||
command_response("start_beacon", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("start_beacon", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# STOP_BEACON -----------------------------------------------------
|
||||
if received_json["command"] == "stop_beacon":
|
||||
try:
|
||||
structlog.get_logger("structlog").warning("[TNC] Stopping beacon!")
|
||||
static.BEACON_STATE = False
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(['BEACON', None, False])
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(["BEACON", None, False])
|
||||
command_response("stop_beacon", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("stop_beacon", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# PING ----------------------------------------------------------
|
||||
if received_json["type"] == 'ping' and received_json["command"] == "ping":
|
||||
if received_json["type"] == "ping" and received_json["command"] == "ping":
|
||||
# send ping frame and wait for ACK
|
||||
try:
|
||||
dxcallsign = received_json["dxcallsign"]
|
||||
|
@ -245,14 +241,14 @@ def process_tnc_commands(data):
|
|||
dxcallsign = helpers.callsign_to_bytes(dxcallsign)
|
||||
dxcallsign = helpers.bytes_to_callsign(dxcallsign)
|
||||
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(['PING', dxcallsign])
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(["PING", dxcallsign])
|
||||
command_response("ping", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("ping", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# CONNECT ----------------------------------------------------------
|
||||
if received_json["type"] == 'arq' and received_json["command"] == "connect":
|
||||
if received_json["type"] == "arq" and received_json["command"] == "connect":
|
||||
static.BEACON_PAUSE = True
|
||||
# send ping frame and wait for ACK
|
||||
try:
|
||||
|
@ -267,24 +263,24 @@ def process_tnc_commands(data):
|
|||
static.DXCALLSIGN = dxcallsign
|
||||
static.DXCALLSIGN_CRC = helpers.get_crc_24(static.DXCALLSIGN)
|
||||
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(['CONNECT', dxcallsign])
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(["CONNECT", dxcallsign])
|
||||
command_response("connect", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("connect", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# DISCONNECT ----------------------------------------------------------
|
||||
if received_json["type"] == 'arq' and received_json["command"] == "disconnect":
|
||||
if received_json["type"] == "arq" and received_json["command"] == "disconnect":
|
||||
# send ping frame and wait for ACK
|
||||
try:
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(['DISCONNECT'])
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(["DISCONNECT"])
|
||||
command_response("disconnect", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("disconnect", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# TRANSMIT RAW DATA -------------------------------------------
|
||||
if received_json["type"] == 'arq' and received_json["command"] == "send_raw":
|
||||
if received_json["type"] == "arq" and received_json["command"] == "send_raw":
|
||||
static.BEACON_PAUSE = True
|
||||
try:
|
||||
if not static.ARQ_SESSION:
|
||||
|
@ -315,32 +311,32 @@ def process_tnc_commands(data):
|
|||
try:
|
||||
arq_uuid = received_json["uuid"]
|
||||
except Exception:
|
||||
arq_uuid = 'no-uuid'
|
||||
arq_uuid = "no-uuid"
|
||||
|
||||
if not len(base64data) % 4:
|
||||
binarydata = base64.b64decode(base64data)
|
||||
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(['ARQ_RAW', binarydata, mode, n_frames, arq_uuid, mycallsign])
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(["ARQ_RAW", binarydata, mode, n_frames, arq_uuid, mycallsign])
|
||||
else:
|
||||
raise TypeError
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("send_raw", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# STOP TRANSMISSION ----------------------------------------------------------
|
||||
if received_json["type"] == 'arq' and received_json["command"] == "stop_transmission":
|
||||
if received_json["type"] == "arq" and received_json["command"] == "stop_transmission":
|
||||
try:
|
||||
if static.TNC_STATE == 'BUSY' or static.ARQ_STATE:
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(['STOP'])
|
||||
if static.TNC_STATE == "BUSY" or static.ARQ_STATE:
|
||||
data_handler.DATA_QUEUE_TRANSMIT.put(["STOP"])
|
||||
structlog.get_logger("structlog").warning("[TNC] Stopping transmission!")
|
||||
static.TNC_STATE = 'IDLE'
|
||||
static.TNC_STATE = "IDLE"
|
||||
static.ARQ_STATE = False
|
||||
command_response("stop_transmission", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("stop_transmission", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
if received_json["type"] == 'get' and received_json["command"] == 'rx_buffer':
|
||||
if received_json["type"] == "get" and received_json["command"] == "rx_buffer":
|
||||
try:
|
||||
output = {
|
||||
"command": "rx_buffer",
|
||||
|
@ -352,36 +348,36 @@ def process_tnc_commands(data):
|
|||
# rawdata = json.loads(static.RX_BUFFER[i][4])
|
||||
base64_data = static.RX_BUFFER[i][4]
|
||||
output["data-array"].append({"uuid": static.RX_BUFFER[i][0], "timestamp": static.RX_BUFFER[i][1],
|
||||
"dxcallsign": str(static.RX_BUFFER[i][2], 'utf-8'),
|
||||
"dxgrid": str(static.RX_BUFFER[i][3], 'utf-8'), "data": base64_data})
|
||||
"dxcallsign": str(static.RX_BUFFER[i][2], "utf-8"),
|
||||
"dxgrid": str(static.RX_BUFFER[i][3], "utf-8"), "data": base64_data})
|
||||
|
||||
jsondata = json.dumps(output)
|
||||
# self.request.sendall(bytes(jsondata, encoding))
|
||||
SOCKET_QUEUE.put(jsondata)
|
||||
command_response("rx_buffer", True)
|
||||
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("rx_buffer", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
if received_json["type"] == 'set' and received_json["command"] == 'del_rx_buffer':
|
||||
if received_json["type"] == "set" and received_json["command"] == "del_rx_buffer":
|
||||
try:
|
||||
static.RX_BUFFER = []
|
||||
command_response("del_rx_buffer", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("del_rx_buffer", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
# exception, if JSON can't be decoded
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").error("[TNC] JSON decoding error", e=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").error("[TNC] JSON decoding error", e=err)
|
||||
|
||||
|
||||
def send_tnc_state():
|
||||
"""
|
||||
send the tnc state to network
|
||||
"""
|
||||
encoding = 'utf-8'
|
||||
encoding = "utf-8"
|
||||
|
||||
output = {
|
||||
"command": "tnc_state",
|
||||
|
@ -417,8 +413,8 @@ def send_tnc_state():
|
|||
# add heard stations to heard stations object
|
||||
for heard in static.HEARD_STATIONS:
|
||||
output["stations"].append({
|
||||
"dxcallsign": str(heard[0], 'utf-8'),
|
||||
"dxgrid": str(heard[1], 'utf-8'),
|
||||
"dxcallsign": str(heard[0], "utf-8"),
|
||||
"dxgrid": str(heard[1], "utf-8"),
|
||||
"timestamp": heard[2],
|
||||
"datatype": heard[3],
|
||||
"snr": heard[4],
|
||||
|
@ -441,40 +437,40 @@ def process_daemon_commands(data):
|
|||
# convert data to json object
|
||||
received_json = json.loads(data)
|
||||
structlog.get_logger("structlog").debug("[SCK] CMD", command=received_json)
|
||||
if received_json["type"] == 'set' and received_json["command"] == 'mycallsign':
|
||||
if received_json["type"] == "set" and received_json["command"] == "mycallsign":
|
||||
try:
|
||||
callsign = received_json["parameter"]
|
||||
|
||||
if bytes(callsign, 'utf-8') == b'':
|
||||
self.request.sendall(b'INVALID CALLSIGN')
|
||||
if bytes(callsign, "utf-8") == b"":
|
||||
self.request.sendall(b"INVALID CALLSIGN")
|
||||
structlog.get_logger("structlog").warning("[DMN] SET MYCALL FAILED", call=static.MYCALLSIGN,
|
||||
crc=static.MYCALLSIGN_CRC)
|
||||
else:
|
||||
static.MYCALLSIGN = bytes(callsign, 'utf-8')
|
||||
static.MYCALLSIGN = bytes(callsign, "utf-8")
|
||||
static.MYCALLSIGN_CRC = helpers.get_crc_24(static.MYCALLSIGN)
|
||||
|
||||
command_response("mycallsign", True)
|
||||
structlog.get_logger("structlog").info("[DMN] SET MYCALL", call=static.MYCALLSIGN,
|
||||
crc=static.MYCALLSIGN_CRC)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("mycallsign", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
if received_json["type"] == 'set' and received_json["command"] == 'mygrid':
|
||||
if received_json["type"] == "set" and received_json["command"] == "mygrid":
|
||||
try:
|
||||
mygrid = received_json["parameter"]
|
||||
|
||||
if bytes(mygrid, 'utf-8') == b'':
|
||||
self.request.sendall(b'INVALID GRID')
|
||||
if bytes(mygrid, "utf-8") == b"":
|
||||
self.request.sendall(b"INVALID GRID")
|
||||
else:
|
||||
static.MYGRID = bytes(mygrid, 'utf-8')
|
||||
static.MYGRID = bytes(mygrid, "utf-8")
|
||||
structlog.get_logger("structlog").info("[SCK] SET MYGRID", grid=static.MYGRID)
|
||||
command_response("mygrid", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("mygrid", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
if received_json["type"] == 'set' and received_json["command"] == 'start_tnc' and not static.TNCSTARTED:
|
||||
if received_json["type"] == "set" and received_json["command"] == "start_tnc" and not static.TNCSTARTED:
|
||||
try:
|
||||
mycall = str(received_json["parameter"][0]["mycall"])
|
||||
mygrid = str(received_json["parameter"][0]["mygrid"])
|
||||
|
@ -504,7 +500,7 @@ def process_daemon_commands(data):
|
|||
for item in received_json["parameter"][0]:
|
||||
structlog.get_logger("structlog").debug(f"[DMN] TNC Startup Config : {item}", value=received_json["parameter"][0][item])
|
||||
|
||||
DAEMON_QUEUE.put(['STARTTNC',
|
||||
DAEMON_QUEUE.put(["STARTTNC",
|
||||
mycall,
|
||||
mygrid,
|
||||
rx_audio,
|
||||
|
@ -531,11 +527,11 @@ def process_daemon_commands(data):
|
|||
])
|
||||
command_response("start_tnc", True)
|
||||
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("start_tnc", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
if received_json["type"] == 'get' and received_json["command"] == 'test_hamlib':
|
||||
if received_json["type"] == "get" and received_json["command"] == "test_hamlib":
|
||||
try:
|
||||
devicename = str(received_json["parameter"][0]["devicename"])
|
||||
deviceport = str(received_json["parameter"][0]["deviceport"])
|
||||
|
@ -549,7 +545,7 @@ def process_daemon_commands(data):
|
|||
rigctld_ip = str(received_json["parameter"][0]["rigctld_ip"])
|
||||
rigctld_port = str(received_json["parameter"][0]["rigctld_port"])
|
||||
|
||||
DAEMON_QUEUE.put(['TEST_HAMLIB',
|
||||
DAEMON_QUEUE.put(["TEST_HAMLIB",
|
||||
devicename,
|
||||
deviceport,
|
||||
serialspeed,
|
||||
|
@ -563,11 +559,11 @@ def process_daemon_commands(data):
|
|||
rigctld_port,
|
||||
])
|
||||
command_response("test_hamlib", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("test_hamlib", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
if received_json["type"] == 'set' and received_json["command"] == 'stop_tnc':
|
||||
if received_json["type"] == "set" and received_json["command"] == "stop_tnc":
|
||||
try:
|
||||
static.TNCPROCESS.kill()
|
||||
# unregister process from atexit to avoid process zombies
|
||||
|
@ -576,9 +572,9 @@ def process_daemon_commands(data):
|
|||
structlog.get_logger("structlog").warning("[DMN] Stopping TNC")
|
||||
static.TNCSTARTED = False
|
||||
command_response("stop_tnc", True)
|
||||
except Exception as e:
|
||||
except Exception as err:
|
||||
command_response("stop_tnc", False)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
|
||||
structlog.get_logger("structlog").warning("[SCK] command execution error", e=err, command=received_json)
|
||||
|
||||
|
||||
def send_daemon_state():
|
||||
|
@ -589,16 +585,16 @@ def send_daemon_state():
|
|||
python_version = f"{str(sys.version_info[0])}.{str(sys.version_info[1])}"
|
||||
|
||||
output = {
|
||||
'command': 'daemon_state',
|
||||
'daemon_state': [],
|
||||
'python_version': str(python_version),
|
||||
'hamlib_version': static.HAMLIB_VERSION,
|
||||
'input_devices': static.AUDIO_INPUT_DEVICES,
|
||||
'output_devices': static.AUDIO_OUTPUT_DEVICES,
|
||||
'serial_devices': static.SERIAL_DEVICES,
|
||||
# 'cpu': str(psutil.cpu_percent()),
|
||||
# 'ram': str(psutil.virtual_memory().percent),
|
||||
'version': '0.1'
|
||||
"command": "daemon_state",
|
||||
"daemon_state": [],
|
||||
"python_version": str(python_version),
|
||||
"hamlib_version": static.HAMLIB_VERSION,
|
||||
"input_devices": static.AUDIO_INPUT_DEVICES,
|
||||
"output_devices": static.AUDIO_OUTPUT_DEVICES,
|
||||
"serial_devices": static.SERIAL_DEVICES,
|
||||
# "cpu": str(psutil.cpu_percent()),
|
||||
# "ram": str(psutil.virtual_memory().percent),
|
||||
"version": "0.1"
|
||||
}
|
||||
|
||||
if static.TNCSTARTED:
|
||||
|
@ -608,8 +604,8 @@ def send_daemon_state():
|
|||
|
||||
return json.dumps(output)
|
||||
|
||||
except Exception as e:
|
||||
structlog.get_logger("structlog").warning("[SCK] error", e=e)
|
||||
except Exception as err:
|
||||
structlog.get_logger("structlog").warning("[SCK] error", e=err)
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ Here we are saving application wide variables and stats, which have to be access
|
|||
Not nice, suggestions are appreciated :-)
|
||||
"""
|
||||
|
||||
VERSION = '0.4.0-alpha'
|
||||
VERSION = "0.4.0-alpha"
|
||||
|
||||
# DAEMON
|
||||
DAEMONPORT = 3001
|
||||
|
@ -16,14 +16,14 @@ TNCSTARTED = False
|
|||
TNCPROCESS = 0
|
||||
|
||||
# Operator Defaults
|
||||
MYCALLSIGN = b'AA0AA'
|
||||
MYCALLSIGN_CRC = b'A'
|
||||
MYCALLSIGN = b"AA0AA"
|
||||
MYCALLSIGN_CRC = b"A"
|
||||
|
||||
DXCALLSIGN = b'AA0AA'
|
||||
DXCALLSIGN_CRC = b'A'
|
||||
DXCALLSIGN = b"AA0AA"
|
||||
DXCALLSIGN_CRC = b"A"
|
||||
|
||||
MYGRID = b''
|
||||
DXGRID = b''
|
||||
MYGRID = b""
|
||||
DXGRID = b""
|
||||
|
||||
SSID_LIST = [] # ssid list we are responding to
|
||||
|
||||
|
@ -41,21 +41,21 @@ SERIAL_DEVICES = []
|
|||
PTT_STATE = False
|
||||
TRANSMITTING = False
|
||||
|
||||
HAMLIB_VERSION = '0'
|
||||
HAMLIB_PTT_TYPE = 'RTS'
|
||||
HAMLIB_DEVICE_NAME = 'RIG_MODEL_DUMMY_NOVFO'
|
||||
HAMLIB_DEVICE_PORT = '/dev/ttyUSB0'
|
||||
HAMLIB_SERIAL_SPEED = '9600'
|
||||
HAMLIB_PTT_PORT = '/dev/ttyUSB0'
|
||||
HAMLIB_STOP_BITS = '1'
|
||||
HAMLIB_DATA_BITS = '8'
|
||||
HAMLIB_HANDSHAKE = 'None'
|
||||
HAMLIB_RADIOCONTROL = 'direct'
|
||||
HAMLIB_RIGCTLD_IP = '127.0.0.1'
|
||||
HAMLIB_RIGCTLD_PORT = '4532'
|
||||
HAMLIB_VERSION = "0"
|
||||
HAMLIB_PTT_TYPE = "RTS"
|
||||
HAMLIB_DEVICE_NAME = "RIG_MODEL_DUMMY_NOVFO"
|
||||
HAMLIB_DEVICE_PORT = "/dev/ttyUSB0"
|
||||
HAMLIB_SERIAL_SPEED = "9600"
|
||||
HAMLIB_PTT_PORT = "/dev/ttyUSB0"
|
||||
HAMLIB_STOP_BITS = "1"
|
||||
HAMLIB_DATA_BITS = "8"
|
||||
HAMLIB_HANDSHAKE = "None"
|
||||
HAMLIB_RADIOCONTROL = "direct"
|
||||
HAMLIB_RIGCTLD_IP = "127.0.0.1"
|
||||
HAMLIB_RIGCTLD_PORT = "4532"
|
||||
|
||||
HAMLIB_FREQUENCY = 0
|
||||
HAMLIB_MODE = ''
|
||||
HAMLIB_MODE = ""
|
||||
HAMLIB_BANDWITH = 0
|
||||
# -------------------------
|
||||
# FreeDV Defaults
|
||||
|
@ -95,10 +95,10 @@ ARQ_SPEED_LEVEL = 0
|
|||
TOTAL_BYTES = 0
|
||||
|
||||
# CHANNEL_STATE = 'RECEIVING_SIGNALLING'
|
||||
TNC_STATE = 'IDLE'
|
||||
TNC_STATE = "IDLE"
|
||||
ARQ_STATE = False
|
||||
ARQ_SESSION = False
|
||||
ARQ_SESSION_STATE = 'disconnected' # disconnected, connecting, connected, disconnecting, failed
|
||||
ARQ_SESSION_STATE = "disconnected" # disconnected, connecting, connected, disconnecting, failed
|
||||
|
||||
# BEACON STATE
|
||||
BEACON_STATE = False
|
||||
|
@ -108,7 +108,7 @@ BEACON_PAUSE = False
|
|||
RX_BUFFER = []
|
||||
RX_MSG_BUFFER = []
|
||||
RX_BURST_BUFFER = []
|
||||
RX_FRAME_BUFFER = b''
|
||||
RX_FRAME_BUFFER = b""
|
||||
# RX_BUFFER_SIZE = 0
|
||||
|
||||
# ------- HEARD STATIONS BUFFER
|
||||
|
|
Loading…
Reference in a new issue