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,26 +7,27 @@ Created on Tue Dec 22 16:58:45 2020
""" """
import argparse import argparse
import threading import threading
import socketserver import socketserver
import pyaudio
import time import time
import ujson as json
import subprocess
import os import os
import static
import psutil
import sys import sys
import subprocess
import ujson as json
import psutil
import serial.tools.list_ports import serial.tools.list_ports
import pyaudio
import static
def start_daemon(): def start_daemon():
try: try:
print("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(PORT)) print("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(PORT))
socketserver.TCPServer.allow_reuse_address = True # https://stackoverflow.com/a/16641793 # https://stackoverflow.com/a/16641793
daemon = socketserver.TCPServer(('0.0.0.0', PORT), CMDTCPRequestHandler) socketserver.TCPServer.allow_reuse_address = True
daemon = socketserver.TCPServer(
('0.0.0.0', PORT), CMDTCPRequestHandler)
daemon.serve_forever() daemon.serve_forever()
finally: finally:
@ -52,12 +53,12 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
while True and socketTimeout > time.time(): while True and socketTimeout > time.time():
chunk = self.request.recv(45) chunk = self.request.recv(45)
data += chunk 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 break
data = data[:-1] # remove b'\n' data = data[:-1] # remove b'\n'
data = str(data, 'utf-8') data = str(data, 'utf-8')
if len(data) > 0: if len(data) > 0:
socketTimeout = time.time() + 3 socketTimeout = time.time() + 3
@ -84,22 +85,25 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
# "data" : "..." # "data" : "..."
# print(received_json) # print(received_json)
#print(received_json["type"]) # print(received_json["type"])
#print(received_json["command"]) # print(received_json["command"])
#try: # try:
if received_json["type"] == 'SET' and received_json["command"] == 'STARTTNC' and not static.TNCSTARTED: if received_json["type"] == 'SET' and received_json["command"] == 'STARTTNC' and not static.TNCSTARTED:
rx_audio = str(received_json["parameter"][0]["rx_audio"]) rx_audio = str(received_json["parameter"][0]["rx_audio"])
tx_audio = str(received_json["parameter"][0]["tx_audio"]) tx_audio = str(received_json["parameter"][0]["tx_audio"])
deviceid = str(received_json["parameter"][0]["deviceid"]) deviceid = str(received_json["parameter"][0]["deviceid"])
deviceport = str(received_json["parameter"][0]["deviceport"]) deviceport = str(
serialspeed = str(received_json["parameter"][0]["serialspeed"]) received_json["parameter"][0]["deviceport"])
pttprotocol = str(received_json["parameter"][0]["pttprotocol"]) serialspeed = str(
received_json["parameter"][0]["serialspeed"])
pttprotocol = str(
received_json["parameter"][0]["pttprotocol"])
pttport = str(received_json["parameter"][0]["pttport"]) pttport = str(received_json["parameter"][0]["pttport"])
print("---- STARTING TNC !") print("---- STARTING TNC !")
print(received_json["parameter"][0]) print(received_json["parameter"][0])
#command = "--rx "+ rx_audio +" \ # command = "--rx "+ rx_audio +" \
# --tx "+ tx_audio +" \ # --tx "+ tx_audio +" \
# --deviceport "+ deviceport +" \ # --deviceport "+ deviceport +" \
# --deviceid "+ deviceid + " \ # --deviceid "+ deviceid + " \
@ -142,11 +146,10 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
p = subprocess.Popen(command) p = subprocess.Popen(command)
print("running TNC from source...") print("running TNC from source...")
static.TNCPROCESS = p#.pid static.TNCPROCESS = p # .pid
static.TNCSTARTED = True static.TNCSTARTED = True
if received_json["type"] == 'SET' and received_json["command"] == 'STOPTNC': if received_json["type"] == 'SET' and received_json["command"] == 'STOPTNC':
parameter = received_json["parameter"]
static.TNCPROCESS.kill() static.TNCPROCESS.kill()
print("KILLING PROCESS ------------") print("KILLING PROCESS ------------")
#os.kill(static.TNCPROCESS, signal.SIGKILL) #os.kill(static.TNCPROCESS, signal.SIGKILL)
@ -154,7 +157,8 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
if received_json["type"] == 'GET' and received_json["command"] == 'DAEMON_STATE': 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: if static.TNCSTARTED:
data["DAEMON_STATE"].append({"STATUS": "running"}) data["DAEMON_STATE"].append({"STATUS": "running"})
@ -165,35 +169,39 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
p = pyaudio.PyAudio() p = pyaudio.PyAudio()
for i in range(0, p.get_device_count()): for i in range(0, p.get_device_count()):
maxInputChannels = p.get_device_info_by_host_api_device_index(0,i).get('maxInputChannels') maxInputChannels = p.get_device_info_by_host_api_device_index(
maxOutputChannels = p.get_device_info_by_host_api_device_index(0,i).get('maxOutputChannels') 0, i).get('maxInputChannels')
name = p.get_device_info_by_host_api_device_index(0,i).get('name') 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: if maxInputChannels > 0:
data["INPUT_DEVICES"].append({"ID": i, "NAME" : str(name)}) data["INPUT_DEVICES"].append(
{"ID": i, "NAME": str(name)})
if maxOutputChannels > 0: if maxOutputChannels > 0:
data["OUTPUT_DEVICES"].append({"ID": i, "NAME" : str(name)}) data["OUTPUT_DEVICES"].append(
{"ID": i, "NAME": str(name)})
# UPDATE LIST OF SERIAL DEVICES # UPDATE LIST OF SERIAL DEVICES
ports = serial.tools.list_ports.comports() ports = serial.tools.list_ports.comports()
for port, desc, hwid in ports: 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) jsondata = json.dumps(data)
self.request.sendall(bytes(jsondata, encoding)) 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: except ValueError as e:
print("############ START OF ERROR #####################") print("############ START OF ERROR #####################")
print('DAEMON PROGRAM ERROR: %s' %str(e)) print('DAEMON PROGRAM ERROR: %s' % str(e))
print("Wrong command") print("Wrong command")
print(data) print(data)
print(e) 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] fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print(exc_type, fname, exc_tb.tb_lineno) print(exc_type, fname, exc_tb.tb_lineno)
print("############ END OF ERROR #######################") print("############ END OF ERROR #######################")
@ -203,12 +211,10 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
if __name__ == '__main__': if __name__ == '__main__':
# --------------------------------------------GET PARAMETER INPUTS # --------------------------------------------GET PARAMETER INPUTS
PARSER = argparse.ArgumentParser(description='Simons TEST TNC') 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() ARGS = PARSER.parse_args()
PORT = ARGS.socket_port PORT = ARGS.socket_port
@ -217,9 +223,3 @@ if __name__ == '__main__':
DAEMON_THREAD = threading.Thread(target=start_daemon, name="daemon") DAEMON_THREAD = threading.Thread(target=start_daemon, name="daemon")
DAEMON_THREAD.start() DAEMON_THREAD.start()

View file

@ -15,6 +15,7 @@ import crcengine
import static import static
import data_handler import data_handler
def wait(seconds): def wait(seconds):
timeout = time.time() + seconds timeout = time.time() + seconds
@ -22,7 +23,6 @@ def wait(seconds):
time.sleep(0.01) time.sleep(0.01)
def get_crc_8(data): def get_crc_8(data):
""" """
Author: DJ2LS Author: DJ2LS
@ -50,6 +50,7 @@ def get_crc_16(data):
crc_data = crc_data.to_bytes(2, byteorder='big') crc_data = crc_data.to_bytes(2, byteorder='big')
return crc_data return crc_data
def watchdog(): def watchdog():
""" """
Author: DJ2LS Author: DJ2LS
@ -60,6 +61,7 @@ def watchdog():
time.sleep(0.01) time.sleep(0.01)
data_channel_keep_alive_watchdog() data_channel_keep_alive_watchdog()
def data_channel_keep_alive_watchdog(): def data_channel_keep_alive_watchdog():
""" """
Author: DJ2LS Author: DJ2LS
@ -67,13 +69,15 @@ def data_channel_keep_alive_watchdog():
""" """
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) time.sleep(0.01)
if static.ARQ_DATA_CHANNEL_LAST_RECEIVED + 30 > time.time(): if static.ARQ_DATA_CHANNEL_LAST_RECEIVED + 30 > time.time():
pass pass
else: else:
static.ARQ_DATA_CHANNEL_LAST_RECEIVED = 0 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() arq_reset_frame_machine()
@ -122,22 +126,22 @@ def arq_reset_frame_machine():
static.TNC_STATE = 'IDLE' static.TNC_STATE = 'IDLE'
static.ARQ_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.ARQ_SEND_KEEP_ALIVE = True
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING' static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
static.ARQ_READY_FOR_DATA = False static.ARQ_READY_FOR_DATA = False
static.ARQ_START_OF_TRANSMISSION = 0 static.ARQ_START_OF_TRANSMISSION = 0
def calculate_transfer_rate(): def calculate_transfer_rate():
if static.ARQ_START_OF_TRANSMISSION > 0: if static.ARQ_START_OF_TRANSMISSION > 0:
static.TOTAL_TRANSMISSION_TIME = time.time() - static.ARQ_START_OF_TRANSMISSION static.TOTAL_TRANSMISSION_TIME = time.time() - static.ARQ_START_OF_TRANSMISSION
print("ARQ_N_ARQ_FRAMES_PER_DATA_FRAME " +
print("ARQ_N_ARQ_FRAMES_PER_DATA_FRAME " + str(static.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_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_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 arq_rx_n_current_arq_frame = static.ARQ_RX_N_CURRENT_ARQ_FRAME
@ -155,51 +159,61 @@ def calculate_transfer_rate():
print("total_transmission_time: " + str(total_transmission_time)) print("total_transmission_time: " + str(total_transmission_time))
print("static.TOTAL_BYTES: " + str(static.TOTAL_BYTES)) print("static.TOTAL_BYTES: " + str(static.TOTAL_BYTES))
static.ARQ_BITS_PER_SECOND = int(
(static.TOTAL_BYTES * 8) / total_transmission_time)
static.ARQ_BITS_PER_SECOND = int((static.TOTAL_BYTES * 8) / total_transmission_time) static.ARQ_BYTES_PER_MINUTE = int(
static.ARQ_BYTES_PER_MINUTE = int(((static.TOTAL_BYTES) / total_transmission_time) * 60) ((static.TOTAL_BYTES) / total_transmission_time) * 60)
burst_bytes = static.ARQ_PAYLOAD_PER_FRAME * static.ARQ_N_RX_FRAMES_PER_BURSTS burst_bytes = static.ARQ_PAYLOAD_PER_FRAME * static.ARQ_N_RX_FRAMES_PER_BURSTS
burst_transmission_time = time.time() - static.ARQ_START_OF_BURST burst_transmission_time = time.time() - static.ARQ_START_OF_BURST
print("BURST TRANSMISSION TIME: " + str(burst_transmission_time)) print("BURST TRANSMISSION TIME: " + str(burst_transmission_time))
static.ARQ_BITS_PER_SECOND_BURST = int((burst_bytes * 8) / burst_transmission_time) static.ARQ_BITS_PER_SECOND_BURST = int(
static.ARQ_BYTES_PER_MINUTE_BURST = int(((burst_bytes) / burst_transmission_time) * 60) (burst_bytes * 8) / burst_transmission_time)
print("static.ARQ_BITS_PER_SECOND_BURST: " + str(static.ARQ_BITS_PER_SECOND_BURST)) static.ARQ_BYTES_PER_MINUTE_BURST = int(
print("static.ARQ_BYTES_PER_MINUTE_BURST: " + str(static.ARQ_BYTES_PER_MINUTE_BURST)) ((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 # PERCENTAGE FOR TRANSMITTING
if static.TX_BUFFER_SIZE > 0: if static.TX_BUFFER_SIZE > 0:
print("static.ARQ_N_SENT_FRAMES: " + str(static.ARQ_N_SENT_FRAMES)) 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 # PERCENTAGE FOR RECEIVING
elif arq_n_arq_frames_per_data_frame > 0: 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: else:
static.ARQ_TRANSMISSION_PERCENT = 0.0 static.ARQ_TRANSMISSION_PERCENT = 0.0
print("static.ARQ_TRANSMISSION_PERCENT: " + str(static.ARQ_TRANSMISSION_PERCENT)) 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_BYTES_PER_MINUTE: " + str(static.ARQ_BYTES_PER_MINUTE))
print("static.ARQ_BITS_PER_SECOND: " + str(static.ARQ_BITS_PER_SECOND)) 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] 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 # check if buffer empty
if len(static.HEARD_STATIONS) == 0: 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 # if not, we search and update
else: else:
for i in range(0, len(static.HEARD_STATIONS)): for i in range(0, len(static.HEARD_STATIONS)):
# update callsign with new timestamp # update callsign with new timestamp
if static.HEARD_STATIONS[i].count(dxcallsign) > 0: 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 break
# insert if nothing found # insert if nothing found
if i == len(static.HEARD_STATIONS) - 1: 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 break
@ -223,21 +237,24 @@ def setup_logging():
""" """
logging.basicConfig(level=logging.INFO, \ logging.basicConfig(level=logging.INFO,
encoding='utf-8', \ encoding='utf-8',
format='%(asctime)s.%(msecs)03d %(levelname)s:\t%(message)s', \ format='%(asctime)s.%(msecs)03d %(levelname)s:\t%(message)s',
datefmt='%H:%M:%S', \ datefmt='%H:%M:%S',
handlers=[logging.FileHandler("codec2-FreeDATA-TNC.log"),logging.StreamHandler()] 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.addLevelName(logging.INFO, "\033[1;37m%s\033[1;0m" % logging.getLevelName(logging.INFO)) logging.DEBUG, "\033[1;36m%s\033[1;0m" % logging.getLevelName(logging.DEBUG))
logging.addLevelName(logging.WARNING, "\033[1;33m%s\033[1;0m" % logging.getLevelName(logging.WARNING)) 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" % "FAILED")
#logging.addLevelName( logging.ERROR, "\033[1;31m%s\033[1;0m" % logging.getLevelName(logging.ERROR)) #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(25, "\033[1;32m%s\033[1;0m" % "SUCCESS")
logging.addLevelName(24, "\033[1;34m%s\033[1;0m" % "DATA") 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 @author: DJ2LS
""" """
import sys
import ctypes import ctypes
from ctypes import * from ctypes import *
import pathlib import pathlib
import pyaudio
import audioop import audioop
import asyncio #import asyncio
#import sys
import logging import logging
import time import time
import threading import threading
import atexit import atexit
import numpy as np
import pyaudio
import helpers import helpers
import static import static
import data_handler import data_handler
import sys
#sys.path.append("hamlib/linux") # sys.path.append("hamlib/linux")
try: try:
import Hamlib import Hamlib
print("running Hamlib from Sys Path") print("running Hamlib from Sys Path")
@ -34,7 +33,7 @@ else:
# place for rigctld # place for rigctld
pass pass
import numpy as np
#import rigctld #import rigctld
#rigctld = rigctld.Rigctld() #rigctld = rigctld.Rigctld()
@ -42,6 +41,7 @@ import numpy as np
MODEM_STATS_NR_MAX = 320 MODEM_STATS_NR_MAX = 320
MODEM_STATS_NC_MAX = 51 MODEM_STATS_NC_MAX = 51
class MODEMSTATS(ctypes.Structure): class MODEMSTATS(ctypes.Structure):
_fields_ = [ _fields_ = [
("Nc", ctypes.c_int), ("Nc", ctypes.c_int),
@ -99,20 +99,23 @@ class RF():
self.audio_writing_to_stream = False self.audio_writing_to_stream = False
# --------------------------------------------START DECODER THREAD # --------------------------------------------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() 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() PLAYBACK_THREAD.start()
self.fft_data = bytes() 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() FFT_THREAD.start()
# --------------------------------------------CONFIGURE HAMLIB # --------------------------------------------CONFIGURE HAMLIB
#my_rig.set_ptt(Hamlib.RIG_PTT_RIG,0) # 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_DTR,0)
#my_rig.set_ptt(Hamlib.RIG_PTT_SERIAL_RTS,1) # my_rig.set_ptt(Hamlib.RIG_PTT_SERIAL_RTS,1)
#self.my_rig.set_conf("dtr_state", "OFF") #self.my_rig.set_conf("dtr_state", "OFF")
#my_rig.set_conf("rts_state", "OFF") #my_rig.set_conf("rts_state", "OFF")
#self.my_rig.set_conf("ptt_type", "RTS") #self.my_rig.set_conf("ptt_type", "RTS")
@ -129,7 +132,6 @@ class RF():
self.my_rig.set_conf("stop_bits", "1") self.my_rig.set_conf("stop_bits", "1")
self.my_rig.set_conf("data_bits", "8") self.my_rig.set_conf("data_bits", "8")
if static.HAMLIB_PTT_TYPE == 'RIG': if static.HAMLIB_PTT_TYPE == 'RIG':
self.hamlib_ptt_type = Hamlib.RIG_PTT_RIG self.hamlib_ptt_type = Hamlib.RIG_PTT_RIG
@ -160,7 +162,6 @@ class RF():
else: # static.HAMLIB_PTT_TYPE == 'RIG_PTT_NONE': else: # static.HAMLIB_PTT_TYPE == 'RIG_PTT_NONE':
self.hamlib_ptt_type = Hamlib.RIG_PTT_NONE self.hamlib_ptt_type = Hamlib.RIG_PTT_NONE
self.my_rig.open() self.my_rig.open()
atexit.register(self.my_rig.close) atexit.register(self.my_rig.close)
@ -168,7 +169,8 @@ class RF():
self.my_rig.set_mode(Hamlib.RIG_MODE_USB) self.my_rig.set_mode(Hamlib.RIG_MODE_USB)
# start thread for getting hamlib data # 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() HAMLIB_THREAD.start()
except: except:
@ -178,18 +180,18 @@ class RF():
# -------------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------------
def ptt_and_wait(self, state): def ptt_and_wait(self, state):
static.PTT_STATE = state static.PTT_STATE = state
if state: if state:
self.my_rig.set_ptt(self.hamlib_ptt_type, 1) self.my_rig.set_ptt(self.hamlib_ptt_type, 1)
#rigctld.ptt_enable() # rigctld.ptt_enable()
ptt_toggle_timeout = time.time() + 0.5 ptt_toggle_timeout = time.time() + 0.5
while time.time() < ptt_toggle_timeout: while time.time() < ptt_toggle_timeout:
pass pass
else: else:
ptt_toggle_timeout = time.time() + 0.5 ptt_toggle_timeout = time.time() + 0.5
@ -197,17 +199,16 @@ class RF():
pass pass
self.my_rig.set_ptt(self.hamlib_ptt_type, 0) self.my_rig.set_ptt(self.hamlib_ptt_type, 0)
#rigctld.ptt_disable() # rigctld.ptt_disable()
return False return False
def play_audio(self): def play_audio(self):
while True: while True:
time.sleep(0.01) time.sleep(0.01)
#while len(self.streambuffer) > 0: # while len(self.streambuffer) > 0:
# time.sleep(0.01) # time.sleep(0.01)
if len(self.streambuffer) > 0 and self.audio_writing_to_stream: if len(self.streambuffer) > 0 and self.audio_writing_to_stream:
self.streambuffer = bytes(self.streambuffer) self.streambuffer = bytes(self.streambuffer)
@ -224,36 +225,47 @@ class RF():
def transmit_signalling(self, data_out, count): def transmit_signalling(self, data_out, count):
state_before_transmit = static.CHANNEL_STATE state_before_transmit = static.CHANNEL_STATE
static.CHANNEL_STATE = 'SENDING_SIGNALLING' static.CHANNEL_STATE = 'SENDING_SIGNALLING'
#print(static.CHANNEL_STATE) # print(static.CHANNEL_STATE)
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte) self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
freedv = self.c_lib.freedv_open(static.FREEDV_SIGNALLING_MODE) 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 payload_per_frame = bytes_per_frame - 2
n_nom_modem_samples = self.c_lib.freedv_get_n_nom_modem_samples(freedv) 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 # 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_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv)
n_tx_postamble_modem_samples = self.c_lib.freedv_get_n_tx_postamble_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 = ctypes.c_short * n_tx_modem_samples
mod_out = mod_out() 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_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() mod_out_postamble = mod_out_postamble()
buffer = bytearray(payload_per_frame) # use this if CRC16 checksum is required ( DATA1-3) # 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 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 = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(
crc = crc.value.to_bytes(2, byteorder='big') # convert crc to 2 byte hex string 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 buffer += crc # append crc16 to buffer
data = (ctypes.c_ubyte * bytes_per_frame).from_buffer_copy(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_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.c_lib.freedv_rawdatapostambletx(freedv, mod_out_postamble)
self.streambuffer = bytearray() self.streambuffer = bytearray()
@ -261,14 +273,15 @@ class RF():
self.streambuffer += bytes(mod_out) self.streambuffer += bytes(mod_out)
self.streambuffer += bytes(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]) self.streambuffer = bytes(converted_audio[0])
# append frame again with as much as in count defined # append frame again with as much as in count defined
for i in range(1, count): for i in range(1, count):
self.streambuffer += bytes(converted_audio[0]) self.streambuffer += bytes(converted_audio[0])
#print(len(self.streambuffer)) # print(len(self.streambuffer))
#self.streambuffer += bytes(converted_audio[0]) #self.streambuffer += bytes(converted_audio[0])
#print(len(self.streambuffer)) # print(len(self.streambuffer))
# -------------- transmit audio # -------------- transmit audio
#logging.debug("SENDING SIGNALLING FRAME " + str(data_out)) #logging.debug("SENDING SIGNALLING FRAME " + str(data_out))
@ -286,7 +299,7 @@ class RF():
static.CHANNEL_STATE = 'SENDING_SIGNALLING' static.CHANNEL_STATE = 'SENDING_SIGNALLING'
self.ptt_and_wait(False) self.ptt_and_wait(False)
## we have a problem with the receiving state # we have a problem with the receiving state
##static.CHANNEL_STATE = state_before_transmit ##static.CHANNEL_STATE = state_before_transmit
if state_before_transmit != 'RECEIVING_DATA': if state_before_transmit != 'RECEIVING_DATA':
static.CHANNEL_STATE = 'RECEIVING_SIGNALLING' static.CHANNEL_STATE = 'RECEIVING_SIGNALLING'
@ -302,8 +315,10 @@ class RF():
# we could place this timing part inside the modem... # we could place this timing part inside the modem...
# lets see if this is a good idea.. # lets see if this is a good idea..
static.ARQ_DATA_CHANNEL_LAST_RECEIVED = int(time.time()) # we need to update our timeout timestamp # we need to update our timeout timestamp
static.ARQ_START_OF_BURST = int(time.time()) # 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 state_before_transmit = static.CHANNEL_STATE
static.CHANNEL_STATE = 'SENDING_DATA' static.CHANNEL_STATE = 'SENDING_DATA'
@ -311,21 +326,27 @@ class RF():
self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte) self.c_lib.freedv_open.restype = ctypes.POINTER(ctypes.c_ubyte)
freedv = self.c_lib.freedv_open(static.ARQ_DATA_CHANNEL_MODE) 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 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_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 # *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_modem_samples = self.c_lib.freedv_get_n_tx_modem_samples(freedv)
n_tx_postamble_modem_samples = self.c_lib.freedv_get_n_tx_postamble_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 = ctypes.c_short * n_tx_modem_samples
mod_out = mod_out() 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_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() mod_out_postamble = mod_out_postamble()
self.streambuffer = bytearray() self.streambuffer = bytearray()
@ -339,10 +360,12 @@ class RF():
frame_type = 10 + n + 1 # static.ARQ_TX_N_FRAMES_PER_BURST frame_type = 10 + n + 1 # static.ARQ_TX_N_FRAMES_PER_BURST
frame_type = bytes([frame_type]) 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 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) n_total_arq_frame = len(static.TX_BUFFER)
#static.ARQ_TX_N_TOTAL_ARQ_FRAMES = n_total_arq_frame #static.ARQ_TX_N_TOTAL_ARQ_FRAMES = n_total_arq_frame
@ -355,19 +378,24 @@ class RF():
static.MYCALLSIGN_CRC8 + \ static.MYCALLSIGN_CRC8 + \
payload_data payload_data
buffer = bytearray(static.FREEDV_DATA_PAYLOAD_PER_FRAME) # create TX buffer # create TX buffer
buffer[:len(arqframe)] = arqframe # set buffersize to length of data which will be send 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 = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(
crc = crc.value.to_bytes(2, byteorder='big') # convert crc to 2 byte hex string 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 buffer += crc # append crc16 to buffer
data = (ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME).from_buffer_copy(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 # modulate DATA and safe it into mod_out pointer
self.c_lib.freedv_rawdatatx(freedv, mod_out, data)
self.streambuffer += bytes(mod_out) self.streambuffer += bytes(mod_out)
elif static.ARQ_RPT_RECEIVED: elif static.ARQ_RPT_RECEIVED:
for n in range(0, len(static.ARQ_RPT_FRAMES)): for n in range(0, len(static.ARQ_RPT_FRAMES)):
@ -378,12 +406,14 @@ class RF():
frame_type = bytes([frame_type]) frame_type = bytes([frame_type])
try: 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: except:
print("modem buffer selection problem with ARQ RPT frames") print("modem buffer selection problem with ARQ RPT frames")
n_current_arq_frame = static.ARQ_N_SENT_FRAMES + missing_frame 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) n_total_arq_frame = len(static.TX_BUFFER)
#static.ARQ_TX_N_TOTAL_ARQ_FRAMES = n_total_arq_frame #static.ARQ_TX_N_TOTAL_ARQ_FRAMES = n_total_arq_frame
@ -396,26 +426,31 @@ class RF():
static.MYCALLSIGN_CRC8 + \ static.MYCALLSIGN_CRC8 + \
payload_data payload_data
buffer = bytearray(static.FREEDV_DATA_PAYLOAD_PER_FRAME) # create TX buffer # create TX buffer
buffer[:len(arqframe)] = arqframe # set buffersize to length of data which will be send 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 = ctypes.c_ushort(self.c_lib.freedv_gen_crc16(
crc = crc.value.to_bytes(2, byteorder='big') # convert crc to 2 byte hex string 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 buffer += crc # append crc16 to buffer
data = (ctypes.c_ubyte * static.FREEDV_DATA_BYTES_PER_FRAME).from_buffer_copy(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 # modulate DATA and safe it into mod_out pointer
self.c_lib.freedv_rawdatatx(freedv, mod_out, data)
self.streambuffer += bytes(mod_out) self.streambuffer += bytes(mod_out)
self.c_lib.freedv_rawdatapostambletx(freedv, mod_out_postamble) self.c_lib.freedv_rawdatapostambletx(freedv, mod_out_postamble)
self.streambuffer += bytes(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]) self.streambuffer = bytes(converted_audio[0])
# -------------- transmit audio # -------------- transmit audio
while self.ptt_and_wait(True): while self.ptt_and_wait(True):
@ -447,10 +482,11 @@ class RF():
datac0_bytes_per_frame = int(self.c_lib.freedv_get_bits_per_modem_frame(datac0_freedv)/8) 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_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 # bytes_per_frame
datac0_bytes_out = datac0_bytes_out() #get pointer from bytes_out 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) self.c_lib.freedv_set_frames_per_burst(datac0_freedv, 1)
datac0_modem_stats_snr = c_float() datac0_modem_stats_snr = c_float()
datac0_modem_stats_sync = c_int() datac0_modem_stats_sync = c_int()
datac0_buffer = bytes() datac0_buffer = bytes()
@ -463,9 +499,10 @@ class RF():
datac1_freedv = self.c_lib.freedv_open(10) 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_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_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 # bytes_per_frame
datac1_bytes_out = datac1_bytes_out() #get pointer from bytes_out datac1_bytes_out = (ctypes.c_ubyte * datac1_bytes_per_frame)
self.c_lib.freedv_set_frames_per_burst(datac1_freedv,1) 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_snr = c_float()
datac1_modem_stats_sync = c_int() datac1_modem_stats_sync = c_int()
datac1_buffer = bytes() datac1_buffer = bytes()
@ -475,9 +512,10 @@ class RF():
datac3_freedv = self.c_lib.freedv_open(12) 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_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_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 # bytes_per_frame
datac3_bytes_out = datac3_bytes_out() #get pointer from bytes_out datac3_bytes_out = (ctypes.c_ubyte * datac3_bytes_per_frame)
self.c_lib.freedv_set_frames_per_burst(datac3_freedv,1) 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_snr = c_float()
datac3_modem_stats_sync = c_int() datac3_modem_stats_sync = c_int()
datac3_buffer = bytes() datac3_buffer = bytes()
@ -503,10 +541,10 @@ class RF():
''' '''
data_in = bytes() 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 #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 = 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 = data_in[0] # .rstrip(b'\x00')
self.fft_data = data_in self.fft_data = data_in
# we need to set nin * 2 beause of byte size in array handling # we need to set nin * 2 beause of byte size in array handling
@ -520,40 +558,36 @@ class RF():
datac1_buffer += data_in datac1_buffer += data_in
datac3_buffer += data_in datac3_buffer += data_in
# DECODING DATAC0 # DECODING DATAC0
if len(datac0_buffer) >= (datac0_nin): if len(datac0_buffer) >= (datac0_nin):
datac0_audio = datac0_buffer[:datac0_nin] datac0_audio = datac0_buffer[:datac0_nin]
datac0_buffer = datac0_buffer[datac0_nin:] datac0_buffer = datac0_buffer[datac0_nin:]
#print(len(datac0_audio)) # print(len(datac0_audio))
self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), datac0_bytes_out, 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) sync = self.c_lib.freedv_get_rx_status(datac0_freedv)
if sync != 0 and nbytes != 0: if sync != 0 and nbytes != 0:
#calculate snr and scatter # calculate snr and scatter
self.get_scatter(datac0_freedv) self.get_scatter(datac0_freedv)
self.calculate_snr(datac0_freedv) self.calculate_snr(datac0_freedv)
datac0_task = threading.Thread(target=self.process_data, args=[datac0_bytes_out, datac0_freedv]) datac0_task = threading.Thread(target=self.process_data, args=[datac0_bytes_out, datac0_freedv])
datac0_task.start() datac0_task.start()
# DECODING DATAC1 # DECODING DATAC1
if len(datac1_buffer) >= (datac1_nin): if len(datac1_buffer) >= (datac1_nin):
datac1_audio = datac1_buffer[:datac1_nin] datac1_audio = datac1_buffer[:datac1_nin]
datac1_buffer = datac1_buffer[datac1_nin:] datac1_buffer = datac1_buffer[datac1_nin:]
#print(len(datac1_audio)) # print(len(datac1_audio))
self.c_lib.freedv_rawdatarx.argtype = [ctypes.POINTER(ctypes.c_ubyte), datac1_bytes_out, 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) sync = self.c_lib.freedv_get_rx_status(datac1_freedv)
if sync != 0 and nbytes != 0: if sync != 0 and nbytes != 0:
#calculate snr and scatter # calculate snr and scatter
self.get_scatter(datac1_freedv) self.get_scatter(datac1_freedv)
self.calculate_snr(datac1_freedv) self.calculate_snr(datac1_freedv)
@ -570,14 +604,13 @@ class RF():
sync = self.c_lib.freedv_get_rx_status(datac3_freedv) sync = self.c_lib.freedv_get_rx_status(datac3_freedv)
if sync != 0 and nbytes != 0: if sync != 0 and nbytes != 0:
#calculate snr and scatter # calculate snr and scatter
self.get_scatter(datac3_freedv) self.get_scatter(datac3_freedv)
self.calculate_snr(datac3_freedv) self.calculate_snr(datac3_freedv)
datac3_task = threading.Thread(target=self.process_data, args=[datac3_bytes_out, datac3_freedv]) datac3_task = threading.Thread(target=self.process_data, args=[datac3_bytes_out, datac3_freedv])
datac3_task.start() datac3_task.start()
# forward data only if broadcast or we are the receiver # 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 # 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 # we could also create an own function, which returns True. In this case we could add callsign blacklists and so on
@ -598,7 +631,8 @@ class RF():
if 50 >= frametype >= 10: if 50 >= frametype >= 10:
if frame != 3 or force == True: if frame != 3 or force == True:
data_handler.arq_data_received(bytes(bytes_out[:-2])) # send payload data to arq checker without CRC16 # send payload data to arq checker without CRC16
data_handler.arq_data_received(bytes(bytes_out[:-2]))
#print("static.ARQ_RX_BURST_BUFFER.count(None) " + str(static.ARQ_RX_BURST_BUFFER.count(None))) #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: if static.ARQ_RX_BURST_BUFFER.count(None) <= 1:
@ -606,7 +640,8 @@ class RF():
self.c_lib.freedv_set_sync(freedv, 0) self.c_lib.freedv_set_sync(freedv, 0)
else: else:
logging.critical("---------------------------SIMULATED MISSING FRAME") logging.critical(
"---------------------------SIMULATED MISSING FRAME")
force = True force = True
# BURST ACK # BURST ACK
@ -645,19 +680,19 @@ class RF():
data_handler.received_ping_ack(bytes_out[:-2]) data_handler.received_ping_ack(bytes_out[:-2])
# ARQ CONNECT # ARQ CONNECT
elif frametype == 220: # elif frametype == 220:
logging.info("ARQ CONNECT RECEIVED....") # logging.info("ARQ CONNECT RECEIVED....")
data_handler.arq_received_connect(bytes_out[:-2]) # data_handler.arq_received_connect(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE # ARQ CONNECT ACK / KEEP ALIVE
elif frametype == 221: # elif frametype == 221:
logging.info("ARQ CONNECT ACK RECEIVED / KEEP ALIVE....") # logging.info("ARQ CONNECT ACK RECEIVED / KEEP ALIVE....")
data_handler.arq_received_connect_keep_alive(bytes_out[:-2]) # data_handler.arq_received_connect_keep_alive(bytes_out[:-2])
# ARQ CONNECT ACK / KEEP ALIVE # ARQ CONNECT ACK / KEEP ALIVE
elif frametype == 222: # elif frametype == 222:
logging.debug("ARQ DISCONNECT RECEIVED") # logging.debug("ARQ DISCONNECT RECEIVED")
data_handler.arq_disconnect_received(bytes_out[:-2]) # data_handler.arq_disconnect_received(bytes_out[:-2])
# ARQ FILE TRANSFER RECEIVED! # ARQ FILE TRANSFER RECEIVED!
elif frametype == 225: elif frametype == 225:
@ -688,29 +723,29 @@ class RF():
# clear bytes_out buffer to be ready for next frames after successfull decoding # clear bytes_out buffer to be ready for next frames after successfull decoding
#bytes_out = (ctypes.c_ubyte * bytes_per_frame) #bytes_out = (ctypes.c_ubyte * bytes_per_frame)
#bytes_out = bytes_out() # get pointer to bytes_out # bytes_out = bytes_out() # get pointer to bytes_out
else: else:
# for debugging purposes to receive all data # for debugging purposes to receive all data
pass pass
# print(bytes_out[:-2]) # print(bytes_out[:-2])
def get_scatter(self, freedv): def get_scatter(self, freedv):
modemStats = MODEMSTATS() modemStats = MODEMSTATS()
self.c_lib.freedv_get_modem_extended_stats.restype = None 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 = [] scatterdata = []
for i in range(MODEM_STATS_NC_MAX): for i in range(MODEM_STATS_NC_MAX):
for j in range(MODEM_STATS_NR_MAX): for j in range(MODEM_STATS_NR_MAX):
#check if odd or not to get every 2nd item for x # check if odd or not to get every 2nd item for x
if (j % 2) == 0: if (j % 2) == 0:
xsymbols = modemStats.rx_symbols[i][j] 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 # check if value 0.0 or has real data
if xsymbols != 0.0 and ysymbols != 0.0: 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 # only append scatter data if new data arrived
if len(scatterdata) > 0: if len(scatterdata) > 0:
@ -732,10 +767,11 @@ class RF():
modem_stats_snr = c_float() modem_stats_snr = c_float()
modem_stats_sync = c_int() 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 modem_stats_snr = modem_stats_snr.value
try: try:
static.SNR = round(modem_stats_snr,1) static.SNR = round(modem_stats_snr, 1)
except: except:
static.SNR = 0 static.SNR = 0
@ -749,7 +785,6 @@ class RF():
#static.HAMLIB_MODE = rigctld.get_mode()[0] #static.HAMLIB_MODE = rigctld.get_mode()[0]
#static.HAMLIB_BANDWITH = rigctld.get_mode()[1] #static.HAMLIB_BANDWITH = rigctld.get_mode()[1]
def calculate_fft(self): def calculate_fft(self):
while True: while True:
time.sleep(0.01) time.sleep(0.01)
@ -776,4 +811,3 @@ class RF():
print("setting fft = 0") print("setting fft = 0")
# else 0 # else 0
static.FFT = [0] * 400 static.FFT = [0] * 400

View file

@ -33,12 +33,14 @@ import static
import data_handler import data_handler
import helpers import helpers
import sys, os import sys
import os
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass pass
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self): def handle(self):
@ -59,12 +61,12 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
chunk = self.request.recv(71) # we keep amount of bytes short chunk = self.request.recv(71) # we keep amount of bytes short
data += chunk 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 break
data = data[:-1] # remove b'\n' data = data[:-1] # remove b'\n'
data = str(data, 'utf-8') data = str(data, 'utf-8')
if len(data) > 0: if len(data) > 0:
socketTimeout = time.time() + static.SOCKET_TIMEOUT socketTimeout = time.time() + static.SOCKET_TIMEOUT
@ -78,7 +80,7 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
data = data.splitlines()[0] data = data.splitlines()[0]
received_json = json.loads(data) received_json = json.loads(data)
#except ValueError as e: # except ValueError as e:
# print("++++++++++++ START OF JSON ERROR +++++++++++++++++++++++") # print("++++++++++++ START OF JSON ERROR +++++++++++++++++++++++")
# print(e) # print(e)
# print("-----------------------------------") # print("-----------------------------------")
@ -86,27 +88,30 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
# print("++++++++++++ END OF JSON ERROR +++++++++++++++++++++++++") # print("++++++++++++ END OF JSON ERROR +++++++++++++++++++++++++")
# received_json = {} # received_json = {}
# break # break
#try: # try:
# CQ CQ CQ ----------------------------------------------------- # CQ CQ CQ -----------------------------------------------------
if received_json["command"] == "CQCQCQ": if received_json["command"] == "CQCQCQ":
#socketTimeout = 0 #socketTimeout = 0
#asyncio.run(data_handler.transmit_cq()) # asyncio.run(data_handler.transmit_cq())
CQ_THREAD = threading.Thread(target=data_handler.transmit_cq, args=[], name="CQ") CQ_THREAD = threading.Thread(
target=data_handler.transmit_cq, args=[], name="CQ")
CQ_THREAD.start() CQ_THREAD.start()
# PING ---------------------------------------------------------- # 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 # send ping frame and wait for ACK
dxcallsign = received_json["dxcallsign"] dxcallsign = received_json["dxcallsign"]
#asyncio.run(data_handler.transmit_ping(dxcallsign)) # asyncio.run(data_handler.transmit_ping(dxcallsign))
PING_THREAD = threading.Thread(target=data_handler.transmit_ping, args=[dxcallsign], name="CQ") PING_THREAD = threading.Thread(
target=data_handler.transmit_ping, args=[dxcallsign], name="CQ")
PING_THREAD.start() 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' 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()) static.ARQ_START_OF_TRANSMISSION = int(time.time())
dxcallsign = received_json["dxcallsign"] dxcallsign = received_json["dxcallsign"]
@ -118,10 +123,11 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
checksum = received_json["checksum"] checksum = received_json["checksum"]
static.DXCALLSIGN = bytes(dxcallsign, 'utf-8') 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 + '"}' #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} #dataframe = {filename: filename}
#data_out = bytes(received_json["data"], 'utf-8') #data_out = bytes(received_json["data"], 'utf-8')
dataframe = json.dumps(rawdata) dataframe = json.dumps(rawdata)
@ -141,8 +147,10 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
self.request.sendall(b'INVALID CALLSIGN') self.request.sendall(b'INVALID CALLSIGN')
else: else:
static.MYCALLSIGN = bytes(callsign, encoding) static.MYCALLSIGN = bytes(callsign, encoding)
static.MYCALLSIGN_CRC8 = helpers.get_crc_8(static.MYCALLSIGN) static.MYCALLSIGN_CRC8 = helpers.get_crc_8(
logging.info("CMD | MYCALLSIGN: " + str(static.MYCALLSIGN)) static.MYCALLSIGN)
logging.info("CMD | MYCALLSIGN: " +
str(static.MYCALLSIGN))
if received_json["type"] == 'SET' and received_json["command"] == 'MYGRID': if received_json["type"] == 'SET' and received_json["command"] == 'MYGRID':
mygrid = received_json["parameter"] mygrid = received_json["parameter"]
@ -153,15 +161,14 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
static.MYGRID = bytes(mygrid, encoding) static.MYGRID = bytes(mygrid, encoding)
logging.info("CMD | MYGRID: " + str(static.MYGRID)) logging.info("CMD | MYGRID: " + str(static.MYGRID))
if received_json["type"] == 'GET' and received_json["command"] == 'STATION_INFO': if received_json["type"] == 'GET' and received_json["command"] == 'STATION_INFO':
output = { output = {
"COMMAND": "STATION_INFO", "COMMAND": "STATION_INFO",
"TIMESTAMP" : received_json["timestamp"], "TIMESTAMP": received_json["timestamp"],
"MY_CALLSIGN": str(static.MYCALLSIGN, encoding), "MY_CALLSIGN": str(static.MYCALLSIGN, encoding),
"DX_CALLSIGN": str(static.DXCALLSIGN, encoding), "DX_CALLSIGN": str(static.DXCALLSIGN, encoding),
"DX_GRID": str(static.DXGRID, encoding), "DX_GRID": str(static.DXGRID, encoding),
"EOF" : "EOF", "EOF": "EOF",
} }
jsondata = json.dumps(output) jsondata = json.dumps(output)
@ -170,7 +177,7 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
if received_json["type"] == 'GET' and received_json["command"] == 'TNC_STATE': if received_json["type"] == 'GET' and received_json["command"] == 'TNC_STATE':
output = { output = {
"COMMAND": "TNC_STATE", "COMMAND": "TNC_STATE",
"TIMESTAMP" : received_json["timestamp"], "TIMESTAMP": received_json["timestamp"],
"PTT_STATE": str(static.PTT_STATE), "PTT_STATE": str(static.PTT_STATE),
"CHANNEL_STATE": str(static.CHANNEL_STATE), "CHANNEL_STATE": str(static.CHANNEL_STATE),
"TNC_STATE": str(static.TNC_STATE), "TNC_STATE": str(static.TNC_STATE),
@ -178,32 +185,32 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
"AUDIO_RMS": str(static.AUDIO_RMS), "AUDIO_RMS": str(static.AUDIO_RMS),
"BER": str(static.BER), "BER": str(static.BER),
"SNR": str(static.SNR), "SNR": str(static.SNR),
"FREQUENCY" : str(static.HAMLIB_FREQUENCY), "FREQUENCY": str(static.HAMLIB_FREQUENCY),
"MODE" : str(static.HAMLIB_MODE), "MODE": str(static.HAMLIB_MODE),
"BANDWITH" : str(static.HAMLIB_BANDWITH), "BANDWITH": str(static.HAMLIB_BANDWITH),
"FFT" : str(static.FFT), "FFT": str(static.FFT),
"SCATTER" : static.SCATTER, "SCATTER": static.SCATTER,
"RX_BUFFER_LENGTH": str(len(static.RX_BUFFER)), "RX_BUFFER_LENGTH": str(len(static.RX_BUFFER)),
"TX_N_MAX_RETRIES": str(static.TX_N_MAX_RETRIES), "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_FRAMES_PER_BURST": str(static.ARQ_TX_N_FRAMES_PER_BURST),
"ARQ_TX_N_BURSTS": str(static.ARQ_TX_N_BURSTS), "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_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_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_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_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": str(static.ARQ_BYTES_PER_MINUTE),
"ARQ_BYTES_PER_MINUTE_BURST" : str(static.ARQ_BYTES_PER_MINUTE_BURST), "ARQ_BYTES_PER_MINUTE_BURST": str(static.ARQ_BYTES_PER_MINUTE_BURST),
"ARQ_TRANSMISSION_PERCENT" : str(static.ARQ_TRANSMISSION_PERCENT), "ARQ_TRANSMISSION_PERCENT": str(static.ARQ_TRANSMISSION_PERCENT),
"TOTAL_BYTES" : str(static.TOTAL_BYTES), "TOTAL_BYTES": str(static.TOTAL_BYTES),
"STATIONS" : [], "STATIONS": [],
"EOF" : "EOF", "EOF": "EOF",
} }
for i in range(0, len(static.HEARD_STATIONS)): 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]}) 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: try:
jsondata = json.dumps(output) jsondata = json.dumps(output)
@ -215,18 +222,17 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
except Exception as e: except Exception as e:
print(e) print(e)
if received_json["type"] == 'GET' and received_json["command"] == 'RX_BUFFER': if received_json["type"] == 'GET' and received_json["command"] == 'RX_BUFFER':
output = { output = {
"COMMAND": "RX_BUFFER", "COMMAND": "RX_BUFFER",
"DATA-ARRAY" : [], "DATA-ARRAY": [],
"EOF" : "EOF", "EOF": "EOF",
} }
for i in range(0, len(static.RX_BUFFER)): for i in range(0, len(static.RX_BUFFER)):
rawdata = json.loads(static.RX_BUFFER[i][3]) 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) jsondata = json.dumps(output)
self.request.sendall(bytes(jsondata, encoding)) self.request.sendall(bytes(jsondata, encoding))
@ -234,9 +240,8 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
if received_json["type"] == 'SET' and received_json["command"] == 'DEL_RX_BUFFER': if received_json["type"] == 'SET' and received_json["command"] == 'DEL_RX_BUFFER':
static.RX_BUFFER = [] static.RX_BUFFER = []
# exception, if JSON cant be decoded
#exception, if JSON cant be decoded # except Exception as e:
#except Exception as e:
except: except:
print("############ START OF ERROR #####################") print("############ START OF ERROR #####################")
print("SOCKET COMMAND ERROR: " + data) print("SOCKET COMMAND ERROR: " + data)
@ -251,17 +256,20 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
#socketTimeout = 0 #socketTimeout = 0
print("Client disconnected...") print("Client disconnected...")
def start_cmd_socket(): def start_cmd_socket():
try: try:
logging.info("SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(static.PORT)) logging.info(
socketserver.TCPServer.allow_reuse_address = True # https://stackoverflow.com/a/16641793 "SRV | STARTING TCP/IP SOCKET FOR CMD ON PORT: " + str(static.PORT))
cmdserver = ThreadedTCPServer((static.HOST, static.PORT), ThreadedTCPRequestHandler) # 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 = threading.Thread(target=cmdserver.serve_forever)
server_thread.daemon = True server_thread.daemon = True
server_thread.start() server_thread.start()
except: except:
print("Socket error...") print("Socket error...")
e = sys.exc_info()[0] e = sys.exc_info()[0]