2021-07-17 07:03:40 +00:00
|
|
|
var net = require('net');
|
2021-09-04 18:23:58 +00:00
|
|
|
const path = require('path')
|
|
|
|
const {
|
|
|
|
ipcRenderer
|
|
|
|
} = require('electron')
|
2022-02-24 09:13:00 +00:00
|
|
|
const log = require('electron-log');
|
|
|
|
const daemonLog = log.scope('daemon');
|
|
|
|
|
|
|
|
|
2021-07-23 15:40:44 +00:00
|
|
|
|
2021-09-04 18:23:58 +00:00
|
|
|
// https://stackoverflow.com/a/26227660
|
2021-09-04 19:37:56 +00:00
|
|
|
var appDataFolder = process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Application Support' : process.env.HOME + "/.config")
|
2021-09-13 16:27:50 +00:00
|
|
|
var configFolder = path.join(appDataFolder, "FreeDATA");
|
2021-09-04 18:23:58 +00:00
|
|
|
var configPath = path.join(configFolder, 'config.json')
|
|
|
|
const config = require(configPath);
|
2021-07-17 07:03:40 +00:00
|
|
|
|
|
|
|
var daemon = new net.Socket();
|
2022-01-30 13:16:08 +00:00
|
|
|
var socketchunk = ''; // Current message, per connection.
|
2021-07-17 07:03:40 +00:00
|
|
|
|
2022-04-24 22:43:30 +00:00
|
|
|
// global to keep track of daemon connection error emissions
|
|
|
|
var daemonShowConnectStateError = 1
|
|
|
|
|
2022-11-25 11:04:15 +00:00
|
|
|
// global for storing ip information
|
|
|
|
var daemon_port = config.daemon_port;
|
|
|
|
var daemon_host = config.daemon_host;
|
|
|
|
|
2021-07-17 07:03:40 +00:00
|
|
|
setTimeout(connectDAEMON, 500)
|
|
|
|
|
2021-07-24 07:06:22 +00:00
|
|
|
function connectDAEMON() {
|
2022-04-24 22:43:30 +00:00
|
|
|
if (daemonShowConnectStateError == 1) {
|
|
|
|
daemonLog.info('connecting to daemon');
|
|
|
|
}
|
2021-07-24 07:06:22 +00:00
|
|
|
|
2022-11-25 11:04:15 +00:00
|
|
|
//clear message buffer after reconnecting or initial connection
|
2022-01-30 13:16:08 +00:00
|
|
|
socketchunk = '';
|
2021-09-04 19:37:56 +00:00
|
|
|
|
2021-09-04 18:23:58 +00:00
|
|
|
if (config.tnclocation == 'localhost') {
|
|
|
|
daemon.connect(3001, '127.0.0.1')
|
2021-09-04 14:33:17 +00:00
|
|
|
} else {
|
2022-11-25 11:04:15 +00:00
|
|
|
daemon.connect(daemon_port, daemon_host)
|
2021-09-04 14:33:17 +00:00
|
|
|
|
|
|
|
}
|
2021-09-04 18:23:58 +00:00
|
|
|
|
2021-07-17 07:03:40 +00:00
|
|
|
//client.setTimeout(5000);
|
|
|
|
}
|
|
|
|
|
2022-02-08 14:27:34 +00:00
|
|
|
daemon.on('connect', function(err) {
|
2022-02-24 09:13:00 +00:00
|
|
|
daemonLog.info('daemon connection established');
|
2022-01-23 06:10:04 +00:00
|
|
|
let Data = {
|
|
|
|
daemon_connection: daemon.readyState,
|
|
|
|
};
|
|
|
|
ipcRenderer.send('request-update-daemon-connection', Data);
|
|
|
|
|
2022-04-24 22:43:30 +00:00
|
|
|
daemonShowConnectStateError = 1
|
2021-07-17 07:03:40 +00:00
|
|
|
})
|
|
|
|
|
2022-02-08 14:27:34 +00:00
|
|
|
daemon.on('error', function(err) {
|
2022-04-24 22:43:30 +00:00
|
|
|
if (daemonShowConnectStateError == 1) {
|
|
|
|
daemonLog.error('daemon connection error');
|
|
|
|
daemonLog.info('Make sure the daemon is started.');
|
|
|
|
daemonLog.info('Run "python daemon.py" in the tnc directory.');
|
|
|
|
daemonLog.debug(err)
|
|
|
|
|
|
|
|
daemonShowConnectStateError = 0
|
|
|
|
}
|
|
|
|
setTimeout(connectDAEMON, 500)
|
2022-02-08 14:27:34 +00:00
|
|
|
daemon.destroy();
|
2022-01-23 06:10:04 +00:00
|
|
|
let Data = {
|
|
|
|
daemon_connection: daemon.readyState,
|
|
|
|
};
|
|
|
|
ipcRenderer.send('request-update-daemon-connection', Data);
|
2021-07-17 07:03:40 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
/*
|
|
|
|
client.on('close', function(data) {
|
|
|
|
console.log(' TNC connection closed');
|
2021-09-13 16:27:50 +00:00
|
|
|
setTimeout(connectTNC, 2000)
|
2022-01-23 06:10:04 +00:00
|
|
|
let Data = {
|
|
|
|
daemon_connection: daemon.readyState,
|
|
|
|
};
|
|
|
|
ipcRenderer.send('request-update-daemon-connection', Data);
|
2021-07-17 07:03:40 +00:00
|
|
|
});
|
|
|
|
*/
|
|
|
|
|
|
|
|
daemon.on('end', function(data) {
|
2022-02-24 09:13:00 +00:00
|
|
|
|
|
|
|
daemonLog.warn('daemon connection ended');
|
2022-02-08 14:27:34 +00:00
|
|
|
daemon.destroy();
|
|
|
|
setTimeout(connectDAEMON, 500)
|
2022-01-23 06:10:04 +00:00
|
|
|
let Data = {
|
|
|
|
daemon_connection: daemon.readyState,
|
|
|
|
};
|
|
|
|
ipcRenderer.send('request-update-daemon-connection', Data);
|
2021-07-17 07:03:40 +00:00
|
|
|
});
|
|
|
|
|
2021-09-13 16:27:50 +00:00
|
|
|
//exports.writeCommand = function(command){
|
2021-07-24 07:06:22 +00:00
|
|
|
writeDaemonCommand = function(command) {
|
|
|
|
|
2021-07-17 07:03:40 +00:00
|
|
|
// we use the writingCommand function to update our TCPIP state because we are calling this function a lot
|
2022-04-10 17:20:58 +00:00
|
|
|
// if socket opened, we are able to run commands
|
2021-07-24 07:06:22 +00:00
|
|
|
if (daemon.readyState == 'open') {
|
2021-09-13 16:27:50 +00:00
|
|
|
//uiMain.setDAEMONconnection('open')
|
2021-07-24 07:06:22 +00:00
|
|
|
daemon.write(command + '\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (daemon.readyState == 'closed') {
|
|
|
|
//uiMain.setDAEMONconnection('closed')
|
2021-07-17 07:03:40 +00:00
|
|
|
}
|
2021-07-24 07:06:22 +00:00
|
|
|
|
|
|
|
if (daemon.readyState == 'opening') {
|
|
|
|
//uiMain.setDAEMONconnection('opening')
|
2021-07-17 07:03:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let Data = {
|
2021-07-24 07:06:22 +00:00
|
|
|
daemon_connection: daemon.readyState,
|
|
|
|
};
|
|
|
|
ipcRenderer.send('request-update-daemon-connection', Data);
|
2021-07-17 07:03:40 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 07:06:22 +00:00
|
|
|
// "https://stackoverflow.com/questions/9070700/nodejs-net-createserver-large-amount-of-data-coming-in"
|
2021-07-17 07:03:40 +00:00
|
|
|
|
2022-01-30 13:16:08 +00:00
|
|
|
daemon.on('data', function(socketdata) {
|
2021-07-24 07:06:22 +00:00
|
|
|
|
2022-01-30 13:16:08 +00:00
|
|
|
/*
|
|
|
|
inspired by:
|
|
|
|
stackoverflow.com questions 9070700 nodejs-net-createserver-large-amount-of-data-coming-in
|
|
|
|
*/
|
2021-07-17 07:03:40 +00:00
|
|
|
|
2021-07-24 07:06:22 +00:00
|
|
|
|
2022-01-30 13:16:08 +00:00
|
|
|
socketdata = socketdata.toString('utf8'); // convert data to string
|
|
|
|
socketchunk += socketdata// append data to buffer so we can stick long data together
|
|
|
|
|
|
|
|
|
|
|
|
// check if we received begin and end of json data
|
|
|
|
if (socketchunk.startsWith('{"') && socketchunk.endsWith('"}\n')) {
|
|
|
|
|
|
|
|
var data = ''
|
|
|
|
|
|
|
|
// split data into chunks if we received multiple commands
|
|
|
|
socketchunk = socketchunk.split("\n");
|
|
|
|
data = JSON.parse(socketchunk[0])
|
|
|
|
|
|
|
|
|
|
|
|
// search for empty entries in socketchunk and remove them
|
|
|
|
for (i = 0; i < socketchunk.length; i++) {
|
|
|
|
if (socketchunk[i] === ''){
|
|
|
|
socketchunk.splice(i, 1);
|
|
|
|
}
|
2021-10-17 13:57:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-01-30 13:16:08 +00:00
|
|
|
//iterate through socketchunks array to execute multiple commands in row
|
|
|
|
for (i = 0; i < socketchunk.length; i++) {
|
|
|
|
|
|
|
|
//check if data is not empty
|
|
|
|
if(socketchunk[i].length > 0){
|
|
|
|
|
|
|
|
//try to parse JSON
|
|
|
|
try {
|
|
|
|
|
|
|
|
data = JSON.parse(socketchunk[i])
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
console.log(e); // "SyntaxError
|
2022-02-24 09:13:00 +00:00
|
|
|
daemonLog.error(e);
|
|
|
|
daemonLog.debug(socketchunk[i])
|
2022-01-30 13:16:08 +00:00
|
|
|
socketchunk = ''
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (data['command'] == 'daemon_state') {
|
|
|
|
let Data = {
|
|
|
|
input_devices: data['input_devices'],
|
|
|
|
output_devices: data['output_devices'],
|
|
|
|
python_version: data['python_version'],
|
|
|
|
hamlib_version: data['hamlib_version'],
|
|
|
|
serial_devices: data['serial_devices'],
|
|
|
|
tnc_running_state: data['daemon_state'][0]['status'],
|
|
|
|
ram_usage: data['ram'],
|
|
|
|
cpu_usage: data['cpu'],
|
|
|
|
version: data['version'],
|
|
|
|
};
|
|
|
|
ipcRenderer.send('request-update-daemon-state', Data);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data['command'] == 'test_hamlib') {
|
|
|
|
let Data = {
|
|
|
|
hamlib_result: data['result'],
|
|
|
|
|
|
|
|
};
|
|
|
|
ipcRenderer.send('request-update-hamlib-test', Data);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-07-24 07:06:22 +00:00
|
|
|
|
2022-01-30 13:16:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//finally delete message buffer
|
|
|
|
socketchunk = '';
|
|
|
|
|
|
|
|
}
|
2021-07-17 07:03:40 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
function hexToBytes(hex) {
|
|
|
|
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
2021-07-24 07:06:22 +00:00
|
|
|
bytes.push(parseInt(hex.substr(c, 2), 16));
|
2021-07-17 07:03:40 +00:00
|
|
|
return bytes;
|
|
|
|
}
|
|
|
|
|
2021-07-24 07:06:22 +00:00
|
|
|
exports.getDaemonState = function() {
|
|
|
|
//function getDaemonState(){
|
2022-01-28 19:07:39 +00:00
|
|
|
command = '{"type" : "get", "command" : "daemon_state"}'
|
2021-07-24 07:06:22 +00:00
|
|
|
writeDaemonCommand(command)
|
2021-07-17 07:03:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// START TNC
|
|
|
|
// ` `== multi line string
|
|
|
|
|
2022-11-05 21:27:33 +00:00
|
|
|
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_bandwidth_mode, tuning_range_fmin, tuning_range_fmax, enable_fsk, tx_audio_level, respond_to_cq, rx_buffer_size, enable_explorer) {
|
2021-07-24 07:06:22 +00:00
|
|
|
var json_command = JSON.stringify({
|
2022-01-28 19:07:39 +00:00
|
|
|
type: 'set',
|
|
|
|
command: 'start_tnc',
|
2021-07-24 07:06:22 +00:00
|
|
|
parameter: [{
|
2022-01-05 13:15:59 +00:00
|
|
|
mycall: mycall,
|
|
|
|
mygrid: mygrid,
|
2021-07-24 07:06:22 +00:00
|
|
|
rx_audio: rx_audio,
|
|
|
|
tx_audio: tx_audio,
|
2022-01-18 18:38:05 +00:00
|
|
|
radiocontrol: radiocontrol,
|
2021-12-26 08:24:22 +00:00
|
|
|
devicename: devicename,
|
2021-07-24 07:06:22 +00:00
|
|
|
deviceport: deviceport,
|
2021-09-13 18:02:14 +00:00
|
|
|
pttprotocol: pttprotocol,
|
|
|
|
pttport: pttport,
|
2021-10-17 13:57:41 +00:00
|
|
|
serialspeed: serialspeed,
|
|
|
|
data_bits: data_bits,
|
|
|
|
stop_bits: stop_bits,
|
2022-01-18 18:38:05 +00:00
|
|
|
handshake: handshake,
|
|
|
|
rigctld_port: rigctld_port,
|
2022-02-02 20:12:16 +00:00
|
|
|
rigctld_ip: rigctld_ip,
|
|
|
|
enable_scatter: enable_scatter,
|
2022-02-08 14:27:34 +00:00
|
|
|
enable_fft: enable_fft,
|
2022-03-31 10:45:44 +00:00
|
|
|
enable_fsk: enable_fsk,
|
2022-05-28 12:08:33 +00:00
|
|
|
low_bandwidth_mode : low_bandwidth_mode,
|
2022-03-19 11:42:10 +00:00
|
|
|
tuning_range_fmin : tuning_range_fmin,
|
2022-03-31 19:13:30 +00:00
|
|
|
tuning_range_fmax : tuning_range_fmax,
|
2022-04-18 15:17:53 +00:00
|
|
|
tx_audio_level : tx_audio_level,
|
2022-09-05 09:54:50 +00:00
|
|
|
respond_to_cq : respond_to_cq,
|
2022-11-05 21:27:33 +00:00
|
|
|
rx_buffer_size : rx_buffer_size,
|
|
|
|
enable_explorer : enable_explorer
|
2021-09-04 18:23:58 +00:00
|
|
|
}]
|
2021-07-24 07:06:22 +00:00
|
|
|
})
|
2021-07-17 07:03:40 +00:00
|
|
|
|
2022-02-24 09:13:00 +00:00
|
|
|
daemonLog.debug(json_command);
|
2021-07-24 07:06:22 +00:00
|
|
|
writeDaemonCommand(json_command)
|
2021-07-17 07:03:40 +00:00
|
|
|
|
2021-07-24 07:06:22 +00:00
|
|
|
}
|
2021-07-17 07:03:40 +00:00
|
|
|
|
2021-07-24 07:06:22 +00:00
|
|
|
// STOP TNC
|
|
|
|
exports.stopTNC = function() {
|
2022-01-28 19:07:39 +00:00
|
|
|
command = '{"type" : "set", "command": "stop_tnc" , "parameter": "---" }'
|
2021-07-24 07:06:22 +00:00
|
|
|
writeDaemonCommand(command)
|
2021-10-17 13:57:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TEST HAMLIB
|
2022-01-18 18:38:05 +00:00
|
|
|
exports.testHamlib = function(radiocontrol, devicename, deviceport, serialspeed, pttprotocol, pttport, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port) {
|
2021-10-17 13:57:41 +00:00
|
|
|
|
|
|
|
var json_command = JSON.stringify({
|
2022-01-28 19:07:39 +00:00
|
|
|
type: 'get',
|
|
|
|
command: 'test_hamlib',
|
2021-10-17 13:57:41 +00:00
|
|
|
parameter: [{
|
2022-01-18 18:38:05 +00:00
|
|
|
radiocontrol: radiocontrol,
|
2021-12-26 08:24:22 +00:00
|
|
|
devicename: devicename,
|
2021-10-17 13:57:41 +00:00
|
|
|
deviceport: deviceport,
|
|
|
|
pttprotocol: pttprotocol,
|
|
|
|
pttport: pttport,
|
|
|
|
serialspeed: serialspeed,
|
|
|
|
data_bits: data_bits,
|
|
|
|
stop_bits: stop_bits,
|
2022-01-18 18:38:05 +00:00
|
|
|
handshake: handshake,
|
|
|
|
rigctld_port: rigctld_port,
|
|
|
|
rigctld_ip: rigctld_ip
|
2021-10-17 13:57:41 +00:00
|
|
|
}]
|
|
|
|
})
|
2022-02-24 09:13:00 +00:00
|
|
|
daemonLog.debug(json_command);
|
2021-10-17 13:57:41 +00:00
|
|
|
writeDaemonCommand(json_command)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-01-05 13:15:59 +00:00
|
|
|
|
|
|
|
//Save myCall
|
|
|
|
exports.saveMyCall = function(callsign) {
|
2022-01-28 19:07:39 +00:00
|
|
|
command = '{"type" : "set", "command": "mycallsign" , "parameter": "' + callsign + '"}'
|
2022-01-05 13:15:59 +00:00
|
|
|
writeDaemonCommand(command)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save myGrid
|
|
|
|
exports.saveMyGrid = function(grid) {
|
2022-01-28 19:07:39 +00:00
|
|
|
command = '{"type" : "set", "command": "mygrid" , "parameter": "' + grid + '"}'
|
2022-01-05 13:15:59 +00:00
|
|
|
writeDaemonCommand(command)
|
|
|
|
}
|
|
|
|
|
2022-11-25 11:04:15 +00:00
|
|
|
ipcRenderer.on('action-update-daemon-ip', (event, arg) => {
|
|
|
|
daemon.destroy();
|
|
|
|
let Data = {
|
|
|
|
busy_state: "-",
|
|
|
|
arq_state: "-",
|
|
|
|
//channel_state: "-",
|
|
|
|
frequency: "-",
|
|
|
|
mode: "-",
|
|
|
|
bandwidth: "-",
|
|
|
|
dbfs_level: 0
|
|
|
|
};
|
|
|
|
ipcRenderer.send('request-update-tnc-state', Data);
|
|
|
|
daemon_port = arg.port;
|
|
|
|
daemon_host = arg.adress;
|
|
|
|
connectDAEMON();
|
|
|
|
});
|