184 lines
6.2 KiB
JavaScript
184 lines
6.2 KiB
JavaScript
import { promises as fs } from 'fs';
|
|
|
|
class OP25ConfigObject {
|
|
constructor() { }
|
|
|
|
async exportToFile(filename) {
|
|
try {
|
|
const jsonConfig = JSON.stringify(this, null, 2);
|
|
await fs.writeFile(filename, jsonConfig);
|
|
console.log(`Config exported to ${filename}`);
|
|
} catch (error) {
|
|
console.error(`Error exporting config to ${filename}: ${error}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
export class P25ConfigGenerator extends OP25ConfigObject {
|
|
constructor({ systemName, controlChannels, tagsFile, whitelistFile = undefined }) {
|
|
super();
|
|
console.log("Generating P25 Config for:", systemName);
|
|
const controlChannelsString = controlChannels.join(',');
|
|
this.channels = [new channelConfig({
|
|
"channelName": systemName,
|
|
"systemName": systemName,
|
|
"enableAnalog": "off",
|
|
"demodType": "cqpsk",
|
|
"cqpskTracking": true,
|
|
"filterType": "rc"
|
|
})];
|
|
this.devices = [new deviceConfig({
|
|
"gain": "LNA:36"
|
|
})];
|
|
this.trunking = new trunkingConfig({
|
|
"module": "tk_p25.py",
|
|
"systemName": systemName,
|
|
"controlChannelsString": controlChannelsString,
|
|
"tagsFile": tagsFile,
|
|
"whitelist": whitelistFile
|
|
});
|
|
this.audio = new audioConfig({});
|
|
this.terminal = new terminalConfig({});
|
|
}
|
|
}
|
|
|
|
export class NBFMConfigGenerator extends OP25ConfigObject {
|
|
constructor({ systemName, frequency, nbfmSquelch = -70 }) {
|
|
super();
|
|
this.channels = new channelConfig({
|
|
"channelName": systemName,
|
|
"enableAnalog": "on",
|
|
"nbfmSquelch": nbfmSquelch,
|
|
"frequency": frequency,
|
|
"demodType": "fsk4",
|
|
"filterType": "widepulse"
|
|
});
|
|
this.devices = new deviceConfig({
|
|
"gain": "LNA:32"
|
|
});
|
|
this.audio = new audioConfig({});
|
|
this.terminal = new terminalConfig({});
|
|
}
|
|
}
|
|
|
|
class channelConfig {
|
|
constructor({
|
|
channelName = "Voice_ch1",
|
|
device = "sdr0",
|
|
systemName,
|
|
metaStreamName,
|
|
demodType, // cqpsk: P25; fsk4: everything else
|
|
cqpskTracking,
|
|
trackingThreshold = 120,
|
|
trackingFeedback = 0.75,
|
|
destination = "udp://127.0.0.1:23456",
|
|
excess_bw = 0.2,
|
|
filterType = "rc", // rc: P25; widepulse: analog
|
|
ifRate = 24000,
|
|
plot = "",
|
|
symbolRate = 4800,
|
|
enableAnalog, //[on, off, auto]
|
|
nbfmDeviation = 4000, // only needed if analog is enabled
|
|
nbfmSquelch = -50, // only needed if analog is enabled
|
|
frequency, // only needed if analog is enabled
|
|
blacklist,
|
|
whitelist,
|
|
cryptKeys
|
|
}) {
|
|
// Core Configs
|
|
this.name = channelName;
|
|
this.device = device;
|
|
this.demod_type = demodType;
|
|
this.destination = destination;
|
|
this.excess_bw = excess_bw;
|
|
this.filter_type = filterType;
|
|
this.if_rate = ifRate;
|
|
this.plot = plot;
|
|
this.symbol_rate = symbolRate;
|
|
this.enable_analog = enableAnalog;
|
|
|
|
// P25 config
|
|
if (!enableAnalog || enableAnalog === "off" || systemName) this.trunking_sysname = systemName;
|
|
if (!enableAnalog || enableAnalog === "off" || systemName && metaStreamName) this.meta_stream_name = metaStreamName ?? "";
|
|
if (!enableAnalog || enableAnalog === "off" || systemName) this.cqpsk_tracking = cqpskTracking;
|
|
if (!enableAnalog || enableAnalog === "off" || systemName) this.tracking_threshold = trackingThreshold;
|
|
if (!enableAnalog || enableAnalog === "off" || systemName) this.tracking_feedback = trackingFeedback;
|
|
if (!enableAnalog || enableAnalog === "off" || systemName && blacklist) this.blacklist = blacklist ?? "";
|
|
if (!enableAnalog || enableAnalog === "off" || systemName && whitelist) this.whitelist = whitelist ?? "";
|
|
if (!enableAnalog || enableAnalog === "off" || systemName && cryptKeys) this.crypt_keys = cryptKeys ?? "";
|
|
|
|
// Analog config
|
|
if (enableAnalog === "on" || enableAnalog === "auto") this.nbfm_deviation = nbfmDeviation;
|
|
if (enableAnalog === "on" || enableAnalog === "auto") this.nbfm_squelch = nbfmSquelch;
|
|
if (enableAnalog === "on" || enableAnalog === "auto") this.frequency = frequency;
|
|
}
|
|
}
|
|
|
|
class deviceConfig {
|
|
constructor({ args = "rtl", gain = "LNA:32", gainMode = false, name = "sdr0", offset = 0, ppm = 0.0, sampleRate = 1920000, tunable = true }) {
|
|
this.args = args
|
|
this.gains = gain
|
|
this.gain_mode = gainMode
|
|
this.name = name
|
|
this.offset = offset
|
|
this.ppm = ppm
|
|
this.rate = sampleRate
|
|
this.usable_bw_pct = 0.85
|
|
this.tunable = tunable
|
|
}
|
|
}
|
|
|
|
class trunkingConfig {
|
|
/**
|
|
*
|
|
* @param {object} *
|
|
*/
|
|
constructor({ module, systemName, controlChannelsString, tagsFile = "", nac = "0x0", wacn = "0x0", cryptBehavior = 2, whitelist = "", blacklist = "" }) {
|
|
this.module = module;
|
|
this.chans = [{
|
|
"nac": nac,
|
|
"wacn": wacn,
|
|
"sysname": systemName,
|
|
"control_channel_list": controlChannelsString,
|
|
"whitelist": whitelist,
|
|
"blacklist": blacklist,
|
|
"tgid_tags_file": tagsFile,
|
|
"tdma_cc": false,
|
|
"crypt_behavior": cryptBehavior
|
|
}];
|
|
}
|
|
}
|
|
|
|
class audioConfig {
|
|
constructor({ module = "sockaudio.py", port = 23456, deviceName = "default" }) {
|
|
this.module = module;
|
|
this.instances = [{
|
|
"instance_name": "audio0",
|
|
"device_name": deviceName,
|
|
"udp_port": port,
|
|
"audio_gain": 2.0,
|
|
"number_channels": 1
|
|
}];
|
|
}
|
|
}
|
|
|
|
class metadataStreamConfig {
|
|
constructor({ }) {
|
|
this.module = "";
|
|
this.streams = [];
|
|
}
|
|
}
|
|
|
|
class terminalConfig {
|
|
constructor({ module = "terminal.py", terminalType = "http:0.0.0.0:8081" }) {
|
|
this.module = module;
|
|
this.terminal_type = terminalType;
|
|
this.curses_plot_interval = 0.1;
|
|
this.http_plot_interval = 1.0;
|
|
this.http_plot_directory = "../www/images";
|
|
this.tuning_step_large = 1200;
|
|
this.tuning_step_small = 100;
|
|
}
|
|
}
|
|
|