Prefer double- over single-quote.

Other minor fixes.
This commit is contained in:
Paul Kronenwetter 2022-05-25 18:27:33 -04:00
parent e05bc262ad
commit 08202bbaec
14 changed files with 565 additions and 563 deletions

View file

@ -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})

View file

@ -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

View file

@ -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()

View file

@ -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()

View file

@ -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()

View file

@ -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,

View file

@ -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)

View file

@ -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)

View file

@ -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):

View file

@ -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:

View file

@ -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:

View file

@ -7,6 +7,7 @@ hamlib_version = 0
class radio:
""" """
def __init__(self):
pass

View file

@ -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

View file

@ -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