cleanup of unused apis and functions
This commit is contained in:
parent
bfb845ac37
commit
2fbaab81c5
1 changed files with 0 additions and 172 deletions
172
src/stats.js
172
src/stats.js
|
|
@ -1,4 +1,3 @@
|
|||
const crypto = require("crypto");
|
||||
const path = require('path');
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
|
@ -12,67 +11,9 @@ const prisma = new PrismaClient();
|
|||
const root = new protobufjs.Root();
|
||||
root.resolvePath = (origin, target) => path.join(__dirname, "protos", target);
|
||||
root.loadSync('meshtastic/mqtt.proto');
|
||||
const Data = root.lookupType("Data");
|
||||
const HardwareModel = root.lookupEnum("HardwareModel");
|
||||
const ServiceEnvelope = root.lookupType("ServiceEnvelope");
|
||||
const PortNum = root.lookupEnum("PortNum");
|
||||
|
||||
const decryptionKeys = [
|
||||
"1PG7OiApB1nwvP+rz05pAQ==", // add default "AQ==" decryption key
|
||||
];
|
||||
|
||||
function createNonce(packetId, fromNode) {
|
||||
|
||||
// Expand packetId to 64 bits
|
||||
const packetId64 = BigInt(packetId);
|
||||
|
||||
// Initialize block counter (32-bit, starts at zero)
|
||||
const blockCounter = 0;
|
||||
|
||||
// Create a buffer for the nonce
|
||||
const buf = Buffer.alloc(16);
|
||||
|
||||
// Write packetId, fromNode, and block counter to the buffer
|
||||
buf.writeBigUInt64LE(packetId64, 0);
|
||||
buf.writeUInt32LE(fromNode, 8);
|
||||
buf.writeUInt32LE(blockCounter, 12);
|
||||
|
||||
return buf;
|
||||
|
||||
}
|
||||
|
||||
function decrypt(packet) {
|
||||
|
||||
// attempt to decrypt with all available decryption keys
|
||||
for(const decryptionKey of decryptionKeys){
|
||||
try {
|
||||
const key = Buffer.from(decryptionKey, "base64");
|
||||
const nonceBuffer = createNonce(packet.id, packet.from);
|
||||
|
||||
// determine algorithm based on key length
|
||||
var algorithm = null;
|
||||
if(key.length === 16){
|
||||
algorithm = "aes-128-ctr";
|
||||
} else if(key.length === 32){
|
||||
algorithm = "aes-256-ctr";
|
||||
} else {
|
||||
// skip this key, try the next one...
|
||||
console.error(`Skipping decryption key with invalid length: ${key.length}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const decipher = crypto.createDecipheriv(algorithm, key, nonceBuffer);
|
||||
const decryptedBuffer = Buffer.concat([decipher.update(packet.encrypted), decipher.final()]);
|
||||
|
||||
return Data.decode(decryptedBuffer);
|
||||
|
||||
} catch(e){}
|
||||
}
|
||||
|
||||
// couldn't decrypt
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
router.get('/hardware-models', async (req, res) => {
|
||||
try {
|
||||
|
|
@ -148,60 +89,7 @@ router.get('/messages-per-hour', async (req, res) => {
|
|||
}
|
||||
});
|
||||
|
||||
router.get('/position-precision', async (req, res) => {
|
||||
try {
|
||||
const sevenDaysAgo = new Date();
|
||||
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
|
||||
|
||||
const result = await prisma.node.groupBy({
|
||||
by: ['position_precision'],
|
||||
where: {
|
||||
position_updated_at: { gte: sevenDaysAgo },
|
||||
position_precision: { not: null },
|
||||
},
|
||||
_count: {
|
||||
position_precision: true,
|
||||
},
|
||||
});
|
||||
|
||||
const formatted = result.map(r => ({
|
||||
position_precision: r.position_precision,
|
||||
count: r._count.position_precision,
|
||||
}));
|
||||
|
||||
res.set('Cache-Control', 'public, max-age=600'); // 10 min cache
|
||||
res.json(formatted);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
res.status(500).json({ error: 'Internal Server Error' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/most-active-nodes', async (req, res) => {
|
||||
try {
|
||||
const result = await prisma.$queryRaw`
|
||||
SELECT n.long_name, COUNT(*) AS count
|
||||
FROM service_envelopes se
|
||||
JOIN nodes n ON se.from = n.node_id
|
||||
WHERE
|
||||
se.created_at >= NOW() - INTERVAL 1 DAY
|
||||
AND se.mqtt_topic NOT LIKE '%/map/'
|
||||
GROUP BY n.long_name
|
||||
ORDER BY count DESC
|
||||
LIMIT 25;
|
||||
`;
|
||||
|
||||
res.set('Cache-Control', 'public, max-age=600'); // 10 min cache
|
||||
res.json(result);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
res.status(500).json({ error: 'Internal Server Error' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/most-active-nodes2', async (req, res) => {
|
||||
try {
|
||||
const result = await prisma.$queryRaw`
|
||||
SELECT n.long_name, COUNT(*) AS count
|
||||
|
|
@ -234,66 +122,6 @@ router.get('/portnum-counts', async (req, res) => {
|
|||
const now = new Date();
|
||||
const startTime = new Date(now.getTime() - hours * 60 * 60 * 1000);
|
||||
|
||||
try {
|
||||
const messages = await prisma.serviceEnvelope.findMany({
|
||||
where: {
|
||||
created_at: { gte: startTime },
|
||||
...(Number.isInteger(nodeId) ? { from: nodeId } : {})
|
||||
},
|
||||
select: { protobuf: true, mqtt_topic: true }
|
||||
});
|
||||
|
||||
const counts = {};
|
||||
for (const row of messages) {
|
||||
try {
|
||||
// We want to filter out any map reports.
|
||||
if (row.mqtt_topic && row.mqtt_topic.endsWith("/map/")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const envelope = ServiceEnvelope.decode(row.protobuf);
|
||||
const packet = envelope.packet;
|
||||
|
||||
if (!packet?.encrypted) {
|
||||
counts[0] = (counts[0] || 0) + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
const dataMessage = decrypt(packet);
|
||||
|
||||
if (dataMessage?.portnum !== undefined) {
|
||||
const portnum = dataMessage.portnum;
|
||||
counts[portnum] = (counts[portnum] || 0) + 1;
|
||||
} else {
|
||||
// couldn't decrypt or no portnum in decrypted message
|
||||
counts[0] = (counts[0] || 0) + 1;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Decode error:", err.message);
|
||||
counts[0] = (counts[0] || 0) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
const result = Object.entries(counts).map(([portnum, count]) => ({
|
||||
portnum: parseInt(portnum),
|
||||
count,
|
||||
label: PortNum.valuesById[portnum] ?? "UNKNOWN",
|
||||
})).sort((a, b) => a.portnum - b.portnum);
|
||||
|
||||
res.json(result);
|
||||
|
||||
} catch (err) {
|
||||
console.error("Error in /portnum-counts:", err);
|
||||
res.status(500).json({ message: "Internal server error" });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/portnum-counts2', async (req, res) => {
|
||||
const nodeId = req.query.nodeId ? parseInt(req.query.nodeId, 10) : null;
|
||||
const hours = 24;
|
||||
const now = new Date();
|
||||
const startTime = new Date(now.getTime() - hours * 60 * 60 * 1000);
|
||||
|
||||
try {
|
||||
const envelopes = await prisma.serviceEnvelope.findMany({
|
||||
where: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue