mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
better pep8 conformity
This commit is contained in:
parent
21eb8fa12b
commit
5c7e05ef70
4 changed files with 531 additions and 472 deletions
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
||||||
|
|
420
tnc/modem.py
420
tnc/modem.py
|
@ -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,21 +41,22 @@ 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),
|
||||||
("snr_est", ctypes.c_float),
|
("snr_est", ctypes.c_float),
|
||||||
("rx_symbols", (ctypes.c_float * MODEM_STATS_NR_MAX)*MODEM_STATS_NC_MAX),
|
("rx_symbols", (ctypes.c_float * MODEM_STATS_NR_MAX)*MODEM_STATS_NC_MAX),
|
||||||
("nr", ctypes.c_int),
|
("nr", ctypes.c_int),
|
||||||
("sync", ctypes.c_int),
|
("sync", ctypes.c_int),
|
||||||
("foff", ctypes.c_float),
|
("foff", ctypes.c_float),
|
||||||
("rx_timing", ctypes.c_float),
|
("rx_timing", ctypes.c_float),
|
||||||
("clock_offset", ctypes.c_float),
|
("clock_offset", ctypes.c_float),
|
||||||
("sync_metric", ctypes.c_float),
|
("sync_metric", ctypes.c_float),
|
||||||
("pre", ctypes.c_int),
|
("pre", ctypes.c_int),
|
||||||
("post", ctypes.c_int),
|
("post", ctypes.c_int),
|
||||||
("uw_fails", ctypes.c_int),
|
("uw_fails", ctypes.c_int),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class RF():
|
class RF():
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -565,19 +599,18 @@ class RF():
|
||||||
datac3_audio = 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]
|
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)
|
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
|
||||||
|
@ -587,130 +620,132 @@ class RF():
|
||||||
print(bytes(bytes_out))
|
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':
|
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()
|
helpers.calculate_transfer_rate()
|
||||||
# CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------
|
# CHECK IF FRAMETYPE IS BETWEEN 10 and 50 ------------------------
|
||||||
frametype = int.from_bytes(bytes(bytes_out[:1]), "big")
|
frametype = int.from_bytes(bytes(bytes_out[:1]), "big")
|
||||||
frame = frametype - 10
|
frame = frametype - 10
|
||||||
n_frames_per_burst = int.from_bytes(bytes(bytes_out[1:2]), "big")
|
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);
|
#self.c_lib.freedv_set_frames_per_burst(freedv_data, n_frames_per_burst);
|
||||||
|
|
||||||
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:
|
||||||
logging.debug("FULL BURST BUFFER ---> UNSYNC")
|
logging.debug("FULL BURST BUFFER ---> UNSYNC")
|
||||||
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(
|
||||||
force = True
|
"---------------------------SIMULATED MISSING FRAME")
|
||||||
|
force = True
|
||||||
|
|
||||||
# BURST ACK
|
# BURST ACK
|
||||||
elif frametype == 60:
|
elif frametype == 60:
|
||||||
logging.debug("ACK RECEIVED....")
|
logging.debug("ACK RECEIVED....")
|
||||||
data_handler.burst_ack_received()
|
data_handler.burst_ack_received()
|
||||||
|
|
||||||
# FRAME ACK
|
# FRAME ACK
|
||||||
elif frametype == 61:
|
elif frametype == 61:
|
||||||
logging.debug("FRAME ACK RECEIVED....")
|
logging.debug("FRAME ACK RECEIVED....")
|
||||||
data_handler.frame_ack_received()
|
data_handler.frame_ack_received()
|
||||||
|
|
||||||
# FRAME RPT
|
# FRAME RPT
|
||||||
elif frametype == 62:
|
elif frametype == 62:
|
||||||
logging.debug("REPEAT REQUEST RECEIVED....")
|
logging.debug("REPEAT REQUEST RECEIVED....")
|
||||||
data_handler.burst_rpt_received(bytes_out[:-2])
|
data_handler.burst_rpt_received(bytes_out[:-2])
|
||||||
|
|
||||||
# FRAME NAK
|
# FRAME NAK
|
||||||
elif frametype == 63:
|
elif frametype == 63:
|
||||||
logging.debug("FRAME NAK RECEIVED....")
|
logging.debug("FRAME NAK RECEIVED....")
|
||||||
data_handler.frame_nack_received(bytes_out[:-2])
|
data_handler.frame_nack_received(bytes_out[:-2])
|
||||||
|
|
||||||
# CQ FRAME
|
# CQ FRAME
|
||||||
elif frametype == 200:
|
elif frametype == 200:
|
||||||
logging.debug("CQ RECEIVED....")
|
logging.debug("CQ RECEIVED....")
|
||||||
data_handler.received_cq(bytes_out[:-2])
|
data_handler.received_cq(bytes_out[:-2])
|
||||||
|
|
||||||
# PING FRAME
|
# PING FRAME
|
||||||
elif frametype == 210:
|
elif frametype == 210:
|
||||||
logging.debug("PING RECEIVED....")
|
logging.debug("PING RECEIVED....")
|
||||||
data_handler.received_ping(bytes_out[:-2])
|
data_handler.received_ping(bytes_out[:-2])
|
||||||
|
|
||||||
# PING ACK
|
# PING ACK
|
||||||
elif frametype == 211:
|
elif frametype == 211:
|
||||||
logging.debug("PING ACK RECEIVED....")
|
logging.debug("PING ACK RECEIVED....")
|
||||||
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:
|
||||||
logging.debug("ARQ arq_received_data_channel_opener RECEIVED")
|
logging.debug("ARQ arq_received_data_channel_opener RECEIVED")
|
||||||
data_handler.arq_received_data_channel_opener(bytes_out[:-2])
|
data_handler.arq_received_data_channel_opener(bytes_out[:-2])
|
||||||
|
|
||||||
# ARQ CHANNEL IS OPENED
|
# ARQ CHANNEL IS OPENED
|
||||||
elif frametype == 226:
|
elif frametype == 226:
|
||||||
logging.debug("ARQ arq_received_channel_is_open RECEIVED")
|
logging.debug("ARQ arq_received_channel_is_open RECEIVED")
|
||||||
data_handler.arq_received_channel_is_open(bytes_out[:-2])
|
data_handler.arq_received_channel_is_open(bytes_out[:-2])
|
||||||
|
|
||||||
# ARQ CONNECT ACK / KEEP ALIVE
|
# ARQ CONNECT ACK / KEEP ALIVE
|
||||||
elif frametype == 230:
|
elif frametype == 230:
|
||||||
logging.debug("BEACON RECEIVED")
|
logging.debug("BEACON RECEIVED")
|
||||||
data_handler.received_beacon(bytes_out[:-2])
|
data_handler.received_beacon(bytes_out[:-2])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logging.info("OTHER FRAME: " + str(bytes_out[:-2]))
|
logging.info("OTHER FRAME: " + str(bytes_out[:-2]))
|
||||||
print(frametype)
|
print(frametype)
|
||||||
|
|
||||||
# DO UNSYNC AFTER LAST BURST by checking the frame nums against the total frames per burst
|
# DO UNSYNC AFTER LAST BURST by checking the frame nums against the total frames per burst
|
||||||
if frame == n_frames_per_burst:
|
if frame == n_frames_per_burst:
|
||||||
|
|
||||||
logging.debug("LAST FRAME ---> UNSYNC")
|
logging.debug("LAST FRAME ---> UNSYNC")
|
||||||
|
|
||||||
self.c_lib.freedv_set_sync(freedv, 0) # FORCE UNSYNC
|
self.c_lib.freedv_set_sync(freedv, 0) # FORCE UNSYNC
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
|
|
96
tnc/sock.py
96
tnc/sock.py
|
@ -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]
|
||||||
|
|
Loading…
Reference in a new issue