Files
DRB-Client/src/op25Handler/modules/op25ConfigGenerators.mjs
2024-08-26 02:33:23 -04:00

186 lines
6.3 KiB
JavaScript

import { DebugBuilder } from "../../modules/debugger.mjs";
const log = new DebugBuilder("client", "op25ConfigGenerator");
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);
log.INFO(`Config exported to ${filename}`);
} catch (error) {
log.ERROR(`Error exporting config to ${filename}: ${error}`);
}
}
}
export class P25ConfigGenerator extends OP25ConfigObject {
constructor({ systemName, controlChannels, tagsFile, whitelistFile = undefined }) {
super();
log.INFO("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;
}
}