2023-02-11 21:49:07 +00:00
|
|
|
var net = require("net");
|
|
|
|
const path = require("path");
|
|
|
|
const { ipcRenderer } = require("electron");
|
|
|
|
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
|
2023-02-11 21:49:07 +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");
|
2023-02-11 21:49:07 +00:00
|
|
|
var configPath = path.join(configFolder, "config.json");
|
2021-09-04 18:23:58 +00:00
|
|
|
const config = require(configPath);
|
2021-07-17 07:03:40 +00:00
|
|
|
|
|
|
|
var daemon = new net.Socket();
|
2023-02-11 21:49:07 +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
|
2023-02-11 21:49:07 +00:00
|
|
|
var daemonShowConnectStateError = 1;
|
2022-04-24 22:43:30 +00:00
|
|
|
|
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;
|
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
setTimeout(connectDAEMON, 500);
|
2021-07-17 07:03:40 +00:00
|
|
|
|
2021-07-24 07:06:22 +00:00
|
|
|
function connectDAEMON() {
|
2023-02-11 21:49:07 +00:00
|
|
|
if (daemonShowConnectStateError == 1) {
|
|
|
|
daemonLog.info("connecting to daemon");
|
|
|
|
}
|
2021-07-24 07:06:22 +00:00
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
//clear message buffer after reconnecting or initial connection
|
|
|
|
socketchunk = "";
|
2021-09-04 14:33:17 +00:00
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
if (config.tnclocation == "localhost") {
|
|
|
|
daemon.connect(3001, "127.0.0.1");
|
|
|
|
} else {
|
|
|
|
daemon.connect(daemon_port, daemon_host);
|
|
|
|
}
|
2021-09-04 18:23:58 +00:00
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
//client.setTimeout(5000);
|
2021-07-17 07:03:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
daemon.on("connect", function (err) {
|
|
|
|
daemonLog.info("daemon connection established");
|
|
|
|
let Data = {
|
|
|
|
daemon_connection: daemon.readyState,
|
|
|
|
};
|
|
|
|
ipcRenderer.send("request-update-daemon-connection", Data);
|
2022-01-23 06:10:04 +00:00
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
daemonShowConnectStateError = 1;
|
|
|
|
});
|
|
|
|
|
|
|
|
daemon.on("error", function (err) {
|
|
|
|
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.');
|
|
|
|
|
|
|
|
daemonShowConnectStateError = 0;
|
|
|
|
}
|
|
|
|
setTimeout(connectDAEMON, 500);
|
|
|
|
daemon.destroy();
|
|
|
|
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
|
|
|
});
|
|
|
|
*/
|
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
daemon.on("end", function (data) {
|
|
|
|
daemonLog.warn("daemon connection ended");
|
|
|
|
daemon.destroy();
|
|
|
|
setTimeout(connectDAEMON, 500);
|
|
|
|
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){
|
2023-02-11 21:49:07 +00:00
|
|
|
writeDaemonCommand = function (command) {
|
|
|
|
// we use the writingCommand function to update our TCPIP state because we are calling this function a lot
|
|
|
|
// if socket opened, we are able to run commands
|
|
|
|
if (daemon.readyState == "open") {
|
|
|
|
//uiMain.setDAEMONconnection('open')
|
|
|
|
daemon.write(command + "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (daemon.readyState == "closed") {
|
|
|
|
//uiMain.setDAEMONconnection('closed')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (daemon.readyState == "opening") {
|
|
|
|
//uiMain.setDAEMONconnection('opening')
|
|
|
|
}
|
|
|
|
|
|
|
|
let Data = {
|
|
|
|
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
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
daemon.on("data", function (socketdata) {
|
|
|
|
/*
|
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
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
socketdata = socketdata.toString("utf8"); // convert data to string
|
|
|
|
socketchunk += socketdata; // append data to buffer so we can stick long data together
|
2021-07-24 07:06:22 +00:00
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
// check if we received begin and end of json data
|
|
|
|
if (socketchunk.startsWith('{"') && socketchunk.endsWith('"}\n')) {
|
|
|
|
var data = "";
|
2022-01-30 13:16:08 +00:00
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
// split data into chunks if we received multiple commands
|
|
|
|
socketchunk = socketchunk.split("\n");
|
|
|
|
data = JSON.parse(socketchunk[0]);
|
2022-01-30 13:16:08 +00:00
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
// search for empty entries in socketchunk and remove them
|
|
|
|
for (i = 0; i < socketchunk.length; i++) {
|
|
|
|
if (socketchunk[i] === "") {
|
|
|
|
socketchunk.splice(i, 1);
|
|
|
|
}
|
|
|
|
}
|
2021-07-24 07:06:22 +00:00
|
|
|
|
2023-02-11 21:49:07 +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
|
|
|
|
daemonLog.error(e);
|
|
|
|
daemonLog.debug(socketchunk[i]);
|
|
|
|
socketchunk = "";
|
2022-01-30 13:16:08 +00:00
|
|
|
}
|
2023-02-11 21:49:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2022-01-30 13:16:08 +00:00
|
|
|
}
|
2023-02-11 21:49:07 +00:00
|
|
|
|
|
|
|
//finally delete message buffer
|
|
|
|
socketchunk = "";
|
|
|
|
}
|
2021-07-17 07:03:40 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
function hexToBytes(hex) {
|
2023-02-11 21:49:07 +00:00
|
|
|
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
|
|
|
bytes.push(parseInt(hex.substr(c, 2), 16));
|
|
|
|
return bytes;
|
2021-07-17 07:03:40 +00:00
|
|
|
}
|
|
|
|
|
2023-02-11 21:49:07 +00:00
|
|
|
exports.getDaemonState = function () {
|
|
|
|
//function getDaemonState(){
|
|
|
|
command = '{"type" : "get", "command" : "daemon_state"}';
|
|
|
|
writeDaemonCommand(command);
|
|
|
|
};
|
2021-07-17 07:03:40 +00:00
|
|
|
|
|
|
|
// START TNC
|
|
|
|
// ` `== multi line string
|
|
|
|
|
2023-02-11 21:49:07 +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,
|
|
|
|
explorer_stats,
|
2023-03-06 11:48:27 +00:00
|
|
|
auto_tune,
|
2023-05-20 07:53:57 +00:00
|
|
|
tx_delay,
|
|
|
|
tci_ip,
|
|
|
|
tci_port
|
2023-02-11 21:49:07 +00:00
|
|
|
) {
|
|
|
|
var json_command = JSON.stringify({
|
|
|
|
type: "set",
|
|
|
|
command: "start_tnc",
|
|
|
|
parameter: [
|
|
|
|
{
|
|
|
|
mycall: mycall,
|
|
|
|
mygrid: mygrid,
|
|
|
|
rx_audio: rx_audio,
|
|
|
|
tx_audio: tx_audio,
|
|
|
|
radiocontrol: radiocontrol,
|
|
|
|
devicename: devicename,
|
|
|
|
deviceport: deviceport,
|
|
|
|
pttprotocol: pttprotocol,
|
|
|
|
pttport: pttport,
|
|
|
|
serialspeed: serialspeed,
|
|
|
|
data_bits: data_bits,
|
|
|
|
stop_bits: stop_bits,
|
|
|
|
handshake: handshake,
|
|
|
|
rigctld_port: rigctld_port,
|
|
|
|
rigctld_ip: rigctld_ip,
|
|
|
|
enable_scatter: enable_scatter,
|
|
|
|
enable_fft: enable_fft,
|
|
|
|
enable_fsk: enable_fsk,
|
|
|
|
low_bandwidth_mode: low_bandwidth_mode,
|
|
|
|
tuning_range_fmin: tuning_range_fmin,
|
|
|
|
tuning_range_fmax: tuning_range_fmax,
|
|
|
|
tx_audio_level: tx_audio_level,
|
|
|
|
respond_to_cq: respond_to_cq,
|
|
|
|
rx_buffer_size: rx_buffer_size,
|
|
|
|
enable_explorer: enable_explorer,
|
|
|
|
enable_stats: explorer_stats,
|
|
|
|
enable_auto_tune: auto_tune,
|
2023-03-06 11:48:27 +00:00
|
|
|
tx_delay: tx_delay,
|
2023-05-20 07:53:57 +00:00
|
|
|
tci_ip: tci_ip,
|
2023-05-20 07:54:56 +00:00
|
|
|
tci_port: tci_port,
|
2023-02-11 21:49:07 +00:00
|
|
|
},
|
|
|
|
],
|
|
|
|
});
|
|
|
|
|
|
|
|
daemonLog.debug(json_command);
|
|
|
|
writeDaemonCommand(json_command);
|
|
|
|
};
|
2021-07-17 07:03:40 +00:00
|
|
|
|
2021-07-24 07:06:22 +00:00
|
|
|
// STOP TNC
|
2023-02-11 21:49:07 +00:00
|
|
|
exports.stopTNC = function () {
|
|
|
|
command = '{"type" : "set", "command": "stop_tnc" , "parameter": "---" }';
|
|
|
|
writeDaemonCommand(command);
|
|
|
|
};
|
2021-10-17 13:57:41 +00:00
|
|
|
|
|
|
|
// TEST HAMLIB
|
2023-02-11 21:49:07 +00:00
|
|
|
exports.testHamlib = function (
|
|
|
|
radiocontrol,
|
|
|
|
devicename,
|
|
|
|
deviceport,
|
|
|
|
serialspeed,
|
|
|
|
pttprotocol,
|
|
|
|
pttport,
|
|
|
|
data_bits,
|
|
|
|
stop_bits,
|
|
|
|
handshake,
|
|
|
|
rigctld_ip,
|
|
|
|
rigctld_port
|
|
|
|
) {
|
|
|
|
var json_command = JSON.stringify({
|
|
|
|
type: "get",
|
|
|
|
command: "test_hamlib",
|
|
|
|
parameter: [
|
|
|
|
{
|
|
|
|
radiocontrol: radiocontrol,
|
|
|
|
devicename: devicename,
|
|
|
|
deviceport: deviceport,
|
|
|
|
pttprotocol: pttprotocol,
|
|
|
|
pttport: pttport,
|
|
|
|
serialspeed: serialspeed,
|
|
|
|
data_bits: data_bits,
|
|
|
|
stop_bits: stop_bits,
|
|
|
|
handshake: handshake,
|
|
|
|
rigctld_port: rigctld_port,
|
|
|
|
rigctld_ip: rigctld_ip,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
});
|
|
|
|
daemonLog.debug(json_command);
|
|
|
|
writeDaemonCommand(json_command);
|
|
|
|
};
|
2022-01-05 13:15:59 +00:00
|
|
|
|
|
|
|
//Save myCall
|
2023-02-11 21:49:07 +00:00
|
|
|
exports.saveMyCall = function (callsign) {
|
|
|
|
command =
|
|
|
|
'{"type" : "set", "command": "mycallsign" , "parameter": "' +
|
|
|
|
callsign +
|
|
|
|
'"}';
|
|
|
|
writeDaemonCommand(command);
|
|
|
|
};
|
2022-01-05 13:15:59 +00:00
|
|
|
|
|
|
|
// Save myGrid
|
2023-02-11 21:49:07 +00:00
|
|
|
exports.saveMyGrid = function (grid) {
|
|
|
|
command =
|
|
|
|
'{"type" : "set", "command": "mygrid" , "parameter": "' + grid + '"}';
|
|
|
|
writeDaemonCommand(command);
|
|
|
|
};
|
|
|
|
|
|
|
|
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();
|
2022-11-25 11:04:15 +00:00
|
|
|
});
|