|
@@ -1,650 +0,0 @@
|
|
|
-package com.tidecloud.dataacceptance.codec;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileNotFoundException;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.OutputStream;
|
|
|
-import java.nio.ByteBuffer;
|
|
|
-import java.nio.channels.FileChannel;
|
|
|
-import java.text.SimpleDateFormat;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.Date;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.Map;
|
|
|
-
|
|
|
-import javax.xml.bind.DatatypeConverter;
|
|
|
-
|
|
|
-import org.apache.commons.lang.ArrayUtils;
|
|
|
-import org.slf4j.Logger;
|
|
|
-import org.slf4j.LoggerFactory;
|
|
|
-
|
|
|
-import com.tidecloud.dataacceptance.common.BCD8421Operater;
|
|
|
-import com.tidecloud.dataacceptance.common.BitOperator;
|
|
|
-import com.tidecloud.dataacceptance.common.Constants;
|
|
|
-import com.tidecloud.dataacceptance.common.NumUtil;
|
|
|
-import com.tidecloud.dataacceptance.entity.CanDevice;
|
|
|
-import com.tidecloud.dataacceptance.entity.LocationInfoUploadMsg;
|
|
|
-import com.tidecloud.dataacceptance.entity.LocationSelfInfoUploadMsg;
|
|
|
-import com.tidecloud.dataacceptance.entity.PackageData;
|
|
|
-import com.tidecloud.dataacceptance.entity.PackageData.MsgHeader;
|
|
|
-import com.tidecloud.dataacceptance.entity.TerminalRegisterMsg;
|
|
|
-import com.tidecloud.dataacceptance.entity.TerminalRegisterMsg.TerminalRegInfo;
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * @author: chudk
|
|
|
- * @date: 2017年11月8日 下午4:09:15
|
|
|
- */
|
|
|
-public class MsgDecoder {
|
|
|
-
|
|
|
- private static final String DATA_PATH = "/home/service/collector_6707/rawdata/";
|
|
|
-// private static final String DATA_PATH = "D:\\var\\log\\tidecloud\\";
|
|
|
- private static File WRITE_FILE = null;
|
|
|
- private static Boolean ISINIT = true;
|
|
|
- private static final Integer TEN_M = 10485760;
|
|
|
- private static final String PREFIX_NAME = "can.";
|
|
|
-
|
|
|
- private static final Logger log = LoggerFactory.getLogger(MsgDecoder.class);
|
|
|
- private static Map<String, Map<Integer, CanDevice>> canDeviceMap = new HashMap<>();
|
|
|
-
|
|
|
- private BitOperator bitOperator;
|
|
|
- private BCD8421Operater bcd8421Operater;
|
|
|
-
|
|
|
- public MsgDecoder() {
|
|
|
- this.bitOperator = new BitOperator();
|
|
|
- this.bcd8421Operater = new BCD8421Operater();
|
|
|
- }
|
|
|
-
|
|
|
- public PackageData bytes2PackageData(byte[] data) {
|
|
|
- PackageData ret = new PackageData();
|
|
|
-
|
|
|
- // 0. 终端套接字地址信息
|
|
|
- // ret.setChannel(msg.getChannel());
|
|
|
-
|
|
|
- // 1. 16byte 或 12byte 消息头
|
|
|
- MsgHeader msgHeader = this.parseMsgHeaderFromBytes(data);
|
|
|
- ret.setMsgHeader(msgHeader);
|
|
|
-
|
|
|
- int msgBodyByteStartIndex = 12;
|
|
|
- // 2. 消息体
|
|
|
- // 有子包信息,消息体起始字节后移四个字节:消息包总数(word(16))+包序号(word(16))
|
|
|
- if (msgHeader.isHasSubPackage()) {
|
|
|
- msgBodyByteStartIndex = 16;
|
|
|
- }
|
|
|
-
|
|
|
- byte[] tmp = new byte[msgHeader.getMsgBodyLength()];
|
|
|
- System.arraycopy(data, msgBodyByteStartIndex, tmp, 0, tmp.length);
|
|
|
- ret.setMsgBodyBytes(tmp);
|
|
|
-
|
|
|
- // 3. 去掉分隔符之后,最后一位就是校验码
|
|
|
- // int checkSumInPkg =
|
|
|
- // this.bitOperator.oneByteToInteger(data[data.length - 1]);
|
|
|
- int checkSumInPkg = data[data.length - 1];
|
|
|
- int calculatedCheckSum = this.bitOperator.getCheckSum4JT808(data, 0, data.length - 1);
|
|
|
- ret.setCheckSum(checkSumInPkg);
|
|
|
- if (checkSumInPkg != calculatedCheckSum) {
|
|
|
- log.warn("检验码不一致,msgid:{},pkg:{},calculated:{}", msgHeader.getMsgId(), checkSumInPkg, calculatedCheckSum);
|
|
|
- }
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- private MsgHeader parseMsgHeaderFromBytes(byte[] data) {
|
|
|
- MsgHeader msgHeader = new MsgHeader();
|
|
|
-
|
|
|
- // 1. 消息ID word(16)
|
|
|
- // byte[] tmp = new byte[2];
|
|
|
- // System.arraycopy(data, 0, tmp, 0, 2);
|
|
|
- // msgHeader.setMsgId(this.bitOperator.twoBytesToInteger(tmp));
|
|
|
- msgHeader.setMsgId(this.parseIntFromBytes(data, 0, 2));
|
|
|
-
|
|
|
- // 2. 消息体属性 word(16)=================>
|
|
|
- // System.arraycopy(data, 2, tmp, 0, 2);
|
|
|
- // int msgBodyProps = this.bitOperator.twoBytesToInteger(tmp);
|
|
|
- int msgBodyProps = this.parseIntFromBytes(data, 2, 2);
|
|
|
- msgHeader.setMsgBodyPropsField(msgBodyProps);
|
|
|
- // [ 0-9 ] 0000,0011,1111,1111(3FF)(消息体长度)
|
|
|
- msgHeader.setMsgBodyLength(msgBodyProps & 0x3ff);
|
|
|
- // [10-12] 0001,1100,0000,0000(1C00)(加密类型)
|
|
|
- msgHeader.setEncryptionType((msgBodyProps & 0x1c00) >> 10);
|
|
|
- // [ 13_ ] 0010,0000,0000,0000(2000)(是否有子包)
|
|
|
- msgHeader.setHasSubPackage(((msgBodyProps & 0x2000) >> 13) == 1);
|
|
|
- // [14-15] 1100,0000,0000,0000(C000)(保留位)
|
|
|
- msgHeader.setReservedBit(((msgBodyProps & 0xc000) >> 14) + "");
|
|
|
- // 消息体属性 word(16)<=================
|
|
|
-
|
|
|
- // 3. 终端手机号 bcd[6]
|
|
|
- // tmp = new byte[6];
|
|
|
- // System.arraycopy(data, 4, tmp, 0, 6);
|
|
|
- // msgHeader.setTerminalPhone(this.bcd8421Operater.bcd2String(tmp));
|
|
|
- msgHeader.setTerminalPhone(this.parseBcdStringFromBytes(data, 4, 6));
|
|
|
-
|
|
|
- // 4. 消息流水号 word(16) 按发送顺序从 0 开始循环累加
|
|
|
- // tmp = new byte[2];
|
|
|
- // System.arraycopy(data, 10, tmp, 0, 2);
|
|
|
- // msgHeader.setFlowId(this.bitOperator.twoBytesToInteger(tmp));
|
|
|
- msgHeader.setFlowId(this.parseIntFromBytes(data, 10, 2));
|
|
|
-
|
|
|
- // 5. 消息包封装项
|
|
|
- // 有子包信息
|
|
|
- if (msgHeader.isHasSubPackage()) {
|
|
|
- // 消息包封装项字段
|
|
|
- msgHeader.setPackageInfoField(this.parseIntFromBytes(data, 12, 4));
|
|
|
- // byte[0-1] 消息包总数(word(16))
|
|
|
- // tmp = new byte[2];
|
|
|
- // System.arraycopy(data, 12, tmp, 0, 2);
|
|
|
- // msgHeader.setTotalSubPackage(this.bitOperator.twoBytesToInteger(tmp));
|
|
|
- msgHeader.setTotalSubPackage(this.parseIntFromBytes(data, 12, 2));
|
|
|
-
|
|
|
- // byte[2-3] 包序号(word(16)) 从 1 开始
|
|
|
- // tmp = new byte[2];
|
|
|
- // System.arraycopy(data, 14, tmp, 0, 2);
|
|
|
- // msgHeader.setSubPackageSeq(this.bitOperator.twoBytesToInteger(tmp));
|
|
|
- msgHeader.setSubPackageSeq(this.parseIntFromBytes(data, 12, 2));
|
|
|
- }
|
|
|
- return msgHeader;
|
|
|
- }
|
|
|
-
|
|
|
- protected String parseStringFromBytes(byte[] data, int startIndex, int lenth) {
|
|
|
- return this.parseStringFromBytes(data, startIndex, lenth, null);
|
|
|
- }
|
|
|
-
|
|
|
- private String parseStringFromBytes(byte[] data, int startIndex, int lenth, String defaultVal) {
|
|
|
- try {
|
|
|
- byte[] tmp = new byte[lenth];
|
|
|
- System.arraycopy(data, startIndex, tmp, 0, lenth);
|
|
|
- return new String(tmp, Constants.GBK_CHARSET);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析字符串出错:{}", e.getMessage());
|
|
|
- e.printStackTrace();
|
|
|
- return defaultVal;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private String parseBcdStringFromBytes(byte[] data, int startIndex, int lenth) {
|
|
|
- return this.parseBcdStringFromBytes(data, startIndex, lenth, null);
|
|
|
- }
|
|
|
-
|
|
|
- private String parseBcdStringFromBytes(byte[] data, int startIndex, int lenth, String defaultVal) {
|
|
|
- try {
|
|
|
- byte[] tmp = new byte[lenth];
|
|
|
- System.arraycopy(data, startIndex, tmp, 0, lenth);
|
|
|
- return this.bcd8421Operater.bcd2String(tmp);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析BCD(8421码)出错:{}", e.getMessage());
|
|
|
- e.printStackTrace();
|
|
|
- return defaultVal;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private int parseIntFromBytes(byte[] data, int startIndex, int length) {
|
|
|
- return this.parseIntFromBytes(data, startIndex, length, 0);
|
|
|
- }
|
|
|
-
|
|
|
- private int parseIntFromBytes(byte[] data, int startIndex, int length, int defaultVal) {
|
|
|
- try {
|
|
|
- // 字节数大于4,从起始索引开始向后处理4个字节,其余超出部分丢弃
|
|
|
- final int len = length > 4 ? 4 : length;
|
|
|
- byte[] tmp = new byte[len];
|
|
|
- System.arraycopy(data, startIndex, tmp, 0, len);
|
|
|
- return bitOperator.byteToInteger(tmp);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析整数出错:{}", e.getMessage());
|
|
|
- return defaultVal;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public TerminalRegisterMsg toTerminalRegisterMsg(PackageData packageData) {
|
|
|
- TerminalRegisterMsg ret = new TerminalRegisterMsg(packageData);
|
|
|
- byte[] data = ret.getMsgBodyBytes();
|
|
|
-
|
|
|
- TerminalRegInfo body = new TerminalRegInfo();
|
|
|
-
|
|
|
- // 1. byte[0-1] 省域ID(WORD)
|
|
|
- // 设备安装车辆所在的省域,省域ID采用GB/T2260中规定的行政区划代码6位中前两位
|
|
|
- // 0保留,由平台取默认值
|
|
|
- body.setProvinceId(this.parseIntFromBytes(data, 0, 2));
|
|
|
-
|
|
|
- // 2. byte[2-3] 设备安装车辆所在的市域或县域,市县域ID采用GB/T2260中规定的行 政区划代码6位中后四位
|
|
|
- // 0保留,由平台取默认值
|
|
|
- body.setCityId(this.parseIntFromBytes(data, 2, 2));
|
|
|
-
|
|
|
- // 3. byte[4-8] 制造商ID(BYTE[5]) 5 个字节,终端制造商编码
|
|
|
- // byte[] tmp = new byte[5];
|
|
|
- body.setManufacturerId(this.parseStringFromBytes(data, 4, 5));
|
|
|
-
|
|
|
- // 4. byte[9-28] 终端型号(BYTE[8]) 八个字节, 此终端型号 由制造商自行定义 位数不足八位的,补空格。
|
|
|
- body.setTerminalType(this.parseStringFromBytes(data, 9, 20));
|
|
|
-
|
|
|
- // 5. byte[29-35] 终端ID(BYTE[7]) 七个字节, 由大写字母 和数字组成, 此终端 ID由制造 商自行定义
|
|
|
- body.setTerminalId(this.parseStringFromBytes(data, 29, 7));
|
|
|
-
|
|
|
- // 6. byte[36-37] 车牌颜色(BYTE) 车牌颜 色按照JT/T415-2006 中5.4.12 的规定
|
|
|
- body.setLicensePlateColor(this.parseIntFromBytes(data, 36, 1));
|
|
|
- // 7. byte[25-x] 车牌(STRING) 公安交 通管理部门颁 发的机动车号牌
|
|
|
-// body.setLicensePlate(this.parseStringFromBytes(data, 25, data.length - 25));
|
|
|
-
|
|
|
- ret.setTerminalRegInfo(body);
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- public LocationSelfInfoUploadMsg toSelfLocationInfoUploadMsg(PackageData packageData) throws Exception{
|
|
|
- LocationSelfInfoUploadMsg ret = new LocationSelfInfoUploadMsg(packageData);
|
|
|
- final byte[] data = ret.getMsgBodyBytes();
|
|
|
- String dataStr = DatatypeConverter.printHexBinary(data);
|
|
|
- log.info("data is [{}]", dataStr);
|
|
|
-// 1. byte[0-2] 子协议
|
|
|
- int subProtocal = this.parseIntFromBytes(data, 0, 3);
|
|
|
-// 1. byte[3-4] 压缩前数据的长度
|
|
|
- int beforeComparssLength = this.parseIntFromBytes(data, 2, 2);
|
|
|
-// 2. byte[5-x] 压缩后的数据
|
|
|
- byte[] realData = Arrays.copyOfRange(data, 5, data.length);
|
|
|
-// realData = JT808ProtocolUtils.doEscape4Receive(realData, 0, realData.length);
|
|
|
-// CanDevice canDevice = new CanDevice();
|
|
|
-// String deviceId = ret.getMsgHeader().getTerminalPhone();
|
|
|
-// canDevice.setDeviceId(deviceId);
|
|
|
-// try {
|
|
|
-// while (realData.length > 0) {
|
|
|
-//// 3. byte[0-1] 数据类型
|
|
|
-// int realDataLength = realData.length;
|
|
|
-// int dataType = this.parseIntFromBytes(realData, 0, 1);
|
|
|
-// if (realDataLength >= 5 && Constants.TYPE_OF_TIME.equals(dataType)) {
|
|
|
-// byte[] subDate = Arrays.copyOfRange(realData, 1, 5);
|
|
|
-// int timestamp = BitOperator.bytesToInt(subDate);
|
|
|
-// canDevice.setDate(timestamp);
|
|
|
-// realData = Arrays.copyOfRange(realData, 5, realData.length);
|
|
|
-// } else if (realDataLength >= 21 && Constants.TYPE_OF_GPS.equals(dataType)) {
|
|
|
-// byte[] gpsByteArray = Arrays.copyOfRange(realData, 2, realData.length);
|
|
|
-// realData = Arrays.copyOfRange(realData, 21, realData.length);
|
|
|
-// } else if (realDataLength >=6 && Constants.TYPE_OF_AD_OIL.equals(dataType)) {
|
|
|
-// realData = Arrays.copyOfRange(realData, 6, realData.length);
|
|
|
-// } else if (realDataLength >= 24 && Constants.TYPE_OF_MILEAGE.equals(dataType)) {
|
|
|
-// realData = Arrays.copyOfRange(realData, 24, realData.length);
|
|
|
-// }else if (realDataLength >= 10 && Constants.TYPE_OF_SWT.equals(dataType)) {
|
|
|
-// realData = Arrays.copyOfRange(realData, 10, realData.length);
|
|
|
-// } else if (realDataLength >= 19 && Constants.TYPE_OF_EXT.equals(dataType)) {
|
|
|
-// realData = Arrays.copyOfRange(realData, 19, realData.length);
|
|
|
-// } else if (realDataLength >= 4 && Constants.TYPE_OF_SPEED.equals(dataType)) {
|
|
|
-// realData = Arrays.copyOfRange(realData, 4, realData.length);
|
|
|
-// } else if (realDataLength >= 7 && Constants.TYPE_OF_DRIVER_DATA.equals(dataType)) {
|
|
|
-// int len = parseIntFromBytes(realData, 1, 1);
|
|
|
-// realData = Arrays.copyOfRange(realData, len + 1, realData.length);
|
|
|
-// } else if (realDataLength >= 7 && Constants.TYPE_OF_CAN_DATA.equals(dataType)) {
|
|
|
-// int subType = this.parseIntFromBytes(realData, 2, 1);
|
|
|
-// int timeDiff = this.parseIntFromBytes(realData, 1, 1);
|
|
|
-// byte[] subData = Arrays.copyOfRange(realData, 3, 7);
|
|
|
-// int value = BitOperator.bytesToInt(subData);
|
|
|
-// CanDevice canDeviceInMap = setCanDevcieFiled(deviceId, canDevice.getDate(), timeDiff);
|
|
|
-// if (Constants.SUB_TYPE_OF_TURNSPEED.equals(subType)) {
|
|
|
-// canDeviceInMap.setTurnSpeed(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_TORQUE.equals(subType)) {
|
|
|
-//// subData = Arrays.copyOfRange(realData, 3, 8);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_VOLTAGE.equals(subType)) {
|
|
|
-// canDeviceInMap.setVoltage(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_OILTEMPERTURE.equals(subType)) {
|
|
|
-// canDeviceInMap.setOilTemperture(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_ENGINEOILPRESSURE.equals(subType)) {
|
|
|
-// canDeviceInMap.setEngineOilPressure(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_AIRPRESSURE.equals(subType)) {
|
|
|
-// canDeviceInMap.setAirPressure(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_AIRINTEMPERTURE.equals(subType)) {
|
|
|
-// canDeviceInMap.setAirInTemperture(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_CANSPEED.equals(subType)) {
|
|
|
-// canDeviceInMap.setCanSpeed(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_COOLANTTEMPERTURE.equals(subType)) {
|
|
|
-// canDeviceInMap.setCoolantTemperture(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_OIL.equals(subType)) {
|
|
|
-// canDeviceInMap.setOil(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_RUNTIME.equals(subType)) {
|
|
|
-// canDeviceInMap.setRunTime(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_DM1FAULTCODE.equals(subType)) {
|
|
|
-// canDeviceInMap.setDm1FaultCode(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else if (Constants.SUB_TYPE_OF_TRANSIENTOIL.equals(dataType)) {
|
|
|
-// canDeviceInMap.setTransientOil(value);
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// } else {
|
|
|
-// realData = Arrays.copyOfRange(realData, 7, realData.length);
|
|
|
-// }
|
|
|
-// }else {
|
|
|
-// break;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// } catch (IllegalArgumentException e) {
|
|
|
-// log.error(e.getMessage(), e);
|
|
|
-// }
|
|
|
-//// 写入文件
|
|
|
-// Map<Integer, CanDevice> timeDiffCanDevcieMap = canDeviceMap.get(deviceId);
|
|
|
-// if (timeDiffCanDevcieMap != null && !timeDiffCanDevcieMap.isEmpty()) {
|
|
|
-// Set<Integer> timeStamps = timeDiffCanDevcieMap.keySet();
|
|
|
-// for (Integer timeStamp : timeStamps) {
|
|
|
-// CanDevice canDeviceWrite = timeDiffCanDevcieMap.get(timeStamp);
|
|
|
-// dataStorage(CanDevice.buildCanDeviceStr(canDeviceWrite));
|
|
|
-// }
|
|
|
-// }
|
|
|
-// timeDiffCanDevcieMap.remove(deviceId);
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- private CanDevice setCanDevcieFiled(String deviceId, Integer date, int timeDiff) {
|
|
|
- Integer timeStamp = date - timeDiff;
|
|
|
- Map<Integer, CanDevice> timeDiffCanDeviceMap = canDeviceMap.get(deviceId);
|
|
|
- if (timeDiffCanDeviceMap == null) {
|
|
|
- timeDiffCanDeviceMap = new HashMap<>();
|
|
|
- CanDevice canDevice = new CanDevice();
|
|
|
- timeDiffCanDeviceMap.put(timeStamp, canDevice);
|
|
|
- canDeviceMap.put(deviceId, timeDiffCanDeviceMap);
|
|
|
- canDevice.setDeviceId(deviceId);
|
|
|
- canDevice.setDate(timeStamp);
|
|
|
- return canDevice;
|
|
|
- } else {
|
|
|
- CanDevice canDeviceInMap = timeDiffCanDeviceMap.get(timeStamp);
|
|
|
- if (canDeviceInMap == null) {
|
|
|
- canDeviceInMap = new CanDevice();
|
|
|
- timeDiffCanDeviceMap.put(timeStamp, canDeviceInMap);
|
|
|
- canDeviceInMap.setDeviceId(deviceId);
|
|
|
- canDeviceInMap.setDate(timeStamp);
|
|
|
- }
|
|
|
- return canDeviceInMap;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public LocationInfoUploadMsg toLocationInfoUploadMsg(PackageData packageData) {
|
|
|
- LocationInfoUploadMsg ret = new LocationInfoUploadMsg(packageData);
|
|
|
- final byte[] data = ret.getMsgBodyBytes();
|
|
|
- // 1. byte[0-3] 报警标志(DWORD(32))
|
|
|
- ret.setWarningFlagField(this.parseIntFromBytes(data, 0, 3));
|
|
|
- // 2. byte[4-7] 状态(DWORD(32))
|
|
|
- int states = this.parseIntFromBytes(data, 4, 4);
|
|
|
- ret.setStatusField(states);
|
|
|
- // 3. byte[8-11] 纬度(DWORD(32)) 以度为单位的纬度值乘以10^6,精确到百万分之一度
|
|
|
- ret.setLatitude(this.parseIntFromBytes(data, 8, 4));
|
|
|
- // 4. byte[12-15] 经度(DWORD(32)) 以度为单位的经度值乘以10^6,精确到百万分之一度
|
|
|
- ret.setLongitude(this.parseIntFromBytes(data, 12, 4));
|
|
|
- // 5. byte[16-17] 高程(WORD(16)) 海拔高度,单位为米( m)
|
|
|
- ret.setElevation(this.parseIntFromBytes(data, 16, 2));
|
|
|
- // byte[18-19] 速度(WORD) 1/10km/h
|
|
|
- ret.setSpeed(this.parseIntFromBytes(data, 18, 2));
|
|
|
- // byte[20-21] 方向(WORD) 0-359,正北为 0,顺时针
|
|
|
- ret.setDirection(this.parseIntFromBytes(data, 20, 2));
|
|
|
- // byte[22-] 时间(BCD[6]) YY-MM-DD-hh-mm-ss
|
|
|
- // GMT+8 时间,本标准中之后涉及的时间均采用此时区
|
|
|
- // ret.setTime(this.par);
|
|
|
- byte[] tmp = new byte[6];
|
|
|
- System.arraycopy(data, 22, tmp, 0, 6);
|
|
|
- String time = this.parseBcdStringFromBytes(data, 22, 6);
|
|
|
- ret.setTime(time);
|
|
|
-
|
|
|
- byte[] additionalInfo = Arrays.copyOfRange(data, 28, data.length);
|
|
|
-// String printHexBinary = DatatypeConverter.printHexBinary(additionalInfo);
|
|
|
-// log.info("acceptance original data [{}]", printHexBinary);
|
|
|
-// // byte[30-33] 里程
|
|
|
-// ret.setMileage(this.parseIntFromBytes(data, 30, 4));
|
|
|
-// // byte[36-37] 油量
|
|
|
-// ret.setOil(this.parseIntFromBytes(data, 36, 2));
|
|
|
-// // acc 状态 0:关 1:开
|
|
|
-// ret.setAccState(states & 0x01);
|
|
|
-// // gps定位状态 0:未定位 1:定位开
|
|
|
-// ret.setGpsState(states & 0x02);
|
|
|
- setAdditionalInfo(ret, additionalInfo);
|
|
|
- ret.setDeviceId(packageData.getMsgHeader().getTerminalPhone());
|
|
|
- dataStorage(LocationInfoUploadMsg.buildLocationInfo2Str(ret));
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- private void setAdditionalInfo(LocationInfoUploadMsg ret, byte[] additionalInfo) {
|
|
|
- while (additionalInfo.length > 0) {
|
|
|
- int type = this.parseIntFromBytes(additionalInfo, 0, 1);
|
|
|
- int length = this.parseIntFromBytes(additionalInfo, 1, 1);
|
|
|
- if (Constants.LocationPackage.TYPE_OF_MILEAGE.equals(type)) {
|
|
|
- ret.setMileage(this.parseIntFromBytes(additionalInfo, 2, length));
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_OIL.equals(type)) {
|
|
|
- ret.setOil(this.parseIntFromBytes(additionalInfo, 2, length));
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_SPEED.equals(type)) {
|
|
|
- int speed = this.parseIntFromBytes(additionalInfo, 2, length);
|
|
|
- if (speed>0&&ret.getSpeed()==0)
|
|
|
- ret.setSpeed(this.parseIntFromBytes(additionalInfo, 2, length));
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_WARN_ID.equals(type)) {
|
|
|
- //ret.setSpeed(this.parseIntFromBytes(additionalInfo, 2, length));
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_RUN_WARN.equals(type)) {
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_ADDITIONAL_STATE.equals(type)) {
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_IO_STATE.equals(type)) {
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_SIMULATION.equals(type)) {
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_SIGNAL_STRENGTH.equals(type)) {
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_SATELLITE.equals(type)) {
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_CUSTOM.equals(type)) {
|
|
|
- byte[] subAdditionalInfo = Arrays.copyOfRange(additionalInfo, 2, length);
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- while (subAdditionalInfo.length > 0) {
|
|
|
- int subLength = this.parseIntFromBytes(subAdditionalInfo, 0, 2);
|
|
|
- if (Constants.LocationPackage.LENGTH_OF_OIL.equals(subLength)) {
|
|
|
-// int oilInteger = this.parseIntFromBytes(subAdditionalInfo, 4, 2);
|
|
|
-// int oilDouble = this.parseIntFromBytes(subAdditionalInfo, 6, 1);
|
|
|
- ret.setFuel(getFuel(Arrays.copyOfRange(subAdditionalInfo, 4, 10)));
|
|
|
-
|
|
|
- }
|
|
|
- if (additionalInfo.length >= 2 + subLength) {
|
|
|
- subAdditionalInfo = Arrays.copyOfRange(subAdditionalInfo, 2 + subLength, subAdditionalInfo.length);
|
|
|
- } else {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_CUSTOM_WAGNRUI.equals(type)) {
|
|
|
- byte[] subAdditionalInfo = Arrays.copyOfRange(additionalInfo, 2, length+2);
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
- while (subAdditionalInfo.length > 0) {
|
|
|
- int subCmd = this.parseIntFromBytes(subAdditionalInfo, 0, 1);
|
|
|
- int subLength = this.parseIntFromBytes(subAdditionalInfo, 1, 1);
|
|
|
- if (Constants.LocationPackage.TYPE_OF_CUSTOM_0XFC_0X01.intValue() == subCmd) {
|
|
|
- //网锐油耗仪扩展报警
|
|
|
- if (subLength == 0x02) {
|
|
|
- int status = parseIntFromBytes(subAdditionalInfo,2,2);
|
|
|
- // 异常油耗报警
|
|
|
- int oilExceptWarning = (status & 0x01);
|
|
|
- ret.setOilExceptWarning(oilExceptWarning);
|
|
|
- // 超时怠速报警
|
|
|
- int timeoutWaitWarning = (status & 0x02) >> 1;
|
|
|
- ret.setTimeoutWaitWarning(timeoutWaitWarning);
|
|
|
- //油耗仪故障报警
|
|
|
- int oilDeviceWarning = (status & 0x04) >> 2;
|
|
|
- ret.setOilDeviceWarning(oilDeviceWarning);
|
|
|
- }
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_CUSTOM_0XFC_0X02.intValue() == subCmd) {
|
|
|
- //各类累计时长 单位:秒
|
|
|
- if (subLength == 0x0C) {
|
|
|
- //byte[] accumulatedFdjWorkTimeArr = Arrays.copyOfRange(subAdditionalInfo, 2, 4);
|
|
|
- int accumulatedFdjWorkTime = parseIntFromBytes(subAdditionalInfo,2,4);
|
|
|
- ret.setAccumulatedFdjWorkTime(accumulatedFdjWorkTime);
|
|
|
- //byte[] accumulatedWorkTimeArr = Arrays.copyOfRange(subAdditionalInfo, 6, 10);
|
|
|
- int accumulatedWorkTime = parseIntFromBytes(subAdditionalInfo,6,4);
|
|
|
- ret.setAccumulatedWorkTime(accumulatedWorkTime);
|
|
|
- //byte[] accumulatedWaitWorkTimeArr = Arrays.copyOfRange(subAdditionalInfo, start, start+8*4);
|
|
|
- int accumulatedWaitWorkTime = parseIntFromBytes(subAdditionalInfo,10,4);
|
|
|
- ret.setAccumulatedWaitWorkTime(accumulatedWaitWorkTime);
|
|
|
- }
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_CUSTOM_0XFC_0X03.intValue() == subCmd) {
|
|
|
- //各类累计油耗 单位: 毫升
|
|
|
- if (subLength == 0x0C) {
|
|
|
- //byte[] accumulatedOilConsumeArr = Arrays.copyOfRange(subAdditionalInfo, start, start+8*4);
|
|
|
- int accumulatedOilConsume = parseIntFromBytes(subAdditionalInfo,2,4);
|
|
|
- ret.setAccumulatedOilConsume(accumulatedOilConsume);
|
|
|
- //byte[] accumulatedWorkOilConsumeArr = Arrays.copyOfRange(subAdditionalInfo, start, start+8*4);
|
|
|
- int accumulatedWorkOilConsume = parseIntFromBytes(subAdditionalInfo,6,4);
|
|
|
- ret.setAccumulatedWorkOilConsume(accumulatedWorkOilConsume);
|
|
|
- //byte[] accumulatedWaitOilConsumeArr = Arrays.copyOfRange(subAdditionalInfo, start, start+8*4);
|
|
|
- int accumulatedWaitOilConsume= parseIntFromBytes(subAdditionalInfo,10,4);
|
|
|
- ret.setAccumulatedWaitOilConsume(accumulatedWaitOilConsume);
|
|
|
- }
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_CUSTOM_0XFC_0X04.intValue() == subCmd) {
|
|
|
- //各类瞬时油耗 单位: 毫升/100KM 毫升/小时
|
|
|
- if (subLength == 0x08) {
|
|
|
- //byte[] OilConsumeOf100KMArr = Arrays.copyOfRange(subAdditionalInfo, start, start+8*4);
|
|
|
- int oilConsumeOf100KM = parseIntFromBytes(subAdditionalInfo,2,4);
|
|
|
- ret.setOilConsumeOf100KM(oilConsumeOf100KM);
|
|
|
- //byte[] OilConsumeOf1HourArr = Arrays.copyOfRange(subAdditionalInfo, start, start+8*4);
|
|
|
- int oilConsumeOf1Hour = parseIntFromBytes(subAdditionalInfo,6,4);
|
|
|
- ret.setOilConsumeOf1Hour(oilConsumeOf1Hour);
|
|
|
-
|
|
|
- }
|
|
|
- } else if (Constants.LocationPackage.TYPE_OF_CUSTOM_0XFC_0X05.intValue() == subCmd) {
|
|
|
- if (subLength == 0x02) {
|
|
|
- //byte[] openStatusArr = Arrays.copyOfRange(subAdditionalInfo, 2, 2);
|
|
|
- int status = parseIntFromBytes(subAdditionalInfo,2,2);
|
|
|
-
|
|
|
- // [ 0-0 ] 0000,0000,0000,0001(0x01)(开机状态)
|
|
|
- int openStatus = (status & 0x01);
|
|
|
- ret.setOpenStatus(openStatus);
|
|
|
- // [1-1] 0000,0000,0000,0010(0x02)(运行状态)
|
|
|
- int runningStatus = (status & 0x02) >> 1;
|
|
|
- ret.setRunningStatus(runningStatus);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (subAdditionalInfo.length >= 2 + subLength) {
|
|
|
- subAdditionalInfo = Arrays.copyOfRange(subAdditionalInfo, 2 + subLength, subAdditionalInfo.length);
|
|
|
- } else {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }else {
|
|
|
- additionalInfo = Arrays.copyOfRange(additionalInfo, length + 2, additionalInfo.length);
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private String getFuel(byte[] copyOfRange) {
|
|
|
- String printHexBinary = DatatypeConverter.printHexBinary(copyOfRange);
|
|
|
- System.out.println(printHexBinary);
|
|
|
- String fuel = "";
|
|
|
- for (byte b : copyOfRange) {
|
|
|
- if (Constants.LocationPackage.POINT.equals(b)) {
|
|
|
- fuel += ".";
|
|
|
- }else {
|
|
|
- fuel += b & 0xf;
|
|
|
- }
|
|
|
- }
|
|
|
- System.out.println(fuel);
|
|
|
- return fuel;
|
|
|
- }
|
|
|
-
|
|
|
- public static void main(String[] args) {
|
|
|
- for (int i = 0; i < 1000; i++) {
|
|
|
- LocationInfoUploadMsg infoUploadMsg = new LocationInfoUploadMsg();
|
|
|
- infoUploadMsg.setDeviceId("14142184169");
|
|
|
- infoUploadMsg.setTime("180119160845");
|
|
|
- infoUploadMsg.setLatitude(34000000);
|
|
|
- infoUploadMsg.setLongitude(12000000);
|
|
|
- infoUploadMsg.setSpeed(11);
|
|
|
- infoUploadMsg.setMileage(133);
|
|
|
- infoUploadMsg.setOil(14);
|
|
|
- infoUploadMsg.setFuel("13");
|
|
|
- dataStorage(LocationInfoUploadMsg.buildLocationInfo2Str(infoUploadMsg));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private static FileChannel fc = null;
|
|
|
-
|
|
|
- private static synchronized FileChannel getFileChannel(File file) {
|
|
|
- if (fc == null) {
|
|
|
- try {
|
|
|
- FileOutputStream fos = new FileOutputStream(file, true);
|
|
|
- fc = fos.getChannel();
|
|
|
- } catch (FileNotFoundException e) {
|
|
|
- log.error(e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
- return fc;
|
|
|
- }
|
|
|
- private static synchronized void dataStorage(String deviceStr) {
|
|
|
- File path = new File(DATA_PATH);
|
|
|
- File[] listFiles = path.listFiles();
|
|
|
- if (ISINIT) {
|
|
|
- for (File sonFile : listFiles) {
|
|
|
- String name = sonFile.getName();
|
|
|
- if (name != null && name.startsWith(PREFIX_NAME)) {
|
|
|
- long len = sonFile.length();
|
|
|
- if (len < TEN_M) {
|
|
|
- WRITE_FILE = sonFile;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- ISINIT = false;
|
|
|
- }
|
|
|
- if (WRITE_FILE == null || WRITE_FILE.length() > TEN_M) {
|
|
|
- String fileName = DATA_PATH + PREFIX_NAME + new SimpleDateFormat("yyMMddHHmmss").format(new Date());
|
|
|
- WRITE_FILE = new File(fileName);
|
|
|
- writeDevice2File(WRITE_FILE, deviceStr);
|
|
|
- log.info("touch new file :" + deviceStr + "timestamp:" + new SimpleDateFormat("yyMMddHHmmss").format(new Date()));
|
|
|
- }else{
|
|
|
- writeDevice2File(WRITE_FILE, deviceStr);
|
|
|
- log.info("write data into file : " + deviceStr);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-// public static void writeDevice2File(File file, String deviceStr){
|
|
|
-// Integer length = deviceStr.getBytes().length;
|
|
|
-// try {
|
|
|
-// OutputStream outputStream = new FileOutputStream(file, true);
|
|
|
-// outputStream.write(NumUtil.int2bytes(length));;
|
|
|
-// outputStream.write(deviceStr.getBytes());
|
|
|
-// outputStream.flush();
|
|
|
-// outputStream.close();
|
|
|
-// } catch (IOException e) {
|
|
|
-// log.error(e.getMessage());
|
|
|
-// }
|
|
|
-// }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- public static void writeDevice2File(File file, String deviceStr){
|
|
|
- FileOutputStream fos = null;
|
|
|
- try {
|
|
|
- fos = new FileOutputStream(file, true);
|
|
|
- Integer length = deviceStr.getBytes().length;
|
|
|
- byte[] lengthBytes = NumUtil.int2bytes(length);
|
|
|
- byte[] deviceBytes = deviceStr.getBytes();
|
|
|
- byte[] dataBytes = ArrayUtils.addAll(lengthBytes, deviceBytes);
|
|
|
-
|
|
|
- FileChannel fc = fos.getChannel();
|
|
|
-
|
|
|
- ByteBuffer bbf = ByteBuffer.wrap(dataBytes);
|
|
|
- // bbf.flip();
|
|
|
- fc.write(bbf) ;
|
|
|
- fc.close();
|
|
|
- fos.flush();
|
|
|
- } catch (IOException e) {
|
|
|
- log.error(e.getMessage());
|
|
|
- } finally {
|
|
|
- if (fos != null) {
|
|
|
- try {
|
|
|
- fos.close();
|
|
|
- } catch (IOException e) {
|
|
|
- log.error(e.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|