chore: initial import of lingniu-vehicle-ingest

Multi-module Spring Boot ingest service for vehicle telemetry. Modules:

- ingest-api / ingest-core / ingest-codec-common: shared SPI, dispatcher,
  Disruptor event bus, BCC/BCD codec helpers
- protocol-gb32960: GB/T 32960.3 inbound (Netty + per-version parser
  packages v2016/v2025), platform login auth, VIN whitelist, idle handler
- protocol-jt808 / protocol-jt1078 / protocol-jsatl12: JT/T inbound
- inbound-mqtt / inbound-xinda-push: alternative ingest channels
- session-core: per-channel session state
- sink-archive / sink-mq: persistence sinks (local file / Kafka)
- command-gateway: terminal control command gateway
- bootstrap-all: aggregator Spring Boot app
- observability: Micrometer / Actuator wiring

Includes hex-dump golden samples under protocol-gb32960/src/test/resources
and the GB/T 32960.3-2016 / 2025 reference PDFs under reference/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
lingniu-dev
2026-04-15 16:08:57 +08:00
commit 064ecc479c
220 changed files with 11874 additions and 0 deletions

34
protocol-jt1078/pom.xml Normal file
View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.lingniu.ingest</groupId>
<artifactId>lingniu-vehicle-ingest</artifactId>
<version>0.1.0-SNAPSHOT</version>
</parent>
<artifactId>protocol-jt1078</artifactId>
<name>protocol-jt1078</name>
<description>
JT/T 1078 音视频信令接入。复用 protocol-jt808 的 Netty server 与会话,
只通过注册新的 BodyParser 热插拔扩展消息集0x1003 / 0x1005 / 0x1205 / 0x1206
</description>
<dependencies>
<dependency>
<groupId>com.lingniu.ingest</groupId>
<artifactId>ingest-api</artifactId>
</dependency>
<dependency>
<groupId>com.lingniu.ingest</groupId>
<artifactId>ingest-core</artifactId>
</dependency>
<dependency>
<groupId>com.lingniu.ingest</groupId>
<artifactId>protocol-jt808</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,20 @@
package com.lingniu.ingest.protocol.jt1078.codec.parser;
import com.lingniu.ingest.protocol.jt1078.model.Jt1078MessageId;
import com.lingniu.ingest.protocol.jt808.codec.BodyParser;
import com.lingniu.ingest.protocol.jt808.model.Jt808Body;
import com.lingniu.ingest.protocol.jt808.model.Jt808Header;
import java.nio.ByteBuffer;
/** 0x1206 文件上传完成通知。PoC 只取 raw。 */
public final class FileUploadCompleteBodyParser implements BodyParser {
@Override public int messageId() { return Jt1078MessageId.TERMINAL_FILE_UPLOAD_DONE; }
@Override
public Jt808Body parse(Jt808Header header, ByteBuffer body) {
byte[] raw = new byte[body.remaining()];
body.get(raw);
return new Jt808Body.Raw(messageId(), raw);
}
}

View File

@@ -0,0 +1,23 @@
package com.lingniu.ingest.protocol.jt1078.codec.parser;
import com.lingniu.ingest.protocol.jt1078.model.Jt1078MessageId;
import com.lingniu.ingest.protocol.jt808.codec.BodyParser;
import com.lingniu.ingest.protocol.jt808.model.Jt808Body;
import com.lingniu.ingest.protocol.jt808.model.Jt808Header;
import java.nio.ByteBuffer;
/**
* 0x1003 终端上传音视频属性 —— PoC 阶段先返回原始字节由下游分析。
* 真实解析字段:音视频编码 / 音频通道数 / 采样率 / 位深 / 最大音视频通道数 / 视频编码 / 分辨率 等。
*/
public final class MediaAttributesBodyParser implements BodyParser {
@Override public int messageId() { return Jt1078MessageId.TERMINAL_MEDIA_ATTRS_REPORT; }
@Override
public Jt808Body parse(Jt808Header header, ByteBuffer body) {
byte[] raw = new byte[body.remaining()];
body.get(raw);
return new Jt808Body.Raw(messageId(), raw);
}
}

View File

@@ -0,0 +1,28 @@
package com.lingniu.ingest.protocol.jt1078.config;
import com.lingniu.ingest.protocol.jt1078.codec.parser.FileUploadCompleteBodyParser;
import com.lingniu.ingest.protocol.jt1078.codec.parser.MediaAttributesBodyParser;
import com.lingniu.ingest.protocol.jt808.codec.BodyParser;
import com.lingniu.ingest.protocol.jt808.config.Jt808AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
/**
* jt1078 在 jt808 之前装配它自己的 Parser BeanSpring 会把它们注入到 jt808 的
* {@code BodyParserRegistry} 里,实现"同一个 Netty 端口复用、消息集热插拔"。
*/
@AutoConfiguration(before = Jt808AutoConfiguration.class)
@ConditionalOnProperty(prefix = "lingniu.ingest.jt1078", name = "enabled", havingValue = "true")
public class Jt1078AutoConfiguration {
@Bean
public BodyParser jt1078MediaAttributesBodyParser() {
return new MediaAttributesBodyParser();
}
@Bean
public BodyParser jt1078FileUploadCompleteBodyParser() {
return new FileUploadCompleteBodyParser();
}
}

View File

@@ -0,0 +1,12 @@
package com.lingniu.ingest.protocol.jt1078.model;
/** JT/T 1078 消息 ID 常量(上行部分核心子集)。 */
public final class Jt1078MessageId {
private Jt1078MessageId() {}
public static final int TERMINAL_MEDIA_ATTRS_REPORT = 0x1003;
public static final int TERMINAL_PASSENGER_VOLUME = 0x1005;
public static final int TERMINAL_FILE_LIST = 0x1205;
public static final int TERMINAL_FILE_UPLOAD_DONE = 0x1206;
}

View File

@@ -0,0 +1 @@
com.lingniu.ingest.protocol.jt1078.config.Jt1078AutoConfiguration