锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

GPGGA NTRIP RTCM 笔记

时间:2022-09-20 18:00:01 连接器q18j4aq18j5a连接器bc40no光电传感器

文章目录

    • 名词简写
    • GPGGA GNGGA
      • 格式说明
      • Linux PTY 虚拟串口对
      • Linux GPGGA 模拟器
    • NTRIP
      • NTRIP2.x vs NTRIP1.0
      • NTRIP2.0 Server/Caster/Client 模拟器
      • Base64
      • Client不发GPGGA的通信过程
      • Client只发一次GPGGA
      • Client周期发GPGGA
      • 一个帐户和两个应用程序不可用的演示
    • RTCM
      • Wireshark千寻NTRIP抓包
      • 串口 CAN 传输说明
      • RTCM电文解析 pyrtcm
      • RTCM各版本演进
      • RTCM Packet 包格式(帧结构)
      • 查表法算CRC24

名词简写

  • GNSS(global navigation satellite system) 全球导航卫星系统
  • GPS(Global Positioning System) 全球定位系统
  • DGPS(Differential Global Position System) 全球定位系统系统, 分为三类位置差分、伪距差分和相位差分(RTK)
  • RTK(Real Time Kinematic) 实时动态载波相位差技术
  • NTRIP(Networked Transport of RTCM via Internet Protocol) 基于互联网 RTCM 网络传输协议 所有的 RTK数据格式(NCT,RTCM,CMR,CMR 等等)可以传输, 是CORS服务接入协议. BASE充当 NTRIP Server, 很多BASE连到NTRIP Caster, Rover充当NTRIP Client
  • NMEA(National Marine Electronics Association) 美国国家海洋电子协会 或者 国家海洋电子协会, 常用的NMEA-0183 3.x, 4.x版本, 定义接收机输出的标准信息语句, 如 $GPGGA, $GPRMC
  • RTCM(Radio Technical Commission for Maritime Services) 海事无线电技术委员会, 常用的RTCM 3.x协议, 定义了 GPS/RTK/多星系等的消息类型
  • CORS(Continuously Operating Reference Stations) 参考站连续运行, 一般 CORS系统至少是: BASE ROVER, 服务提供商可以自建或使用基站, ROVER漫游端(漫游站/流动站/移动站) 所有的名字都应该可以)
  • DTU(Data Transfer unit) 数据传输单元, 将串口数据转换为IP数据或将IP通过有线/无线通信网络将数据转换为串口数据(4)G/5G/WiFi/LoRa/Zigbee/ETH/CAN…)传输的终端设备

GPGGA GNGGA

格式说明

GP: GPS

GN: GNSS, 一般是GPS与北斗混合, 或掺杂Glonass, Galileo

常见的 GPRMC和GNRMC, GPGGA和GNGGA, 写法不同(GP*, GN*), 格式相似. 可通过串口等配置GPS接收器的输出(GP*, GN*)

GPGGA或GNGGA一般是GPS/GNSS接收器发出的, 通常是串口, 现在为了车规,很多串口都拿到了,然后变成了CAN了. 发送此数据CORS服务器, 然后服务器将返回差分数据.

格式是 NMEA 定的, 参考

  • GPGGA (novatel.com)
  • GPGGA格式详解 | 豌豆荚博客 (lehoon.cn)
  • 关于0x0d和0x0a回车换行\r和\n - bingcaihuang - 博客园 (cnblogs.com)
$GPGGA,134658.00,5106.9792,N,11402.3003,W,2,09,1.0,1048.47,M,-16.27,M,08,0000*60 - $GPGGA: Log Header, 起始引导符和句子格式描述 - 134658.00: UTC时间(比北京慢8个小时), 格式为hhmmss.sss, 24小时制, hh总是2位数 - 5106.9792: 纬度, 格式为ddmm.mmmm - N: 纬度半球, 北纬N, 南纬S - 11402.3003: 经度, 格式为dddmm.mmmm - W: 经度半球, 东经E, 西经W - 2: GPS状态, 0初始化,1单点定位,2码差/伪差,3无效PPS,4RTK固定歧义解,5RTK浮点解,6航位计算模式,7人工输入固定值,8模拟模式,9WAAS差分, 这取决于数据是否差分。 - 09: 使用卫星数量, 00~12 - 1.0: HDOP, 水平精度因子, 0.5~99.9, 质量越小越好 - 1048.47: 椭球高, -9999.9~9999.9米 - M: 米 - -16.27: 地面高度异常, -9999.9~9999.9米 - M: 米 - 08: 差分GPS数据期限(如果不是差分定位,从最后一次收到差分信号开始的秒数将是空的, 没有空格), 最大99s - 0000: 差异参考基站标号, 0000~1023, 差分定位不是空的, 没有空格, 存在差分但是0000的情况 - *: 句子结束标志 - 60: 从$开始到*之间的所有ASCII代码的异常或验证, 不包含$和* - <CR> 回车符,结束标记, 0x0A, \r - <LF> 换行符,结束标记, 0x0D, \n 

例如,不同或验证的C代码

#include  #include   uint8_t cal_xor
       
        (
        uint8_t 
        *data
        , 
        uint8_t len
        ) 
        { 
          
        uint8_t i
        ; 
        uint8_t xor 
        = 
        0
        ; 
        for 
        (i 
        = 
        0
        ; i 
        < len
        ; i
        ++
        ) 
        { 
          xor 
        ^= data
        [i
        ]
        ; 
        } 
        return xor
        ; 
        } 
        int 
        main
        (
        void
        ) 
        { 
          
        // char str[] = "$GPGGA,172814.0,3723.46587704,N,12202.26957864,W,2,6,1.2,18.893,M,-25.669,M,2.0,0031*4F"; 
        char str
        [
        ] 
        = 
        "$GPGGA,115739.00,4158.8441367,N,09147.4416929,W,4,13,0.9,255.747,M,-32.00,M,01,0000*6E"
        ; 
        uint8_t xor 
        = 
        cal_xor
        (
        (
        uint8_t 
        *
        )str 
        + 
        1
        , 
        sizeof
        (str
        ) 
        / 
        sizeof
        (str
        [
        0
        ]
        ) 
        - 
        5
        )
        ; 
        // skip $ and *6E and \0 
        printf
        (
        "xor: %02X\n"
        , xor
        )
        ; 
        // xor: 6E 
        return 
        0
        ; 
        } 
       

Linux PTY 虚拟串口对

很多GPGGA数据是从串口发出来的, 模拟的话可以虚拟出一对串口.

代码来自(原作者也不知道是哪个):

  • ser2net/mkpty.py at master · qchats/ser2net (github.com)
  • ruiyunli/ttytool (github.com)
  • Linux下的虚拟终端(可用于在本机上模拟串口进行调试)_h小白请指教的博客-CSDN博客

关于pty(全称pseudo terminal, 伪终端), 参考:

  • Linux 伪终端(pty) - sparkdev - 博客园 (cnblogs.com)
#! /usr/bin/env python
#coding=utf-8

import pty
import os
import select

def mkpty():
    # Open the pseudo terminal
    master1, slave = pty.openpty()
    slaveName1 = os.ttyname(slave)
    master2, slave = pty.openpty()
    slaveName2 = os.ttyname(slave)
    print '\nslave device names: ', slaveName1, slaveName2
    return master1, master2

if __name__ == "__main__":
    master1, master2 = mkpty()
    while True:
        rl, wl, el = select.select([master1,master2], [], [], 1)
        for master in rl:
            data = os.read(master, 128)
            print "read %d data." % len(data)
            if master==master1:
                os.write(master2, data)
            else:
                os.write(master1, data)

代码就是造了两个pty, 把一个读的写到另一个去, 运行

$ python mkpty.py
slave device names:  /dev/pts/9 /dev/pts/10

打印出的 /dev/pts/9/dev/pts/10 就是一对虚拟串口, 可以相互收发, 用minicom测试

sudo minicom -b 115200 -D /dev/pts/9
sudo minicom -b 115200 -D /dev/pts/10

Linux GPGGA 模拟器

这个Github上有很多, 如:

  • zzjoey/GenGPGGA: GPS - GPGGA Message Simulator (github.com)

NTRIP

Ntrip Server: 通过某种途径获得到RTK差分信息,然后传送给 Ntrip Caster.

Ntrip Caster:接收Ntrip Server的差分数据。给ntrip client发送GPS差分数据。

Ntrip Client: 向Ntrip Caster申请GPS差分数据,最终实现RTK定位。

NTRIP2.x vs NTRIP1.0

NTRIP2.0协议是ntrip1.0的基础上,修改了不符合 HTTP 1.1 协议的一些地方:

  • 用POST替换SOURCE
  • 全部时间戳采用GMT(Greenwich Mean Time, 格林威治时间)
  • 使用分块传输编码(chunked transfer encoding), 不需要额外的长度指示
  • 解决代理服务器/防火墙/的问题

NTRIP2.0向下兼容, 又增加了一些实时性好的协议或特性:

  • UDP 单播
  • RTSP-UDP协议
  • 源表过滤(Sourcetable filtering), 解决显示或内存受限的问题, 最小化传输成本和时间

SSL for NTRIP:

  • 传输数据的加密(包括用户名和密码)
  • 服务器或数据提供商的身份验证
  • 用户身份验证
  • 用户设备身份验证
  • 通信隐私
  • SSL 已建立 Internet 标准

参考:

  • ntrip协议_wandersky0822的博客-程序员秘密_ntrip - 程序员秘密 (cxymm.net)
  • NTRIP1.0协议文档: Microsoft Word - NtripDocumentationExtract.doc (esa.int)
  • Ntrip Modernization and Professional Ntrip Caster (alberding.eu)
  • [PowerPoint-Präsentation (iku.edu.tr)](http://cors-tr.iku.edu.tr/images/Christian_Waese - NTRIP - Purpose and Perspectives.pdf)

虽然NTRIP2很好, 但下面还是以NTRIP1为例, 资料多, 流程简单粗暴, 也更容易理解.

TCP -> HTTP 1.1 -> NTRIP 1.0(不完全兼容HTTP 1.1)

了解TCP的3次握手四次挥手, HTTP的SOURCE, GET, 200 OK等将很容易理解NTRIP.

NTRIP2.0 Server/Caster/Client 模拟器

sevensx/ntrip: Simple ntrip caster/client/server example programs, using the NTRIP2.0 protocol (github.com)

对照他的博客看 NTRIP通信协议之NTRIPCaster | Work and Learning Journey (sevensx.github.io)

无需任何硬件或服务, 使用127.0.0.1进行本机通信, 端口8090, 简直人才…

$ make
$ ./ntrip_caster
$ ./ntrip_server
$ ./ntrip_client

# Client收到然后打印出的RTCM
D3 00 40 41 2E 06 44 19 1E F5 00 A4 00 00 10 B6 11 08 C2 E8 1D 58 1A 72 C8 46 CD 1A 08 EA 81 2C 3E DC 1B BB D9 5D 90 61 E8 05 2F FB 89 9A 4D CC EB FE 4C 25 28 FB 6C DA 7F 61 8E 60 9C BF FB 6A 2D 30 02 19 8F 73

# 解析出来是1042电文, 北斗卫星星历数据
<RTCM(1042, DF002=1042, DF488=56, DF489=802, DF490=0, DF491=-0.0, DF492=29, DF493=262800, DF494=0.0, DF495=0.0, DF496=0.00012996, DF497=29, DF498=58.6875, DF499=0.0, DF500=0.78233034, DF501=2.13e-06, DF502=0.00458138, DF503=2.645e-05, DF504=6493.56399345, DF505=262800, DF506=-1.3e-07, DF507=0.80137482, DF508=-2e-07, DF509=0.29031317, DF510=-600.046875, DF511=-0.95136995, DF512=-0.0, DF513=-30.1, DF514=0.0, DF515=1)>

# 38720 server
# 8090 caster?
# 39130 client
# server发给caster的差分数据被caster原封不动转给了client
$ sudo tcpdump -X -i lo port 8090
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
18:06:58.755481 IP localhost.39130 > localhost.8090: Flags [S], seq 2200508889, win 65495, options [mss 65495,sackOK,TS val 3891838375 ecr 0,nop,wscale 7], length 0
        0x0000:  4500 003c fc70 4000 4006 4049 7f00 0001  E..<.p@.@.@I....
        0x0010:  7f00 0001 98da 1f9a 8329 19d9 0000 0000  .........)......
        0x0020:  a002 ffd7 fe30 0000 0204 ffd7 0402 080a  .....0..........
        0x0030:  e7f8 bda7 0000 0000 0103 0307            ............
18:06:58.755488 IP localhost.8090 > localhost.39130: Flags [S.], seq 2521087539, ack 2200508890, win 65483, options [mss 65495,sackOK,TS val 3891838375 ecr 3891838375,nop,wscale 7], length 0
        0x0000:  4500 003c 0000 4000 4006 3cba 7f00 0001  E..<..@.@.<.....
        0x0010:  7f00 0001 1f9a 98da 9644 be33 8329 19da  .........D.3.)..
        0x0020:  a012 ffcb fe30 0000 0204 ffd7 0402 080a  .....0..........
        0x0030:  e7f8 bda7 e7f8 bda7 0103 0307            ............
18:06:58.755494 IP localhost.39130 > localhost.8090: Flags [.], ack 1, win 512, options [nop,nop,TS val 3891838375 ecr 3891838375], length 0
        0x0000:  4500 0034 fc71 4000 4006 4050 7f00 0001  E..4.q@.@.@P....
        0x0010:  7f00 0001 98da 1f9a 8329 19da 9644 be34  .........)...D.4
        0x0020:  8010 0200 fe28 0000 0101 080a e7f8 bda7  .....(..........
        0x0030:  e7f8 bda7                                ....
18:06:58.755533 IP localhost.39130 > localhost.8090: Flags [P.], seq 1:176, ack 1, win 512, options [nop,nop,TS val 3891838376 ecr 3891838375], length 175
        0x0000:  4500 00e3 fc72 4000 4006 3fa0 7f00 0001  E....r@.@.?.....
        0x0010:  7f00 0001 98da 1f9a 8329 19da 9644 be34  .........)...D.4
        0x0020:  8018 0200 fed7 0000 0101 080a e7f8 bda8  ................
        0x0030:  e7f8 bda7 4745 5420 2f52 5443 4d33 3220  ....GET./RTCM32.
        0x0040:  4854 5450 2f31 2e31 0d0a 5573 6572 2d41  HTTP/1.1..User-A
        0x0050:  6765 6e74 3a20 4e54 5249 5020 4e54 5249  gent:.NTRIP.NTRI
        0x0060:  5043 6c69 656e 742f 404e 5452 4950 5f56  PClient/@NTRIP_V
        0x0070:  4552 5349 4f4e 5f4d 414a 4f52 402e 404e  ERSION_MAJOR@.@N
        0x0080:  5452 4950 5f56 4552 5349 4f4e 5f4d 494e  TRIP_VERSION_MIN
        0x0090:  4f52 402e 404e 5452 4950 5f56 4552 5349  OR@.@NTRIP_VERSI
        0x00a0:  4f4e 5f50 4154 4348 402e 4047 4954 5f48  ON_PATCH@.@GIT_H
        0x00b0:  4153 4840 0d0a 4175 7468 6f72 697a 6174  ASH@..Authorizat
        0x00c0:  696f 6e3a 2042 6173 6963 2064 4756 7a64  ion:.Basic.dGVzd
        0x00d0:  4441 784f 6a45 794d 7a51 314e 673d 3d0d  DAxOjEyMzQ1Ng==.
        0x00e0:  0a0d 0a                                  ...
18:06:59.177309 IP localhost.38720 > localhost.8090: Flags [P.], seq 358293405:358293475, ack 2768753666, win 512, options [nop,nop,TS val 3891838797 ecr 3891837797], length 70
        0x0000:  4500 007a 32fa 4000 4006 0982 7f00 0001  E..z2.@.@.......
        0x0010:  7f00 0001 9740 1f9a 155b 1f9d a507 d402  .....@...[......
        0x0020:  8018 0200 fe6e 0000 0101 080a e7f8 bf4d  .....n.........M
        0x0030:  e7f8 bb65 d300 4041 2e06 4419 1ef5 00a4  ...e..@A..D.....
        0x0040:  0000 10b6 1108 c2e8 1d58 1a72 c846 cd1a  .........X.r.F..
        0x0050:  08ea 812c 3edc 1bbb d95d 9061 e805 2ffb  ...,>....].a../.
        0x0060:  899a 4dcc ebfe 4c25 28fb 6cda 7f61 8e60  ..M...L%(.l..a.` 0x0070: 9cbf fb6a 2d30 0219 8f73 ...j-0...s 18:06:59.177332 IP localhost.8090 > localhost.38720: Flags [.], ack 70, win 512, options [nop,nop,TS val 3891838797 ecr 3891838797], length 0 0x0000: 4500 0034 ac52 4000 4006 906f 7f00 0001 E..4.R@.@..o.... 0x0010: 7f00 0001 1f9a 9740 a507 d402 155b 1fe3 .......@.....[.. 0x0020: 8010 0200 fe28 0000 0101 080a e7f8 bf4d .....(.........M 0x0030: e7f8 bf4d ...M 18:06:59.177387 IP localhost.8090 > localhost.39130: Flags [P.], seq 18:88, ack 176, win 512, options [nop,nop,TS val 3891838797 ecr 3891838376], length 70 0x0000: 4500 007a 08a0 4000 4006 33dc 7f00 0001 E..z..@.@.3..... 0x0010: 7f00 0001 1f9a 98da 9644 be45 8329 1a89 .........D.E.).. 0x0020: 8018 0200 fe6e 0000 0101 080a e7f8 bf4d .....n.........M 0x0030: e7f8 bda8 d300 4041 2e06 4419 1ef5 00a4 ......@A..D..... 0x0040: 0000 10b6 1108 c2e8 1d58 1a72 c846 cd1a .........X.r.F.. 0x0050: 08ea 812c 3edc 1bbb d95d 9061 e805 2ffb ...,>....].a../. 0x0060: 899a 4dcc ebfe 4c25 28fb 6cda 7f61 8e60 ..M...L%(.l..a.`
        0x0070:  9cbf fb6a 2d30 0219 8f73                 ...j-0...s
18:06:59.177391 IP localhost.39130 > localhost.8090: Flags [.], ack 88, win 512, options [nop,nop,TS val 3891838797 ecr 3891838797], length 0
        0x0000:  4500 0034 fc74 4000 4006 404d 7f00 0001  E..4.t@.@.@M....
        0x0010:  7f00 0001 98da 1f9a 8329 1a89 9644 be8b  .........)...D..
        0x0020:  8010 0200 fe28 0000 0101 080a e7f8 bf4d  .....(.........M
        0x0030:  e7f8 bf4d                                ...M
18:06:59.755752 IP localhost.39130 > localhost.8090: Flags [P.], seq 176:262, ack 88, win 512, options [nop,nop,TS val 3891839376 ecr 3891838797], length 86
        0x0000:  4500 008a fc75 4000 4006 3ff6 7f00 0001  E....u@.@.?.....
        0x0010:  7f00 0001 98da 1f9a 8329 1a89 9644 be8b  .........)...D..
        0x0020:  8018 0200 fe7e 0000 0101 080a e7f8 c190  .....~..........
        0x0030:  e7f8 bf4d 2447 5047 4741 2c31 3030 3635  ...M$GPGGA,10065
        0x0040:  392e 3030 2c32 3233 342e 3338 3636 3030  9.00,2234.386600
        0x0050:  302c 4e2c 3131 3335 362e 3934 3330 3030  0,N,11356.943000
        0x0060:  302c 452c 312c 3130 2c31 2e32 2c31 302e  0,E,1,10,1.2,10.
        0x0070:  3030 3030 2c4d 2c2d 322e 3836 302c 4d2c  0000,M,-2.860,M,
        0x0080:  2c30 3030 302a 3737 0d0a                 ,0000*77..
18:06:59.755776 IP localhost.8090 > localhost.39130: Flags [.], ack 262, win 512, options [nop,nop,TS val 3891839376 ecr 3891839376], length 0
        0x0000:  4500 0034 08a1 4000 4006 3421 7f00 0001  E..4..@.@.4!....
        0x0010:  7f00 0001 1f9a 98da 9644 be8b 8329 1adf  .........D...)..
        0x0020:  8010 0200 fe28 0000 0101 080a e7f8 c190  .....(..........
        0x0030:  e7f8 c190                                ....
18:07:00.177507 IP localhost.38720 > localhost.8090: Flags [P.], seq 70:140, ack 1, win 512, options [nop,nop,TS val 3891839797 ecr 3891838797], length 70
        0x0000:  4500 007a 32fb 4000 4006 0981 7f00 0001  E..z2.@.@.......
        0x0010:  7f00 0001 9740 1f9a 155b 1fe3 a507 d402  .....@...[......
        0x0020:  8018 0200 fe6e 0000 0101 080a e7f8 c335  .....n.........5
        0x0030:  e7f8 bf4d d300 4041 2e06 4419 1ef5 00a4  ...M..@A..D.....
        0x0040:  0000 10b6 1108 c2e8 1d58 1a72 c846 cd1a  .........X.r.F..
        0x0050:  08ea 812c 3edc 1bbb d95d 9061 e805 2ffb  ...,>....].a../.
        0x0060:  899a 4dcc ebfe 4c25 28fb 6cda 7f61 8e60  ..M...L%(.l..a.`
        0x0070:  9cbf fb6a 2d30 0219 8f73                 ...j-0...s

如果只是测试和千寻NTRIP通信的话, 使用ntrip_client就可以了, 参考:

  • 如何使用千寻知寸_千寻知寸-千寻位置帮中心 (qxwz.com)

把相关信息填入ntrip/examples/ntrip_client.cc

  std::string ip = "203.107.45.154";	//千寻IP
  int port = 8001;	//8001:ITRF2008; 8002:WGS84; 8003:CGCS2000
  std::string user = "username";	//差分帐号
  std::string passwd = "password";	//差分密码
  std::string mountpoint = "AUTO";	//随时关注官方文档, 之前是RTCMxx, 现在AUTO

重新make运行即可

单Client的话, 这个用的也挺多的:

  • nunojpg/ntripclient: Ntrip Version 2.0 Command Line Client (github.com)

Base64

Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,转换后的字符串理论上将要比原来的长1/3(四字节对齐?), Base64能够将任何数据转换为易移植的字符串,避免了传输过程中的失真问题

一般是 明文数据通过MD5 、SHA等手段加密后,经过Base64编码为字符串后, 再传.

密码学 | Base64是加密算法吗? - 知乎 (zhihu.com)

Base64只是编码方式, 不是加密方式

NTRIP 1.0 中的用户名和密码只是简单的进行了Base64编码, 然后就明文传输出去了, 走的HTTP(另一个走HTTP的是GPGGA数据无需编码), 还不是HTTPS, 这其实是相当危险的行为, 可能意味着Connect时只要能抓包, 就能获取差分帐号和密码

# ntrip/examples/ntrip_client.cc
  std::string ip = "127.0.0.1";
  int port = 8090;
  std::string user = "test01";
  std::string passwd = "123456";
  std::string mountpoint = "RTCM32";
  
# ntrip/src/ntrip_client.cc
  std::string user_passwd = user_ + ":" + passwd_;
  std::string user_passwd_base64;
  Base64Encode(user_passwd, &user_passwd_base64);
  ret = snprintf(buffer.get(), kBufferSize-1,
      "GET /%s HTTP/1.1\r\n"
      "User-Agent: %s\r\n"
      "Authorization: Basic %s\r\n"
      "\r\n",
      mountpoint_.c_str(), kClientAgent, user_passwd_base64.c_str());
      
$ sudo tcpdump -X -i lo port 8090
  18:06:58.755533 IP localhost.39130 > localhost.8090: Flags [P.], seq 1:176, ack 1, win 512,  options [nop,nop,TS val 3891838376 ecr 3891838375], length 175
        0x0000:  4500 00e3 fc72 4000 4006 3fa0 7f00 0001  E....r@.@.?.....
        0x0010:  7f00 0001 98da 1f9a 8329 19da 9644 be34  .........)...D.4
        0x0020:  8018 0200 fed7 0000 0101 080a e7f8 bda8  ................
        0x0030:  e7f8 bda7 4745 5420 2f52 5443 4d33 3220  ....GET./RTCM32.
        0x0040:  4854 5450 2f31 2e31 0d0a 5573 6572 2d41  HTTP/1.1..User-A
        0x0050:  6765 6e74 3a20 4e54 5249 5020 4e54 5249  gent:.NTRIP.NTRI
        0x0060:  5043 6c69 656e 742f 404e 5452 4950 5f56  PClient/@NTRIP_V
        0x0070:  4552 5349 4f4e 5f4d 414a 4f52 402e 404e  ERSION_MAJOR@.@N
        0x0080:  5452 4950 5f56 4552 5349 4f4e 5f4d 494e  TRIP_VERSION_MIN
        0x0090:  4f52 402e 404e 5452 4950 5f56 4552 5349  OR@.@NTRIP_VERSI
        0x00a0:  4f4e 5f50 4154 4348 402e 4047 4954 5f48  ON_PATCH@.@GIT_H
        0x00b0:  4153 4840 0d0a 4175 7468 6f72 697a 6174  ASH@..Authorizat
        0x00c0:  696f 6e3a 2042 6173 6963 2064 4756 7a64  ion:.Basic.dGVzd
        0x00d0:  4441 784f 6a45 794d 7a51 314e 673d 3d0d  DAxOjEyMzQ1Ng==.
        0x00e0:  0a0d 0a                                  ...

从中可以看到, Base64编码后的用户名:密码dGVzdDAxOjEyMzQ1Ng==, 粘贴到Base64 在线编码解码 | Base64 加密解密 - Base64.us
在这里插入图片描述

可怕

Python代码示例

#!/usr/bin/python3
import base64
encodedStr = "dGVzdDAxOjEyMzQ1Ng=="
# Standard Base64 Decoding
decodedBytes = base64.b64decode(encodedStr)
decodedStr = str(decodedBytes, "utf-8")
print(decodedStr)	# test01:123456

NTRIP 2.x 中给出了一些SSL的方法, 来避免明文传输用户名和密码

Client不发GPGGA的通信过程

  • 如果是自建基站, Ntrip建立连接后, Caster就可以一秒一次的一直给Client转RTCM数据
  • 如果是用的CORS服务商, 一个基站或虚拟基站只能覆盖几公里或几十公里, NtripClient不发GPGGA, 服务商很难知道你在哪, 也就没法建虚拟基站发RTCM数据, 下面截图说明了这个过程

连接过程(可能没有获取源列表的过程):

# Client HTTP 发
GET /挂载点 HTTP/1.1
User-Agent: NTRIP NTRIPClient/版本号
Authorization: Basic Base64编码(用户名:密码)
# Caster TCP 回
ICY 200 OK

可参考:

  • 图解HTTP(1)_CopperDong的博客-CSDN博客
  • (图文并茂,权威最详细)Wireshark抓包分析 TCP三次握手/四次挥手详解 - 腾讯云开发者社区-腾讯云 (tencent.com)
  • Ntrip通讯协议1.0 - hanford - 博客园 (cnblogs.com)

30s TCP Alive的设置(如果发GPGGA, 一直有RTCM回传, 就没有TCP Alive了)

  // TCP socket keepalive.
  int keepalive = 1;  // Enable keepalive attributes.
  int keepidle = 30;  // Time out for starting detection.
  int keepinterval = 5;  // Time interval for sending packets during detection.
  int keepcount = 3;  // Max times for sending packets during detection.
  setsockopt(socket_fd, SOL_SOCKET, SO_KEEPALIVE,
      &keepalive, sizeof(keepalive));
  setsockopt(socket_fd, SOL_TCP, TCP_KEEPIDLE, &keepidle, sizeof(keepidle));
  setsockopt(socket_fd, SOL_TCP, TCP_KEEPINTVL,
      &keepinterval, sizeof(keepinterva

相关文章