500hz mode, protocol improvements....

...and a lot of different changes. Also deactivated single mode transmission. This needs to be optimised another day...Time is the missing ressource...
This commit is contained in:
dj2ls 2022-02-08 15:27:34 +01:00
parent 92cf30225e
commit 35d95bbb14
12 changed files with 709 additions and 693 deletions

View file

@ -32,7 +32,7 @@ function connectDAEMON() {
//client.setTimeout(5000);
}
daemon.on('connect', function(data) {
daemon.on('connect', function(err) {
console.log('DAEMON connection established')
let Data = {
daemon_connection: daemon.readyState,
@ -41,8 +41,10 @@ daemon.on('connect', function(data) {
})
daemon.on('error', function(data) {
daemon.on('error', function(err) {
console.log('DAEMON connection error');
console.log(err)
daemon.destroy();
setTimeout(connectDAEMON, 2000)
let Data = {
daemon_connection: daemon.readyState,
@ -64,7 +66,8 @@ client.on('close', function(data) {
daemon.on('end', function(data) {
console.log('DAEMON connection ended');
setTimeout(connectDAEMON, 2000)
daemon.destroy();
setTimeout(connectDAEMON, 500)
let Data = {
daemon_connection: daemon.readyState,
};
@ -198,7 +201,7 @@ exports.getDaemonState = function() {
// START TNC
// ` `== multi line string
exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, radiocontrol, devicename, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port, enable_fft, enable_scatter) {
exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, radiocontrol, devicename, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port, enable_fft, enable_scatter, low_bandwith_mode) {
var json_command = JSON.stringify({
type: 'set',
command: 'start_tnc',
@ -219,7 +222,8 @@ exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, radiocontrol, de
rigctld_port: rigctld_port,
rigctld_ip: rigctld_ip,
enable_scatter: enable_scatter,
enable_fft: enable_fft
enable_fft: enable_fft,
low_bandwith_mode : low_bandwith_mode
}]
})

View file

@ -2,15 +2,15 @@ const {
app,
BrowserWindow,
ipcMain
} = require('electron')
const path = require('path')
const fs = require('fs')
} = require('electron');
const path = require('path');
const fs = require('fs');
const os = require('os');
app.setName("FreeDATA");
var appDataFolder = process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Application Support' : process.env.HOME + "/.config")
var appDataFolder = process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Application Support' : process.env.HOME + "/.config");
var configFolder = path.join(appDataFolder, "FreeDATA");
var configPath = path.join(configFolder, 'config.json')
var configPath = path.join(configFolder, 'config.json');
// create config folder if not exists
if (!fs.existsSync(configFolder)) {
@ -44,6 +44,7 @@ var configContent = `
"rigctld_ip" : "127.0.0.1",
"enable_scatter" : "False",
"enable_fft" : "False",
"low_bandwith_mode" : "False"
}
`;
@ -67,7 +68,7 @@ var configContent = `
}
`;
if (!fs.existsSync(chatDB)) {
fs.writeFileSync(chatDB, configContent)
fs.writeFileSync(chatDB, configContent);
}
@ -134,8 +135,8 @@ function createWindow() {
}
})
chat.loadFile('src/chat-module.html')
chat.setMenuBarVisibility(false)
chat.loadFile('src/chat-module.html');
chat.setMenuBarVisibility(false);
// Emitted when the window is closed.
@ -158,13 +159,13 @@ function createWindow() {
// https://stackoverflow.com/questions/44258831/only-hide-the-window-when-closing-it-electron
chat.on('close', function(evt) {
evt.preventDefault();
chat.hide()
chat.hide();
});
}
app.whenReady().then(() => {
createWindow()
createWindow();
// start daemon by checking os
// https://stackoverflow.com/a/5775120
@ -173,8 +174,8 @@ app.whenReady().then(() => {
if(os.platform()=='linux' || os.platform()=='darwin'){
daemonProcess = exec('./tnc/daemon', function callback(err, stdout, stderr) {
if (err) {
console.log(os.platform())
console.error(err)
console.log(os.platform());
console.error(err);
console.error("Can't start daemon binary");
console.error("--> this is only working with the app bundle and a precompiled binaries");
return;
@ -186,8 +187,8 @@ app.whenReady().then(() => {
if(os.platform()=='win32' || os.platform()=='win64'){
daemonProcess = exec('./tnc/daemon.exe', function callback(err, stdout, stderr) {
if (err) {
console.log(os.platform())
console.error(err)
console.log(os.platform());
console.error(err);
console.error("Can't start daemon binary");
console.error("--> this is only working with the app bundle and a precompiled binaries");
return;
@ -200,7 +201,7 @@ app.whenReady().then(() => {
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
createWindow();
}
})
})
@ -210,14 +211,14 @@ app.on('window-all-closed', () => {
daemonProcess.kill('SIGINT');
if (process.platform !== 'darwin') {
app.quit()
app.quit();
}
})
// IPC HANDLER
ipcMain.on('request-show-chat-window', (event, arg) => {
chat.show()
chat.show();
});

File diff suppressed because it is too large Load diff

View file

@ -57,8 +57,8 @@ client.on('error', function(data) {
};
ipcRenderer.send('request-update-tnc-state', Data);
setTimeout(connectTNC, 2000)
client.destroy();
setTimeout(connectTNC, 500)
// setTimeout( function() { exports.connectTNC(tnc_host, tnc_port); }, 2000 );
});
@ -72,32 +72,26 @@ client.on('close', function(data) {
client.on('end', function(data) {
console.log('TNC connection ended');
//setTimeout(connectTNC, 2000)
setTimeout(connectTNC, 0)
// setTimeout( function() { exports.connectTNC(tnc_host, tnc_port); }, 2000 );
client.destroy();
setTimeout(connectTNC, 500)
});
//exports.writeTncCommand = function(command){
writeTncCommand = function(command) {
//console.log(command)
// we use the writingCommand function to update our TCPIP state because we are calling this function a lot
// if socket openend, we are able to run commands
if (client.readyState == 'open') {
//uiMain.setTNCconnection('open')
client.write(command + '\n');
}
if (client.readyState == 'closed') {
//uiMain.setTNCconnection('closed')
//console.log("CLOSED!!!!!")
console.log("CLOSED!")
}
if (client.readyState == 'opening') {
//uiMain.setTNCconnection('opening')
//console.log("OPENING!!!!!")
console.log('connecting to TNC...')
}
}
@ -238,12 +232,12 @@ client.on('data', function(socketdata) {
if(splitted_data[0] == 'f'){
dataArray.push(data['data-array'][i])
//dataArray.push(splitted_data)
}
if(splitted_data[0] == 'm'){
messageArray.push(data['data-array'][i])
//messageArray.push(splitted_data)
}
} catch (e) {

View file

@ -722,13 +722,16 @@
<label class="form-check-label" for="scatterSwitch">Scatter</label>
</div>
<div class="form-check form-switch form-check-inline">
<input class="form-check-input" type="checkbox" id="500HzModeSwitch">
<label class="form-check-label" for="500HzModeSwitch">500Hz</label>
</div>
<!--<button class="btn btn-secondary btn-sm" id="python_version" type="button" disabled>Python</button>-->
<!--<button class="btn btn-secondary btn-sm" id="node_version" type="button" disabled>Node</button>-->
<!--<button class="btn btn-secondary btn-sm" id="hamlib_version" type="button" disabled>Hamlib</button>-->
<!--<button class="btn btn-secondary btn-sm" id="operating_system" type="button" disabled>OS</button>-->
<button class="btn btn-secondary btn-sm" id="cpu_load_button" type="button" disabled>
<!--<button class="btn btn-secondary btn-sm" id="cpu_load_button" type="button" disabled>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cpu" viewBox="0 0 16 16">
<path d="M5 0a.5.5 0 0 1 .5.5V2h1V.5a.5.5 0 0 1 1 0V2h1V.5a.5.5 0 0 1 1 0V2h1V.5a.5.5 0 0 1 1 0V2A2.5 2.5 0 0 1 14 4.5h1.5a.5.5 0 0 1 0 1H14v1h1.5a.5.5 0 0 1 0 1H14v1h1.5a.5.5 0 0 1 0 1H14v1h1.5a.5.5 0 0 1 0 1H14a2.5 2.5 0 0 1-2.5 2.5v1.5a.5.5 0 0 1-1 0V14h-1v1.5a.5.5 0 0 1-1 0V14h-1v1.5a.5.5 0 0 1-1 0V14h-1v1.5a.5.5 0 0 1-1 0V14A2.5 2.5 0 0 1 2 11.5H.5a.5.5 0 0 1 0-1H2v-1H.5a.5.5 0 0 1 0-1H2v-1H.5a.5.5 0 0 1 0-1H2v-1H.5a.5.5 0 0 1 0-1H2A2.5 2.5 0 0 1 4.5 2V.5A.5.5 0 0 1 5 0zm-.5 3A1.5 1.5 0 0 0 3 4.5v7A1.5 1.5 0 0 0 4.5 13h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 11.5 3h-7zM5 6.5A1.5 1.5 0 0 1 6.5 5h3A1.5 1.5 0 0 1 11 6.5v3A1.5 1.5 0 0 1 9.5 11h-3A1.5 1.5 0 0 1 5 9.5v-3zM6.5 6a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z" />
</svg> <span id="cpu_load">---</span>
@ -738,12 +741,13 @@
<path d="M1 3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h4.586a1 1 0 0 0 .707-.293l.353-.353a.5.5 0 0 1 .708 0l.353.353a1 1 0 0 0 .707.293H15a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H1Zm.5 1h3a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-4a.5.5 0 0 1 .5-.5Zm5 0h3a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-4a.5.5 0 0 1 .5-.5Zm4.5.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-4ZM2 10v2H1v-2h1Zm2 0v2H3v-2h1Zm2 0v2H5v-2h1Zm3 0v2H8v-2h1Zm2 0v2h-1v-2h1Zm2 0v2h-1v-2h1Zm2 0v2h-1v-2h1Z" />
</svg> <span id="ram_load">---</span>
</button>
-->
</div>
</div>
</div>
</div>
</div>
<!--<hr class="m-1">-->
<div class="container mt-2 p-0">
<div class="row collapse multi-collapse" id="collapseThirdRow">
<div class="col-5">
@ -964,19 +968,18 @@
<div class="card-body p-2">
<div class="row">
<div class="col">
<div class="input-group input-group-sm"> <span class="input-group-text" id="basic-addon1">Mode</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="datamode">
<!--<option value="14">low SNR (DC0)</option>-->
<div class="input-group input-group-sm"> <span class="input-group-text" id="basic-addon1" >Mode</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="datamode" disabled>
<option selected value="255">AUTO</option>
<option value="10">HIGH SNR (DC1)</option>
<option value="12">MED SNR (DC3)</option>
<option value="14">LOW SNR (DC0)</option>
<!--<option value="232">HIGH SNR (DC1)</option>-->
<!--<option value="231">MED SNR (DC3)</option>-->
<!--<option value="230">LOW SNR (DC0)</option>-->
</select>
</div>
</div>
<div class="col-auto">
<div class="input-group input-group-sm"> <span class="input-group-text" id="basic-addon1">Frames</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="framesperburst">
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="framesperburst" disabled>
<option selected value="1">1</option>
</select>
</div>

View file

@ -146,7 +146,7 @@ class audio_buffer:
# a buffer of int16 samples, using a fixed length numpy array self.buffer for storage
# self.nbuffer is the current number of samples in the buffer
def __init__(self, size):
print("create audio_buffer: ", size)
structlog.get_logger("structlog").debug("[C2 ] creating audio buffer", size=size)
self.size = size
self.buffer = np.zeros(size, dtype=np.int16)
self.nbuffer = 0
@ -180,7 +180,7 @@ class resampler:
MEM48 = api.FDMDV_OS_TAPS_48K
def __init__(self):
print("create 48<->8 kHz resampler")
structlog.get_logger("structlog").debug("[C2 ] create 48<->8 kHz resampler")
self.filter_mem8 = np.zeros(self.MEM8, dtype=np.int16)
self.filter_mem48 = np.zeros(self.MEM48)

View file

@ -26,7 +26,7 @@ import os
import queue
import audio
import sock
import atexit
class DAEMON():
def __init__(self):
@ -89,7 +89,8 @@ class DAEMON():
# data[15] rigctld_port
# data[16] send_scatter
# data[17] send_fft
# data[18] low_bandwith_mode
if data[0] == 'STARTTNC':
structlog.get_logger("structlog").warning("[DMN] Starting TNC", rig=data[5], port=data[6])
@ -149,7 +150,10 @@ class DAEMON():
if data[17] == 'True':
options.append('--fft')
if data[18] == 'True':
options.append('--500hz')
# try running tnc from binary, else run from source
# this helps running the tnc in a developer environment
try:
@ -161,6 +165,8 @@ class DAEMON():
command += options
p = subprocess.Popen(command)
atexit.register(p.kill)
structlog.get_logger("structlog").info("[DMN] TNC started", path="binary")
except:
command = []
@ -176,7 +182,14 @@ class DAEMON():
static.TNCPROCESS = p # .pid
static.TNCSTARTED = True
'''
# WE HAVE THIS PART in SOCKET
if data[0] == 'STOPTNC':
static.TNCPROCESS.kill()
structlog.get_logger("structlog").warning("[DMN] Stopping TNC")
#os.kill(static.TNCPROCESS, signal.SIGKILL)
static.TNCSTARTED = False
'''
# data[1] devicename
# data[2] deviceport
# data[3] serialspeed

View file

@ -32,8 +32,6 @@ class DATA():
def __init__(self):
print("init DATA handler...")
self.data_queue_transmit = DATA_QUEUE_TRANSMIT
self.data_queue_received = DATA_QUEUE_RECEIVED
@ -48,10 +46,30 @@ class DATA():
self.data_frame_bof = b'BOF' # 2 bytes for the BOF End of File indicator in a data frame
self.data_frame_eof = b'EOF' # 2 bytes for the EOF End of File indicator in a data frame
#self.mode_list = [14,14,14,12,10] # mode list of available modes, each mode will be used 2times per speed level
self.mode_list = [14,12,10] # mode list of available modes, each mode will be used 2times per speed level
self.time_list = [3, 6, 7] # list for time to wait for correspinding mode in seconds
self.rx_n_max_retries_per_burst = 10
self.n_retries_per_burst = 0
self.received_low_bandwith_mode = False # indicator if we recevied a low bandwith mode channel ope ner
self.data_channel_max_retries = 3
self.mode_list_low_bw = [14,12]
self.time_list_low_bw = [3,6]
self.mode_list_high_bw = [14,12,10] # mode list of available modes, each mode will be used 2times per speed level
self.time_list_high_bw = [3, 6, 7] # list for time to wait for correspinding mode in seconds
# mode list for selecting between low bandwith ( 500Hz ) and normal modes with higher bandwith
if static.LOW_BANDWITH_MODE:
self.mode_list = self.mode_list_low_bw # mode list of available modes, each mode will be used 2times per speed level
self.time_list = self.time_list_low_bw # list for time to wait for correspinding mode in seconds
else:
self.mode_list = self.mode_list_high_bw # mode list of available modes, each mode will be used 2times per speed level
self.time_list = self.time_list_high_bw # list for time to wait for correspinding mode in seconds
self.speed_level = len(self.mode_list) - 1 # speed level for selecting mode
self.is_IRS = False
self.burst_nack = False
self.burst_nack_counter = 0
@ -60,7 +78,7 @@ class DATA():
self.rx_frame_bof_received = False
self.rx_frame_eof_received = False
self.transmission_timeout = 120 # transmission timeout in seconds
self.transmission_timeout = 30 # transmission timeout in seconds
worker_thread_transmit = threading.Thread(target=self.worker_transmit, name="worker thread transmit")
worker_thread_transmit.start()
@ -222,24 +240,31 @@ class DATA():
self.received_ping_ack(bytes_out[:-2])
# ARQ FILE TRANSFER RECEIVED!
elif frametype == 225:
elif frametype == 225 or frametype == 227:
structlog.get_logger("structlog").debug("ARQ arq_received_data_channel_opener")
self.arq_received_data_channel_opener(bytes_out[:-2])
# ARQ CHANNEL IS OPENED
elif frametype == 226:
elif frametype == 226 or frametype == 228:
structlog.get_logger("structlog").debug("ARQ arq_received_channel_is_open")
self.arq_received_channel_is_open(bytes_out[:-2])
# ARQ MANUAL MODE TRANSMISSION
elif 230 <= frametype <= 240 :
structlog.get_logger("structlog").debug("ARQ manual mode ")
self.arq_received_data_channel_opener(bytes_out[:-2])
# ARQ STOP TRANSMISSION
elif frametype == 227:
elif frametype == 249:
structlog.get_logger("structlog").debug("ARQ received stop transmission")
self.received_stop_transmission()
# ARQ CONNECT ACK / KEEP ALIVE
# this is outdated and we may remove it
elif frametype == 230:
elif frametype == 250:
structlog.get_logger("structlog").debug("BEACON RECEIVED")
self.received_beacon(bytes_out[:-2])
@ -283,7 +308,6 @@ class DATA():
if len(static.RX_BURST_BUFFER) != RX_N_FRAMES_PER_BURST:
static.RX_BURST_BUFFER = [None] * RX_N_FRAMES_PER_BURST
# append data to rx burst buffer
static.RX_BURST_BUFFER[RX_N_FRAME_OF_BURST] = data_in[6:] # [frame_type][n_frames_per_burst][CRC16][CRC16]
@ -320,7 +344,7 @@ class DATA():
self.speed_level = len(self.mode_list) - 1
# updated modes we are listening to
self.set_listening_modes()
self.set_listening_modes(self.mode_list[self.speed_level])
# create an ack frame
@ -379,8 +403,6 @@ class DATA():
# we should never reach this point
else:
structlog.get_logger("structlog").error("we shouldnt reach this point...", frame=RX_N_FRAME_OF_BURST, frames=RX_N_FRAMES_PER_BURST)
# We have a BOF and EOF flag in our data. If we received both we received our frame.
@ -391,9 +413,15 @@ class DATA():
# get total bytes per transmission information as soon we recevied a frame with a BOF
if bof_position >=0:
crc_position = bof_position+len(self.data_frame_bof)
size_position = crc_position + 4
static.TOTAL_BYTES = int.from_bytes(bytes(static.RX_FRAME_BUFFER[size_position:size_position + 4]), "big") # Bytes
payload = static.RX_FRAME_BUFFER[bof_position+len(self.data_frame_bof):eof_position]
frame_length = int.from_bytes(payload[4:8], "big") #4:8 4bytes
static.TOTAL_BYTES = frame_length
compression_factor = int.from_bytes(payload[8:9], "big") #4:8 4bytes
static.ARQ_COMPRESSION_FACTOR = compression_factor / 10
self.calculate_transfer_rate_rx(self.rx_start_of_transmission, len(static.RX_FRAME_BUFFER))
if bof_position >= 0 and eof_position > 0 and not None in static.RX_BURST_BUFFER:
print(f"bof_position {bof_position} / eof_position {eof_position}")
self.rx_frame_bof_received = True
@ -402,11 +430,13 @@ class DATA():
#now extract raw data from buffer
payload = static.RX_FRAME_BUFFER[bof_position+len(self.data_frame_bof):eof_position]
# get the data frame crc
data_frame_crc = payload[:4] #0:4 4bytes
frame_length = int.from_bytes(payload[4:8], "big") #4:8 4bytes
static.TOTAL_BYTES = frame_length
# 8:9 = compression factor
data_frame_crc = payload[:4]
frame_length = int.from_bytes(bytes(static.RX_FRAME_BUFFER[size_position:size_position + 4]), "big")
data_frame = payload[9:]
data_frame = payload[8:]
data_frame_crc_received = helpers.get_crc_32(data_frame)
# check if data_frame_crc is equal with received crc
if data_frame_crc == data_frame_crc_received:
@ -500,7 +530,6 @@ class DATA():
global TESTMODE
self.speed_level = len(self.mode_list) - 1 # speed level for selecting mode
TX_N_SENT_BYTES = 0 # already sent bytes per data frame
self.tx_n_retry_of_burst = 0 # retries we already sent data
@ -524,7 +553,10 @@ class DATA():
# compression
data_frame_compressed = zlib.compress(data_out)
static.ARQ_COMPRESSION_FACTOR = len(data_out) / len(data_frame_compressed)
compression_factor = len(data_out) / len(data_frame_compressed)
static.ARQ_COMPRESSION_FACTOR = compression_factor
compression_factor = bytes([int(static.ARQ_COMPRESSION_FACTOR * 10)])
data_out = data_frame_compressed
# reset statistics
@ -534,7 +566,7 @@ class DATA():
# append a crc and beginn and end of file indicators
frame_payload_crc = helpers.get_crc_32(data_out)
# data_out = self.data_frame_bof + frame_payload_crc + data_out + self.data_frame_eof
data_out = self.data_frame_bof + frame_payload_crc + frame_total_size + data_out + self.data_frame_eof
data_out = self.data_frame_bof + frame_payload_crc + frame_total_size + compression_factor + data_out + self.data_frame_eof
#initial bufferposition is 0
bufferposition = 0
@ -559,17 +591,25 @@ class DATA():
# as soon as we received an ACK for the current burst, speed_level will increase
# by 1.
# the can be optimised by checking the optimal speed level for the current conditions
'''
if not self.tx_n_retry_of_burst % 2 and self.tx_n_retry_of_burst > 0:
self.speed_level -= 1
if self.speed_level < 0:
self.speed_level = 0
'''
#if self.tx_n_retry_of_burst <= 1:
# self.speed_level += 1
# if self.speed_level >= len(self.mode_list)-1:
# self.speed_level = len(self.mode_list)-1
# if speed level is greater than our available modes, set speed level to maximum = lenght of mode list -1
print(self.mode_list)
if self.speed_level >= len(self.mode_list):
self.speed_level = len(self.mode_list) - 1
data_mode = self.mode_list[self.speed_level]
structlog.get_logger("structlog").debug("Speed-level", level=self.speed_level, retry=self.tx_n_retry_of_burst)
@ -625,11 +665,14 @@ class DATA():
time.sleep(0.01)
# after transmission finished wait for an ACK or RPT frame
'''
burstacktimeout = time.time() + BURST_ACK_TIMEOUT_SECONDS + 100
while not self.burst_ack and not self.burst_nack and not self.rpt_request_received and not self.data_frame_ack_received and time.time() < burstacktimeout and static.ARQ_STATE:
time.sleep(0.01)
#structlog.get_logger("structlog").debug("[TNC] waiting for ack", burst_ack=self.burst_ack, frame_ack = self.data_frame_ack_received, arq_state = static.ARQ_STATE, overflows=static.BUFFER_OVERFLOW_COUNTER)
'''
#burstacktimeout = time.time() + BURST_ACK_TIMEOUT_SECONDS + 100
while not self.burst_ack and not self.burst_nack and not self.rpt_request_received and not self.data_frame_ack_received and static.ARQ_STATE:
time.sleep(0.01)
# once we received a burst ack, reset its state and break the RETRIES loop
if self.burst_ack:
@ -781,39 +824,36 @@ class DATA():
else:
return False
def arq_open_data_channel(self, mode:int, n_frames_per_burst:int):
self.is_IRS = False
DATA_CHANNEL_MAX_RETRIES = 5 # N attempts for connecting to another station
def arq_open_data_channel(self, mode:int, n_frames_per_burst:int):
self.is_IRS = False
self.data_channel_last_received = int(time.time())
# devide by 1024 for getting Bytes -> kBytes
#data_len = int(data_len / 1024)
if static.LOW_BANDWITH_MODE and mode == 255:
frametype = bytes([227])
structlog.get_logger("structlog").debug("requesting low bandwith mode")
# multiply compression factor for reducing it from float to int
compression_factor = int(static.ARQ_COMPRESSION_FACTOR * 10)
else:
frametype = bytes([225])
structlog.get_logger("structlog").debug("requesting high bandwith mode")
if 230 <= mode <= 240:
structlog.get_logger("structlog").debug("requesting manual mode --> not yet implemented ")
frametype = bytes([mode])
connection_frame = bytearray(14)
connection_frame[:1] = bytes([225])
connection_frame[:1] = frametype
connection_frame[1:3] = static.DXCALLSIGN_CRC
connection_frame[3:5] = static.MYCALLSIGN_CRC
connection_frame[5:11] = static.MYCALLSIGN
connection_frame[11:12] = bytes([mode])
#connection_frame[10:12] = data_len.to_bytes(2, byteorder='big')
connection_frame[12:13] = bytes([compression_factor])
connection_frame[13:14] = bytes([n_frames_per_burst])
connection_frame[13:14] = bytes([n_frames_per_burst])
while not static.ARQ_STATE:
time.sleep(0.01)
for attempt in range(1,DATA_CHANNEL_MAX_RETRIES+1):
for attempt in range(1,self.data_channel_max_retries+1):
static.INFO.append("DATACHANNEL;OPENING")
structlog.get_logger("structlog").info("[TNC] ARQ | DATA | TX | [" + str(static.MYCALLSIGN, 'utf-8') + "]>> <<[" + str(static.DXCALLSIGN, 'utf-8') + "]", attempt=str(attempt) + "/" + str(DATA_CHANNEL_MAX_RETRIES))
txbuffer = [connection_frame]
structlog.get_logger("structlog").info("[TNC] ARQ | DATA | TX | [" + str(static.MYCALLSIGN, 'utf-8') + "]>> <<[" + str(static.DXCALLSIGN, 'utf-8') + "]", attempt=str(attempt) + "/" + str(self.data_channel_max_retries))
txbuffer = [connection_frame]
static.TRANSMITTING = True
modem.MODEM_TRANSMIT_QUEUE.put([14,1,0,txbuffer])
# wait while transmitting
@ -829,7 +869,7 @@ class DATA():
if static.ARQ_STATE:
break
if not static.ARQ_STATE and attempt == DATA_CHANNEL_MAX_RETRIES:
if not static.ARQ_STATE and attempt == self.data_channel_max_retries:
static.INFO.append("DATACHANNEL;FAILED")
structlog.get_logger("structlog").warning("[TNC] ARQ | TX | DATA [" + str(static.MYCALLSIGN, 'utf-8') + "]>>X<<[" + str(static.DXCALLSIGN, 'utf-8') + "]")
@ -839,60 +879,61 @@ class DATA():
return False
#sys.exit() # close thread and so connection attempts
def arq_received_data_channel_opener(self, data_in:bytes):
self.is_IRS = True
def arq_received_data_channel_opener(self, data_in:bytes):
self.is_IRS = True
static.INFO.append("DATACHANNEL;RECEIVEDOPENER")
static.DXCALLSIGN_CRC = bytes(data_in[3:5])
static.DXCALLSIGN = bytes(data_in[5:11]).rstrip(b'\x00')
static.ARQ_COMPRESSION_FACTOR = float(int.from_bytes(bytes(data_in[12:13]), "big") / 10)
n_frames_per_burst = int.from_bytes(bytes(data_in[13:14]), "big")
mode = int.from_bytes(bytes(data_in[11:12]), "big")
# updated modes we are listening to
self.set_listening_modes()
'''
# set modes we want to listening to
mode_name = codec2.freedv_get_mode_name_by_value(mode)
if mode_name == 'datac1':
modem.RECEIVE_DATAC1 = True
elif mode_name == 'datac3':
modem.RECEIVE_DATAC3 = True
elif mode_name == 'allmodes':
pass
#modem.RECEIVE_DATAC1 = True
#modem.RECEIVE_DATAC3 = True
'''
frametype = int.from_bytes(bytes(data_in[:1]), "big")
#check if we received low bandwith mode
if frametype == 225:
self.received_low_bandwith_mode = False
self.mode_list = self.mode_list_high_bw
self.time_list = self.time_list_high_bw
self.speed_level = len(self.mode_list) - 1
else:
self.received_low_bandwith_mode = True
self.mode_list = self.mode_list_low_bw
self.time_list = self.time_list_low_bw
self.speed_level = len(self.mode_list) - 1
#we need to find a way how to do this. this isn't working anymore since we mode to a class based module
#modem.set_frames_per_burst(n_frames_per_burst)
if 230 <= frametype <= 240:
print("manual mode request")
# updated modes we are listening to
self.set_listening_modes(self.mode_list[self.speed_level])
helpers.add_to_heard_stations(static.DXCALLSIGN,static.DXGRID, 'DATA-CHANNEL', static.SNR, static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
structlog.get_logger("structlog").info("[TNC] ARQ | DATA | RX | [" + str(static.MYCALLSIGN, 'utf-8') + "]>> <<[" + str(static.DXCALLSIGN, 'utf-8') + "]")
structlog.get_logger("structlog").info("[TNC] ARQ | DATA | RX | [" + str(static.MYCALLSIGN, 'utf-8') + "]>> <<[" + str(static.DXCALLSIGN, 'utf-8') + "]", bandwith="wide")
static.ARQ_STATE = True
static.TNC_STATE = 'BUSY'
# reset ARQ statistics
static.ARQ_BYTES_PER_MINUTE_BURST = 0
static.ARQ_BYTES_PER_MINUTE = 0
static.ARQ_BITS_PER_SECOND_BURST = 0
static.ARQ_BITS_PER_SECOND = 0
static.ARQ_TRANSMISSION_PERCENT = 0
static.TOTAL_BYTES = 0
self.reset_statistics()
self.data_channel_last_received = int(time.time())
# check if we are in low bandwith mode
if static.LOW_BANDWITH_MODE or self.received_low_bandwith_mode:
frametype = bytes([228])
structlog.get_logger("structlog").debug("responding with low bandwith mode")
else:
frametype = bytes([226])
structlog.get_logger("structlog").debug("responding with high bandwith mode")
connection_frame = bytearray(14)
connection_frame[:1] = bytes([226])
connection_frame[:1] = frametype
connection_frame[1:3] = static.DXCALLSIGN_CRC
connection_frame[3:5] = static.MYCALLSIGN_CRC
#connection_frame[5:11] = static.MYCALLSIGN
connection_frame[13:14] = bytes([static.ARQ_PROTOCOL_VERSION]) #crc8 of version for checking protocol version
txbuffer = [connection_frame]
@ -901,28 +942,46 @@ class DATA():
# wait while transmitting
while static.TRANSMITTING:
time.sleep(0.01)
structlog.get_logger("structlog").info("[TNC] ARQ | DATA | RX | [" + str(static.MYCALLSIGN, 'utf-8') + "]>>|<<[" + str(static.DXCALLSIGN, 'utf-8') + "]", snr=static.SNR)
structlog.get_logger("structlog").info("[TNC] ARQ | DATA | RX | [" + str(static.MYCALLSIGN, 'utf-8') + "]>>|<<[" + str(static.DXCALLSIGN, 'utf-8') + "]", bandwith="wide", snr=static.SNR)
# set start of transmission for our statistics
self.rx_start_of_transmission = time.time()
def arq_received_channel_is_open(self, data_in:bytes):
static.INFO.append("DATACHANNEL;OPEN")
static.DXCALLSIGN_CRC = bytes(data_in[3:5])
#static.DXCALLSIGN = bytes(data_in[5:11]).rstrip(b'\x00')
helpers.add_to_heard_stations(static.DXCALLSIGN,static.DXGRID, 'DATA-CHANNEL', static.SNR, static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
self.data_channel_last_received = int(time.time())
structlog.get_logger("structlog").info("[TNC] ARQ | DATA | TX | [" + str(static.MYCALLSIGN, 'utf-8') + "]>>|<<[" + str(static.DXCALLSIGN, 'utf-8') + "]", snr=static.SNR)
# as soon as we set ARQ_STATE to DATA, transmission starts
static.ARQ_STATE = True
self.data_channel_last_received = int(time.time())
protocol_version = int.from_bytes(bytes(data_in[13:14]), "big")
if protocol_version == static.ARQ_PROTOCOL_VERSION:
static.INFO.append("DATACHANNEL;OPEN")
static.DXCALLSIGN_CRC = bytes(data_in[3:5])
frametype = int.from_bytes(bytes(data_in[:1]), "big")
if frametype == 228:
self.received_low_bandwith_mode = True
self.mode_list = self.mode_list_low_bw
self.time_list = self.time_list_low_bw
self.speed_level = len(self.mode_list) - 1
structlog.get_logger("structlog").debug("low bandwith mode", modes=self.mode_list)
else:
self.received_low_bandwith_mode = False
self.mode_list = self.mode_list_high_bw
self.time_list = self.time_list_high_bw
self.speed_level = len(self.mode_list) - 1
structlog.get_logger("structlog").debug("high bandwith mode", modes=self.mode_list)
helpers.add_to_heard_stations(static.DXCALLSIGN,static.DXGRID, 'DATA-CHANNEL', static.SNR, static.FREQ_OFFSET, static.HAMLIB_FREQUENCY)
structlog.get_logger("structlog").info("[TNC] ARQ | DATA | TX | [" + str(static.MYCALLSIGN, 'utf-8') + "]>>|<<[" + str(static.DXCALLSIGN, 'utf-8') + "]", snr=static.SNR)
# as soon as we set ARQ_STATE to DATA, transmission starts
static.ARQ_STATE = True
self.data_channel_last_received = int(time.time())
else:
static.TNC_STATE = 'IDLE'
static.ARQ_STATE = False
static.INFO.append("PROTOCOL;VERSION_MISSMATCH")
structlog.get_logger("structlog").warning("protocol version missmatch", received=protocol_version, own=static.ARQ_PROTOCOL_VERSION)
self.arq_cleanup()
# ---------- PING
@ -986,7 +1045,7 @@ class DATA():
def stop_transmission(self):
structlog.get_logger("structlog").warning("[TNC] Stopping transmission!")
stop_frame = bytearray(14)
stop_frame[:1] = bytes([227])
stop_frame[:1] = bytes([249])
stop_frame[1:3] = static.DXCALLSIGN_CRC
stop_frame[3:5] = static.MYCALLSIGN_CRC
@ -1017,7 +1076,7 @@ class DATA():
while static.BEACON_STATE and not static.ARQ_STATE:
beacon_frame = bytearray(14)
beacon_frame[:1] = bytes([230])
beacon_frame[:1] = bytes([250])
beacon_frame[1:2] = b'\x01'
beacon_frame[2:8] = static.MYCALLSIGN
beacon_frame[8:14] = static.MYGRID
@ -1099,7 +1158,15 @@ class DATA():
def reset_statistics(self):
# reset ARQ statistics
static.ARQ_BYTES_PER_MINUTE_BURST = 0
static.ARQ_BYTES_PER_MINUTE = 0
static.ARQ_BITS_PER_SECOND_BURST = 0
static.ARQ_BITS_PER_SECOND = 0
static.ARQ_TRANSMISSION_PERCENT = 0
static.TOTAL_BYTES = 0
def calculate_transfer_rate_tx(self, tx_start_of_transmission:float, sentbytes:int, tx_buffer_length:int) -> list:
try:
@ -1155,7 +1222,15 @@ class DATA():
self.burst_nack_counter = 0
self.frame_received_counter = 0
self.speed_level = len(self.mode_list) - 1
# low bandwith mode indicator
self.received_low_bandwith_mode = False
# reset retry counter for rx channel / burst
self.n_retries_per_burst = 0
def arq_reset_ack(self,state:bool):
self.burst_ack = state
@ -1163,16 +1238,21 @@ class DATA():
self.data_frame_ack_received = state
def set_listening_modes(self):
# set modes we want to listening to
mode_name = codec2.freedv_get_mode_name_by_value(self.mode_list[self.speed_level])
def set_listening_modes(self, mode):
# set modes we want listening to
mode_name = codec2.freedv_get_mode_name_by_value(mode)
if mode_name == 'datac1':
modem.RECEIVE_DATAC1 = True
structlog.get_logger("structlog").debug("changing listening data mode", mode="datac1")
elif mode_name == 'datac3':
modem.RECEIVE_DATAC3 = True
structlog.get_logger("structlog").debug("changing listening data mode", mode="datac3")
elif mode_name == 'allmodes':
modem.RECEIVE_DATAC1 = True
modem.RECEIVE_DATAC3 = True
structlog.get_logger("structlog").debug("changing listening data mode", mode="datac1/datac3")
# ------------------------- WATCHDOG FUNCTIONS FOR TIMER
@ -1188,20 +1268,12 @@ class DATA():
self.burst_watchdog()
def burst_watchdog(self):
'''
# ISS SIDE WE ALSO NEED TO CHECK TIME SO WE ARE SENDING IN CORRECT MODE IF WE MISSED A NACK FRAME
if static.ARQ_STATE and static.TNC_STATE == 'BUSY' and not self.is_IRS:
if self.data_channel_last_received + self.time_list[self.speed_level] < time.time():
self.speed_level -= 1
if self.speed_level <= 0:
self.speed_level = 0
self.data_channel_last_received = time.time()
'''
# IRS SIDE
if static.ARQ_STATE and static.TNC_STATE == 'BUSY' and self.is_IRS:
if self.data_channel_last_received + self.time_list[self.speed_level] > time.time():
print((self.data_channel_last_received + self.time_list[self.speed_level])-time.time())
#pass
#print((self.data_channel_last_received + self.time_list[self.speed_level])-time.time())
pass
else:
print("TIMEOUT")
self.frame_received_counter = 0
@ -1210,7 +1282,7 @@ class DATA():
self.speed_level = 0
# updated modes we are listening to
self.set_listening_modes()
self.set_listening_modes(self.mode_list[self.speed_level])
# BUILDING NACK FRAME FOR DATA FRAME
burst_nack_frame = bytearray(14)
@ -1229,7 +1301,13 @@ class DATA():
# #time.sleep(0.01)
# self.data_channel_last_received = time.time()
self.data_channel_last_received = time.time()
self.n_retries_per_burst += 1
if self.n_retries_per_burst >= self.rx_n_max_retries_per_burst:
self.arq_cleanup()
print("RX TIMEOUT!!!!")
#print(self.n_retries_per_burst)
def data_channel_keep_alive_watchdog(self):
"""
Author: DJ2LS
@ -1241,6 +1319,7 @@ class DATA():
time.sleep(0.01)
if self.data_channel_last_received + self.transmission_timeout > time.time():
time.sleep(0.01)
#print(self.data_channel_last_received + self.transmission_timeout - time.time())
#pass
else:
self.data_channel_last_received = 0

View file

@ -42,8 +42,8 @@ if __name__ == '__main__':
PARSER.add_argument('--rigctld_ip', dest="rigctld_ip", default="direct", help="Set rigctld ip")
PARSER.add_argument('--scatter', dest="send_scatter", action="store_true", help="Send scatter information via network")
PARSER.add_argument('--fft', dest="send_fft", action="store_true", help="Send fft information via network")
PARSER.add_argument('--500hz', dest="low_bandwith_mode", action="store_true", help="Enable low bandwith mode ( 500 Hz only )")
ARGS = PARSER.parse_args()
@ -67,6 +67,11 @@ if __name__ == '__main__':
static.HAMLIB_RGICTLD_PORT = ARGS.rigctld_port
static.ENABLE_SCATTER = ARGS.send_scatter
static.ENABLE_FFT = ARGS.send_fft
static.LOW_BANDWITH_MODE = ARGS.low_bandwith_mode
# we need to wait until we got all parameters from argparse first before we can load the other modules
import sock

View file

@ -106,7 +106,6 @@ class radio:
# get devicenumber by looking for deviceobject in Hamlib module
try:
self.devicenumber = int(getattr(Hamlib, self.devicename))
print(self.devicenumber)
except:
structlog.get_logger("structlog").error("[RIG] Hamlib: rig not supported...")
self.devicenumber = 0
@ -120,17 +119,9 @@ class radio:
self.my_rig.set_conf("stop_bits", self.stop_bits)
self.my_rig.set_conf("data_bits", self.data_bits)
self.my_rig.set_conf("ptt_pathname", self.pttport)
print(self.my_rig.get_conf("rig_pathname"))
print(self.my_rig.get_conf("retry"))
print(self.my_rig.get_conf("serial_speed"))
print(self.my_rig.get_conf("serial_handshake"))
print(self.my_rig.get_conf("stop_bits"))
print(self.my_rig.get_conf("data_bits"))
print(self.my_rig.get_conf("ptt_pathname"))
if self.hamlib_ptt_type == 'RIG':
self.hamlib_ptt_type = Hamlib.RIG_PTT_RIG
@ -168,7 +159,9 @@ class radio:
else: #self.hamlib_ptt_type == 'RIG_PTT_NONE':
self.hamlib_ptt_type = Hamlib.RIG_PTT_NONE
structlog.get_logger("structlog").info("[RIG] Opening...", device=self.devicenumber, path=self.my_rig.get_conf("rig_pathname"), serial_speed=self.my_rig.get_conf("serial_speed"), serial_handshake=self.my_rig.get_conf("serial_handshake"), stop_bits=self.my_rig.get_conf("stop_bits"), data_bits=self.my_rig.get_conf("data_bits"), ptt_pathname=self.my_rig.get_conf("ptt_pathname"))
self.my_rig.open()
atexit.register(self.my_rig.close)

View file

@ -50,16 +50,21 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
def send_to_client(self):
tempdata = b''
while self.connection_alive:
# send tnc state as network stream
# check server port against daemon port and send corresponding data
if self.server.server_address[1] == static.PORT and not static.TNCSTARTED:
data = send_tnc_state()
SOCKET_QUEUE.put(data)
if data != tempdata:
tempdata = data
SOCKET_QUEUE.put(data)
else:
data = send_daemon_state()
SOCKET_QUEUE.put(data)
if data != tempdata:
tempdata = data
SOCKET_QUEUE.put(data)
time.sleep(0.5)
@ -96,14 +101,20 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
#print("connection broken. Closing...")
self.connection_alive = False
if data.startswith(b'{"type"') and data.endswith(b'}\n'):
data = data[:-1] # remove b'\n'
print(data)
if self.server.server_address[1] == static.PORT:
process_tnc_commands(data)
else:
process_daemon_commands(data)
if data.startswith(b'{') and data.endswith(b'}\n'):
# split data by \n if we have multiple commands in socket buffer
data = data.split(b'\n')
# remove empty data
data.remove(b'')
# iterate thorugh data list
for commands in data:
if self.server.server_address[1] == static.PORT:
process_tnc_commands(commands)
else:
process_daemon_commands(commands)
# finally delete our rx buffer to be ready for new commands
data = bytes()
@ -128,7 +139,6 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
CONNECTED_CLIENTS.remove(self.request)
except:
print("client connection already removed from client list")
print(CONNECTED_CLIENTS)
def process_tnc_commands(data):
@ -189,90 +199,7 @@ def process_tnc_commands(data):
except Exception as e:
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
# TRANSMIT FILE ----------------------------------------------------------
'''
if received_json["type"] == 'arq' and received_json["command"] == "send_file":
try:
static.TNC_STATE = 'BUSY'
# on a new transmission we reset the timer
static.ARQ_START_OF_TRANSMISSION = int(time.time())
dxcallsign = received_json["parameter"][0]["dxcallsign"]
mode = int(received_json["parameter"][0]["mode"])
n_frames = int(received_json["parameter"][0]["n_frames"])
filename = received_json["parameter"][0]["filename"]
filetype = received_json["parameter"][0]["filetype"]
data = received_json["parameter"][0]["data"]
checksum = received_json["parameter"][0]["checksum"]
static.DXCALLSIGN = bytes(dxcallsign, 'utf-8')
static.DXCALLSIGN_CRC = helpers.get_crc_16(static.DXCALLSIGN)
# dt = datatype
# --> f = file
# --> m = message
# fn = filename
# ft = filetype
# d = data
# crc = checksum
#rawdata = {"dt": "f", "fn": filename, "ft": filetype,"d": data, "crc": checksum}
#dataframe = json.dumps(rawdata)
#data_out = bytes(dataframe, 'utf-8')
rawdata = bytes()
rawdata += bytes('f', 'utf-8')
rawdata += bytes(';', 'utf-8')
rawdata += bytes(filename, 'utf-8')
rawdata += bytes(';', 'utf-8')
rawdata += bytes(filetype, 'utf-8')
rawdata += bytes(';', 'utf-8')
rawdata += bytes(checksum, 'utf-8')
rawdata += bytes(';', 'utf-8')
rawdata += bytes(data, 'utf-8')
data_handler.DATA_QUEUE_TRANSMIT.put(['ARQ_FILE', data_out, mode, n_frames])
print(data_handler.DATA_QUEUE_TRANSMIT.qsize())
except Exception as e:
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
# TRANSMIT MESSAGE ----------------------------------------------------------
if received_json["type"] == 'arq' and received_json["command"] == "send_message":
try:
static.TNC_STATE = 'BUSY'
print(received_json)
# on a new transmission we reset the timer
static.ARQ_START_OF_TRANSMISSION = int(time.time())
dxcallsign = received_json["parameter"][0]["dxcallsign"]
mode = int(received_json["parameter"][0]["mode"])
n_frames = int(received_json["parameter"][0]["n_frames"])
data = received_json["parameter"][0]["data"] # d = data
checksum = received_json["parameter"][0]["checksum"] # crc = checksum
static.DXCALLSIGN = bytes(dxcallsign, 'utf-8')
static.DXCALLSIGN_CRC = helpers.get_crc_16(static.DXCALLSIGN)
# dt = datatype
# --> f = file
# --> m = message
# fn = filename
# ft = filetype
# d = data
# crc = checksum
rawdata = {"dt": "m","d": data, "crc": checksum}
dataframe = json.dumps(rawdata)
data_out = bytes(dataframe, 'utf-8')
data_handler.DATA_QUEUE_TRANSMIT.put(['ARQ_MESSAGE', data_out, mode, n_frames])
except Exception as e:
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
'''
# STOP TRANSMISSION ----------------------------------------------------------
if received_json["type"] == 'arq' and received_json["command"] == "stop_transmission":
@ -306,31 +233,13 @@ def process_tnc_commands(data):
except Exception as e:
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
'''
if received_json["type"] == 'GET' and received_json["command"] == 'rx_msg_buffer':
output = {
"command": "rx_msg_buffer",
"data-array": [],
}
for i in range(0, len(static.RX_MSG_BUFFER)):
rawdata = json.loads(static.RX_MSG_BUFFER[i][3])
output["data-array"].append({"dxcallsign": str(static.RX_MSG_BUFFER[i][0], 'utf-8'), "dxgrid": str(static.RX_MSG_BUFFER[i][1], 'utf-8'), "timestamp": static.RX_MSG_BUFFER[i][2], "rxdata": [rawdata]})
jsondata = json.dumps(output)
#self.request.sendall(bytes(jsondata, encoding))
SOCKET_QUEUE.put(jsondata)
'''
if received_json["type"] == 'set' and received_json["command"] == 'del_rx_buffer':
try:
static.RX_BUFFER = []
except Exception as e:
structlog.get_logger("structlog").warning("[SCK] command execution error", e=e, command=received_json)
'''
if received_json["type"] == 'set' and received_json["command"] == 'del_rx_msg_buffer':
static.RX_MSG_BUFFER = []
'''
# exception, if JSON cant be decoded
except Exception as e:
structlog.get_logger("structlog").error("[TNC] JSON decoding error", e=e)
@ -427,6 +336,7 @@ def process_daemon_commands(data):
rigctld_port = str(received_json["parameter"][0]["rigctld_port"])
enable_scatter = str(received_json["parameter"][0]["enable_scatter"])
enable_fft = str(received_json["parameter"][0]["enable_fft"])
low_bandwith_mode = str(received_json["parameter"][0]["low_bandwith_mode"])
DAEMON_QUEUE.put(['STARTTNC', \
mycall, \
@ -445,7 +355,8 @@ def process_daemon_commands(data):
rigctld_ip, \
rigctld_port, \
enable_scatter, \
enable_fft \
enable_fft, \
low_bandwith_mode \
])
except Exception as e:
@ -465,6 +376,7 @@ def process_daemon_commands(data):
radiocontrol = str(received_json["parameter"][0]["radiocontrol"])
rigctld_ip = str(received_json["parameter"][0]["rigctld_ip"])
rigctld_port = str(received_json["parameter"][0]["rigctld_port"])
DAEMON_QUEUE.put(['TEST_HAMLIB', \
devicename, \
deviceport, \
@ -501,8 +413,8 @@ def send_daemon_state():
'input_devices': static.AUDIO_INPUT_DEVICES,
'output_devices': static.AUDIO_OUTPUT_DEVICES,
'serial_devices': static.SERIAL_DEVICES,
'cpu': str(psutil.cpu_percent()),
'ram': str(psutil.virtual_memory().percent),
#'cpu': str(psutil.cpu_percent()),
#'ram': str(psutil.virtual_memory().percent),
'version': '0.1'
}

View file

@ -7,6 +7,9 @@ Created on Wed Dec 23 11:13:57 2020
Here we are saving application wide variables and stats, which have to be accessed everywhere.
Not nice, tipps are appreciated :-)
"""
VERSION = '0.1'
# DAEMON
DAEMONPORT = 3001
TNCSTARTED = False
@ -23,6 +26,7 @@ DXCALLSIGN_CRC = b'A'
MYGRID = b''
DXGRID = b''
LOW_BANDWITH_MODE = False
# ---------------------------------
# Server Defaults
@ -73,6 +77,9 @@ AUDIO_RMS = 0
FFT = [0]
ENABLE_FFT = False
# ARQ PROTOCOL VERSION
ARQ_PROTOCOL_VERSION = 0
# ARQ statistics
ARQ_BYTES_PER_MINUTE_BURST = 0
ARQ_BYTES_PER_MINUTE = 0