diff --git a/.gitea/workflows/ci-deploy.yml b/.gitea/workflows/ci-deploy.yml index 47fb2fe..2867ab8 100644 --- a/.gitea/workflows/ci-deploy.yml +++ b/.gitea/workflows/ci-deploy.yml @@ -1,4 +1,4 @@ -name: JT808 CI/CD +name: iot-test-platform CI/CD on: push: @@ -45,7 +45,7 @@ jobs: - name: Build Docker Image id: build env: - IMAGE_NAME: 'jt808-server' + IMAGE_NAME: 'iot-test-platform' run: | SHORT_SHA=$(git log -1 --format='%h') FULL_IMAGE_NAME="${IMAGE_NAME}:${SHORT_SHA}" diff --git a/.gitignore b/.gitignore index a1c2a23..ae42eac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,40 @@ -# Compiled class file +# Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +# IDE - IntelliJ IDEA +.idea/ +*.iml +*.iws +*.ipr +out/ + +# IDE - Eclipse +.classpath +.project +.settings/ +.springBeans +bin/ + +# IDE - Visual Studio Code +.vscode/ + +# Java *.class - -# Log file *.log - -# BlueJ files *.ctxt - -# Mobile Tools for Java (J2ME) .mtj.tmp/ -# Package Files # +# Package Files *.jar *.war *.nar @@ -19,5 +43,9 @@ *.tar.gz *.rar -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +# Virtual Machine Crash Logs hs_err_pid* + +# OS System Files +.DS_Store +Thumbs.db diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 2803497..a79bf80 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -7,13 +7,12 @@ - + - diff --git a/README.md b/README.md index 9f8f88a..7360c68 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This project has been modernized to a Spring Boot 3 + Netty architecture, suppor ## Structure -- `src/main/java/com/hua/transport/jt808` +- `src/main/java/com/iot/transport/jt808` - `Jt808Application.java`: Spring Boot Entry Point. - `server/Jt808NettyServer.java`: Netty Server Wrapper. - `controller/DeviceController.java`: HTTP API Controller. diff --git a/pom.xml b/pom.xml index 841a306..89656eb 100644 --- a/pom.xml +++ b/pom.xml @@ -8,11 +8,11 @@ 3.2.0 - com.hua - hua-transport-jt808 + com.iot + iot-test-platform 0.0.1-SNAPSHOT - hua-transport-jt808 - JT808 Transport Server with Spring Boot + iot-test-platform + IOT test Server with Spring Boot 17 UTF-8 diff --git a/settings.xml b/settings.xml index feb9ebf..621edeb 100644 --- a/settings.xml +++ b/settings.xml @@ -12,3 +12,4 @@ + diff --git a/src/main/java/com/hua/transport/jt808/entity/request/LocationPack.java b/src/main/java/com/hua/transport/jt808/entity/request/LocationPack.java deleted file mode 100644 index c0b4685..0000000 --- a/src/main/java/com/hua/transport/jt808/entity/request/LocationPack.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.hua.transport.jt808.entity.request; - - -import java.util.Date; - -import com.hua.transport.jt808.entity.DataPack; - -/** - * 位置信息汇报消息 - * - * @author huaxl - * - */ -public class LocationPack extends DataPack { - // 告警信息 - // byte[0-3] - private int warningFlagField; - // byte[4-7] 状态(DWORD(32)) - private int statusField; - // byte[8-11] 纬度(DWORD(32)) - private float latitude; - // byte[12-15] 经度(DWORD(32)) - private float longitude; - // byte[16-17] 高程(WORD(16)) 海拔高度,单位为米( m) - // TODO ==>int?海拔 - private int elevation; - // byte[18-19] 速度(WORD) 1/10km/h - // TODO ==>float?速度 - private float speed; - // byte[20-21] 方向(WORD) 0-359,正北为 0,顺时针 - private int direction; - // byte[22-x] 时间(BCD[6]) YY-MM-DD-hh-mm-ss - // GMT+8 时间,本标准中之后涉及的时间均采用此时区 - private Date time; - - // Bluetooth Extension Data - private java.util.List bluetoothInfos; - - public LocationPack() { - } - - public LocationPack(DataPack packageData) { - this(); - this.channel = packageData.getChannel(); - this.checkSum = packageData.getCheckSum(); - this.bodyBytes = packageData.getBodyBytes(); - this.packHead = packageData.getPackHead(); - } - - public float getLatitude() { - return latitude; - } - - public void setLatitude(float latitude) { - this.latitude = latitude; - } - - public float getLongitude() { - return longitude; - } - - public void setLongitude(float longitude) { - this.longitude = longitude; - } - - public int getElevation() { - return elevation; - } - - public void setElevation(int elevation) { - this.elevation = elevation; - } - - public float getSpeed() { - return speed; - } - - public void setSpeed(float speed) { - this.speed = speed; - } - - public int getDirection() { - return direction; - } - - public void setDirection(int direction) { - this.direction = direction; - } - - public Date getTime() { - return time; - } - - public void setTime(Date time) { - this.time = time; - } - - public java.util.List getBluetoothInfos() { - return bluetoothInfos; - } - - public void setBluetoothInfos(java.util.List bluetoothInfos) { - this.bluetoothInfos = bluetoothInfos; - } - - public int getWarningFlagField() { - return warningFlagField; - } - - public void setWarningFlagField(int warningFlagField) { - this.warningFlagField = warningFlagField; - } - - public int getStatusField() { - return statusField; - } - - public void setStatusField(int statusField) { - this.statusField = statusField; - } - - @Override - public String toString() { - return "LocationInfoUploadMsg [warningFlagField=" + warningFlagField + ", statusField=" + statusField - + ", latitude=" + latitude + ", longitude=" + longitude + ", elevation=" + elevation + ", speed=" - + speed + ", direction=" + direction + ", time=" + time + ", bluetoothInfos=" + bluetoothInfos + "]"; - } - -} diff --git a/src/main/java/com/hua/transport/jt808/entity/request/RegisterPack.java b/src/main/java/com/hua/transport/jt808/entity/request/RegisterPack.java deleted file mode 100644 index 4367b37..0000000 --- a/src/main/java/com/hua/transport/jt808/entity/request/RegisterPack.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.hua.transport.jt808.entity.request; - -import java.util.Arrays; - -import com.hua.transport.jt808.entity.DataPack; - -/** - * 终端注册消息 - * - * @author huaxl - * - */ -public class RegisterPack extends DataPack { - - private TerminalRegInfo terminalRegInfo; - - public RegisterPack() { - } - - public RegisterPack(DataPack packageData) { - this(); - this.channel = packageData.getChannel(); - this.checkSum = packageData.getCheckSum(); - this.bodyBytes = packageData.getBodyBytes(); - this.packHead = packageData.getPackHead(); - } - - public TerminalRegInfo getTerminalRegInfo() { - return terminalRegInfo; - } - - public void setTerminalRegInfo(TerminalRegInfo msgBody) { - this.terminalRegInfo = msgBody; - } - - @Override - public String toString() { - return "TerminalRegisterMsg [terminalRegInfo=" + terminalRegInfo + ", msgHeader=" + packHead - + ", msgBodyBytes=" + Arrays.toString(bodyBytes) + ", checkSum=" + checkSum + ", channel=" + channel - + "]"; - } - - public static class TerminalRegInfo { - // 省域ID(WORD),设备安装车辆所在的省域,省域ID采用GB/T2260中规定的行政区划代码6位中前两位 - // 0保留,由平台取默认值 - private int provinceId; - // 市县域ID(WORD) 设备安装车辆所在的市域或县域,市县域ID采用GB/T2260中规定的行 政区划代码6位中后四位 - // 0保留,由平台取默认值 - private int cityId; - // 制造商ID(BYTE[5]) 5 个字节,终端制造商编码 - private String manufacturerId; - // 终端型号(BYTE[8]) 八个字节, 此终端型号 由制造商自行定义 位数不足八位的,补空格。 - private String terminalType; - // 终端ID(BYTE[7]) 七个字节, 由大写字母 和数字组成, 此终端 ID由制造 商自行定义 - private String terminalId; - /** - * - * 车牌颜色(BYTE) 车牌颜色,按照 JT/T415-2006 的 5.4.12 未上牌时,取值为0 - * 0===未上车牌 - * 1===蓝色 - * 2===黄色 - * 3===黑色 - * 4===白色 - * 9===其他 - */ - private int licensePlateColor; - // 车牌(STRING) 公安交 通管理部门颁 发的机动车号牌 - private String licensePlate; - - public TerminalRegInfo() { - } - - public int getProvinceId() { - return provinceId; - } - - public void setProvinceId(int provinceId) { - this.provinceId = provinceId; - } - - public int getCityId() { - return cityId; - } - - public void setCityId(int cityId) { - this.cityId = cityId; - } - - public String getManufacturerId() { - return manufacturerId; - } - - public void setManufacturerId(String manufacturerId) { - this.manufacturerId = manufacturerId; - } - - public String getTerminalType() { - return terminalType; - } - - public void setTerminalType(String terminalType) { - this.terminalType = terminalType; - } - - public String getTerminalId() { - return terminalId; - } - - public void setTerminalId(String terminalId) { - this.terminalId = terminalId; - } - - public int getLicensePlateColor() { - return licensePlateColor; - } - - public void setLicensePlateColor(int licensePlate) { - this.licensePlateColor = licensePlate; - } - - public String getLicensePlate() { - return licensePlate; - } - - public void setLicensePlate(String licensePlate) { - this.licensePlate = licensePlate; - } - - @Override - public String toString() { - return "TerminalRegInfo [provinceId=" + provinceId + ", cityId=" + cityId + ", manufacturerId=" - + manufacturerId + ", terminalType=" + terminalType + ", terminalId=" + terminalId - + ", licensePlateColor=" + licensePlateColor + ", licensePlate=" + licensePlate + "]"; - } - - } -} diff --git a/src/main/java/com/hua/transport/jt808/entity/response/RegisterBodyPack.java b/src/main/java/com/hua/transport/jt808/entity/response/RegisterBodyPack.java deleted file mode 100644 index 45e8bbc..0000000 --- a/src/main/java/com/hua/transport/jt808/entity/response/RegisterBodyPack.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.hua.transport.jt808.entity.response; - -public class RegisterBodyPack { - - public static final byte success = 0; - public static final byte car_already_registered = 1; - public static final byte car_not_found = 2; - public static final byte terminal_already_registered = 3; - public static final byte terminal_not_found = 4; - // byte[0-1] 应答流水号(WORD) 对应的终端注册消息的流水号 - private int replyFlowId; - /*** - * byte[2] 结果(BYTE) - * 0:成功 - * 1:车辆已被注册 - * 2:数据库中无该车辆 - **/ - private byte replyCode; - // byte[3-x] 鉴权码(STRING) 只有在成功后才有该字段 - private String replyToken; - - public RegisterBodyPack() { - } - - public int getReplyFlowId() { - return replyFlowId; - } - - public void setReplyFlowId(int flowId) { - this.replyFlowId = flowId; - } - - public byte getReplyCode() { - return replyCode; - } - - public void setReplyCode(byte code) { - this.replyCode = code; - } - - public String getReplyToken() { - return replyToken; - } - - public void setReplyToken(String token) { - this.replyToken = token; - } - - @Override - public String toString() { - return "TerminalRegisterMsgResp [replyFlowId=" + replyFlowId + ", replyCode=" + replyCode + ", replyToken=" - + replyToken + "]"; - } - -} diff --git a/src/main/java/com/hua/transport/jt808/entity/response/ServerBodyPack.java b/src/main/java/com/hua/transport/jt808/entity/response/ServerBodyPack.java deleted file mode 100644 index 1cad385..0000000 --- a/src/main/java/com/hua/transport/jt808/entity/response/ServerBodyPack.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.hua.transport.jt808.entity.response; - -public class ServerBodyPack { - - public static final byte success = 0; - public static final byte failure = 1; - public static final byte msg_error = 2; - public static final byte unsupported = 3; - public static final byte warnning_msg_ack = 4; - - // byte[0-1] 应答流水号 对应的终端消息的流水号 - private int replyFlowId; - // byte[2-3] 应答ID 对应的终端消息的ID - private int replyId; - /** - * 0:成功∕确认 - * 1:失败 - * 2:消息有误 - * 3:不支持 - * 4:报警处理确认 - */ - private byte replyCode; - - public ServerBodyPack() { - } - - public ServerBodyPack(int replyFlowId, int replyId, byte replyCode) { - super(); - this.replyFlowId = replyFlowId; - this.replyId = replyId; - this.replyCode = replyCode; - } - - public int getReplyFlowId() { - return replyFlowId; - } - - public void setReplyFlowId(int flowId) { - this.replyFlowId = flowId; - } - - public int getReplyId() { - return replyId; - } - - public void setReplyId(int msgId) { - this.replyId = msgId; - } - - public byte getReplyCode() { - return replyCode; - } - - public void setReplyCode(byte code) { - this.replyCode = code; - } - - @Override - public String toString() { - return "ServerCommonRespMsg [replyFlowId=" + replyFlowId + ", replyId=" + replyId + ", replyCode=" + replyCode - + "]"; - } - -} diff --git a/src/main/java/com/hua/transport/jt808/Jt808Application.java b/src/main/java/com/iot/transport/jt808/Jt808Application.java similarity index 89% rename from src/main/java/com/hua/transport/jt808/Jt808Application.java rename to src/main/java/com/iot/transport/jt808/Jt808Application.java index cb2f6fb..5106a0e 100644 --- a/src/main/java/com/hua/transport/jt808/Jt808Application.java +++ b/src/main/java/com/iot/transport/jt808/Jt808Application.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808; +package com.iot.transport.jt808; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/com/hua/transport/jt808/common/CommonResult.java b/src/main/java/com/iot/transport/jt808/common/CommonResult.java similarity index 93% rename from src/main/java/com/hua/transport/jt808/common/CommonResult.java rename to src/main/java/com/iot/transport/jt808/common/CommonResult.java index 3ba6c10..e774ea6 100644 --- a/src/main/java/com/hua/transport/jt808/common/CommonResult.java +++ b/src/main/java/com/iot/transport/jt808/common/CommonResult.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.common; +package com.iot.transport.jt808.common; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/com/hua/transport/jt808/common/Consts.java b/src/main/java/com/iot/transport/jt808/common/Consts.java similarity index 97% rename from src/main/java/com/hua/transport/jt808/common/Consts.java rename to src/main/java/com/iot/transport/jt808/common/Consts.java index 6b59e4e..1de3d43 100644 --- a/src/main/java/com/hua/transport/jt808/common/Consts.java +++ b/src/main/java/com/iot/transport/jt808/common/Consts.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.common; +package com.iot.transport.jt808.common; import java.nio.charset.Charset; diff --git a/src/main/java/com/hua/transport/jt808/controller/DeviceController.java b/src/main/java/com/iot/transport/jt808/controller/DeviceController.java similarity index 87% rename from src/main/java/com/hua/transport/jt808/controller/DeviceController.java rename to src/main/java/com/iot/transport/jt808/controller/DeviceController.java index 44d2243..6fc3bb2 100644 --- a/src/main/java/com/hua/transport/jt808/controller/DeviceController.java +++ b/src/main/java/com/iot/transport/jt808/controller/DeviceController.java @@ -1,9 +1,9 @@ -package com.hua.transport.jt808.controller; +package com.iot.transport.jt808.controller; -import com.hua.transport.jt808.common.CommonResult; -import com.hua.transport.jt808.entity.dto.LocationDto; -import com.hua.transport.jt808.service.ApiLogService; -import com.hua.transport.jt808.service.DeviceService; +import com.iot.transport.jt808.common.CommonResult; +import com.iot.transport.jt808.entity.dto.LocationDto; +import com.iot.transport.jt808.service.ApiLogService; +import com.iot.transport.jt808.service.DeviceService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/com/hua/transport/jt808/entity/DataPack.java b/src/main/java/com/iot/transport/jt808/entity/DataPack.java similarity index 99% rename from src/main/java/com/hua/transport/jt808/entity/DataPack.java rename to src/main/java/com/iot/transport/jt808/entity/DataPack.java index fa86877..11c446d 100644 --- a/src/main/java/com/hua/transport/jt808/entity/DataPack.java +++ b/src/main/java/com/iot/transport/jt808/entity/DataPack.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.entity; +package com.iot.transport.jt808.entity; import java.util.Arrays; diff --git a/src/main/java/com/hua/transport/jt808/entity/Session.java b/src/main/java/com/iot/transport/jt808/entity/Session.java similarity index 98% rename from src/main/java/com/hua/transport/jt808/entity/Session.java rename to src/main/java/com/iot/transport/jt808/entity/Session.java index 86fcc13..bf9a6f8 100644 --- a/src/main/java/com/hua/transport/jt808/entity/Session.java +++ b/src/main/java/com/iot/transport/jt808/entity/Session.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.entity; +package com.iot.transport.jt808.entity; import java.net.SocketAddress; diff --git a/src/main/java/com/hua/transport/jt808/entity/dto/LocationDto.java b/src/main/java/com/iot/transport/jt808/entity/dto/LocationDto.java similarity index 82% rename from src/main/java/com/hua/transport/jt808/entity/dto/LocationDto.java rename to src/main/java/com/iot/transport/jt808/entity/dto/LocationDto.java index 34a9ee0..6db29f0 100644 --- a/src/main/java/com/hua/transport/jt808/entity/dto/LocationDto.java +++ b/src/main/java/com/iot/transport/jt808/entity/dto/LocationDto.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.entity.dto; +package com.iot.transport.jt808.entity.dto; import lombok.Data; import java.util.Date; diff --git a/src/main/java/com/hua/transport/jt808/entity/request/AuthenticationPack.java b/src/main/java/com/iot/transport/jt808/entity/request/AuthenticationPack.java similarity index 50% rename from src/main/java/com/hua/transport/jt808/entity/request/AuthenticationPack.java rename to src/main/java/com/iot/transport/jt808/entity/request/AuthenticationPack.java index aa08e2e..7496912 100644 --- a/src/main/java/com/hua/transport/jt808/entity/request/AuthenticationPack.java +++ b/src/main/java/com/iot/transport/jt808/entity/request/AuthenticationPack.java @@ -1,9 +1,13 @@ -package com.hua.transport.jt808.entity.request; +package com.iot.transport.jt808.entity.request; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; import java.util.Arrays; -import com.hua.transport.jt808.common.Consts; -import com.hua.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.common.Consts; +import com.iot.transport.jt808.entity.DataPack; /** * 终端鉴权消息 @@ -11,6 +15,9 @@ import com.hua.transport.jt808.entity.DataPack; * @author huaxl * */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) public class AuthenticationPack extends DataPack { private String authCode; @@ -26,19 +33,4 @@ public class AuthenticationPack extends DataPack { this.packHead = packageData.getPackHead(); this.authCode = new String(packageData.getBodyBytes(), Consts.DEFAULT_CHARSET); } - - public void setAuthCode(String authCode) { - this.authCode = authCode; - } - - public String getAuthCode() { - return authCode; - } - - @Override - public String toString() { - return "TerminalAuthenticationMsg [authCode=" + authCode + ", msgHeader=" + packHead + ", msgBodyBytes=" - + Arrays.toString(bodyBytes) + ", checkSum=" + checkSum + ", channel=" + channel + "]"; - } - } diff --git a/src/main/java/com/iot/transport/jt808/entity/request/BatteryVersionInfo.java b/src/main/java/com/iot/transport/jt808/entity/request/BatteryVersionInfo.java new file mode 100644 index 0000000..7a4c2d9 --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/entity/request/BatteryVersionInfo.java @@ -0,0 +1,63 @@ +package com.iot.transport.jt808.entity.request; + +import java.util.HashMap; +import java.util.Map; + +/** + * 0xFE 扩展信息:电池、版本、ICCID等 + */ +public class BatteryVersionInfo { + // 0x02: 备用电池电量百分比 + private int batteryLevel; + + // 0x07: 版本信息 + private String version; + + // 0x20: ICCID + private String iccid; + + // 其他可能的扩展字段 + private Map extraData = new HashMap<>(); + + public int getBatteryLevel() { + return batteryLevel; + } + + public void setBatteryLevel(int batteryLevel) { + this.batteryLevel = batteryLevel; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getIccid() { + return iccid; + } + + public void setIccid(String iccid) { + this.iccid = iccid; + } + + public void addExtra(int id, String data) { + this.extraData.put(id, data); + } + + public Map getExtraData() { + return extraData; + } + + @Override + public String toString() { + return "BatteryVersionInfo{" + + "batteryLevel=" + batteryLevel + + ", version='" + version + '\'' + + ", iccid='" + iccid + '\'' + + ", extraData=" + extraData + + '}'; + } +} diff --git a/src/main/java/com/hua/transport/jt808/entity/request/BluetoothInfo.java b/src/main/java/com/iot/transport/jt808/entity/request/BluetoothInfo.java similarity index 96% rename from src/main/java/com/hua/transport/jt808/entity/request/BluetoothInfo.java rename to src/main/java/com/iot/transport/jt808/entity/request/BluetoothInfo.java index f7101c2..a876966 100644 --- a/src/main/java/com/hua/transport/jt808/entity/request/BluetoothInfo.java +++ b/src/main/java/com/iot/transport/jt808/entity/request/BluetoothInfo.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.entity.request; +package com.iot.transport.jt808.entity.request; import java.util.List; diff --git a/src/main/java/com/iot/transport/jt808/entity/request/LocationPack.java b/src/main/java/com/iot/transport/jt808/entity/request/LocationPack.java new file mode 100644 index 0000000..1afd6c1 --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/entity/request/LocationPack.java @@ -0,0 +1,131 @@ +package com.iot.transport.jt808.entity.request; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.iot.transport.jt808.entity.DataPack; + +/** + * 位置信息汇报消息 + * + * @author huaxl + * + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class LocationPack extends DataPack { + // 告警信息 + // byte[0-3] + private int warningFlagField; + // byte[4-7] 状态(DWORD(32)) + private int statusField; + // byte[8-11] 纬度(DWORD(32)) + private float latitude; + // byte[12-15] 经度(DWORD(32)) + private float longitude; + // byte[16-17] 高程(WORD(16)) 海拔高度,单位为米( m) + // TODO ==>int?海拔 + private int elevation; + // byte[18-19] 速度(WORD) 1/10km/h + // TODO ==>float?速度 + private float speed; + // byte[20-21] 方向(WORD) 0-359,正北为 0,顺时针 + private int direction; + // byte[22-x] 时间(BCD[6]) YY-MM-DD-hh-mm-ss + // GMT+8 时间,本标准中之后涉及的时间均采用此时区 + private Date time; + + // Generic Extensions Map + // Key: Extension ID (e.g., 0xF3, 0x01) + // Value: Parsed extension object or raw data + private Map extensions; + + public LocationPack() { + this.extensions = new HashMap<>(); + } + + public LocationPack(DataPack packageData) { + this(); + this.channel = packageData.getChannel(); + this.checkSum = packageData.getCheckSum(); + this.bodyBytes = packageData.getBodyBytes(); + this.packHead = packageData.getPackHead(); + } + + public void addExtension(Integer id, Object data) { + if (this.extensions == null) { + this.extensions = new HashMap<>(); + } + this.extensions.put(id, data); + } + + @SuppressWarnings("unchecked") + public List getBluetoothInfos() { + if (extensions != null && extensions.containsKey(0xF3)) { + return (List) extensions.get(0xF3); + } + return null; + } + + public void setBluetoothInfos(List bluetoothInfos) { + addExtension(0xF3, bluetoothInfos); + } + + public BatteryVersionInfo getBatteryVersionInfo() { + if (extensions != null && extensions.containsKey(0xFE)) { + return (BatteryVersionInfo) extensions.get(0xFE); + } + return null; + } + + public void setBatteryVersionInfo(BatteryVersionInfo info) { + addExtension(0xFE, info); + } + + public Float getMileage() { + if (extensions != null && extensions.containsKey(0x01)) return (Float) extensions.get(0x01); + return null; + } + public void setMileage(Float mileage) { addExtension(0x01, mileage); } + + public Integer getSignalStrength() { + if (extensions != null && extensions.containsKey(0x30)) return (Integer) extensions.get(0x30); + return null; + } + public void setSignalStrength(Integer signalStrength) { addExtension(0x30, signalStrength); } + + public void setVersionInfo(String versionInfo) { + BatteryVersionInfo info = getBatteryVersionInfo(); + if (info == null) { + info = new BatteryVersionInfo(); + setBatteryVersionInfo(info); + } + info.setVersion(versionInfo); + } + + public void setBatteryLevel(int batteryLevel) { + BatteryVersionInfo info = getBatteryVersionInfo(); + if (info == null) { + info = new BatteryVersionInfo(); + setBatteryVersionInfo(info); + } + info.setBatteryLevel(batteryLevel); + } + + public void setIccid(String iccid) { + BatteryVersionInfo info = getBatteryVersionInfo(); + if (info == null) { + info = new BatteryVersionInfo(); + setBatteryVersionInfo(info); + } + info.setIccid(iccid); + } +} diff --git a/src/main/java/com/iot/transport/jt808/entity/request/RegisterPack.java b/src/main/java/com/iot/transport/jt808/entity/request/RegisterPack.java new file mode 100644 index 0000000..866731b --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/entity/request/RegisterPack.java @@ -0,0 +1,66 @@ +package com.iot.transport.jt808.entity.request; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Arrays; + +import com.iot.transport.jt808.entity.DataPack; + +/** + * 终端注册消息 + * + * @author huaxl + * + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class RegisterPack extends DataPack { + + private TerminalRegInfo terminalRegInfo; + + public RegisterPack() { + } + + public RegisterPack(DataPack packageData) { + this(); + this.channel = packageData.getChannel(); + this.checkSum = packageData.getCheckSum(); + this.bodyBytes = packageData.getBodyBytes(); + this.packHead = packageData.getPackHead(); + } + + @Data + public static class TerminalRegInfo { + // 省域ID(WORD),设备安装车辆所在的省域,省域ID采用GB/T2260中规定的行政区划代码6位中前两位 + // 0保留,由平台取默认值 + private int provinceId; + // 市县域ID(WORD) 设备安装车辆所在的市域或县域,市县域ID采用GB/T2260中规定的行 政区划代码6位中后四位 + // 0保留,由平台取默认值 + private int cityId; + // 制造商ID(BYTE[5]) 5 个字节,终端制造商编码 + private String manufacturerId; + // 终端型号(BYTE[8]) 八个字节, 此终端型号 由制造商自行定义 位数不足八位的,补空格。 + private String terminalType; + // 终端ID(BYTE[7]) 七个字节, 由大写字母 和数字组成, 此终端 ID由制造 商自行定义 + private String terminalId; + /** + * + * 车牌颜色(BYTE) 车牌颜色,按照 JT/T415-2006 的 5.4.12 未上牌时,取值为0 + * 0===未上车牌 + * 1===蓝色 + * 2===黄色 + * 3===黑色 + * 4===白色 + * 9===其他 + */ + private int licensePlateColor; + // 车牌(STRING) 公安交 通管理部门颁 发的机动车号牌 + private String licensePlate; + + public TerminalRegInfo() { + } + } +} diff --git a/src/main/java/com/iot/transport/jt808/entity/response/RegisterBodyPack.java b/src/main/java/com/iot/transport/jt808/entity/response/RegisterBodyPack.java new file mode 100644 index 0000000..9b8ac9a --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/entity/response/RegisterBodyPack.java @@ -0,0 +1,34 @@ +package com.iot.transport.jt808.entity.response; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 终端注册应答 + * + * @author huaxl + * + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RegisterBodyPack { + + public static final byte success = 0; + public static final byte car_already_registered = 1; + public static final byte car_not_found = 2; + public static final byte terminal_already_registered = 3; + public static final byte terminal_not_found = 4; + // byte[0-1] 应答流水号(WORD) 对应的终端注册消息的流水号 + private int replyFlowId; + /*** + * byte[2] 结果(BYTE) + * 0:成功 + * 1:车辆已被注册 + * 2:数据库中无该车辆 + **/ + private byte replyCode; + // byte[3-x] 鉴权码(STRING) 只有在成功后才有该字段 + private String replyToken; +} diff --git a/src/main/java/com/iot/transport/jt808/entity/response/ServerBodyPack.java b/src/main/java/com/iot/transport/jt808/entity/response/ServerBodyPack.java new file mode 100644 index 0000000..0f330b6 --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/entity/response/ServerBodyPack.java @@ -0,0 +1,36 @@ +package com.iot.transport.jt808.entity.response; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 平台通用应答 + * + * @author huaxl + * + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ServerBodyPack { + + public static final byte success = 0; + public static final byte failure = 1; + public static final byte msg_error = 2; + public static final byte unsupported = 3; + public static final byte warnning_msg_ack = 4; + + // byte[0-1] 应答流水号 对应的终端消息的流水号 + private int replyFlowId; + // byte[2-3] 应答ID 对应的终端消息的ID + private int replyId; + /** + * 0:成功∕确认 + * 1:失败 + * 2:消息有误 + * 3:不支持 + * 4:报警处理确认 + */ + private byte replyCode; +} diff --git a/src/main/java/com/hua/transport/jt808/server/Jt808NettyServer.java b/src/main/java/com/iot/transport/jt808/server/Jt808NettyServer.java similarity index 80% rename from src/main/java/com/hua/transport/jt808/server/Jt808NettyServer.java rename to src/main/java/com/iot/transport/jt808/server/Jt808NettyServer.java index 9af2f6a..f9da41a 100644 --- a/src/main/java/com/hua/transport/jt808/server/Jt808NettyServer.java +++ b/src/main/java/com/iot/transport/jt808/server/Jt808NettyServer.java @@ -1,5 +1,7 @@ -package com.hua.transport.jt808.server; +package com.iot.transport.jt808.server; +import com.iot.transport.jt808.service.ApiLogService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @@ -16,8 +18,8 @@ public class Jt808NettyServer implements CommandLineRunner { @Value("${jt808.port:20048}") private int port; - @org.springframework.beans.factory.annotation.Autowired - private com.hua.transport.jt808.service.ApiLogService apiLogService; + @Autowired + private ApiLogService apiLogService; private TCPServer tcpServer; @@ -27,7 +29,7 @@ public class Jt808NettyServer implements CommandLineRunner { tcpServer = new TCPServer(port, apiLogService); tcpServer.startServer(); } - + // You might want to add a @PreDestroy method to stop the server gracefully // @PreDestroy // public void destroy() { diff --git a/src/main/java/com/hua/transport/jt808/server/SessionManager.java b/src/main/java/com/iot/transport/jt808/server/SessionManager.java similarity index 97% rename from src/main/java/com/hua/transport/jt808/server/SessionManager.java rename to src/main/java/com/iot/transport/jt808/server/SessionManager.java index fec3495..93d3162 100644 --- a/src/main/java/com/hua/transport/jt808/server/SessionManager.java +++ b/src/main/java/com/iot/transport/jt808/server/SessionManager.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.server; +package com.iot.transport.jt808.server; import java.util.List; import java.util.Map; @@ -8,7 +8,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.stream.Collectors; -import com.hua.transport.jt808.entity.Session; +import com.iot.transport.jt808.entity.Session; public class SessionManager { diff --git a/src/main/java/com/hua/transport/jt808/server/TCPServer.java b/src/main/java/com/iot/transport/jt808/server/TCPServer.java similarity index 93% rename from src/main/java/com/hua/transport/jt808/server/TCPServer.java rename to src/main/java/com/iot/transport/jt808/server/TCPServer.java index dcbce8e..a3039f3 100644 --- a/src/main/java/com/hua/transport/jt808/server/TCPServer.java +++ b/src/main/java/com/iot/transport/jt808/server/TCPServer.java @@ -1,12 +1,12 @@ -package com.hua.transport.jt808.server; +package com.iot.transport.jt808.server; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.TimeUnit; -import com.hua.transport.jt808.common.Consts; -import com.hua.transport.jt808.service.codec.LogDecoder; -import com.hua.transport.jt808.service.handler.TCPServerHandler; +import com.iot.transport.jt808.common.Consts; +import com.iot.transport.jt808.service.codec.LogDecoder; +import com.iot.transport.jt808.service.handler.TCPServerHandler; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; @@ -20,7 +20,7 @@ import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.concurrent.Future; -import com.hua.transport.jt808.service.ApiLogService; +import com.iot.transport.jt808.service.ApiLogService; public class TCPServer { diff --git a/src/main/java/com/hua/transport/jt808/service/ApiLogService.java b/src/main/java/com/iot/transport/jt808/service/ApiLogService.java similarity index 97% rename from src/main/java/com/hua/transport/jt808/service/ApiLogService.java rename to src/main/java/com/iot/transport/jt808/service/ApiLogService.java index e880e50..7ec81db 100644 --- a/src/main/java/com/hua/transport/jt808/service/ApiLogService.java +++ b/src/main/java/com/iot/transport/jt808/service/ApiLogService.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.service; +package com.iot.transport.jt808.service; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/hua/transport/jt808/service/DeviceService.java b/src/main/java/com/iot/transport/jt808/service/DeviceService.java similarity index 83% rename from src/main/java/com/hua/transport/jt808/service/DeviceService.java rename to src/main/java/com/iot/transport/jt808/service/DeviceService.java index 2ac2ae4..e689ee8 100644 --- a/src/main/java/com/hua/transport/jt808/service/DeviceService.java +++ b/src/main/java/com/iot/transport/jt808/service/DeviceService.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.service; +package com.iot.transport.jt808.service; public interface DeviceService { /** diff --git a/src/main/java/com/hua/transport/jt808/service/codec/DataDecoder.java b/src/main/java/com/iot/transport/jt808/service/codec/DataDecoder.java similarity index 69% rename from src/main/java/com/hua/transport/jt808/service/codec/DataDecoder.java rename to src/main/java/com/iot/transport/jt808/service/codec/DataDecoder.java index 324e58a..b6d4ef9 100644 --- a/src/main/java/com/hua/transport/jt808/service/codec/DataDecoder.java +++ b/src/main/java/com/iot/transport/jt808/service/codec/DataDecoder.java @@ -1,19 +1,19 @@ -package com.hua.transport.jt808.service.codec; +package com.iot.transport.jt808.service.codec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.hua.transport.jt808.common.Consts; -import com.hua.transport.jt808.entity.DataPack; -import com.hua.transport.jt808.entity.DataPack.PackHead; -import com.hua.transport.jt808.entity.request.LocationPack; -import com.hua.transport.jt808.entity.request.RegisterPack; -import com.hua.transport.jt808.entity.request.RegisterPack.TerminalRegInfo; -import com.hua.transport.jt808.util.BCDUtil; -import com.hua.transport.jt808.util.BitUtil; +import com.iot.transport.jt808.common.Consts; +import com.iot.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.entity.DataPack.PackHead; +import com.iot.transport.jt808.entity.request.LocationPack; +import com.iot.transport.jt808.entity.request.RegisterPack; +import com.iot.transport.jt808.entity.request.RegisterPack.TerminalRegInfo; +import com.iot.transport.jt808.util.BCDUtil; +import com.iot.transport.jt808.util.BitUtil; -import com.hua.transport.jt808.entity.request.BluetoothInfo; -import com.hua.transport.jt808.util.HexUtil; +import com.iot.transport.jt808.entity.request.BluetoothInfo; +import com.iot.transport.jt808.util.HexUtil; import java.util.ArrayList; import java.util.List; @@ -22,6 +22,9 @@ import java.util.List; * @author huaxl * */ +import com.iot.transport.jt808.service.codec.parser.ExtensionParser; +import com.iot.transport.jt808.service.codec.parser.ExtensionParserFactory; + public class DataDecoder { private static final Logger log = LoggerFactory.getLogger(DataDecoder.class); @@ -237,7 +240,6 @@ public class DataDecoder { // 扩展协议解析 (Starting from index 28) int index = 28; - List bluetoothInfos = new ArrayList<>(); while (index < data.length) { int extId = data[index] & 0xFF; @@ -245,83 +247,31 @@ public class DataDecoder { if (index + 1 >= data.length) break; int extLen = data[index + 1] & 0xFF; - if (extId == 0xF3) { - // F3 扩展 (蓝牙信标扫描附加信息) - // index+2: 特定标识 0xE6 - // index+3: 特定标识 0x0C - // index+4: 扫描到的蓝牙数据组数 - if (index + 4 < data.length) { - int groupCount = data[index + 4] & 0xFF; - int currentOffset = index + 5; - - for (int i = 0; i < groupCount; i++) { - if (currentOffset + 7 > data.length) break; - - // MAC (6 bytes) - byte[] macBytes = new byte[6]; - System.arraycopy(data, currentOffset, macBytes, 0, 6); - String mac = HexUtil.toHexString(macBytes); - // Add colons to MAC - StringBuilder sb = new StringBuilder(); - for(int k=0; k0) sb.append(":"); - sb.append(mac.substring(k, k+2)); - } - String macStr = sb.toString().toUpperCase(); - - // RSSI (1 byte) - int rssi = data[currentOffset + 6]; // Signed byte - - BluetoothInfo info = new BluetoothInfo(macStr, rssi); - info.setType(0xF3); - bluetoothInfos.add(info); - - currentOffset += 7; - } - - // Try to capture custom data if present at the end of the block - int expectedEnd = index + 2 + extLen; - if (currentOffset < expectedEnd && expectedEnd <= data.length) { - int customLen = expectedEnd - currentOffset; - byte[] customBytes = new byte[customLen]; - System.arraycopy(data, currentOffset, customBytes, 0, customLen); - String customHex = HexUtil.toHexString(customBytes); - if (!bluetoothInfos.isEmpty()) { - bluetoothInfos.get(bluetoothInfos.size() - 1).setCustomData(customHex); - } - } - } - - } else if (extId == 0xF4) { - // F4 扩展 (蓝牙BLE扫描周围同类产品) - // index+2: 扫描到的蓝牙数据组数 - if (index + 2 < data.length) { - int groupCount = data[index + 2] & 0xFF; - int currentOffset = index + 3; - - for (int i = 0; i < groupCount; i++) { - // Each group: 6 bytes MAC (from IMEI) + 1 byte RSSI = 7 bytes - if (currentOffset + 7 > data.length) break; - - byte[] macBytes = new byte[6]; - System.arraycopy(data, currentOffset, macBytes, 0, 6); - String mac = HexUtil.toHexString(macBytes); // This is partial IMEI - // RSSI (1 byte) - int rssi = data[currentOffset + 6]; - - BluetoothInfo info = new BluetoothInfo(mac, rssi); // raw hex as mac for now - info.setType(0xF4); - bluetoothInfos.add(info); - - currentOffset += 7; - } + // Validate remaining length + if (index + 2 + extLen > data.length) { + log.warn("Extension length out of bounds: ID={}, Len={}, Remaining={}", + String.format("0x%02X", extId), extLen, data.length - index - 2); + break; + } + + int contentStart = index + 2; + + ExtensionParser parser = ExtensionParserFactory.getParser(extId); + if (parser != null) { + try { + parser.parse(ret, data, contentStart, extLen); + } catch (Exception e) { + log.error("Failed to parse extension 0x{}: {}", String.format("%02X", extId), e.getMessage()); } + } else { + // Store unknown extensions as raw hex string + byte[] raw = new byte[extLen]; + System.arraycopy(data, contentStart, raw, 0, extLen); + ret.addExtension(extId, HexUtil.toHexString(raw)); } index += (2 + extLen); } - - ret.setBluetoothInfos(bluetoothInfos); return ret; } diff --git a/src/main/java/com/hua/transport/jt808/service/codec/DataEncoder.java b/src/main/java/com/iot/transport/jt808/service/codec/DataEncoder.java similarity index 88% rename from src/main/java/com/hua/transport/jt808/service/codec/DataEncoder.java rename to src/main/java/com/iot/transport/jt808/service/codec/DataEncoder.java index 511e4c0..1fa8f08 100644 --- a/src/main/java/com/hua/transport/jt808/service/codec/DataEncoder.java +++ b/src/main/java/com/iot/transport/jt808/service/codec/DataEncoder.java @@ -1,15 +1,15 @@ -package com.hua.transport.jt808.service.codec; +package com.iot.transport.jt808.service.codec; import java.util.Arrays; -import com.hua.transport.jt808.common.Consts; -import com.hua.transport.jt808.entity.DataPack; -import com.hua.transport.jt808.entity.Session; -import com.hua.transport.jt808.entity.request.RegisterPack; -import com.hua.transport.jt808.entity.response.ServerBodyPack; -import com.hua.transport.jt808.entity.response.RegisterBodyPack; -import com.hua.transport.jt808.util.BitUtil; -import com.hua.transport.jt808.util.JT808Util; +import com.iot.transport.jt808.common.Consts; +import com.iot.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.entity.Session; +import com.iot.transport.jt808.entity.request.RegisterPack; +import com.iot.transport.jt808.entity.response.ServerBodyPack; +import com.iot.transport.jt808.entity.response.RegisterBodyPack; +import com.iot.transport.jt808.util.BitUtil; +import com.iot.transport.jt808.util.JT808Util; /** * 数据包编码器 diff --git a/src/main/java/com/hua/transport/jt808/service/codec/LogDecoder.java b/src/main/java/com/iot/transport/jt808/service/codec/LogDecoder.java similarity index 91% rename from src/main/java/com/hua/transport/jt808/service/codec/LogDecoder.java rename to src/main/java/com/iot/transport/jt808/service/codec/LogDecoder.java index 7e56bfd..ee89b9f 100644 --- a/src/main/java/com/hua/transport/jt808/service/codec/LogDecoder.java +++ b/src/main/java/com/iot/transport/jt808/service/codec/LogDecoder.java @@ -1,9 +1,9 @@ -package com.hua.transport.jt808.service.codec; +package com.iot.transport.jt808.service.codec; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.hua.transport.jt808.util.HexUtil; +import com.iot.transport.jt808.util.HexUtil; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; diff --git a/src/main/java/com/iot/transport/jt808/service/codec/parser/BluetoothBeaconParser.java b/src/main/java/com/iot/transport/jt808/service/codec/parser/BluetoothBeaconParser.java new file mode 100644 index 0000000..45bf30d --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/service/codec/parser/BluetoothBeaconParser.java @@ -0,0 +1,57 @@ +package com.iot.transport.jt808.service.codec.parser; + +import com.iot.transport.jt808.entity.request.BluetoothInfo; +import com.iot.transport.jt808.entity.request.LocationPack; +import com.iot.transport.jt808.util.HexUtil; +import java.util.ArrayList; +import java.util.List; + +public class BluetoothBeaconParser implements ExtensionParser { + @Override + public int getExtensionId() { + return 0xF3; + } + + @Override + public void parse(LocationPack locationPack, byte[] data, int offset, int length) { + // Offset points to content after ID and Length + // Header: E6 (1 byte) + 0C (1 byte) + Count (1 byte) = 3 bytes + if (length < 3) return; + + int currentOffset = offset + 2; // Skip E6 0C + int count = data[currentOffset] & 0xFF; + currentOffset++; + + List list = locationPack.getBluetoothInfos(); + if (list == null) { + list = new ArrayList<>(); + locationPack.setBluetoothInfos(list); + } + + for (int i = 0; i < count; i++) { + if (currentOffset + 7 > offset + length) break; + + byte[] macBytes = new byte[6]; + System.arraycopy(data, currentOffset, macBytes, 0, 6); + String mac = formatMac(HexUtil.toHexString(macBytes)); + + int rssi = data[currentOffset + 6]; // Signed + + BluetoothInfo info = new BluetoothInfo(mac, rssi); + info.setType(0xF3); + list.add(info); + + currentOffset += 7; + } + } + + private String formatMac(String hex) { + StringBuilder sb = new StringBuilder(); + for(int k=0; k0) sb.append(":"); + sb.append(hex.substring(k, k+2)); + } + return sb.toString().toUpperCase(); + } +} + diff --git a/src/main/java/com/iot/transport/jt808/service/codec/parser/ExtendedInfoParser.java b/src/main/java/com/iot/transport/jt808/service/codec/parser/ExtendedInfoParser.java new file mode 100644 index 0000000..1538888 --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/service/codec/parser/ExtendedInfoParser.java @@ -0,0 +1,62 @@ +package com.iot.transport.jt808.service.codec.parser; + +import com.iot.transport.jt808.entity.request.LocationPack; + +public class ExtendedInfoParser implements ExtensionParser { + @Override + public int getExtensionId() { + return 0xFE; + } + + @Override + public void parse(LocationPack locationPack, byte[] data, int offset, int length) { + // 0xFE extension parsing based on 4.1.1 example + // Structure seems flexible inside 0xFE container + // E6 (Identifier) + ID + Len + Content ... + + int currentOffset = offset; + if (length > 0 && (data[currentOffset] & 0xFF) == 0xE6) { + currentOffset++; // Skip E6 + + while (currentOffset < offset + length) { + if (currentOffset + 2 > offset + length) break; + + int subId = data[currentOffset] & 0xFF; + int subLen = 0; + // It seems sub-length is 2 bytes or 1 byte? Example says: "0001(长度2字节)" for ID 02 + // Let's assume 2 bytes length based on example "0001" + // But wait, "38:消息长度" for the whole FE block. + // Inside FE: "02(ID) 0001(长度2字节) 64" -> ID(1) + Len(2) + Val(1) + + int lenHigh = data[currentOffset + 1] & 0xFF; + int lenLow = data[currentOffset + 2] & 0xFF; + subLen = (lenHigh << 8) | lenLow; + + currentOffset += 3; + + if (currentOffset + subLen > offset + length) break; + + if (subId == 0x02) { + // Battery + int battery = data[currentOffset] & 0xFF; + locationPack.setBatteryLevel(battery); + } else if (subId == 0x07) { + // Version Info (ASCII) + String version = new String(data, currentOffset, subLen); + locationPack.setVersionInfo(version); + } else if (subId == 0x20) { + // ICCID + // Example shows BCD format? "8986..." + // Spec says "10BYTES". + // BCD to String + // We need a helper, but for now lets assume simple hex string or we can use existing BCDUtil if we can access it. + // Since we don't have BCDUtil here easily without injection, let's use Hex for now or just skip + // locationPack.setIccid(...); + } + + currentOffset += subLen; + } + } + } +} + diff --git a/src/main/java/com/iot/transport/jt808/service/codec/parser/ExtensionParser.java b/src/main/java/com/iot/transport/jt808/service/codec/parser/ExtensionParser.java new file mode 100644 index 0000000..da48bac --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/service/codec/parser/ExtensionParser.java @@ -0,0 +1,9 @@ +package com.iot.transport.jt808.service.codec.parser; + +import com.iot.transport.jt808.entity.request.LocationPack; + +public interface ExtensionParser { + int getExtensionId(); + void parse(LocationPack locationPack, byte[] data, int offset, int length); +} + diff --git a/src/main/java/com/iot/transport/jt808/service/codec/parser/ExtensionParserFactory.java b/src/main/java/com/iot/transport/jt808/service/codec/parser/ExtensionParserFactory.java new file mode 100644 index 0000000..0597397 --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/service/codec/parser/ExtensionParserFactory.java @@ -0,0 +1,25 @@ +package com.iot.transport.jt808.service.codec.parser; + +import java.util.HashMap; +import java.util.Map; + +public class ExtensionParserFactory { + private static final Map parsers = new HashMap<>(); + + static { + register(new MileageParser()); + register(new SignalStrengthParser()); + register(new BluetoothBeaconParser()); + register(new NearbyBleParser()); + register(new ExtendedInfoParser()); + } + + public static void register(ExtensionParser parser) { + parsers.put(parser.getExtensionId(), parser); + } + + public static ExtensionParser getParser(int extensionId) { + return parsers.get(extensionId); + } +} + diff --git a/src/main/java/com/iot/transport/jt808/service/codec/parser/MileageParser.java b/src/main/java/com/iot/transport/jt808/service/codec/parser/MileageParser.java new file mode 100644 index 0000000..06d954b --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/service/codec/parser/MileageParser.java @@ -0,0 +1,24 @@ +package com.iot.transport.jt808.service.codec.parser; + +import com.iot.transport.jt808.entity.request.LocationPack; + +public class MileageParser implements ExtensionParser { + @Override + public int getExtensionId() { + return 0x01; + } + + @Override + public void parse(LocationPack locationPack, byte[] data, int offset, int length) { + if (length == 4) { + long mileage = 0; + mileage |= (data[offset] & 0xFFL) << 24; + mileage |= (data[offset + 1] & 0xFFL) << 16; + mileage |= (data[offset + 2] & 0xFFL) << 8; + mileage |= (data[offset + 3] & 0xFFL); + // 1/10 km -> km + locationPack.setMileage(mileage / 10.0f); + } + } +} + diff --git a/src/main/java/com/iot/transport/jt808/service/codec/parser/NearbyBleParser.java b/src/main/java/com/iot/transport/jt808/service/codec/parser/NearbyBleParser.java new file mode 100644 index 0000000..c9388bf --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/service/codec/parser/NearbyBleParser.java @@ -0,0 +1,46 @@ +package com.iot.transport.jt808.service.codec.parser; + +import com.iot.transport.jt808.entity.request.BluetoothInfo; +import com.iot.transport.jt808.entity.request.LocationPack; +import com.iot.transport.jt808.util.HexUtil; +import java.util.ArrayList; +import java.util.List; + +public class NearbyBleParser implements ExtensionParser { + @Override + public int getExtensionId() { + return 0xF4; + } + + @Override + public void parse(LocationPack locationPack, byte[] data, int offset, int length) { + // Content: Count (1 byte) + N * (MAC 6 bytes + RSSI 1 byte) + if (length < 1) return; + + int count = data[offset] & 0xFF; + int currentOffset = offset + 1; + + List list = locationPack.getBluetoothInfos(); + if (list == null) { + list = new ArrayList<>(); + locationPack.setBluetoothInfos(list); + } + + for (int i = 0; i < count; i++) { + if (currentOffset + 7 > offset + length) break; + + byte[] macBytes = new byte[6]; + System.arraycopy(data, currentOffset, macBytes, 0, 6); + String mac = HexUtil.toHexString(macBytes); // Partial IMEI usually + + int rssi = data[currentOffset + 6]; + + BluetoothInfo info = new BluetoothInfo(mac, rssi); + info.setType(0xF4); + list.add(info); + + currentOffset += 7; + } + } +} + diff --git a/src/main/java/com/iot/transport/jt808/service/codec/parser/SignalStrengthParser.java b/src/main/java/com/iot/transport/jt808/service/codec/parser/SignalStrengthParser.java new file mode 100644 index 0000000..ab7ad71 --- /dev/null +++ b/src/main/java/com/iot/transport/jt808/service/codec/parser/SignalStrengthParser.java @@ -0,0 +1,19 @@ +package com.iot.transport.jt808.service.codec.parser; + +import com.iot.transport.jt808.entity.request.LocationPack; + +public class SignalStrengthParser implements ExtensionParser { + @Override + public int getExtensionId() { + return 0x30; + } + + @Override + public void parse(LocationPack locationPack, byte[] data, int offset, int length) { + if (length == 1) { + int signal = data[offset] & 0xFF; + locationPack.setSignalStrength(signal); + } + } +} + diff --git a/src/main/java/com/hua/transport/jt808/service/handler/MessageHandler.java b/src/main/java/com/iot/transport/jt808/service/handler/MessageHandler.java similarity index 81% rename from src/main/java/com/hua/transport/jt808/service/handler/MessageHandler.java rename to src/main/java/com/iot/transport/jt808/service/handler/MessageHandler.java index abc67d5..17ea803 100644 --- a/src/main/java/com/hua/transport/jt808/service/handler/MessageHandler.java +++ b/src/main/java/com/iot/transport/jt808/service/handler/MessageHandler.java @@ -1,13 +1,13 @@ -package com.hua.transport.jt808.service.handler; +package com.iot.transport.jt808.service.handler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.hua.transport.jt808.entity.DataPack; -import com.hua.transport.jt808.entity.Session; -import com.hua.transport.jt808.server.SessionManager; -import com.hua.transport.jt808.service.codec.DataDecoder; -import com.hua.transport.jt808.service.codec.DataEncoder; +import com.iot.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.entity.Session; +import com.iot.transport.jt808.server.SessionManager; +import com.iot.transport.jt808.service.codec.DataDecoder; +import com.iot.transport.jt808.service.codec.DataEncoder; import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; diff --git a/src/main/java/com/hua/transport/jt808/service/handler/MessageHandlerFactory.java b/src/main/java/com/iot/transport/jt808/service/handler/MessageHandlerFactory.java similarity index 70% rename from src/main/java/com/hua/transport/jt808/service/handler/MessageHandlerFactory.java rename to src/main/java/com/iot/transport/jt808/service/handler/MessageHandlerFactory.java index 65b20b6..326bd1d 100644 --- a/src/main/java/com/hua/transport/jt808/service/handler/MessageHandlerFactory.java +++ b/src/main/java/com/iot/transport/jt808/service/handler/MessageHandlerFactory.java @@ -1,13 +1,13 @@ -package com.hua.transport.jt808.service.handler; +package com.iot.transport.jt808.service.handler; import java.util.HashMap; import java.util.Map; -import com.hua.transport.jt808.common.Consts; -import com.hua.transport.jt808.service.handler.terminal.AuthenticationHandler; -import com.hua.transport.jt808.service.handler.terminal.HeartbeatHandler; -import com.hua.transport.jt808.service.handler.terminal.LocationUploadHandler; -import com.hua.transport.jt808.service.handler.terminal.LoginOutHandler; -import com.hua.transport.jt808.service.handler.terminal.RegisterHandler; +import com.iot.transport.jt808.common.Consts; +import com.iot.transport.jt808.service.handler.terminal.AuthenticationHandler; +import com.iot.transport.jt808.service.handler.terminal.HeartbeatHandler; +import com.iot.transport.jt808.service.handler.terminal.LocationUploadHandler; +import com.iot.transport.jt808.service.handler.terminal.LoginOutHandler; +import com.iot.transport.jt808.service.handler.terminal.RegisterHandler; public class MessageHandlerFactory { diff --git a/src/main/java/com/hua/transport/jt808/service/handler/TCPServerHandler.java b/src/main/java/com/iot/transport/jt808/service/handler/TCPServerHandler.java similarity index 71% rename from src/main/java/com/hua/transport/jt808/service/handler/TCPServerHandler.java rename to src/main/java/com/iot/transport/jt808/service/handler/TCPServerHandler.java index 3e74cb2..1a845fe 100644 --- a/src/main/java/com/hua/transport/jt808/service/handler/TCPServerHandler.java +++ b/src/main/java/com/iot/transport/jt808/service/handler/TCPServerHandler.java @@ -1,13 +1,13 @@ -package com.hua.transport.jt808.service.handler; +package com.iot.transport.jt808.service.handler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.hua.transport.jt808.entity.DataPack; -import com.hua.transport.jt808.entity.Session; -import com.hua.transport.jt808.entity.DataPack.PackHead; -import com.hua.transport.jt808.server.SessionManager; -import com.hua.transport.jt808.service.codec.DataDecoder; +import com.iot.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.entity.Session; +import com.iot.transport.jt808.entity.DataPack.PackHead; +import com.iot.transport.jt808.server.SessionManager; +import com.iot.transport.jt808.service.codec.DataDecoder; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; @@ -16,12 +16,15 @@ import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; import io.netty.util.ReferenceCountUtil; -import com.hua.transport.jt808.service.ApiLogService; +import com.iot.transport.jt808.service.ApiLogService; import java.util.HashMap; import java.util.Map; -import com.hua.transport.jt808.common.Consts; -import com.hua.transport.jt808.entity.request.LocationPack; +import com.iot.transport.jt808.common.Consts; +import com.iot.transport.jt808.entity.request.BatteryVersionInfo; +import com.iot.transport.jt808.entity.request.BluetoothInfo; +import com.iot.transport.jt808.entity.request.LocationPack; +import java.util.List; public class TCPServerHandler extends ChannelInboundHandlerAdapter { // (1) @@ -67,6 +70,36 @@ public class TCPServerHandler extends ChannelInboundHandlerAdapter { // (1) try { LocationPack locPack = this.decoder.toLocationInfoUploadMsg(packageData); logMap.put("details", locPack.toString()); + + // Enhanced fields for Frontend Dashboard + logMap.put("type", "badge"); + logMap.put("id", header.getTerminalPhone()); + + // Battery + BatteryVersionInfo batInfo = locPack.getBatteryVersionInfo(); + if (batInfo != null) { + logMap.put("battery", batInfo.getBatteryLevel()); + } + + // Status (Simple logic: SOS if bit 0 of warning flag is set) + if ((locPack.getWarningFlagField() & 0x01) != 0) { + logMap.put("status", "sos"); + } else { + logMap.put("status", "active"); + } + + // Bluetooth + List bles = locPack.getBluetoothInfos(); + if (bles != null) { + logMap.put("bluetooth", bles); + } + + // Location + Map locMap = new HashMap<>(); + locMap.put("lat", locPack.getLatitude()); + locMap.put("lon", locPack.getLongitude()); + logMap.put("location", locMap); + } catch (Exception e) { logMap.put("details", packageData.toString() + " (Parse Error: " + e.getMessage() + ")"); } diff --git a/src/main/java/com/hua/transport/jt808/service/handler/terminal/AuthenticationHandler.java b/src/main/java/com/iot/transport/jt808/service/handler/terminal/AuthenticationHandler.java similarity index 81% rename from src/main/java/com/hua/transport/jt808/service/handler/terminal/AuthenticationHandler.java rename to src/main/java/com/iot/transport/jt808/service/handler/terminal/AuthenticationHandler.java index 1f5f3ff..b5e2f4d 100644 --- a/src/main/java/com/hua/transport/jt808/service/handler/terminal/AuthenticationHandler.java +++ b/src/main/java/com/iot/transport/jt808/service/handler/terminal/AuthenticationHandler.java @@ -1,13 +1,13 @@ -package com.hua.transport.jt808.service.handler.terminal; +package com.iot.transport.jt808.service.handler.terminal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.hua.transport.jt808.entity.DataPack; -import com.hua.transport.jt808.entity.Session; -import com.hua.transport.jt808.entity.DataPack.PackHead; -import com.hua.transport.jt808.entity.request.AuthenticationPack; -import com.hua.transport.jt808.entity.response.ServerBodyPack; -import com.hua.transport.jt808.service.handler.MessageHandler; +import com.iot.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.entity.Session; +import com.iot.transport.jt808.entity.DataPack.PackHead; +import com.iot.transport.jt808.entity.request.AuthenticationPack; +import com.iot.transport.jt808.entity.response.ServerBodyPack; +import com.iot.transport.jt808.service.handler.MessageHandler; /** * 终端鉴权 ==> 平台通用应答 diff --git a/src/main/java/com/hua/transport/jt808/service/handler/terminal/HeartbeatHandler.java b/src/main/java/com/iot/transport/jt808/service/handler/terminal/HeartbeatHandler.java similarity index 78% rename from src/main/java/com/hua/transport/jt808/service/handler/terminal/HeartbeatHandler.java rename to src/main/java/com/iot/transport/jt808/service/handler/terminal/HeartbeatHandler.java index bf993e8..948e801 100644 --- a/src/main/java/com/hua/transport/jt808/service/handler/terminal/HeartbeatHandler.java +++ b/src/main/java/com/iot/transport/jt808/service/handler/terminal/HeartbeatHandler.java @@ -1,11 +1,11 @@ -package com.hua.transport.jt808.service.handler.terminal; +package com.iot.transport.jt808.service.handler.terminal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.hua.transport.jt808.entity.DataPack; -import com.hua.transport.jt808.entity.DataPack.PackHead; -import com.hua.transport.jt808.entity.response.ServerBodyPack; -import com.hua.transport.jt808.service.handler.MessageHandler; +import com.iot.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.entity.DataPack.PackHead; +import com.iot.transport.jt808.entity.response.ServerBodyPack; +import com.iot.transport.jt808.service.handler.MessageHandler; /** * 终端心跳-消息体为空 ==> 平台通用应答 diff --git a/src/main/java/com/hua/transport/jt808/service/handler/terminal/LocationUploadHandler.java b/src/main/java/com/iot/transport/jt808/service/handler/terminal/LocationUploadHandler.java similarity index 74% rename from src/main/java/com/hua/transport/jt808/service/handler/terminal/LocationUploadHandler.java rename to src/main/java/com/iot/transport/jt808/service/handler/terminal/LocationUploadHandler.java index 4f00604..62911b6 100644 --- a/src/main/java/com/hua/transport/jt808/service/handler/terminal/LocationUploadHandler.java +++ b/src/main/java/com/iot/transport/jt808/service/handler/terminal/LocationUploadHandler.java @@ -1,12 +1,12 @@ -package com.hua.transport.jt808.service.handler.terminal; +package com.iot.transport.jt808.service.handler.terminal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.hua.transport.jt808.entity.DataPack; -import com.hua.transport.jt808.entity.DataPack.PackHead; -import com.hua.transport.jt808.entity.request.LocationPack; -import com.hua.transport.jt808.entity.response.ServerBodyPack; -import com.hua.transport.jt808.service.handler.MessageHandler; +import com.iot.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.entity.DataPack.PackHead; +import com.iot.transport.jt808.entity.request.LocationPack; +import com.iot.transport.jt808.entity.response.ServerBodyPack; +import com.iot.transport.jt808.service.handler.MessageHandler; /** * 处理模板 diff --git a/src/main/java/com/hua/transport/jt808/service/handler/terminal/LoginOutHandler.java b/src/main/java/com/iot/transport/jt808/service/handler/terminal/LoginOutHandler.java similarity index 79% rename from src/main/java/com/hua/transport/jt808/service/handler/terminal/LoginOutHandler.java rename to src/main/java/com/iot/transport/jt808/service/handler/terminal/LoginOutHandler.java index 8130e86..ab2c478 100644 --- a/src/main/java/com/hua/transport/jt808/service/handler/terminal/LoginOutHandler.java +++ b/src/main/java/com/iot/transport/jt808/service/handler/terminal/LoginOutHandler.java @@ -1,12 +1,12 @@ -package com.hua.transport.jt808.service.handler.terminal; +package com.iot.transport.jt808.service.handler.terminal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.hua.transport.jt808.entity.DataPack; -import com.hua.transport.jt808.entity.DataPack.PackHead; -import com.hua.transport.jt808.entity.response.ServerBodyPack; -import com.hua.transport.jt808.service.handler.MessageHandler; +import com.iot.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.entity.DataPack.PackHead; +import com.iot.transport.jt808.entity.response.ServerBodyPack; +import com.iot.transport.jt808.service.handler.MessageHandler; /** * 终端注销(终端注销数据消息体为空) ==> 平台通用应答 diff --git a/src/main/java/com/hua/transport/jt808/service/handler/terminal/RegisterHandler.java b/src/main/java/com/iot/transport/jt808/service/handler/terminal/RegisterHandler.java similarity index 80% rename from src/main/java/com/hua/transport/jt808/service/handler/terminal/RegisterHandler.java rename to src/main/java/com/iot/transport/jt808/service/handler/terminal/RegisterHandler.java index dfb899a..c9a3fdc 100644 --- a/src/main/java/com/hua/transport/jt808/service/handler/terminal/RegisterHandler.java +++ b/src/main/java/com/iot/transport/jt808/service/handler/terminal/RegisterHandler.java @@ -1,14 +1,14 @@ -package com.hua.transport.jt808.service.handler.terminal; +package com.iot.transport.jt808.service.handler.terminal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.hua.transport.jt808.entity.DataPack; -import com.hua.transport.jt808.entity.Session; -import com.hua.transport.jt808.entity.DataPack.PackHead; -import com.hua.transport.jt808.entity.request.RegisterPack; -import com.hua.transport.jt808.entity.response.RegisterBodyPack; -import com.hua.transport.jt808.service.handler.MessageHandler; +import com.iot.transport.jt808.entity.DataPack; +import com.iot.transport.jt808.entity.Session; +import com.iot.transport.jt808.entity.DataPack.PackHead; +import com.iot.transport.jt808.entity.request.RegisterPack; +import com.iot.transport.jt808.entity.response.RegisterBodyPack; +import com.iot.transport.jt808.service.handler.MessageHandler; /** * 终端注册 ==> 终端注册应答 diff --git a/src/main/java/com/hua/transport/jt808/service/impl/DeviceServiceImpl.java b/src/main/java/com/iot/transport/jt808/service/impl/DeviceServiceImpl.java similarity index 83% rename from src/main/java/com/hua/transport/jt808/service/impl/DeviceServiceImpl.java rename to src/main/java/com/iot/transport/jt808/service/impl/DeviceServiceImpl.java index 5503ba0..316f80b 100644 --- a/src/main/java/com/hua/transport/jt808/service/impl/DeviceServiceImpl.java +++ b/src/main/java/com/iot/transport/jt808/service/impl/DeviceServiceImpl.java @@ -1,6 +1,6 @@ -package com.hua.transport.jt808.service.impl; +package com.iot.transport.jt808.service.impl; -import com.hua.transport.jt808.service.DeviceService; +import com.iot.transport.jt808.service.DeviceService; import org.springframework.stereotype.Service; import lombok.extern.slf4j.Slf4j; import java.util.Date; diff --git a/src/main/java/com/hua/transport/jt808/util/BCDUtil.java b/src/main/java/com/iot/transport/jt808/util/BCDUtil.java similarity index 97% rename from src/main/java/com/hua/transport/jt808/util/BCDUtil.java rename to src/main/java/com/iot/transport/jt808/util/BCDUtil.java index 521728a..8beb1a6 100644 --- a/src/main/java/com/hua/transport/jt808/util/BCDUtil.java +++ b/src/main/java/com/iot/transport/jt808/util/BCDUtil.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.util; +package com.iot.transport.jt808.util; public class BCDUtil { diff --git a/src/main/java/com/hua/transport/jt808/util/BitUtil.java b/src/main/java/com/iot/transport/jt808/util/BitUtil.java similarity index 99% rename from src/main/java/com/hua/transport/jt808/util/BitUtil.java rename to src/main/java/com/iot/transport/jt808/util/BitUtil.java index 4742ebe..6600160 100644 --- a/src/main/java/com/hua/transport/jt808/util/BitUtil.java +++ b/src/main/java/com/iot/transport/jt808/util/BitUtil.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.util; +package com.iot.transport.jt808.util; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/com/hua/transport/jt808/util/HexUtil.java b/src/main/java/com/iot/transport/jt808/util/HexUtil.java similarity index 75% rename from src/main/java/com/hua/transport/jt808/util/HexUtil.java rename to src/main/java/com/iot/transport/jt808/util/HexUtil.java index 8d1ae97..3a7bef7 100644 --- a/src/main/java/com/hua/transport/jt808/util/HexUtil.java +++ b/src/main/java/com/iot/transport/jt808/util/HexUtil.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.util; +package com.iot.transport.jt808.util; public class HexUtil { @@ -58,4 +58,16 @@ public class HexUtil { System.out.println("十六进制字符串:" + hex); System.out.println("还原:" + decode); } + + public static String toHexString(byte[] data, int offset, int subLen) { + if (data == null || offset < 0 || subLen < 0 || offset + subLen > data.length) { + return ""; + } + char[] out = new char[subLen << 1]; + for (int i = 0, j = 0; i < subLen; i++) { + out[j++] = DIGITS_HEX[(0xF0 & data[offset + i]) >>> 4]; + out[j++] = DIGITS_HEX[0x0F & data[offset + i]]; + } + return new String(out); + } } \ No newline at end of file diff --git a/src/main/java/com/hua/transport/jt808/util/JT808Util.java b/src/main/java/com/iot/transport/jt808/util/JT808Util.java similarity index 99% rename from src/main/java/com/hua/transport/jt808/util/JT808Util.java rename to src/main/java/com/iot/transport/jt808/util/JT808Util.java index 5852fdb..056f5b6 100644 --- a/src/main/java/com/hua/transport/jt808/util/JT808Util.java +++ b/src/main/java/com/iot/transport/jt808/util/JT808Util.java @@ -1,4 +1,4 @@ -package com.hua.transport.jt808.util; +package com.iot.transport.jt808.util; import java.io.ByteArrayOutputStream; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 74eaa76..a110527 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -7,5 +7,5 @@ jt808: logging: level: root: INFO - com.hua.transport.jt808: DEBUG + com.iot.transport.jt808: DEBUG diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 786dc61..b9c5cee 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -1,101 +1,354 @@ - + - JT808 Server Dashboard + IoT 设备测试平台 + + + + - - + + + - JT808 Transport Server - - Status: - - {{ connected ? 'Connected' : 'Disconnected' }} + + IoT 数据监控平台 + + + + + {{ connected ? '已连接实时流' : '断开连接' }} - + - - - - - - - Device Simulation (Typed API) + + + + + + + 数据模拟器 - - - - IMEI - - - - - Lat - - - - Lon - - - - Send Location - - - + + + + 工牌 + + + 计数器 + + + 自定义 + + - - - - Universal Upload Test (/upload) - - - - Arbitrary JSON Payload - + + + 工牌 ID + + + + 电量 (%) + + {{ badgeForm.battery }}% + + + 状态 + + 活跃 + 静止 + SOS报警 + + + + 发送工牌数据 + + + + + + 设备 ID + + + + + 进入人数 + + + + 离开人数 + + + + + 发送计数数据 + + + + + + JSON 数据 + + + 发送自定义数据 - Send to /upload - - - - - Live Data Stream (/api/v1/device/upload) - Clear + + + + + + + + + + + + + 智能工牌监控 + 实时人员定位与状态 + + + {{ Object.keys(badges).length }} 在线 + + + + + 暂无工牌数据接入 + + + + + + + + + + {{ badge.id }} + SOS + 在线 + + + {{ formatTime(badge.lastUpdate) }} + + + + + {{ badge.battery }}% + + + + + + + + + + {{ (badge.bluetooth || []).length }} + + 蓝牙信标 + + + + {{ badge.location.lat.toFixed(4) }}, {{ badge.location.lon.toFixed(4) }} + + - + GPS坐标 + + + + + + + + MAC: {{ ble.mac }} + RSSI: {{ ble.rssi }} + + + +{{ badge.bluetooth.length - 2 }} 更多... + + + + + + + + + + + + + + + + + 客流计数器 + 进出人流实时统计 + + + {{ Object.keys(counters).length }} 设备 + + + + + 暂无计数器在线 + + + + + {{ counter.id }} + {{ formatTime(counter.lastUpdate) }} + + + + {{ counter.inCount }} + In + + + {{ counter.outCount }} + Out + + + {{ counter.inCount - counter.outCount }} + Stay + + + + + + + - - - Waiting for data... - + + + + + + + + + 实时数据日志流 + + + + + + {{ logs.length }} + + + + 等待数据接入... + [{{ log.time }}] - {{ log.source }} - {{ log.data }} + {{ log.source }} + {{ log.data }} @@ -107,19 +360,30 @@ + + + - - + + + - JT808 Transport Server - - Status: - - {{ connected ? 'Connected' : 'Disconnected' }} + + IoT 数据监控平台 + + + + + {{ connected ? '已连接实时流' : '断开连接' }} - + - - - - - - - Device Simulation (Typed API) + + + + + + + 数据模拟器 - - - - IMEI - - - - - Lat - - - - Lon - - - - Send Location - - - + + + + 工牌 + + + 计数器 + + + 自定义 + + - - - - Universal Upload Test (/upload) - - - - Arbitrary JSON Payload - + + + 工牌 ID + + + + 电量 (%) + + {{ badgeForm.battery }}% + + + 状态 + + 活跃 + 静止 + SOS报警 + + + + 发送工牌数据 + + + + + + 设备 ID + + + + + 进入人数 + + + + 离开人数 + + + + + 发送计数数据 + + + + + + JSON 数据 + + + 发送自定义数据 - Send to /upload - - - - - Live Data Stream (/api/v1/device/upload) - Clear + + + + + + + + + + + + + 智能工牌监控 + 实时人员定位与状态 + + + {{ Object.keys(badges).length }} 在线 + + + + + 暂无工牌数据接入 + + + + + + + + + + {{ badge.id }} + SOS + 在线 + + + {{ formatTime(badge.lastUpdate) }} + + + + + {{ badge.battery }}% + + + + + + + + + + {{ (badge.bluetooth || []).length }} + + 蓝牙信标 + + + + {{ badge.location.lat.toFixed(4) }}, {{ badge.location.lon.toFixed(4) }} + + - + GPS坐标 + + + + + + + + MAC: {{ ble.mac }} + RSSI: {{ ble.rssi }} + + + +{{ badge.bluetooth.length - 2 }} 更多... + + + + + + + + + + + + + + + + + 客流计数器 + 进出人流实时统计 + + + {{ Object.keys(counters).length }} 设备 + + + + + 暂无计数器在线 + + + + + {{ counter.id }} + {{ formatTime(counter.lastUpdate) }} + + + + {{ counter.inCount }} + In + + + {{ counter.outCount }} + Out + + + {{ counter.inCount - counter.outCount }} + Stay + + + + + + + - - - Waiting for data... - + + + + + + + + + 实时数据日志流 + + + + + + {{ logs.length }} + + + + 等待数据接入... + [{{ log.time }}] - {{ log.data }} + {{ log.source }} + {{ log.data }} @@ -106,19 +360,30 @@
暂无工牌数据接入
暂无计数器在线