2020-12-26 10:02:14 +00:00
|
|
|
#!/usr/bin/python3
|
2020-12-23 16:48:22 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
Created on Tue Dec 22 16:58:45 2020
|
|
|
|
|
|
|
|
@author: DJ2LS
|
|
|
|
|
2022-03-04 15:50:32 +00:00
|
|
|
main module for running the tnc
|
2020-12-23 16:48:22 +00:00
|
|
|
"""
|
2020-12-23 17:25:50 +00:00
|
|
|
import argparse
|
2022-05-11 22:10:59 +00:00
|
|
|
import multiprocessing
|
|
|
|
import os
|
|
|
|
import signal
|
2022-01-06 21:15:14 +00:00
|
|
|
import socketserver
|
2022-05-11 22:10:59 +00:00
|
|
|
import sys
|
|
|
|
import threading
|
|
|
|
import time
|
|
|
|
|
|
|
|
import data_handler
|
|
|
|
import helpers
|
2022-04-11 09:10:32 +00:00
|
|
|
import log_handler
|
|
|
|
import modem
|
2022-05-11 22:10:59 +00:00
|
|
|
import static
|
2022-05-26 01:23:30 +00:00
|
|
|
import structlog
|
|
|
|
|
2022-06-01 00:35:35 +00:00
|
|
|
log = structlog.get_logger("main")
|
2021-11-18 18:40:22 +00:00
|
|
|
|
2022-05-30 17:47:51 +00:00
|
|
|
|
2022-02-16 08:11:32 +00:00
|
|
|
def signal_handler(sig, frame):
|
2022-03-04 15:50:32 +00:00
|
|
|
"""
|
|
|
|
a signal handler, which closes the network/socket when closing the application
|
|
|
|
Args:
|
|
|
|
sig: signal
|
2022-05-09 00:41:49 +00:00
|
|
|
frame:
|
2022-03-04 15:50:32 +00:00
|
|
|
|
|
|
|
Returns: system exit
|
|
|
|
|
|
|
|
"""
|
2022-05-26 01:23:30 +00:00
|
|
|
print("Closing TNC...")
|
2022-02-16 08:11:32 +00:00
|
|
|
sock.CLOSE_SIGNAL = True
|
|
|
|
sys.exit(0)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
|
2022-02-16 08:11:32 +00:00
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
if __name__ == "__main__":
|
2022-05-28 15:52:05 +00:00
|
|
|
# This is for Windows multiprocessing support
|
2022-02-17 19:45:20 +00:00
|
|
|
multiprocessing.freeze_support()
|
2021-03-12 13:14:36 +00:00
|
|
|
# --------------------------------------------GET PARAMETER INPUTS
|
2022-05-26 01:23:30 +00:00
|
|
|
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",
|
2022-05-30 20:40:58 +00:00
|
|
|
dest="low_bandwidth_mode",
|
2022-05-26 01:23:30 +00:00
|
|
|
action="store_true",
|
2022-05-30 20:40:58 +00:00
|
|
|
help="Enable low bandwidth mode ( 500 Hz only )",
|
2022-05-26 01:23:30 +00:00
|
|
|
)
|
|
|
|
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,
|
|
|
|
)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2021-03-11 17:03:48 +00:00
|
|
|
ARGS = PARSER.parse_args()
|
2022-01-05 13:15:59 +00:00
|
|
|
|
2022-05-28 12:31:58 +00:00
|
|
|
# additional step for being sure our callsign is correctly
|
2022-02-24 21:04:38 +00:00
|
|
|
# in case we are not getting a station ssid
|
|
|
|
# then we are forcing a station ssid = 0
|
2022-05-26 01:23:30 +00:00
|
|
|
mycallsign = bytes(ARGS.mycall.upper(), "utf-8")
|
2022-02-24 21:04:38 +00:00
|
|
|
mycallsign = helpers.callsign_to_bytes(mycallsign)
|
|
|
|
static.MYCALLSIGN = helpers.bytes_to_callsign(mycallsign)
|
2022-05-09 00:41:49 +00:00
|
|
|
static.MYCALLSIGN_CRC = helpers.get_crc_24(static.MYCALLSIGN)
|
|
|
|
|
2022-03-19 11:42:10 +00:00
|
|
|
static.SSID_LIST = ARGS.ssid_list
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
static.MYGRID = bytes(ARGS.mygrid, "utf-8")
|
2021-03-11 17:03:48 +00:00
|
|
|
static.AUDIO_INPUT_DEVICE = ARGS.audio_input_device
|
|
|
|
static.AUDIO_OUTPUT_DEVICE = ARGS.audio_output_device
|
|
|
|
static.PORT = ARGS.socket_port
|
2021-12-26 08:20:58 +00:00
|
|
|
static.HAMLIB_DEVICE_NAME = ARGS.hamlib_device_name
|
2021-05-09 09:36:08 +00:00
|
|
|
static.HAMLIB_DEVICE_PORT = ARGS.hamlib_device_port
|
2021-07-10 21:27:33 +00:00
|
|
|
static.HAMLIB_PTT_TYPE = ARGS.hamlib_ptt_type
|
2021-12-26 14:25:35 +00:00
|
|
|
static.HAMLIB_PTT_PORT = ARGS.hamlib_ptt_port
|
2022-02-15 17:10:14 +00:00
|
|
|
static.HAMLIB_SERIAL_SPEED = str(ARGS.hamlib_serialspeed)
|
|
|
|
static.HAMLIB_DATA_BITS = str(ARGS.hamlib_data_bits)
|
|
|
|
static.HAMLIB_STOP_BITS = str(ARGS.hamlib_stop_bits)
|
2021-12-28 16:05:48 +00:00
|
|
|
static.HAMLIB_HANDSHAKE = ARGS.hamlib_handshake
|
2022-01-18 18:38:05 +00:00
|
|
|
static.HAMLIB_RADIOCONTROL = ARGS.hamlib_radiocontrol
|
2022-05-11 22:10:59 +00:00
|
|
|
static.HAMLIB_RIGCTLD_IP = ARGS.rigctld_ip
|
|
|
|
static.HAMLIB_RIGCTLD_PORT = str(ARGS.rigctld_port)
|
2022-02-02 20:12:16 +00:00
|
|
|
static.ENABLE_SCATTER = ARGS.send_scatter
|
2022-03-31 10:45:44 +00:00
|
|
|
static.ENABLE_FFT = ARGS.send_fft
|
2022-05-09 00:41:49 +00:00
|
|
|
static.ENABLE_FSK = ARGS.enable_fsk
|
2022-05-28 12:08:33 +00:00
|
|
|
static.LOW_BANDWIDTH_MODE = ARGS.low_bandwidth_mode
|
2022-05-09 00:41:49 +00:00
|
|
|
static.TUNING_RANGE_FMIN = ARGS.tuning_range_fmin
|
|
|
|
static.TUNING_RANGE_FMAX = ARGS.tuning_range_fmax
|
|
|
|
static.TX_AUDIO_LEVEL = ARGS.tx_audio_level
|
|
|
|
static.RESPOND_TO_CQ = ARGS.enable_respond_to_cq
|
|
|
|
|
2021-05-13 15:11:26 +00:00
|
|
|
# we need to wait until we got all parameters from argparse first before we can load the other modules
|
2022-05-09 00:41:49 +00:00
|
|
|
import sock
|
|
|
|
|
|
|
|
# config logging
|
|
|
|
try:
|
2022-05-26 01:23:30 +00:00
|
|
|
if sys.platform == "linux":
|
|
|
|
logging_path = os.getenv("HOME") + "/.config/" + "FreeDATA/" + "tnc"
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
if sys.platform == "darwin":
|
|
|
|
logging_path = (
|
|
|
|
os.getenv("HOME")
|
|
|
|
+ "/Library/"
|
|
|
|
+ "Application Support/"
|
|
|
|
+ "FreeDATA/"
|
|
|
|
+ "tnc"
|
|
|
|
)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
if sys.platform in ["win32", "win64"]:
|
|
|
|
logging_path = os.getenv("APPDATA") + "/" + "FreeDATA/" + "tnc"
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-02-21 16:58:44 +00:00
|
|
|
if not os.path.exists(logging_path):
|
|
|
|
os.makedirs(logging_path)
|
|
|
|
log_handler.setup_logging(logging_path)
|
2022-05-26 01:23:30 +00:00
|
|
|
except Exception as err:
|
|
|
|
log.error("[DMN] logger init error", exception=err)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
log.info(
|
|
|
|
"[TNC] Starting FreeDATA", author="DJ2LS", year="2022", version=static.VERSION
|
|
|
|
)
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-01-07 10:25:28 +00:00
|
|
|
# start data handler
|
|
|
|
data_handler.DATA()
|
2022-05-09 00:41:49 +00:00
|
|
|
|
2022-01-07 10:25:28 +00:00
|
|
|
# start modem
|
|
|
|
modem = modem.RF()
|
|
|
|
|
2021-03-12 13:14:36 +00:00
|
|
|
# --------------------------------------------START CMD SERVER
|
2022-01-06 21:15:14 +00:00
|
|
|
try:
|
2022-05-26 01:23:30 +00:00
|
|
|
log.info("[TNC] Starting TCP/IP socket", port=static.PORT)
|
2022-01-06 21:15:14 +00:00
|
|
|
# https://stackoverflow.com/a/16641793
|
|
|
|
socketserver.TCPServer.allow_reuse_address = True
|
2022-05-26 01:23:30 +00:00
|
|
|
cmdserver = sock.ThreadedTCPServer(
|
|
|
|
(static.HOST, static.PORT), sock.ThreadedTCPRequestHandler
|
|
|
|
)
|
2022-01-06 21:15:14 +00:00
|
|
|
server_thread = threading.Thread(target=cmdserver.serve_forever)
|
2022-02-16 08:11:32 +00:00
|
|
|
|
2022-01-06 21:15:14 +00:00
|
|
|
server_thread.daemon = True
|
|
|
|
server_thread.start()
|
|
|
|
|
2022-05-26 01:23:30 +00:00
|
|
|
except Exception as err:
|
|
|
|
log.error("[TNC] Starting TCP/IP socket failed", port=static.PORT, e=err)
|
2022-05-11 22:10:59 +00:00
|
|
|
sys.exit(1)
|
2022-05-28 02:17:15 +00:00
|
|
|
while True:
|
2022-02-17 13:25:22 +00:00
|
|
|
time.sleep(1)
|