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:
34
protocol-jt1078/pom.xml
Normal file
34
protocol-jt1078/pom.xml
Normal 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>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 Bean,Spring 会把它们注入到 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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
com.lingniu.ingest.protocol.jt1078.config.Jt1078AutoConfiguration
|
||||
Reference in New Issue
Block a user