From 63b8263dbbc947709394d3f1a4a16ba22c733066 Mon Sep 17 00:00:00 2001 From: qubiaobiao <3294694717@qq.com> Date: Fri, 15 May 2026 10:40:26 +0800 Subject: [PATCH] =?UTF-8?q?ntrip-caster=E6=9C=8D=E5=8A=A1=E5=90=8E?= =?UTF-8?q?=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/home.js | 10 -- app/middleware/ntripCaster/ntripCaster.js | 139 ++++++++++++++++------ 2 files changed, 100 insertions(+), 49 deletions(-) diff --git a/app/controller/home.js b/app/controller/home.js index 02cee69..62d38e3 100644 --- a/app/controller/home.js +++ b/app/controller/home.js @@ -1,15 +1,5 @@ const { Controller } = require('egg'); -const GBK = require("gbk.js"); - -const decode = (data) => { - let arr = []; - data.match(/..?/g).forEach((element) => { - arr.push(parseInt(element, 16)); - }); - return GBK.decode(arr); -} - const CryptoJS = require("crypto-js"); const KEY = CryptoJS.enc.Utf8.parse('BDQH'); diff --git a/app/middleware/ntripCaster/ntripCaster.js b/app/middleware/ntripCaster/ntripCaster.js index 2e1aa1e..90ce825 100644 --- a/app/middleware/ntripCaster/ntripCaster.js +++ b/app/middleware/ntripCaster/ntripCaster.js @@ -124,46 +124,106 @@ class SimpleNtripCaster { const headers = this.parseHeaders(lines.slice(1, lines.indexOf(''))); let table = ''; this.sourcetable.forEach(element => { - const { mountpoint, MountpointOptions } = element; - // 源ID - const SourceID = MountpointOptions[0] || 'STR: '; - // 格式 - const Format = MountpointOptions[1] || 'RTCM'; - // 格式详情 - const FormatDetails = MountpointOptions[2] || ''; - // 载体 - const Carrier = MountpointOptions[3] || ''; - // 导航系统 - const NavSystem = MountpointOptions[4] || ''; - // 网络 - const NetWork = MountpointOptions[5] || ''; - // 国家 - const Country = MountpointOptions[6] || ''; - // 纬度 - const Latitude = MountpointOptions[7] || 0.0; - // 经度 - const Longitude = MountpointOptions[8] || 0.0; - // NMEA - const NMEA = MountpointOptions[9] || ''; - // 解决方案 - const Soution = MountpointOptions[10] || ''; - // 发生器 - const Generator = MountpointOptions[11] || ''; - // 压缩加密 - const ComprEncryp = MountpointOptions[12] || ''; - // 认证 - const Auth = MountpointOptions[13] || ''; - // 费用 - const Fee = MountpointOptions[14] || ''; - // 比特率 - const Bitrate = MountpointOptions[15] || ''; + // SourceID 数据源唯一标识 + // StreamFormat 0=RTCM 2, 1=RTCM 3.0, 2=RTCM 3.1/3.2, ... + // Details 位掩码,支持的 RTCM 消息类型 + // StreamType 1=OBS, 2=NAV, 3=STA, 4=COR + // Carrier 载波相位类型 + // NavSys 导航系统位掩码 + // Net 网络标识符 + // Country ISO 3166 数字代码 + // Latitude 纬度 + // Longitude 经度 + // NMEA NMEA 消息支持 + // Solution 解算类型 + // Compressed Y/N 是否压缩 + // Framed Y/N 是否帧格式 + // MSM MSM 支持掩码 + const { mountpoint, SourceAgent, MountpointOptions } = element; + let SourceID, Format, FormatDetails, StreamType, Carrier, NavSystem, NetWork, Country, Latitude, Longitude, NMEA, Soution, Compressed, Framed, MSM, Description, StreamID, Generator, Compression, Authenticated, Fee, Bitrate; + if (SourceAgent == 'NTRIP RTKLIB/demo5_b34L_pre1') { + // 源ID + SourceID = MountpointOptions[0] == '' ? '' : MountpointOptions[0]; + // 格式 + Format = MountpointOptions[1] == '' ? 'RTCM 3.2' : MountpointOptions[1]; + // 格式详情 + FormatDetails = MountpointOptions[2] == '' ? '1005(1),1033(1),1074(1),1084(1),1094(1),1114(1),1124(1)' : MountpointOptions[2]; + // 载体 + Carrier = MountpointOptions[3] == '' ? 2 : MountpointOptions[3]; + // 导航系统 + NavSystem = MountpointOptions[4] == '' ? 'GPS+GLO+GAL+BDS+QZS' : MountpointOptions[4]; + // 网络 + NetWork = MountpointOptions[5] == '' ? '' : MountpointOptions[5]; + // 国家 + Country = MountpointOptions[6] == '' ? '' : MountpointOptions[6]; + // 纬度 + Latitude = MountpointOptions[7] == '' ? 0.0 : MountpointOptions[7]; + // 经度 + Longitude = MountpointOptions[8] == '' ? 0.0 : MountpointOptions[8]; + // NMEA 消息支持 + NMEA = MountpointOptions[9] == '' ? 0 : MountpointOptions[9]; + // 解算类型 + Soution = MountpointOptions[10] == '' ? 0 : MountpointOptions[10]; + // 发生器 + Generator = MountpointOptions[11] == '' ? 'B' : MountpointOptions[11]; + // 压缩加密 + Compression = MountpointOptions[12] == '' ? 'N' : MountpointOptions[12]; + // 认证 + Authenticated = MountpointOptions[13] == '' ? 'N' : MountpointOptions[13]; + // 费用 + Fee = MountpointOptions[14] == '' ? 'N' : MountpointOptions[14]; + // 比特率 + Bitrate = MountpointOptions[15] == '' ? '115200' : MountpointOptions[15]; + // 描述 + Description = 'RTK'; + // 流ID + StreamID = 'none'; + } else { + // 源ID + SourceID = MountpointOptions[0] == '' ? '' : MountpointOptions[0]; + // 格式 + Format = MountpointOptions[1] == '' ? 'RTCM 3.2' : MountpointOptions[1]; + // 格式详情 + FormatDetails = MountpointOptions[2] == '' ? '1005(1),1033(1),1074(1),1084(1),1094(1),1114(1),1124(1)' : MountpointOptions[2]; + StreamType = MountpointOptions[3] == '' ? '' : MountpointOptions[3]; + // 载体 + Carrier = MountpointOptions[4] == '' ? 2 : MountpointOptions[4]; + // 导航系统 + NavSystem = MountpointOptions[5] == '' ? 'GPS+GLO+GAL+BDS+QZS' : MountpointOptions[5]; + // 网络 + NetWork = MountpointOptions[6] == '' ? '' : MountpointOptions[6]; + // 国家 + Country = MountpointOptions[7] == '' ? '' : MountpointOptions[7]; + // 纬度 + Latitude = MountpointOptions[8] == '' ? 0.0 : MountpointOptions[8]; + // 经度 + Longitude = MountpointOptions[9] == '' ? 0.0 : MountpointOptions[9]; + // NMEA + NMEA = MountpointOptions[10] == '' ? 0 : MountpointOptions[10]; + // 解决方案 + Soution = MountpointOptions[11] == '' ? 0 : MountpointOptions[11]; + // 描述 + Description = 'RTK'; + // 流ID + StreamID = 'none'; + // 发生器 + Generator = 'B'; + // 压缩加密 + Compression = 'N'; + } const found = lines.find(line => line.startsWith('Ntrip-Version: Ntrip/2.0')); if (found == 'Ntrip-Version: Ntrip/2.0') { - // 变体B:RTCM/ntrip-2风格 - table += `STR;${Format};${mountpoint};${FormatDetails};;${Carrier};${NavSystem};${NetWork};${Country};${Latitude};${Longitude};${NMEA};${SourceID};;;;\r\n`; + if (SourceAgent == 'NTRIP RTKLIB/demo5_b34L_pre1') { + table += `STR;${mountpoint};${SourceID};${Format};${FormatDetails};${Carrier};${NavSystem};${NetWork};${Country};${Latitude};${Longitude};${NMEA};${Soution};${Description};${StreamID};${Generator};${Compression};${Authenticated};${Fee};${Bitrate};none\r\n`; + } else { + // 变体B:RTCM/ntrip-2风格 + // table += `STR;${Format};${mountpoint};${FormatDetails};;${Carrier};${NavSystem};${NetWork};${Country};${Latitude};${Longitude};${NMEA};${SourceID};;;;\r\n`; + table += `STR;${Format};${SourceID};${mountpoint};${Format};${FormatDetails};${Carrier};${NavSystem};${NetWork};${Country};${Latitude};${Longitude};${NMEA};${Soution};${Description};${StreamID};${Generator};${Compression};${Authenticated};${Fee};${Bitrate};0\r\n`; + } } else { // 变体A:BKG/NTRIP 1.0风格 - table += `STR;${Format};${mountpoint};${FormatDetails};;${Carrier};${NavSystem};${SourceID};${Latitude};${Longitude};0.0;${NetWork};${Country};;;;\r\n`; + // table += `STR;${Format};${mountpoint};${FormatDetails};;${Carrier};${NavSystem};${SourceID};${Latitude};${Longitude};0.0;${NetWork};${Country};;;;\r\n`; + table += `STR;${Format};${mountpoint};${Format};${FormatDetails};${Carrier};${NavSystem};${NetWork};${Country};${Latitude};${Longitude};${NMEA};${Soution};${Description};${StreamID};${Generator};${Compression};0\r\n`; } }); table += 'ENDSOURCETABLE\r\n'; @@ -206,8 +266,9 @@ class SimpleNtripCaster { this.sendResponse(socket, 401, 'Unauthorized', {}); return; } - const MountpointOptions = lines[2].split(';'); - this.sourcetable.push({ password, mountpoint, MountpointOptions }); + const SourceAgent = lines[1].split(': ')[1]; + const MountpointOptions = lines[2].split(': ')[1].split(';'); + this.sourcetable.push({ password, mountpoint, SourceAgent, MountpointOptions }); this.serverSockets.set(mountpoint, socket); this.mountData.set(mountpoint, { socket: socket, @@ -278,7 +339,7 @@ class SimpleNtripCaster { if (find !== 'Request-Type: SIZE') { if (!this.mountData.has(mountpoint)) { this.sendResponse(socket, 404, 'Mountpoint Not Found', { - 'Access-Control-Allow-Origin': headers.origin + 'Access-Control-Allow-Origin': '*' }); return; }