better pep8 conformity

This commit is contained in:
DJ2LS 2021-09-25 15:24:25 +02:00
parent 21eb8fa12b
commit 5c7e05ef70
4 changed files with 531 additions and 472 deletions

View file

@ -7,37 +7,38 @@ Created on Tue Dec 22 16:58:45 2020
"""
import argparse
import threading
import socketserver
import pyaudio
import time
import ujson as json
import subprocess
import os
import static
import psutil
import sys
import subprocess
import ujson as json
import psutil
import serial.tools.list_ports
import pyaudio
import static
def start_daemon():
try:
print("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(PORT))
socketserver.TCPServer.allow_reuse_address = True # https://stackoverflow.com/a/16641793
daemon = socketserver.TCPServer(('0.0.0.0', PORT), CMDTCPRequestHandler)
# https://stackoverflow.com/a/16641793
socketserver.TCPServer.allow_reuse_address = True
daemon = socketserver.TCPServer(
('0.0.0.0', PORT), CMDTCPRequestHandler)
daemon.serve_forever()
finally:
daemon.server_close()
class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
print("Client connected...")
print("Client connected...")
# loop through socket buffer until timeout is reached. then close buffer
socketTimeout = time.time() + 3
while socketTimeout > time.time():
@ -47,23 +48,23 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
#data = str(self.request.recv(1024), 'utf-8')
data = bytes()
# we need to loop through buffer until end of chunk is reached or timeout occured
while True and socketTimeout > time.time():
chunk = self.request.recv(45)
data += chunk
if chunk.endswith(b'}\n') or chunk.endswith(b'}'): # or chunk.endswith(b'\n'):
# or chunk.endswith(b'\n'):
if chunk.endswith(b'}\n') or chunk.endswith(b'}'):
break
data = data[:-1] # remove b'\n'
data = str(data, 'utf-8')
if len(data) > 0:
socketTimeout = time.time() + 3
# convert data to json object
# we need to do some error handling in case of socket timeout
try:
# only read first line of string. multiple lines will cause an json error
# this occurs possibly, if we are getting data too fast
@ -72,41 +73,44 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
# GET COMMANDS
# "command" : "..."
# SET COMMANDS
# "command" : "..."
# "parameter" : " ..."
# DATA COMMANDS
# "command" : "..."
# "type" : "..."
# "dxcallsign" : "..."
# "data" : "..."
# print(received_json)
#print(received_json["type"])
#print(received_json["command"])
#try:
# print(received_json["type"])
# print(received_json["command"])
# try:
if received_json["type"] == 'SET' and received_json["command"] == 'STARTTNC' and not static.TNCSTARTED:
rx_audio = str(received_json["parameter"][0]["rx_audio"])
tx_audio = str(received_json["parameter"][0]["tx_audio"])
deviceid = str(received_json["parameter"][0]["deviceid"])
deviceport = str(received_json["parameter"][0]["deviceport"])
serialspeed = str(received_json["parameter"][0]["serialspeed"])
pttprotocol = str(received_json["parameter"][0]["pttprotocol"])
deviceport = str(
received_json["parameter"][0]["deviceport"])
serialspeed = str(
received_json["parameter"][0]["serialspeed"])
pttprotocol = str(
received_json["parameter"][0]["pttprotocol"])
pttport = str(received_json["parameter"][0]["pttport"])
print("---- STARTING TNC !")
print(received_json["parameter"][0])
#command = "--rx "+ rx_audio +" \
# command = "--rx "+ rx_audio +" \
# --tx "+ tx_audio +" \
# --deviceport "+ deviceport +" \
# --deviceid "+ deviceid + " \
# --serialspeed "+ serialspeed + " \
# --pttprotocol "+ pttprotocol + " \
# --pttport "+ pttport
# list of parameters, necessary for running subprocess command as a list
options = []
options.append('--rx')
@ -123,7 +127,7 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
options.append(pttprotocol)
options.append('--pttport')
options.append(pttport)
# try running tnc from binary, else run from source
# this helps running the tnc in a developer environment
try:
@ -141,20 +145,20 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
command += options
p = subprocess.Popen(command)
print("running TNC from source...")
static.TNCPROCESS = p#.pid
static.TNCPROCESS = p # .pid
static.TNCSTARTED = True
if received_json["type"] == 'SET' and received_json["command"] == 'STOPTNC':
parameter = received_json["parameter"]
static.TNCPROCESS.kill()
print("KILLING PROCESS ------------")
#os.kill(static.TNCPROCESS, signal.SIGKILL)
static.TNCSTARTED = False
if received_json["type"] == 'GET' and received_json["command"] == 'DAEMON_STATE':
data = {'COMMAND' : 'DAEMON_STATE', 'DAEMON_STATE' : [], 'INPUT_DEVICES': [], 'OUTPUT_DEVICES': [], 'SERIAL_DEVICES': [], "CPU": str(psutil.cpu_percent()),"RAM": str(psutil.virtual_memory().percent), "VERSION": "0.1-prototype"}
data = {'COMMAND': 'DAEMON_STATE', 'DAEMON_STATE': [], 'INPUT_DEVICES': [], 'OUTPUT_DEVICES': [], 'SERIAL_DEVICES': [
], "CPU": str(psutil.cpu_percent()), "RAM": str(psutil.virtual_memory().percent), "VERSION": "0.1-prototype"}
if static.TNCSTARTED:
data["DAEMON_STATE"].append({"STATUS": "running"})
@ -164,36 +168,40 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
# UPDATE LIST OF AUDIO DEVICES
p = pyaudio.PyAudio()
for i in range(0, p.get_device_count()):
maxInputChannels = p.get_device_info_by_host_api_device_index(0,i).get('maxInputChannels')
maxOutputChannels = p.get_device_info_by_host_api_device_index(0,i).get('maxOutputChannels')
name = p.get_device_info_by_host_api_device_index(0,i).get('name')
if maxInputChannels > 0:
data["INPUT_DEVICES"].append({"ID": i, "NAME" : str(name)})
if maxOutputChannels > 0:
data["OUTPUT_DEVICES"].append({"ID": i, "NAME" : str(name)})
maxInputChannels = p.get_device_info_by_host_api_device_index(
0, i).get('maxInputChannels')
maxOutputChannels = p.get_device_info_by_host_api_device_index(
0, i).get('maxOutputChannels')
name = p.get_device_info_by_host_api_device_index(
0, i).get('name')
if maxInputChannels > 0:
data["INPUT_DEVICES"].append(
{"ID": i, "NAME": str(name)})
if maxOutputChannels > 0:
data["OUTPUT_DEVICES"].append(
{"ID": i, "NAME": str(name)})
# UPDATE LIST OF SERIAL DEVICES
ports = serial.tools.list_ports.comports()
for port, desc, hwid in ports:
data["SERIAL_DEVICES"].append({"PORT": str(port), "DESCRIPTION" : str(desc)})
data["SERIAL_DEVICES"].append(
{"PORT": str(port), "DESCRIPTION": str(desc)})
#print(data)
# print(data)
jsondata = json.dumps(data)
self.request.sendall(bytes(jsondata, encoding))
#exception, if JSON cant be decoded
#except Exception as e:
# exception, if JSON cant be decoded
# except Exception as e:
except ValueError as e:
print("############ START OF ERROR #####################")
print('DAEMON PROGRAM ERROR: %s' %str(e))
print('DAEMON PROGRAM ERROR: %s' % str(e))
print("Wrong command")
print(data)
print(e)
exc_type, exc_obj, exc_tb = sys.exc_info()
exc_type, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print(exc_type, fname, exc_tb.tb_lineno)
print("############ END OF ERROR #######################")
@ -203,13 +211,11 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
if __name__ == '__main__':
# --------------------------------------------GET PARAMETER INPUTS
PARSER = argparse.ArgumentParser(description='Simons TEST TNC')
PARSER.add_argument('--port', dest="socket_port", default=3001, help="Socket port", type=int)
PARSER.add_argument('--port', dest="socket_port",
default=3001, help="Socket port", type=int)
ARGS = PARSER.parse_args()
PORT = ARGS.socket_port
@ -217,9 +223,3 @@ if __name__ == '__main__':
DAEMON_THREAD = threading.Thread(target=start_daemon, name="daemon")
DAEMON_THREAD.start()

View file

@ -15,13 +15,13 @@ import crcengine
import static
import data_handler
def wait(seconds):
timeout = time.time() + seconds
while time.time() < timeout:
time.sleep(0.01)
def get_crc_8(data):
"""
@ -50,30 +50,34 @@ def get_crc_16(data):
crc_data = crc_data.to_bytes(2, byteorder='big')
return crc_data
def watchdog():
"""
Author: DJ2LS
watchdog master function. Frome here we call the watchdogs
"""
while True:
time.sleep(0.01)
data_channel_keep_alive_watchdog()
def data_channel_keep_alive_watchdog():
"""
Author: DJ2LS
"""
if static.ARQ_STATE == 'DATA' and static.TNC_STATE == 'BUSY': # and not static.ARQ_SEND_KEEP_ALIVE:
# and not static.ARQ_SEND_KEEP_ALIVE:
if static.ARQ_STATE == 'DATA' and static.TNC_STATE == 'BUSY':
time.sleep(0.01)
if static.ARQ_DATA_CHANNEL_LAST_RECEIVED + 30 > time.time():
pass
else:
static.ARQ_DATA_CHANNEL_LAST_RECEIVED = 0
logging.info("DATA [" + str(static.MYCALLSIGN, 'utf-8') + "]<<T>>[" + str(static.DXCALLSIGN, 'utf-8') + "] [BER." + str(static.BER) + "]")
logging.info("DATA [" + str(static.MYCALLSIGN, 'utf-8') + "]<<T>>[" + str(
static.DXCALLSIGN, 'utf-8') + "] [BER." + str(static.BER) + "]")
arq_reset_frame_machine()
@ -116,128 +120,141 @@ def arq_reset_frame_machine():
static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME = 0
static.ARQ_FRAME_BOF_RECEIVED = False
static.ARQ_FRAME_EOF_RECEIVED = False
static.ARQ_RX_BURST_BUFFER = []
static.ARQ_RX_FRAME_BUFFER = []
static.TNC_STATE = 'IDLE'
static.ARQ_STATE = 'IDLE'
###static.ARQ_CONNECTION_KEEP_ALIVE_RECEIVED = int(time.time()) # we need to reset the counter at this point
# static.ARQ_CONNECTION_KEEP_ALIVE_RECEIVED = int(time.time()) # we need to reset the counter at this point
###static.ARQ_SEND_KEEP_ALIVE = True
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
static.ARQ_READY_FOR_DATA = False
static.ARQ_START_OF_TRANSMISSION = 0
def calculate_transfer_rate():
if static.ARQ_START_OF_TRANSMISSION > 0:
static.TOTAL_TRANSMISSION_TIME = time.time() - static.ARQ_START_OF_TRANSMISSION
print("ARQ_N_ARQ_FRAMES_PER_DATA_FRAME " + str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME))
print("ARQ_RX_N_CURRENT_ARQ_FRAME " + str(static.ARQ_RX_N_CURRENT_ARQ_FRAME))
print("ARQ_N_ARQ_FRAMES_PER_DATA_FRAME " +
str(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME))
print("ARQ_RX_N_CURRENT_ARQ_FRAME " +
str(static.ARQ_RX_N_CURRENT_ARQ_FRAME))
arq_n_arq_frames_per_data_frame = static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME
arq_rx_n_current_arq_frame = static.ARQ_RX_N_CURRENT_ARQ_FRAME
if static.TX_BUFFER_SIZE == 0:
total_n_frames = arq_n_arq_frames_per_data_frame
elif arq_n_arq_frames_per_data_frame == 0:
total_n_frames = static.TX_BUFFER_SIZE
else:
total_n_frames = 0
if static.TOTAL_TRANSMISSION_TIME > 0:
#total_transmission_time = time.time() - static.ARQ_START_OF_TRANSMISSION
total_transmission_time = static.TOTAL_TRANSMISSION_TIME
print("total_transmission_time: " + str(total_transmission_time))
total_transmission_time = static.TOTAL_TRANSMISSION_TIME
print("total_transmission_time: " + str(total_transmission_time))
print("static.TOTAL_BYTES: " + str(static.TOTAL_BYTES))
static.ARQ_BITS_PER_SECOND = int(
(static.TOTAL_BYTES * 8) / total_transmission_time)
static.ARQ_BYTES_PER_MINUTE = int(
((static.TOTAL_BYTES) / total_transmission_time) * 60)
static.ARQ_BITS_PER_SECOND = int((static.TOTAL_BYTES * 8) / total_transmission_time)
static.ARQ_BYTES_PER_MINUTE = int(((static.TOTAL_BYTES) / total_transmission_time) * 60)
burst_bytes = static.ARQ_PAYLOAD_PER_FRAME * static.ARQ_N_RX_FRAMES_PER_BURSTS
burst_transmission_time = time.time() - static.ARQ_START_OF_BURST
print("BURST TRANSMISSION TIME: " + str(burst_transmission_time))
static.ARQ_BITS_PER_SECOND_BURST = int((burst_bytes * 8) / burst_transmission_time)
static.ARQ_BYTES_PER_MINUTE_BURST = int(((burst_bytes) / burst_transmission_time) * 60)
print("static.ARQ_BITS_PER_SECOND_BURST: " + str(static.ARQ_BITS_PER_SECOND_BURST))
print("static.ARQ_BYTES_PER_MINUTE_BURST: " + str(static.ARQ_BYTES_PER_MINUTE_BURST))
static.ARQ_BITS_PER_SECOND_BURST = int(
(burst_bytes * 8) / burst_transmission_time)
static.ARQ_BYTES_PER_MINUTE_BURST = int(
((burst_bytes) / burst_transmission_time) * 60)
print("static.ARQ_BITS_PER_SECOND_BURST: " +
str(static.ARQ_BITS_PER_SECOND_BURST))
print("static.ARQ_BYTES_PER_MINUTE_BURST: " +
str(static.ARQ_BYTES_PER_MINUTE_BURST))
# PERCENTAGE FOR TRANSMITTING
if static.TX_BUFFER_SIZE > 0:
print("static.ARQ_N_SENT_FRAMES: " + str(static.ARQ_N_SENT_FRAMES))
static.ARQ_TRANSMISSION_PERCENT = int((static.ARQ_N_SENT_FRAMES / static.TX_BUFFER_SIZE) * 100)
static.ARQ_TRANSMISSION_PERCENT = int(
(static.ARQ_N_SENT_FRAMES / static.TX_BUFFER_SIZE) * 100)
# PERCENTAGE FOR RECEIVING
elif arq_n_arq_frames_per_data_frame > 0:
static.ARQ_TRANSMISSION_PERCENT = int((static.ARQ_RX_N_CURRENT_ARQ_FRAME / static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME) * 100)
static.ARQ_TRANSMISSION_PERCENT = int(
(static.ARQ_RX_N_CURRENT_ARQ_FRAME / static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME) * 100)
else:
static.ARQ_TRANSMISSION_PERCENT = 0.0
print("static.ARQ_TRANSMISSION_PERCENT: " + str(static.ARQ_TRANSMISSION_PERCENT))
static.ARQ_TRANSMISSION_PERCENT = 0.0
print("static.ARQ_TRANSMISSION_PERCENT: " +
str(static.ARQ_TRANSMISSION_PERCENT))
print("static.ARQ_BYTES_PER_MINUTE: " + str(static.ARQ_BYTES_PER_MINUTE))
print("static.ARQ_BITS_PER_SECOND: " + str(static.ARQ_BITS_PER_SECOND))
return [static.ARQ_BITS_PER_SECOND, static.ARQ_BYTES_PER_MINUTE, static.ARQ_BITS_PER_SECOND_BURST, static.ARQ_BYTES_PER_MINUTE_BURST]
def add_to_heard_stations(dxcallsign,dxgrid, datatype, snr):
def add_to_heard_stations(dxcallsign, dxgrid, datatype, snr):
# check if buffer empty
if len(static.HEARD_STATIONS) == 0:
static.HEARD_STATIONS.append([dxcallsign,dxgrid, int(time.time()), datatype, snr])
static.HEARD_STATIONS.append(
[dxcallsign, dxgrid, int(time.time()), datatype, snr])
# if not, we search and update
else:
for i in range(0, len(static.HEARD_STATIONS)):
# update callsign with new timestamp
if static.HEARD_STATIONS[i].count(dxcallsign) > 0:
static.HEARD_STATIONS[i] = [dxcallsign,dxgrid, int(time.time()), datatype, snr]
static.HEARD_STATIONS[i] = [dxcallsign,
dxgrid, int(time.time()), datatype, snr]
break
# insert if nothing found
if i == len(static.HEARD_STATIONS) - 1:
static.HEARD_STATIONS.append([dxcallsign,dxgrid, int(time.time()), datatype, snr])
static.HEARD_STATIONS.append(
[dxcallsign, dxgrid, int(time.time()), datatype, snr])
break
# for idx, item in enumerate(static.HEARD_STATIONS):
# if dxcallsign in item:
# item = [dxcallsign, int(time.time())]
# static.HEARD_STATIONS[idx] = item
# static.HEARD_STATIONS[idx] = item
def setup_logging():
"""
Author: DJ2LS
Set the custom logging format so we can use colors
# https://stackoverflow.com/questions/384076/how-can-i-color-python-logging-output
# 'DEBUG' : 37, # white
# 'INFO' : 36, # cyan
# 'WARNING' : 33, # yellow
# 'ERROR' : 31, # red
# 'CRITICAL': 41, # white on red bg
"""
logging.basicConfig(level=logging.INFO, \
encoding='utf-8', \
format='%(asctime)s.%(msecs)03d %(levelname)s:\t%(message)s', \
datefmt='%H:%M:%S', \
handlers=[logging.FileHandler("codec2-FreeDATA-TNC.log"),logging.StreamHandler()]
)
logging.basicConfig(level=logging.INFO,
encoding='utf-8',
format='%(asctime)s.%(msecs)03d %(levelname)s:\t%(message)s',
datefmt='%H:%M:%S',
handlers=[logging.FileHandler(
"codec2-FreeDATA-TNC.log"), logging.StreamHandler()]
)
logging.addLevelName(logging.DEBUG, "\033[1;36m%s\033[1;0m" % logging.getLevelName(logging.DEBUG))
logging.addLevelName(logging.INFO, "\033[1;37m%s\033[1;0m" % logging.getLevelName(logging.INFO))
logging.addLevelName(logging.WARNING, "\033[1;33m%s\033[1;0m" % logging.getLevelName(logging.WARNING))
logging.addLevelName(
logging.DEBUG, "\033[1;36m%s\033[1;0m" % logging.getLevelName(logging.DEBUG))
logging.addLevelName(
logging.INFO, "\033[1;37m%s\033[1;0m" % logging.getLevelName(logging.INFO))
logging.addLevelName(
logging.WARNING, "\033[1;33m%s\033[1;0m" % logging.getLevelName(logging.WARNING))
logging.addLevelName(logging.ERROR, "\033[1;31m%s\033[1;0m" % "FAILED")
#logging.addLevelName( logging.ERROR, "\033[1;31m%s\033[1;0m" % logging.getLevelName(logging.ERROR))
logging.addLevelName(logging.CRITICAL, "\033[1;41m%s\033[1;0m" % logging.getLevelName(logging.CRITICAL))
logging.addLevelName(
logging.CRITICAL, "\033[1;41m%s\033[1;0m" % logging.getLevelName(logging.CRITICAL))
logging.addLevelName(25, "\033[1;32m%s\033[1;0m" % "SUCCESS")
logging.addLevelName(24, "\033[1;34m%s\033[1;0m" % "DATA")

View file

@ -5,25 +5,24 @@ Created on Wed Dec 23 07:04:24 2020
@author: DJ2LS
"""
import sys
import ctypes
from ctypes import *
import pathlib
import pyaudio
import audioop
import asyncio
#import sys
#import asyncio
import logging
import time
import threading
import atexit
import numpy as np
import pyaudio
import helpers
import static
import data_handler
import sys
#sys.path.append("hamlib/linux")
# sys.path.append("hamlib/linux")
try:
import Hamlib
print("running Hamlib from Sys Path")
@ -34,7 +33,7 @@ else:
# place for rigctld
pass
import numpy as np
#import rigctld
#rigctld = rigctld.Rigctld()
@ -42,27 +41,28 @@ import numpy as np
MODEM_STATS_NR_MAX = 320
MODEM_STATS_NC_MAX = 51
class MODEMSTATS(ctypes.Structure):
_fields_ = [
("Nc", ctypes.c_int),
("snr_est", ctypes.c_float),
("rx_symbols", (ctypes.c_float * MODEM_STATS_NR_MAX)*MODEM_STATS_NC_MAX),
("nr", ctypes.c_int),
("sync", ctypes.c_int),
("foff", ctypes.c_float),
("rx_timing", ctypes.c_float),
("clock_offset", ctypes.c_float),
("sync_metric", ctypes.c_float),
("pre", ctypes.c_int),
("post", ctypes.c_int),
("uw_fails", ctypes.c_int),
]
_fields_ = [
("Nc", ctypes.c_int),
("snr_est", ctypes.c_float),
("rx_symbols", (ctypes.c_float * MODEM_STATS_NR_MAX)*MODEM_STATS_NC_MAX),
("nr", ctypes.c_int),
("sync", ctypes.c_int),
("foff", ctypes.c_float),
("rx_timing", ctypes.c_float),
("clock_offset", ctypes.c_float),
("sync_metric", ctypes.c_float),
("pre", ctypes.c_int),
("post", ctypes.c_int),
("uw_fails", ctypes.c_int),
]
class RF():
def __init__(self):
def __init__(self):
# -------------------------------------------- LOAD FREEDV
try:
# we check at first for libcodec2 in root - necessary if we want to run it inside a pyinstaller binary
@ -99,20 +99,23 @@ class RF():
self.audio_writing_to_stream = False
# --------------------------------------------START DECODER THREAD
DECODER_THREAD = threading.Thread(target=self.receive, name="DECODER_THREAD")
DECODER_THREAD = threading.Thread(
target=self.receive, name="DECODER_THREAD")
DECODER_THREAD.start()
PLAYBACK_THREAD = threading.Thread(target=self.play_audio, name="PLAYBACK_THREAD")
PLAYBACK_THREAD = threading.Thread(
target=self.play_audio, name="PLAYBACK_THREAD")
PLAYBACK_THREAD.start()
self.fft_data = bytes()
FFT_THREAD = threading.Thread(target=self.calculate_fft, name="FFT_THREAD")
FFT_THREAD = threading.Thread(
target=self.calculate_fft, name="FFT_THREAD")
FFT_THREAD.start()
# --------------------------------------------CONFIGURE HAMLIB
#my_rig.set_ptt(Hamlib.RIG_PTT_RIG,0)
#my_rig.set_ptt(Hamlib.RIG_PTT_SERIAL_DTR,0)
#my_rig.set_ptt(Hamlib.RIG_PTT_SERIAL_RTS,1)
# my_rig.set_ptt(Hamlib.RIG_PTT_RIG,0)
# my_rig.set_ptt(Hamlib.RIG_PTT_SERIAL_DTR,0)
# my_rig.set_ptt(Hamlib.RIG_PTT_SERIAL_RTS,1)
#self.my_rig.set_conf("dtr_state", "OFF")
#my_rig.set_conf("rts_state", "OFF")
#self.my_rig.set_conf("ptt_type", "RTS")
@ -128,221 +131,241 @@ class RF():
self.my_rig.set_conf("serial_handshake", "None")
self.my_rig.set_conf("stop_bits", "1")
self.my_rig.set_conf("data_bits", "8")
if static.HAMLIB_PTT_TYPE == 'RIG':
self.hamlib_ptt_type = Hamlib.RIG_PTT_RIG
elif static.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 static.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 static.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")
self.my_rig.set_conf("ptt_type", "RTS")
elif static.HAMLIB_PTT_TYPE == 'PARALLEL':
self.hamlib_ptt_type = Hamlib.RIG_PTT_PARALLEL
elif static.HAMLIB_PTT_TYPE == 'MICDATA':
self.hamlib_ptt_type = Hamlib.RIG_PTT_RIG_MICDATA
elif static.HAMLIB_PTT_TYPE == 'CM108':
self.hamlib_ptt_type = Hamlib.RIG_PTT_CM108
else: # static.HAMLIB_PTT_TYPE == 'RIG_PTT_NONE':
self.hamlib_ptt_type = Hamlib.RIG_PTT_NONE
self.my_rig.open()
atexit.register(self.my_rig.close)
# set rig mode to USB
self.my_rig.set_mode(Hamlib.RIG_MODE_USB)
# start thread for getting hamlib data
HAMLIB_THREAD = threading.Thread(target=self.get_radio_stats, name="HAMLIB_THREAD")
HAMLIB_THREAD = threading.Thread(
target=self.get_radio_stats, name="HAMLIB_THREAD")
HAMLIB_THREAD.start()
except:
print("Unexpected error:", sys.exc_info()[0])
print("can't open rig")
sys.exit("hamlib error")
# --------------------------------------------------------------------------------------------------------
def ptt_and_wait(self, state):
static.PTT_STATE = state
if state:
self.my_rig.set_ptt(self.hamlib_ptt_type, 1)
#rigctld.ptt_enable()
# rigctld.ptt_enable()
ptt_toggle_timeout = time.time() + 0.5
while time.time() < ptt_toggle_timeout:
pass
else:
ptt_toggle_timeout = time.time() + 0.5
while time.time() < ptt_toggle_timeout:
pass
self.my_rig.set_ptt(self.hamlib_ptt_type, 0)
#rigctld.ptt_disable()
return False
self.my_rig.set_ptt(self.hamlib_ptt_type, 0)
# rigctld.ptt_disable()
return False
def play_audio(self):
while True:
time.sleep(0.01)
#while len(self.streambuffer) > 0:
# while len(self.streambuffer) > 0:
# time.sleep(0.01)
if len(self.streambuffer) > 0 and self.audio_writing_to_stream:
self.streambuffer = bytes(self.streambuffer)
# we need t wait a little bit until the buffer is filled. If we are not waiting, we are sending empty data
time.sleep(0.1)
self.stream_tx.write(self.streambuffer)
# clear stream buffer after sending
self.streambuffer = bytes()
self.audio_writing_to_stream = False
# --------------------------------------------------------------------------------------------------------
def transmit_signalling(self, data_out, count):
state_before_transmit = static.CHANNEL_STATE
static.CHANNEL_STATE = 'SENDING_SIGNALLING'
#print(static.CHANNEL_STATE)
# print(static.CHANNEL_STATE)
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
freedv = self.c_lib.freedv_open(static.FREEDV_SIGNALLING_MODE)
bytes_per_frame = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv) / 8)
bytes_per_frame = int(
self.c_lib.freedv_get_bits_per_modem_frame(freedv) / 8)
payload_per_frame = bytes_per_frame - 2
n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(freedv)
n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv) # get n_tx_modem_samples which defines the size of the modulation object
n_tx_preamble_modem_samples = self.c_lib.freedv_get_n_tx_preamble_modem_samples(freedv)
n_tx_postamble_modem_samples = self.c_lib.freedv_get_n_tx_postamble_modem_samples(freedv)
# get n_tx_modem_samples which defines the size of the modulation object
n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv)
n_tx_preamble_modem_samples = self.c_lib.freedv_get_n_tx_preamble_modem_samples(
freedv)
n_tx_postamble_modem_samples = self.c_lib.freedv_get_n_tx_postamble_modem_samples(
freedv)
mod_out = ctypes.c_short * n_tx_modem_samples
mod_out = mod_out()
mod_out_preamble = ctypes.c_short * n_tx_preamble_modem_samples # *2 #1760 for mode 10,11,12 #4000 for mode 9
# *2 #1760 for mode 10,11,12 #4000 for mode 9
mod_out_preamble = ctypes.c_short * n_tx_preamble_modem_samples
mod_out_preamble = mod_out_preamble()
mod_out_postamble = ctypes.c_short * n_tx_postamble_modem_samples # *2 #1760 for mode 10,11,12 #4000 for mode 9
# *2 #1760 for mode 10,11,12 #4000 for mode 9
mod_out_postamble = ctypes.c_short * n_tx_postamble_modem_samples
mod_out_postamble = mod_out_postamble()
buffer = bytearray(payload_per_frame) # use this if CRC16 checksum is required ( DATA1-3)
buffer[:len(data_out)] = data_out # set buffersize to length of data which will be send
# use this if CRC16 checksum is required ( DATA1-3)
buffer = bytearray(payload_per_frame)
# set buffersize to length of data which will be send
buffer[:len(data_out)] = data_out
crc = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(bytes(buffer), payload_per_frame)) # generate CRC16
crc = crc.value.to_bytes(2, byteorder='big') # convert crc to 2 byte hex string
crc = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(
bytes(buffer), payload_per_frame)) # generate CRC16
# convert crc to 2 byte hex string
crc = crc.value.to_bytes(2, byteorder='big')
buffer += crc # append crc16 to buffer
data = (ctypes.c_ubyte * bytes_per_frame).from_buffer_copy(buffer)
self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble)
self.c_lib.freedv_rawdatatx(freedv, mod_out, data) # modulate DATA and safe it into mod_out pointer
# modulate DATA and safe it into mod_out pointer
self.c_lib.freedv_rawdatatx(freedv, mod_out, data)
self.c_lib.freedv_rawdatapostambletx(freedv, mod_out_postamble)
self.streambuffer = bytearray()
self.streambuffer += bytes(mod_out_preamble)
self.streambuffer += bytes(mod_out)
self.streambuffer += bytes(mod_out_postamble)
converted_audio = audioop.ratecv(self.streambuffer,2,1,static.MODEM_SAMPLE_RATE, static.AUDIO_SAMPLE_RATE_TX, None)
converted_audio = audioop.ratecv(
self.streambuffer, 2, 1, static.MODEM_SAMPLE_RATE, static.AUDIO_SAMPLE_RATE_TX, None)
self.streambuffer = bytes(converted_audio[0])
# append frame again with as much as in count defined
for i in range(1, count):
self.streambuffer += bytes(converted_audio[0])
#print(len(self.streambuffer))
# print(len(self.streambuffer))
#self.streambuffer += bytes(converted_audio[0])
#print(len(self.streambuffer))
# print(len(self.streambuffer))
# -------------- transmit audio
#logging.debug("SENDING SIGNALLING FRAME " + str(data_out))
##state_before_transmit = static.CHANNEL_STATE
##static.CHANNEL_STATE = 'SENDING_SIGNALLING'
while self.ptt_and_wait(True):
pass
self.audio_writing_to_stream = True
# wait until audio has been processed
while self.audio_writing_to_stream:
time.sleep(0.01)
static.CHANNEL_STATE = 'SENDING_SIGNALLING'
self.ptt_and_wait(False)
## we have a problem with the receiving state
self.ptt_and_wait(False)
# we have a problem with the receiving state
##static.CHANNEL_STATE = state_before_transmit
if state_before_transmit != 'RECEIVING_DATA':
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
else:
static.CHANNEL_STATE = state_before_transmit
self.c_lib.freedv_close(freedv)
# --------------------------------------------------------------------------------------------------------
# GET ARQ BURST FRAME VOM BUFFER AND MODULATE IT
def transmit_arq_burst(self):
# we could place this timing part inside the modem...
# lets see if this is a good idea..
static.ARQ_DATA_CHANNEL_LAST_RECEIVED = int(time.time()) # we need to update our timeout timestamp
static.ARQ_START_OF_BURST = int(time.time()) # we need to update our timeout timestamp
# we need to update our timeout timestamp
static.ARQ_DATA_CHANNEL_LAST_RECEIVED = int(time.time())
# we need to update our timeout timestamp
static.ARQ_START_OF_BURST = int(time.time())
state_before_transmit = static.CHANNEL_STATE
static.CHANNEL_STATE = 'SENDING_DATA'
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
freedv = self.c_lib.freedv_open(static.ARQ_DATA_CHANNEL_MODE)
static.FREEDV_DATA_BYTES_PER_FRAME = int(self.c_lib.freedv_get_bits_per_modem_frame(freedv) / 8)
static.FREEDV_DATA_BYTES_PER_FRAME = int(
self.c_lib.freedv_get_bits_per_modem_frame(freedv) / 8)
static.FREEDV_DATA_PAYLOAD_PER_FRAME = static.FREEDV_DATA_BYTES_PER_FRAME - 2
n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(freedv)
n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv) # *2 #get n_tx_modem_samples which defines the size of the modulation object
n_tx_preamble_modem_samples = self.c_lib.freedv_get_n_tx_preamble_modem_samples(freedv)
n_tx_postamble_modem_samples = self.c_lib.freedv_get_n_tx_postamble_modem_samples(freedv)
# *2 #get n_tx_modem_samples which defines the size of the modulation object
n_tx_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv)
n_tx_preamble_modem_samples = self.c_lib.freedv_get_n_tx_preamble_modem_samples(
freedv)
n_tx_postamble_modem_samples = self.c_lib.freedv_get_n_tx_postamble_modem_samples(
freedv)
mod_out = ctypes.c_short * n_tx_modem_samples
mod_out = mod_out()
mod_out_preamble = ctypes.c_short * n_tx_preamble_modem_samples # *2 #1760 for mode 10,11,12 #4000 for mode 9
# *2 #1760 for mode 10,11,12 #4000 for mode 9
mod_out_preamble = ctypes.c_short * n_tx_preamble_modem_samples
mod_out_preamble = mod_out_preamble()
mod_out_postamble = ctypes.c_short * n_tx_postamble_modem_samples # *2 #1760 for mode 10,11,12 #4000 for mode 9
# *2 #1760 for mode 10,11,12 #4000 for mode 9
mod_out_postamble = ctypes.c_short * n_tx_postamble_modem_samples
mod_out_postamble = mod_out_postamble()
self.streambuffer = bytearray()
self.c_lib.freedv_rawdatapreambletx(freedv, mod_out_preamble)
self.streambuffer += bytes(mod_out_preamble)
if not static.ARQ_RPT_RECEIVED:
for n in range(0, static.ARQ_TX_N_FRAMES_PER_BURST):
# ---------------------------BUILD ARQ BURST ---------------------------------------------------------------------
frame_type = 10 + n + 1 # static.ARQ_TX_N_FRAMES_PER_BURST
frame_type = bytes([frame_type])
payload_data = bytes(static.TX_BUFFER[static.ARQ_N_SENT_FRAMES + n])
payload_data = bytes(
static.TX_BUFFER[static.ARQ_N_SENT_FRAMES + n])
n_current_arq_frame = static.ARQ_N_SENT_FRAMES + n + 1
static.ARQ_TX_N_CURRENT_ARQ_FRAME = n_current_arq_frame.to_bytes(2, byteorder='big')
static.ARQ_TX_N_CURRENT_ARQ_FRAME = n_current_arq_frame.to_bytes(
2, byteorder='big')
n_total_arq_frame = len(static.TX_BUFFER)
#static.ARQ_TX_N_TOTAL_ARQ_FRAMES = n_total_arq_frame
@ -355,18 +378,23 @@ class RF():
static.MYCALLSIGN_CRC8 + \
payload_data
buffer = bytearray(static.FREEDV_DATA_PAYLOAD_PER_FRAME) # create TX buffer
buffer[:len(arqframe)] = arqframe # set buffersize to length of data which will be send
# create TX buffer
buffer = bytearray(static.FREEDV_DATA_PAYLOAD_PER_FRAME)
# set buffersize to length of data which will be send
buffer[:len(arqframe)] = arqframe
crc = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(bytes(buffer), static.FREEDV_DATA_PAYLOAD_PER_FRAME)) # generate CRC16
crc = crc.value.to_bytes(2, byteorder='big') # convert crc to 2 byte hex string
crc = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(
bytes(buffer), static.FREEDV_DATA_PAYLOAD_PER_FRAME)) # generate CRC16
# convert crc to 2 byte hex string
crc = crc.value.to_bytes(2, byteorder='big')
buffer += crc # append crc16 to buffer
data = (ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME).from_buffer_copy(buffer)
self.c_lib.freedv_rawdatatx(freedv, mod_out, data) # modulate DATA and safe it into mod_out pointer
data = (
ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME).from_buffer_copy(buffer)
# modulate DATA and safe it into mod_out pointer
self.c_lib.freedv_rawdatatx(freedv, mod_out, data)
self.streambuffer += bytes(mod_out)
elif static.ARQ_RPT_RECEIVED:
@ -378,12 +406,14 @@ class RF():
frame_type = bytes([frame_type])
try:
payload_data = bytes(static.TX_BUFFER[static.ARQ_N_SENT_FRAMES + missing_frame - 1])
payload_data = bytes(
static.TX_BUFFER[static.ARQ_N_SENT_FRAMES + missing_frame - 1])
except:
print("modem buffer selection problem with ARQ RPT frames")
n_current_arq_frame = static.ARQ_N_SENT_FRAMES + missing_frame
static.ARQ_TX_N_CURRENT_ARQ_FRAME = n_current_arq_frame.to_bytes(2, byteorder='big')
static.ARQ_TX_N_CURRENT_ARQ_FRAME = n_current_arq_frame.to_bytes(
2, byteorder='big')
n_total_arq_frame = len(static.TX_BUFFER)
#static.ARQ_TX_N_TOTAL_ARQ_FRAMES = n_total_arq_frame
@ -396,28 +426,33 @@ class RF():
static.MYCALLSIGN_CRC8 + \
payload_data
buffer = bytearray(static.FREEDV_DATA_PAYLOAD_PER_FRAME) # create TX buffer
buffer[:len(arqframe)] = arqframe # set buffersize to length of data which will be send
# create TX buffer
buffer = bytearray(static.FREEDV_DATA_PAYLOAD_PER_FRAME)
# set buffersize to length of data which will be send
buffer[:len(arqframe)] = arqframe
crc = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(bytes(buffer), static.FREEDV_DATA_PAYLOAD_PER_FRAME)) # generate CRC16
crc = crc.value.to_bytes(2, byteorder='big') # convert crc to 2 byte hex string
crc = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(
bytes(buffer), static.FREEDV_DATA_PAYLOAD_PER_FRAME)) # generate CRC16
# convert crc to 2 byte hex string
crc = crc.value.to_bytes(2, byteorder='big')
buffer += crc # append crc16 to buffer
data = (ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME).from_buffer_copy(buffer)
self.c_lib.freedv_rawdatatx(freedv, mod_out, data) # modulate DATA and safe it into mod_out pointer
data = (
ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME).from_buffer_copy(buffer)
# modulate DATA and safe it into mod_out pointer
self.c_lib.freedv_rawdatatx(freedv, mod_out, data)
self.streambuffer += bytes(mod_out)
self.c_lib.freedv_rawdatapostambletx(freedv, mod_out_postamble)
self.streambuffer += bytes(mod_out_postamble)
converted_audio = audioop.ratecv(self.streambuffer,2,1,static.MODEM_SAMPLE_RATE, static.AUDIO_SAMPLE_RATE_TX, None)
converted_audio = audioop.ratecv(
self.streambuffer, 2, 1, static.MODEM_SAMPLE_RATE, static.AUDIO_SAMPLE_RATE_TX, None)
self.streambuffer = bytes(converted_audio[0])
# -------------- transmit audio
while self.ptt_and_wait(True):
pass
# this triggers writing buffer to audio stream
@ -439,22 +474,23 @@ class RF():
# --------------------------------------------------------------------------------------------------------
def receive(self):
# DATAC0
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
datac0_freedv = self.c_lib.freedv_open(14)
self.c_lib.freedv_get_bits_per_modem_frame(datac0_freedv)
datac0_bytes_per_frame = int(self.c_lib.freedv_get_bits_per_modem_frame(datac0_freedv)/8)
datac0_n_max_modem_samples = self.c_lib.freedv_get_n_max_modem_samples(datac0_freedv)
datac0_bytes_out = (ctypes.c_ubyte * datac0_bytes_per_frame) #bytes_per_frame
datac0_bytes_out = datac0_bytes_out() #get pointer from bytes_out
self.c_lib.freedv_set_frames_per_burst(datac0_freedv,1)
datac0_n_max_modem_samples = self.c_lib.freedv_get_n_max_modem_samples(datac0_freedv)
# bytes_per_frame
datac0_bytes_out = (ctypes.c_ubyte * datac0_bytes_per_frame)
datac0_bytes_out = datac0_bytes_out() # get pointer from bytes_out
self.c_lib.freedv_set_frames_per_burst(datac0_freedv, 1)
datac0_modem_stats_snr = c_float()
datac0_modem_stats_sync = c_int()
datac0_buffer = bytes()
static.FREEDV_SIGNALLING_BYTES_PER_FRAME = datac0_bytes_per_frame
static.FREEDV_SIGNALLING_PAYLOAD_PER_FRAME = datac0_bytes_per_frame - 2
@ -462,10 +498,11 @@ class RF():
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
datac1_freedv = self.c_lib.freedv_open(10)
datac1_bytes_per_frame = int(self.c_lib.freedv_get_bits_per_modem_frame(datac1_freedv)/8)
datac1_n_max_modem_samples = self.c_lib.freedv_get_n_max_modem_samples(datac1_freedv)
datac1_bytes_out = (ctypes.c_ubyte * datac1_bytes_per_frame) #bytes_per_frame
datac1_bytes_out = datac1_bytes_out() #get pointer from bytes_out
self.c_lib.freedv_set_frames_per_burst(datac1_freedv,1)
datac1_n_max_modem_samples = self.c_lib.freedv_get_n_max_modem_samples(datac1_freedv)
# bytes_per_frame
datac1_bytes_out = (ctypes.c_ubyte * datac1_bytes_per_frame)
datac1_bytes_out = datac1_bytes_out() # get pointer from bytes_out
self.c_lib.freedv_set_frames_per_burst(datac1_freedv, 1)
datac1_modem_stats_snr = c_float()
datac1_modem_stats_sync = c_int()
datac1_buffer = bytes()
@ -474,10 +511,11 @@ class RF():
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
datac3_freedv = self.c_lib.freedv_open(12)
datac3_bytes_per_frame = int(self.c_lib.freedv_get_bits_per_modem_frame(datac3_freedv)/8)
datac3_n_max_modem_samples = self.c_lib.freedv_get_n_max_modem_samples(datac3_freedv)
datac3_bytes_out = (ctypes.c_ubyte * datac3_bytes_per_frame) #bytes_per_frame
datac3_bytes_out = datac3_bytes_out() #get pointer from bytes_out
self.c_lib.freedv_set_frames_per_burst(datac3_freedv,1)
datac3_n_max_modem_samples = self.c_lib.freedv_get_n_max_modem_samples(datac3_freedv)
# bytes_per_frame
datac3_bytes_out = (ctypes.c_ubyte * datac3_bytes_per_frame)
datac3_bytes_out = datac3_bytes_out() # get pointer from bytes_out
self.c_lib.freedv_set_frames_per_burst(datac3_freedv, 1)
datac3_modem_stats_snr = c_float()
datac3_modem_stats_sync = c_int()
datac3_buffer = bytes()
@ -503,242 +541,240 @@ class RF():
'''
data_in = bytes()
data_in = self.stream_rx.read(1024, exception_on_overflow = False)
data_in = self.stream_rx.read(1024, exception_on_overflow=False)
#self.fft_data = data_in
data_in = audioop.ratecv(data_in,2,1,static.AUDIO_SAMPLE_RATE_RX, static.MODEM_SAMPLE_RATE, None)
data_in = data_in[0]#.rstrip(b'\x00')
data_in = audioop.ratecv(data_in, 2, 1, static.AUDIO_SAMPLE_RATE_RX, static.MODEM_SAMPLE_RATE, None)
data_in = data_in[0] # .rstrip(b'\x00')
self.fft_data = data_in
# we need to set nin * 2 beause of byte size in array handling
datac0_nin = self.c_lib.freedv_nin(datac0_freedv) * 2
datac1_nin = self.c_lib.freedv_nin(datac1_freedv) * 2
datac3_nin = self.c_lib.freedv_nin(datac3_freedv) * 2
# refill buffer only if every mode has worked with its data
if (len(datac0_buffer) < (datac0_nin*2)) and (len(datac1_buffer) < (datac1_nin*2)) and (len(datac3_buffer) < (datac3_nin*2)):
datac0_buffer += data_in
datac1_buffer += data_in
datac3_buffer += data_in
# DECODING DATAC0
# DECODING DATAC0
if len(datac0_buffer) >= (datac0_nin):
datac0_audio = datac0_buffer[:datac0_nin]
datac0_buffer = datac0_buffer[datac0_nin:]
#print(len(datac0_audio))
datac0_buffer = datac0_buffer[datac0_nin:]
# print(len(datac0_audio))
self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), datac0_bytes_out, datac0_audio]
nbytes = self.c_lib.freedv_rawdatarx(datac0_freedv, datac0_bytes_out, datac0_audio) # demodulate audio
nbytes = self.c_lib.freedv_rawdatarx(datac0_freedv, datac0_bytes_out, datac0_audio) # demodulate audio
sync = self.c_lib.freedv_get_rx_status(datac0_freedv)
if sync != 0 and nbytes != 0:
#calculate snr and scatter
if sync != 0 and nbytes != 0:
# calculate snr and scatter
self.get_scatter(datac0_freedv)
self.calculate_snr(datac0_freedv)
datac0_task = threading.Thread(target=self.process_data, args=[datac0_bytes_out, datac0_freedv])
datac0_task.start()
# DECODING DATAC1
# DECODING DATAC1
if len(datac1_buffer) >= (datac1_nin):
datac1_audio = datac1_buffer[:datac1_nin]
datac1_buffer = datac1_buffer[datac1_nin:]
#print(len(datac1_audio))
datac1_buffer = datac1_buffer[datac1_nin:]
# print(len(datac1_audio))
self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), datac1_bytes_out, datac1_audio]
nbytes = self.c_lib.freedv_rawdatarx(datac1_freedv, datac1_bytes_out, datac1_audio) # demodulate audio
nbytes = self.c_lib.freedv_rawdatarx(datac1_freedv, datac1_bytes_out, datac1_audio) # demodulate audio
sync = self.c_lib.freedv_get_rx_status(datac1_freedv)
if sync != 0 and nbytes != 0:
#calculate snr and scatter
# calculate snr and scatter
self.get_scatter(datac1_freedv)
self.calculate_snr(datac1_freedv)
datac1_task = threading.Thread(target=self.process_data, args=[datac1_bytes_out, datac1_freedv])
datac1_task.start()
# DECODING DATAC3
datac1_task.start()
# DECODING DATAC3
if len(datac3_buffer) >= (datac3_nin):
datac3_audio = datac3_buffer[:datac3_nin]
datac3_buffer = datac3_buffer[datac3_nin:]
datac3_buffer = datac3_buffer[datac3_nin:]
self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), datac3_bytes_out, datac3_audio]
nbytes = self.c_lib.freedv_rawdatarx(datac3_freedv, datac3_bytes_out, datac3_audio) # demodulate audio
nbytes = self.c_lib.freedv_rawdatarx(datac3_freedv, datac3_bytes_out, datac3_audio) # demodulate audio
sync = self.c_lib.freedv_get_rx_status(datac3_freedv)
if sync != 0 and nbytes != 0:
#calculate snr and scatter
# calculate snr and scatter
self.get_scatter(datac3_freedv)
self.calculate_snr(datac3_freedv)
datac3_task = threading.Thread(target=self.process_data, args=[datac3_bytes_out, datac3_freedv])
datac3_task.start()
# forward data only if broadcast or we are the receiver
# bytes_out[1:2] == callsign check for signalling frames, bytes_out[6:7] == callsign check for data frames, bytes_out[1:2] == b'\x01' --> broadcasts like CQ
# we could also create an own function, which returns True. In this case we could add callsign blacklists and so on
def process_data(self, bytes_out, freedv):
force = True
print(bytes(bytes_out))
if bytes(bytes_out[1:2]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[6:7]) == static.MYCALLSIGN_CRC8 or bytes(bytes_out[1:2]) == b'\x01':
helpers.calculate_transfer_rate()
# CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------
frametype = int.from_bytes(bytes(bytes_out[:1]), "big")
frame = frametype - 10
n_frames_per_burst = int.from_bytes(bytes(bytes_out[1:2]), "big")
#self.c_lib.freedv_set_frames_per_burst(freedv_data, n_frames_per_burst);
helpers.calculate_transfer_rate()
# CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------
frametype = int.from_bytes(bytes(bytes_out[:1]), "big")
frame = frametype - 10
n_frames_per_burst = int.from_bytes(bytes(bytes_out[1:2]), "big")
if 50 >= frametype >= 10:
if frame != 3 or force == True:
#self.c_lib.freedv_set_frames_per_burst(freedv_data, n_frames_per_burst);
data_handler.arq_data_received(bytes(bytes_out[:-2])) # send payload data to arq checker without CRC16
if 50 >= frametype >= 10:
if frame != 3 or force == True:
#print("static.ARQ_RX_BURST_BUFFER.count(None) " + str(static.ARQ_RX_BURST_BUFFER.count(None)))
if static.ARQ_RX_BURST_BUFFER.count(None) <= 1:
logging.debug("FULL BURST BUFFER ---> UNSYNC")
self.c_lib.freedv_set_sync(freedv, 0)
# send payload data to arq checker without CRC16
data_handler.arq_data_received(bytes(bytes_out[:-2]))
else:
logging.critical("---------------------------SIMULATED MISSING FRAME")
force = True
#print("static.ARQ_RX_BURST_BUFFER.count(None) " + str(static.ARQ_RX_BURST_BUFFER.count(None)))
if static.ARQ_RX_BURST_BUFFER.count(None) <= 1:
logging.debug("FULL BURST BUFFER ---> UNSYNC")
self.c_lib.freedv_set_sync(freedv, 0)
# BURST ACK
elif frametype == 60:
logging.debug("ACK RECEIVED....")
data_handler.burst_ack_received()
else:
logging.critical(
"---------------------------SIMULATED MISSING FRAME")
force = True
# FRAME ACK
elif frametype == 61:
logging.debug("FRAME ACK RECEIVED....")
data_handler.frame_ack_received()
# BURST ACK
elif frametype == 60:
logging.debug("ACK RECEIVED....")
data_handler.burst_ack_received()
# FRAME RPT
elif frametype == 62:
logging.debug("REPEAT REQUEST RECEIVED....")
data_handler.burst_rpt_received(bytes_out[:-2])
# FRAME ACK
elif frametype == 61:
logging.debug("FRAME ACK RECEIVED....")
data_handler.frame_ack_received()
# FRAME NAK
elif frametype == 63:
logging.debug("FRAME NAK RECEIVED....")
data_handler.frame_nack_received(bytes_out[:-2])
# CQ FRAME
elif frametype == 200:
logging.debug("CQ RECEIVED....")
data_handler.received_cq(bytes_out[:-2])
# FRAME RPT
elif frametype == 62:
logging.debug("REPEAT REQUEST RECEIVED....")
data_handler.burst_rpt_received(bytes_out[:-2])
# PING FRAME
elif frametype == 210:
logging.debug("PING RECEIVED....")
data_handler.received_ping(bytes_out[:-2])
# FRAME NAK
elif frametype == 63:
logging.debug("FRAME NAK RECEIVED....")
data_handler.frame_nack_received(bytes_out[:-2])
# PING ACK
elif frametype == 211:
logging.debug("PING ACK RECEIVED....")
data_handler.received_ping_ack(bytes_out[:-2])
# CQ FRAME
elif frametype == 200:
logging.debug("CQ RECEIVED....")
data_handler.received_cq(bytes_out[:-2])
# ARQ CONNECT
elif frametype == 220:
logging.info("ARQ CONNECT RECEIVED....")
data_handler.arq_received_connect(bytes_out[:-2])
# PING FRAME
elif frametype == 210:
logging.debug("PING RECEIVED....")
data_handler.received_ping(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE
elif frametype == 221:
logging.info("ARQ CONNECT ACK RECEIVED / KEEP ALIVE....")
data_handler.arq_received_connect_keep_alive(bytes_out[:-2])
# PING ACK
elif frametype == 211:
logging.debug("PING ACK RECEIVED....")
data_handler.received_ping_ack(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE
elif frametype == 222:
logging.debug("ARQ DISCONNECT RECEIVED")
data_handler.arq_disconnect_received(bytes_out[:-2])
# ARQ CONNECT
# elif frametype == 220:
# logging.info("ARQ CONNECT RECEIVED....")
# data_handler.arq_received_connect(bytes_out[:-2])
# ARQ FILE TRANSFER RECEIVED!
elif frametype == 225:
logging.debug("ARQ arq_received_data_channel_opener RECEIVED")
data_handler.arq_received_data_channel_opener(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE
# elif frametype == 221:
# logging.info("ARQ CONNECT ACK RECEIVED / KEEP ALIVE....")
# data_handler.arq_received_connect_keep_alive(bytes_out[:-2])
# ARQ CHANNEL IS OPENED
elif frametype == 226:
logging.debug("ARQ arq_received_channel_is_open RECEIVED")
data_handler.arq_received_channel_is_open(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE
# elif frametype == 222:
# logging.debug("ARQ DISCONNECT RECEIVED")
# data_handler.arq_disconnect_received(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE
elif frametype == 230:
logging.debug("BEACON RECEIVED")
data_handler.received_beacon(bytes_out[:-2])
# ARQ FILE TRANSFER RECEIVED!
elif frametype == 225:
logging.debug("ARQ arq_received_data_channel_opener RECEIVED")
data_handler.arq_received_data_channel_opener(bytes_out[:-2])
else:
logging.info("OTHER FRAME: " + str(bytes_out[:-2]))
print(frametype)
# ARQ CHANNEL IS OPENED
elif frametype == 226:
logging.debug("ARQ arq_received_channel_is_open RECEIVED")
data_handler.arq_received_channel_is_open(bytes_out[:-2])
# DO UNSYNC AFTER LAST BURST by checking the frame nums against the total frames per burst
if frame == n_frames_per_burst:
logging.debug("LAST FRAME ---> UNSYNC")
self.c_lib.freedv_set_sync(freedv, 0) # FORCE UNSYNC
# clear bytes_out buffer to be ready for next frames after successfull decoding
# ARQ CONNECT ACK / KEEP ALIVE
elif frametype == 230:
logging.debug("BEACON RECEIVED")
data_handler.received_beacon(bytes_out[:-2])
#bytes_out = (ctypes.c_ubyte * bytes_per_frame)
#bytes_out = bytes_out() # get pointer to bytes_out
else:
logging.info("OTHER FRAME: " + str(bytes_out[:-2]))
print(frametype)
# DO UNSYNC AFTER LAST BURST by checking the frame nums against the total frames per burst
if frame == n_frames_per_burst:
logging.debug("LAST FRAME ---> UNSYNC")
self.c_lib.freedv_set_sync(freedv, 0) # FORCE UNSYNC
# clear bytes_out buffer to be ready for next frames after successfull decoding
#bytes_out = (ctypes.c_ubyte * bytes_per_frame)
# bytes_out = bytes_out() # get pointer to bytes_out
else:
# for debugging purposes to receive all data
# for debugging purposes to receive all data
pass
# print(bytes_out[:-2])
# print(bytes_out[:-2])
def get_scatter(self, freedv):
modemStats = MODEMSTATS()
self.c_lib.freedv_get_modem_extended_stats.restype = None
self.c_lib.freedv_get_modem_extended_stats(freedv, ctypes.byref(modemStats))
self.c_lib.freedv_get_modem_extended_stats(
freedv, ctypes.byref(modemStats))
scatterdata = []
for i in range(MODEM_STATS_NC_MAX):
for j in range(MODEM_STATS_NR_MAX):
#check if odd or not to get every 2nd item for x
if (j % 2) == 0:
for j in range(MODEM_STATS_NR_MAX):
# check if odd or not to get every 2nd item for x
if (j % 2) == 0:
xsymbols = modemStats.rx_symbols[i][j]
ysymbols = modemStats.rx_symbols[i][j+1]
ysymbols = modemStats.rx_symbols[i][j+1]
# check if value 0.0 or has real data
if xsymbols != 0.0 and ysymbols != 0.0:
scatterdata.append({"x" : xsymbols, "y" : ysymbols })
scatterdata.append({"x": xsymbols, "y": ysymbols})
# only append scatter data if new data arrived
if len(scatterdata) > 0:
static.SCATTER = scatterdata
static.SCATTER = scatterdata
def calculate_ber(self, freedv):
Tbits = self.c_lib.freedv_get_total_bits(freedv)
Terrs = self.c_lib.freedv_get_total_bit_errors(freedv)
if Tbits != 0:
ber = (Terrs / Tbits) * 100
static.BER = int(ber)
self.c_lib.freedv_set_total_bit_errors(freedv, 0)
self.c_lib.freedv_set_total_bits(freedv, 0)
def calculate_snr(self, freedv):
modem_stats_snr = c_float()
modem_stats_sync = c_int()
self.c_lib.freedv_get_modem_stats(freedv,byref(modem_stats_sync), byref(modem_stats_snr))
self.c_lib.freedv_get_modem_stats(freedv, byref(
modem_stats_sync), byref(modem_stats_snr))
modem_stats_snr = modem_stats_snr.value
try:
static.SNR = round(modem_stats_snr,1)
static.SNR = round(modem_stats_snr, 1)
except:
static.SNR = 0
def get_radio_stats(self):
while True:
time.sleep(0.1)
@ -748,14 +784,13 @@ class RF():
#static.HAMLIB_FREQUENCY = rigctld.get_frequency()
#static.HAMLIB_MODE = rigctld.get_mode()[0]
#static.HAMLIB_BANDWITH = rigctld.get_mode()[1]
def calculate_fft(self):
while True:
time.sleep(0.01)
# WE NEED TO OPTIMIZE THIS!
data_in = self.fft_data
# https://gist.github.com/ZWMiller/53232427efc5088007cab6feee7c6e4c
audio_data = np.fromstring(data_in, np.int16)
# Fast Fourier Transform, 10*log10(abs) is to scale it to dB
@ -763,11 +798,11 @@ class RF():
try:
fftarray = np.fft.rfft(audio_data)
# set value 0 to 1 to avoid division by zero
# set value 0 to 1 to avoid division by zero
fftarray[fftarray == 0] = 1
dfft = 10.*np.log10(abs(fftarray))
dfftlist = dfft.tolist()
# send fft only if receiving
if static.CHANNEL_STATE == 'RECEIVING_SIGNALLING' or static.CHANNEL_STATE == 'RECEIVING_DATA':
#static.FFT = dfftlist[20:100]
@ -776,4 +811,3 @@ class RF():
print("setting fft = 0")
# else 0
static.FFT = [0] * 400

View file

@ -33,17 +33,19 @@ import static
import data_handler
import helpers
import sys, os
import sys
import os
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
print("Client connected...")
print("Client connected...")
# loop through socket buffer until timeout is reached. then close buffer
socketTimeout = time.time() + 3
while socketTimeout > time.time():
@ -53,21 +55,21 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
#data = str(self.request.recv(1024), 'utf-8')
data = bytes()
# we need to loop through buffer until end of chunk is reached or timeout occured
while True and socketTimeout > time.time():
chunk = self.request.recv(71) # we keep amount of bytes short
data += chunk
if chunk.endswith(b'}\n') or chunk.endswith(b'}'): # or chunk.endswith(b'\n'):
# or chunk.endswith(b'\n'):
if chunk.endswith(b'}\n') or chunk.endswith(b'}'):
break
data = data[:-1] # remove b'\n'
data = str(data, 'utf-8')
if len(data) > 0:
socketTimeout = time.time() + static.SOCKET_TIMEOUT
# convert data to json object
# we need to do some error handling in case of socket timeout or decoding issue
try:
@ -78,7 +80,7 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
data = data.splitlines()[0]
received_json = json.loads(data)
#except ValueError as e:
# except ValueError as e:
# print("++++++++++++ START OF JSON ERROR +++++++++++++++++++++++")
# print(e)
# print("-----------------------------------")
@ -86,29 +88,32 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
# print("++++++++++++ END OF JSON ERROR +++++++++++++++++++++++++")
# received_json = {}
# break
#try:
# try:
# CQ CQ CQ -----------------------------------------------------
if received_json["command"] == "CQCQCQ":
#socketTimeout = 0
#asyncio.run(data_handler.transmit_cq())
CQ_THREAD = threading.Thread(target=data_handler.transmit_cq, args=[], name="CQ")
# asyncio.run(data_handler.transmit_cq())
CQ_THREAD = threading.Thread(
target=data_handler.transmit_cq, args=[], name="CQ")
CQ_THREAD.start()
# PING ----------------------------------------------------------
if received_json["type"] == 'PING' and received_json["command"] == "PING":
# send ping frame and wait for ACK
dxcallsign = received_json["dxcallsign"]
#asyncio.run(data_handler.transmit_ping(dxcallsign))
PING_THREAD = threading.Thread(target=data_handler.transmit_ping, args=[dxcallsign], name="CQ")
# asyncio.run(data_handler.transmit_ping(dxcallsign))
PING_THREAD = threading.Thread(
target=data_handler.transmit_ping, args=[dxcallsign], name="CQ")
PING_THREAD.start()
if received_json["type"] == 'ARQ' and received_json["command"] == "sendFile":# and static.ARQ_READY_FOR_DATA == True: # and static.ARQ_STATE == 'CONNECTED' :
# and static.ARQ_READY_FOR_DATA == True: # and static.ARQ_STATE == 'CONNECTED' :
if received_json["type"] == 'ARQ' and received_json["command"] == "sendFile":
static.TNC_STATE = 'BUSY'
#on a new transmission we reset the timer
# on a new transmission we reset the timer
static.ARQ_START_OF_TRANSMISSION = int(time.time())
dxcallsign = received_json["dxcallsign"]
mode = int(received_json["mode"])
n_frames = int(received_json["n_frames"])
@ -116,12 +121,13 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
filetype = received_json["filetype"]
data = received_json["data"]
checksum = received_json["checksum"]
static.DXCALLSIGN = bytes(dxcallsign, 'utf-8')
static.DXCALLSIGN_CRC8 = helpers.get_crc_8(static.DXCALLSIGN)
static.DXCALLSIGN_CRC8 = helpers.get_crc_8(
static.DXCALLSIGN)
#dataframe = '{"filename": "'+ filename + '", "filetype" : "' + filetype + '", "data" : "' + data + '", "checksum" : "' + checksum + '"}'
rawdata = {"filename" : filename , "filetype" :filetype, "data" : data, "checksum" : checksum}
rawdata = {"filename": filename, "filetype": filetype,"data": data, "checksum": checksum}
#dataframe = {filename: filename}
#data_out = bytes(received_json["data"], 'utf-8')
dataframe = json.dumps(rawdata)
@ -141,9 +147,11 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
self.request.sendall(b'INVALID CALLSIGN')
else:
static.MYCALLSIGN = bytes(callsign, encoding)
static.MYCALLSIGN_CRC8 = helpers.get_crc_8(static.MYCALLSIGN)
logging.info("CMD | MYCALLSIGN: " + str(static.MYCALLSIGN))
static.MYCALLSIGN_CRC8 = helpers.get_crc_8(
static.MYCALLSIGN)
logging.info("CMD | MYCALLSIGN: " +
str(static.MYCALLSIGN))
if received_json["type"] == 'SET' and received_json["command"] == 'MYGRID':
mygrid = received_json["parameter"]
@ -152,25 +160,24 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
else:
static.MYGRID = bytes(mygrid, encoding)
logging.info("CMD | MYGRID: " + str(static.MYGRID))
if received_json["type"] == 'GET' and received_json["command"] == 'STATION_INFO':
output = {
"COMMAND": "STATION_INFO",
"TIMESTAMP" : received_json["timestamp"],
"TIMESTAMP": received_json["timestamp"],
"MY_CALLSIGN": str(static.MYCALLSIGN, encoding),
"DX_CALLSIGN": str(static.DXCALLSIGN, encoding),
"DX_GRID": str(static.DXGRID, encoding),
"EOF" : "EOF",
"EOF": "EOF",
}
jsondata = json.dumps(output)
self.request.sendall(bytes(jsondata, encoding))
if received_json["type"] == 'GET' and received_json["command"] == 'TNC_STATE':
output = {
"COMMAND": "TNC_STATE",
"TIMESTAMP" : received_json["timestamp"],
"TIMESTAMP": received_json["timestamp"],
"PTT_STATE": str(static.PTT_STATE),
"CHANNEL_STATE": str(static.CHANNEL_STATE),
"TNC_STATE": str(static.TNC_STATE),
@ -178,65 +185,63 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
"AUDIO_RMS": str(static.AUDIO_RMS),
"BER": str(static.BER),
"SNR": str(static.SNR),
"FREQUENCY" : str(static.HAMLIB_FREQUENCY),
"MODE" : str(static.HAMLIB_MODE),
"BANDWITH" : str(static.HAMLIB_BANDWITH),
"FFT" : str(static.FFT),
"SCATTER" : static.SCATTER,
"FREQUENCY": str(static.HAMLIB_FREQUENCY),
"MODE": str(static.HAMLIB_MODE),
"BANDWITH": str(static.HAMLIB_BANDWITH),
"FFT": str(static.FFT),
"SCATTER": static.SCATTER,
"RX_BUFFER_LENGTH": str(len(static.RX_BUFFER)),
"TX_N_MAX_RETRIES": str(static.TX_N_MAX_RETRIES),
"ARQ_TX_N_FRAMES_PER_BURST": str(static.ARQ_TX_N_FRAMES_PER_BURST),
"ARQ_TX_N_BURSTS": str(static.ARQ_TX_N_BURSTS),
"ARQ_TX_N_CURRENT_ARQ_FRAME": str(int.from_bytes(bytes(static.ARQ_TX_N_CURRENT_ARQ_FRAME), "big")),
"ARQ_TX_N_TOTAL_ARQ_FRAMES": str(int.from_bytes(bytes(static.TX_BUFFER_SIZE), "big")), # WE NEED TO CHANGE THE JSON TO TX_BUFFER_SIZE?!
# WE NEED TO CHANGE THE JSON TO TX_BUFFER_SIZE?!
"ARQ_TX_N_TOTAL_ARQ_FRAMES": str(int.from_bytes(bytes(static.TX_BUFFER_SIZE), "big")),
"ARQ_RX_FRAME_N_BURSTS": str(static.ARQ_RX_FRAME_N_BURSTS),
"ARQ_RX_N_CURRENT_ARQ_FRAME": str(static.ARQ_RX_N_CURRENT_ARQ_FRAME),
"ARQ_N_ARQ_FRAMES_PER_DATA_FRAME": str(int.from_bytes(bytes(static.ARQ_N_ARQ_FRAMES_PER_DATA_FRAME), "big")),
"ARQ_BYTES_PER_MINUTE" : str(static.ARQ_BYTES_PER_MINUTE),
"ARQ_BYTES_PER_MINUTE_BURST" : str(static.ARQ_BYTES_PER_MINUTE_BURST),
"ARQ_TRANSMISSION_PERCENT" : str(static.ARQ_TRANSMISSION_PERCENT),
"TOTAL_BYTES" : str(static.TOTAL_BYTES),
"STATIONS" : [],
"EOF" : "EOF",
"ARQ_BYTES_PER_MINUTE": str(static.ARQ_BYTES_PER_MINUTE),
"ARQ_BYTES_PER_MINUTE_BURST": str(static.ARQ_BYTES_PER_MINUTE_BURST),
"ARQ_TRANSMISSION_PERCENT": str(static.ARQ_TRANSMISSION_PERCENT),
"TOTAL_BYTES": str(static.TOTAL_BYTES),
"STATIONS": [],
"EOF": "EOF",
}
for i in range(0, len(static.HEARD_STATIONS)):
output["STATIONS"].append({"DXCALLSIGN": str(static.HEARD_STATIONS[i][0], 'utf-8'),"DXGRID": str(static.HEARD_STATIONS[i][1], 'utf-8'), "TIMESTAMP": static.HEARD_STATIONS[i][2], "DATATYPE": static.HEARD_STATIONS[i][3], "SNR": static.HEARD_STATIONS[i][4]})
try:
output["STATIONS"].append({"DXCALLSIGN": str(static.HEARD_STATIONS[i][0], 'utf-8'), "DXGRID": str(static.HEARD_STATIONS[i][1], 'utf-8'),"TIMESTAMP": static.HEARD_STATIONS[i][2], "DATATYPE": static.HEARD_STATIONS[i][3], "SNR": static.HEARD_STATIONS[i][4]})
try:
jsondata = json.dumps(output)
except ValueError as e:
print(e)
try:
self.request.sendall(bytes(jsondata, encoding))
except Exception as e:
print(e)
if received_json["type"] == 'GET' and received_json["command"] == 'RX_BUFFER':
output = {
"COMMAND": "RX_BUFFER",
"DATA-ARRAY" : [],
"EOF" : "EOF",
"DATA-ARRAY": [],
"EOF": "EOF",
}
for i in range(0, len(static.RX_BUFFER)):
rawdata = json.loads(static.RX_BUFFER[i][3])
output["DATA-ARRAY"].append({"DXCALLSIGN": str(static.RX_BUFFER[i][0], 'utf-8'),"DXGRID": str(static.RX_BUFFER[i][1], 'utf-8'), "TIMESTAMP": static.RX_BUFFER[i][2], "RXDATA": [rawdata]})
output["DATA-ARRAY"].append({"DXCALLSIGN": str(static.RX_BUFFER[i][0], 'utf-8'), "DXGRID": str(static.RX_BUFFER[i][1], 'utf-8'), "TIMESTAMP": static.RX_BUFFER[i][2], "RXDATA": [rawdata]})
jsondata = json.dumps(output)
self.request.sendall(bytes(jsondata, encoding))
if received_json["type"] == 'SET' and received_json["command"] == 'DEL_RX_BUFFER':
static.RX_BUFFER = []
#exception, if JSON cant be decoded
#except Exception as e:
# exception, if JSON cant be decoded
# except Exception as e:
except:
print("############ START OF ERROR #####################")
print("SOCKET COMMAND ERROR: " + data)
@ -248,19 +253,22 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
print("############ END OF ERROR #######################")
print("reset of connection...")
#socketTimeout = 0
#socketTimeout = 0
print("Client disconnected...")
def start_cmd_socket():
try:
logging.info("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(static.PORT))
socketserver.TCPServer.allow_reuse_address = True # https://stackoverflow.com/a/16641793
cmdserver = ThreadedTCPServer((static.HOST, static.PORT), ThreadedTCPRequestHandler)
logging.info(
"SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(static.PORT))
# https://stackoverflow.com/a/16641793
socketserver.TCPServer.allow_reuse_address = True
cmdserver = ThreadedTCPServer(
(static.HOST, static.PORT), ThreadedTCPRequestHandler)
server_thread = threading.Thread(target=cmdserver.serve_forever)
server_thread.daemon = True
server_thread.start()
server_thread.start()
except:
print("Socket error...")