|
@@ -1,33 +1,19 @@
|
|
|
package com.tidecloud.dataacceptance.service.impl;
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.OutputStream;
|
|
|
-import java.text.SimpleDateFormat;
|
|
|
+
|
|
|
import java.util.Date;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.UUID;
|
|
|
-import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
import javax.xml.bind.DatatypeConverter;
|
|
|
|
|
|
-import org.apache.commons.lang.ArrayUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
-import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
-import com.smartsanitation.common.util.StringUtil;
|
|
|
import com.tidecloud.dataacceptance.common.CRCUtil;
|
|
|
-import com.tidecloud.dataacceptance.common.Constants;
|
|
|
import com.tidecloud.dataacceptance.common.DateUtil;
|
|
|
import com.tidecloud.dataacceptance.common.NumUtil;
|
|
|
-import com.tidecloud.dataacceptance.entity.ConnectMsg;
|
|
|
import com.tidecloud.dataacceptance.entity.YiTongGPSDevice;
|
|
|
import com.tidecloud.dataacceptance.entity.YiTongGpsForWarnDevice;
|
|
|
-import com.tidecloud.dataacceptance.service.AcceptanceInboundHandlerAdapter;
|
|
|
+import com.tidecloud.dataacceptance.service.HexBinaryAcceptanceHandlerAdapter;
|
|
|
|
|
|
import io.netty.bootstrap.ServerBootstrap;
|
|
|
import io.netty.buffer.ByteBuf;
|
|
@@ -43,355 +29,259 @@ import io.netty.channel.nio.NioEventLoopGroup;
|
|
|
import io.netty.channel.socket.SocketChannel;
|
|
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
|
|
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
|
|
|
-import io.netty.handler.timeout.IdleStateHandler;
|
|
|
import io.netty.util.concurrent.Future;
|
|
|
import io.netty.util.concurrent.GenericFutureListener;
|
|
|
-import redis.clients.jedis.Jedis;
|
|
|
-import redis.clients.jedis.JedisPool;
|
|
|
|
|
|
/**
|
|
|
* @author cdk
|
|
|
*/
|
|
|
@Component
|
|
|
@ChannelHandler.Sharable
|
|
|
-public class YiTongGpsServerHandler extends AcceptanceInboundHandlerAdapter {
|
|
|
-
|
|
|
- private static final Logger logger = LoggerFactory.getLogger(YiTongGpsServerHandler.class);
|
|
|
- public static String PREFIX_LINK = "s.";
|
|
|
- public static String PREFIX_LINK_BACK = "s.b.";
|
|
|
- public static String PREFIX_DEVICE = "d.";
|
|
|
- private static Boolean ISINIT = true;
|
|
|
-
|
|
|
- private static final Integer START_BITS = 2;
|
|
|
- private static final Byte START_BIT = 0x78;
|
|
|
- private static final Byte START_BIT2 = 0X79;
|
|
|
+public class YiTongGpsServerHandler extends HexBinaryAcceptanceHandlerAdapter {
|
|
|
|
|
|
- private static final Integer TEN_M = 10485760;
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(YiTongGpsServerHandler.class);
|
|
|
|
|
|
- private static final byte LOGIN_MSG = 0x01;
|
|
|
- private static final byte LOCATION_MSG = 0x22;
|
|
|
- private static final byte STATUS_MSG = 0x13;
|
|
|
- private static final byte WARNING_MSG = 0x26;
|
|
|
- private static final byte CORRECT_TIME_MSG = (byte)0x8A;
|
|
|
- private static final byte VOLTAGE_MSG = (byte)0x94;
|
|
|
- private static final byte VOLTAGE_SUB_MSG = (byte)0x00;
|
|
|
- private static final byte COMMAND_COPY_MSG = 0x15;
|
|
|
- private static final byte ASCII_CODE = 0x01;
|
|
|
- private static final byte UTF16_BE_CODE = 0x02;
|
|
|
-
|
|
|
- private static final String DATA_PATH = "/home/service/collector_yitong/rawdata-car/";
|
|
|
- private static final String PREFIX_NAME = "yitong";
|
|
|
- private static final Integer DATA_SIZE = 6;
|
|
|
- public static final Integer REDIS_INDEX_LINK = 15;
|
|
|
- private static File WRITE_FILE = null;
|
|
|
+ private static final Integer START_BITS = 2;
|
|
|
+ private static final Byte START_BIT = 0x78;
|
|
|
+ private static final Byte START_BIT2 = 0X79;
|
|
|
|
|
|
+ private static final byte LOGIN_MSG = 0x01;
|
|
|
+ private static final byte LOCATION_MSG = 0x22;
|
|
|
+ private static final byte STATUS_MSG = 0x13;
|
|
|
+ private static final byte WARNING_MSG = 0x26;
|
|
|
+ private static final byte CORRECT_TIME_MSG = (byte) 0x8A;
|
|
|
+ private static final byte VOLTAGE_MSG = (byte) 0x94;
|
|
|
+ private static final byte VOLTAGE_SUB_MSG = (byte) 0x00;
|
|
|
+ private static final byte COMMAND_COPY_MSG = 0x15;
|
|
|
|
|
|
- public static Map<String, Channel> socketyChannelMap = new HashMap<>();
|
|
|
- public static Map<Channel, String> channelDeviceMap = new HashMap<>();
|
|
|
- public static Map<String, String> commandCopy = new HashMap<>();
|
|
|
-
|
|
|
- @Autowired
|
|
|
- private JedisPool jedisPool;
|
|
|
-
|
|
|
- @Value("${server.localaddress}")
|
|
|
- private String address;
|
|
|
-
|
|
|
- @Override
|
|
|
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
|
|
- ByteBuf in = (ByteBuf) msg;
|
|
|
- ByteBuf copy = in.copy();
|
|
|
- byte[] bytes = new byte[copy.readableBytes()];
|
|
|
- copy.readBytes(bytes);
|
|
|
- String printHexBinary = DatatypeConverter.printHexBinary(bytes);
|
|
|
- logger.info("设备: [{}] 传入数据为 : [{}]",channelDeviceMap.get(ctx.channel()), printHexBinary);
|
|
|
- try {
|
|
|
- int index = 0;
|
|
|
- byte b = 0;
|
|
|
- while (index < START_BITS) {
|
|
|
- b = in.readByte();
|
|
|
- if (START_BIT != b && START_BIT2 != b) {
|
|
|
- ctx.close();
|
|
|
- }
|
|
|
- index++;
|
|
|
- }
|
|
|
- int length = 0;
|
|
|
- if (START_BIT == b) {
|
|
|
- length = in.readByte() & 0xff;
|
|
|
- }else {
|
|
|
- length = in.readShort() & 0xffff;
|
|
|
- }
|
|
|
- handle(in, length, ctx.channel());
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error(e.getMessage(), e);
|
|
|
- }
|
|
|
- ctx.flush();
|
|
|
- }
|
|
|
-
|
|
|
- private void handle(ByteBuf in, int length, Channel channel) throws Exception{
|
|
|
- if (in.isReadable()) {
|
|
|
- in = in.readBytes(length);
|
|
|
- byte msgType = in.readByte();
|
|
|
- if (LOGIN_MSG == msgType) {
|
|
|
- resolveLoginMSG(in, channel);
|
|
|
- } else if (LOCATION_MSG == msgType) {
|
|
|
- String deviceId = channelDeviceMap.get(channel);
|
|
|
- if (deviceId == null) {
|
|
|
- logger.info("链接管理失效。。。。。。。");
|
|
|
- }else {
|
|
|
- resolveLocationMSG(in, deviceId);
|
|
|
- }
|
|
|
- } else if (STATUS_MSG == msgType) {
|
|
|
- reply(channel, STATUS_MSG);
|
|
|
- } else if (WARNING_MSG == msgType) {
|
|
|
- String deviceId = channelDeviceMap.get(channel);
|
|
|
- resolveWarningMsg(in, deviceId);
|
|
|
- reply(channel, WARNING_MSG);
|
|
|
- } else if (CORRECT_TIME_MSG == msgType) {
|
|
|
- reply(channel, CORRECT_TIME_MSG);
|
|
|
- } else if (VOLTAGE_MSG == msgType) {
|
|
|
- resolveVoltageMSG(in, channel);
|
|
|
- } else if (COMMAND_COPY_MSG == msgType) {
|
|
|
- resolveCommandCopyMSG(in, channel, length);
|
|
|
- } else {
|
|
|
- logger.info("client send data without handle type ...");
|
|
|
- }
|
|
|
- }
|
|
|
+ private static final Integer DATA_SIZE = 6;
|
|
|
|
|
|
- }
|
|
|
+ @Override
|
|
|
+ protected void handle(ByteBuf in, Channel channel) throws Exception {
|
|
|
+ try {
|
|
|
+ int index = 0;
|
|
|
+ byte b = 0;
|
|
|
+ while (index < START_BITS) {
|
|
|
+ b = in.readByte();
|
|
|
+ if (START_BIT != b && START_BIT2 != b) {
|
|
|
+ channel.close();
|
|
|
+ }
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+ int length = 0;
|
|
|
+ if (START_BIT == b) {
|
|
|
+ length = in.readByte() & 0xff;
|
|
|
+ } else {
|
|
|
+ length = in.readShort() & 0xffff;
|
|
|
+ }
|
|
|
+ handle(in, length, channel);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error(e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- private void resolveCommandCopyMSG(ByteBuf in, Channel channel, Integer length) {
|
|
|
- byte readByte = in.readByte();
|
|
|
- int checkCode = in.readInt();
|
|
|
- if (checkCode != 0) {
|
|
|
- logger.error("illegal checkcode [{}]", checkCode);
|
|
|
- } else {
|
|
|
-// byte codingType = in.readByte();
|
|
|
- byte[] coypByes = new byte[length -14];
|
|
|
- in.readBytes(coypByes);
|
|
|
- String copyStr = new String(coypByes);
|
|
|
- logger.info("设备指令回复 [{}]", copyStr);
|
|
|
- }
|
|
|
- }
|
|
|
+ private void handle(ByteBuf in, int length, Channel channel) throws Exception {
|
|
|
+ if (in.isReadable()) {
|
|
|
+ in = in.readBytes(length);
|
|
|
+ byte msgType = in.readByte();
|
|
|
+ if (LOGIN_MSG == msgType) {
|
|
|
+ resolveLoginMSG(in, channel);
|
|
|
+ } else if (LOCATION_MSG == msgType) {
|
|
|
+ String deviceId = channelDeviceMap.get(channel);
|
|
|
+ if (deviceId == null) {
|
|
|
+ logger.info("链接管理失效。。。。。。。");
|
|
|
+ } else {
|
|
|
+ resolveLocationMSG(in, deviceId);
|
|
|
+ }
|
|
|
+ } else if (STATUS_MSG == msgType) {
|
|
|
+ reply(channel, STATUS_MSG);
|
|
|
+ } else if (WARNING_MSG == msgType) {
|
|
|
+ String deviceId = channelDeviceMap.get(channel);
|
|
|
+ resolveWarningMsg(in, deviceId);
|
|
|
+ reply(channel, WARNING_MSG);
|
|
|
+ } else if (CORRECT_TIME_MSG == msgType) {
|
|
|
+ reply(channel, CORRECT_TIME_MSG);
|
|
|
+ } else if (VOLTAGE_MSG == msgType) {
|
|
|
+ resolveVoltageMSG(in, channel);
|
|
|
+ } else if (COMMAND_COPY_MSG == msgType) {
|
|
|
+ resolveCommandCopyMSG(in, channel, length);
|
|
|
+ } else {
|
|
|
+ logger.info("client send data without handle type ...");
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- private void resolveWarningMsg(ByteBuf in, String deviceId) {
|
|
|
- YiTongGpsForWarnDevice yiTongGPSDevice = new YiTongGpsForWarnDevice();
|
|
|
- StringBuffer dateTimeStrBuf = new StringBuffer();
|
|
|
- int indexOfDateTime = 0;
|
|
|
- while(indexOfDateTime < DATA_SIZE){
|
|
|
- byte b = in.readByte();
|
|
|
- dateTimeStrBuf.append(NumUtil.byte2String(b));
|
|
|
- indexOfDateTime ++;
|
|
|
- }
|
|
|
- //日期
|
|
|
- yiTongGPSDevice.setDate(dateTimeStrBuf.toString());
|
|
|
- //gps信息卫星数
|
|
|
- yiTongGPSDevice.setGpsCount(in.readByte());
|
|
|
- //维度
|
|
|
- yiTongGPSDevice.setLat(in.readInt());
|
|
|
- //经度
|
|
|
- yiTongGPSDevice.setLng(in.readInt());
|
|
|
- //速度
|
|
|
- yiTongGPSDevice.setSpeedbyte(in.readByte());
|
|
|
- //航向
|
|
|
- yiTongGPSDevice.setCourseStatus(in.readShort());
|
|
|
- in.readByte();
|
|
|
- //国家代号
|
|
|
- yiTongGPSDevice.setMcc(in.readShort());
|
|
|
- //移动网号码
|
|
|
- yiTongGPSDevice.setMnc(in.readByte());
|
|
|
- //位置区码
|
|
|
- yiTongGPSDevice.setLac(in.readShort());
|
|
|
- in.readMedium();
|
|
|
- yiTongGPSDevice.setTerminalMsg((int)in.readByte());
|
|
|
- yiTongGPSDevice.setElectric((int)in.readByte());
|
|
|
- yiTongGPSDevice.setGmsSign((int)in.readByte());
|
|
|
- yiTongGPSDevice.setWarningReason((int)in.readByte());
|
|
|
- in.readByte();
|
|
|
- yiTongGPSDevice.setDeviceId(deviceId);
|
|
|
- //写文件操作
|
|
|
- String deviceStr = yiTongGPSDevice.buildDeviceStr();
|
|
|
+ }
|
|
|
|
|
|
- dataStorage(deviceStr);
|
|
|
- }
|
|
|
+ private void resolveCommandCopyMSG(ByteBuf in, Channel channel, Integer length) {
|
|
|
+ byte readByte = in.readByte();
|
|
|
+ int checkCode = in.readInt();
|
|
|
+ if (checkCode != 0) {
|
|
|
+ logger.error("illegal checkcode [{}]", checkCode);
|
|
|
+ } else {
|
|
|
+ // byte codingType = in.readByte();
|
|
|
+ byte[] coypByes = new byte[length - 14];
|
|
|
+ in.readBytes(coypByes);
|
|
|
+ String copyStr = new String(coypByes);
|
|
|
+ logger.info("设备指令回复 [{}]", copyStr);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- private void resolveVoltageMSG(ByteBuf in, Channel channel) {
|
|
|
- String deviceId = channelDeviceMap.get(channel);
|
|
|
- byte subMsgType = in.readByte();
|
|
|
- if (VOLTAGE_SUB_MSG == subMsgType) {
|
|
|
- short voltage = in.readShort();
|
|
|
- Double voltageDouble = NumUtil.toFixed2Place((double)voltage);
|
|
|
- String date = DateUtil.formatDate2String(DateUtil.calculateByHour(new Date(), -8));
|
|
|
- YiTongGPSDevice yiTongGPSDevice = buildYiTongGpsDevcie(voltageDouble, deviceId, date);
|
|
|
- String deviceStr = YiTongGPSDevice.buildDeviceStr(yiTongGPSDevice);
|
|
|
- dataStorage(deviceStr);
|
|
|
- }
|
|
|
- }
|
|
|
+ private void resolveWarningMsg(ByteBuf in, String deviceId) {
|
|
|
+ YiTongGpsForWarnDevice yiTongGPSDevice = new YiTongGpsForWarnDevice();
|
|
|
+ StringBuffer dateTimeStrBuf = new StringBuffer();
|
|
|
+ int indexOfDateTime = 0;
|
|
|
+ while (indexOfDateTime < DATA_SIZE) {
|
|
|
+ byte b = in.readByte();
|
|
|
+ dateTimeStrBuf.append(NumUtil.byte2String(b));
|
|
|
+ indexOfDateTime++;
|
|
|
+ }
|
|
|
+ // 日期
|
|
|
+ yiTongGPSDevice.setDate(dateTimeStrBuf.toString());
|
|
|
+ // gps信息卫星数
|
|
|
+ yiTongGPSDevice.setGpsCount(in.readByte());
|
|
|
+ // 维度
|
|
|
+ yiTongGPSDevice.setLat(in.readInt());
|
|
|
+ // 经度
|
|
|
+ yiTongGPSDevice.setLng(in.readInt());
|
|
|
+ // 速度
|
|
|
+ yiTongGPSDevice.setSpeedbyte(in.readByte());
|
|
|
+ // 航向
|
|
|
+ yiTongGPSDevice.setCourseStatus(in.readShort());
|
|
|
+ in.readByte();
|
|
|
+ // 国家代号
|
|
|
+ yiTongGPSDevice.setMcc(in.readShort());
|
|
|
+ // 移动网号码
|
|
|
+ yiTongGPSDevice.setMnc(in.readByte());
|
|
|
+ // 位置区码
|
|
|
+ yiTongGPSDevice.setLac(in.readShort());
|
|
|
+ in.readMedium();
|
|
|
+ yiTongGPSDevice.setTerminalMsg((int) in.readByte());
|
|
|
+ yiTongGPSDevice.setElectric((int) in.readByte());
|
|
|
+ yiTongGPSDevice.setGmsSign((int) in.readByte());
|
|
|
+ yiTongGPSDevice.setWarningReason((int) in.readByte());
|
|
|
+ in.readByte();
|
|
|
+ yiTongGPSDevice.setDeviceId(deviceId);
|
|
|
+ // 写文件操作
|
|
|
+ String deviceStr = yiTongGPSDevice.buildDeviceStr();
|
|
|
|
|
|
- private YiTongGPSDevice buildYiTongGpsDevcie(Double voltageDouble, String deviceId, String date) {
|
|
|
- return new YiTongGPSDevice(deviceId, date, null, null, null, null, null, null, null, null, null, null, null, null, null, null, voltageDouble, 0);
|
|
|
- }
|
|
|
+ dataStorage(deviceStr);
|
|
|
+ }
|
|
|
|
|
|
- private void resolveLoginMSG(ByteBuf in, Channel channel) {
|
|
|
- byte[] deviceIdBytes = new byte[8];
|
|
|
- in.readBytes(deviceIdBytes);
|
|
|
- String deviceId = DatatypeConverter.printHexBinary(deviceIdBytes);
|
|
|
- // 回复和链接管理
|
|
|
- String deviceIdInMap = channelDeviceMap.get(channel);
|
|
|
- if (!deviceId.equals(deviceIdInMap)) {
|
|
|
- manageChannel(channel, deviceId);
|
|
|
- }
|
|
|
- reply(channel, LOGIN_MSG);
|
|
|
- }
|
|
|
+ private void resolveVoltageMSG(ByteBuf in, Channel channel) {
|
|
|
+ String deviceId = channelDeviceMap.get(channel);
|
|
|
+ byte subMsgType = in.readByte();
|
|
|
+ if (VOLTAGE_SUB_MSG == subMsgType) {
|
|
|
+ short voltage = in.readShort();
|
|
|
+ Double voltageDouble = NumUtil.toFixed2Place((double) voltage);
|
|
|
+ String date = DateUtil.formatDate2String(DateUtil.calculateByHour(new Date(), -8));
|
|
|
+ YiTongGPSDevice yiTongGPSDevice = buildYiTongGpsDevcie(voltageDouble, deviceId, date);
|
|
|
+ String deviceStr = YiTongGPSDevice.buildDeviceStr(yiTongGPSDevice);
|
|
|
+ dataStorage(deviceStr);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- private void manageChannel(Channel channel, String deviceId) {
|
|
|
- String socketkey = UUID.randomUUID().toString();
|
|
|
- logger.info("device [{}] socketId is [{}]", deviceId, socketkey);
|
|
|
- socketyChannelMap.put(socketkey, channel);
|
|
|
- channelDeviceMap.put(channel, deviceId);
|
|
|
- String addressStr = ConnectMsg.ipToLong(address);
|
|
|
- ConnectMsg cMsg = new ConnectMsg(address, socketkey);
|
|
|
- try (Jedis jedis = jedisPool.getResource()) {
|
|
|
- jedis.select(REDIS_INDEX_LINK);
|
|
|
- String insertKey = PREFIX_LINK + addressStr;
|
|
|
- String selectKey = PREFIX_DEVICE + deviceId;
|
|
|
- String insertBackupKey = PREFIX_LINK_BACK + addressStr;
|
|
|
- jedis.sadd(insertKey, socketkey);
|
|
|
- jedis.sadd(insertBackupKey, deviceId);
|
|
|
- jedis.set(selectKey, StringUtil.convert2String(cMsg));
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error(e.getMessage(), e);
|
|
|
- }
|
|
|
- }
|
|
|
+ private YiTongGPSDevice buildYiTongGpsDevcie(Double voltageDouble, String deviceId, String date) {
|
|
|
+ return new YiTongGPSDevice(deviceId, date, null, null, null, null, null, null, null, null, null, null, null,
|
|
|
+ null, null, null, voltageDouble, 0);
|
|
|
+ }
|
|
|
|
|
|
- private void resolveLocationMSG(ByteBuf in, String deviceId) throws Exception{
|
|
|
- YiTongGPSDevice yiTongGPSDevice = new YiTongGPSDevice();
|
|
|
- StringBuffer dateTimeStrBuf = new StringBuffer();
|
|
|
- int indexOfDateTime = 0;
|
|
|
- while(indexOfDateTime < DATA_SIZE){
|
|
|
- byte b = in.readByte();
|
|
|
- dateTimeStrBuf.append(NumUtil.byte2String(b));
|
|
|
- indexOfDateTime ++;
|
|
|
- }
|
|
|
- //日期
|
|
|
- yiTongGPSDevice.setDate(dateTimeStrBuf.toString());
|
|
|
- //gps信息卫星数
|
|
|
- yiTongGPSDevice.setGpsCount(in.readByte());
|
|
|
- //维度
|
|
|
- yiTongGPSDevice.setLat(in.readInt());
|
|
|
- //经度
|
|
|
- yiTongGPSDevice.setLng(in.readInt());
|
|
|
- //速度
|
|
|
- yiTongGPSDevice.setSpeedbyte(in.readByte());
|
|
|
- //航向
|
|
|
- yiTongGPSDevice.setCourseStatus(in.readShort());
|
|
|
- //国家代号
|
|
|
- yiTongGPSDevice.setMcc(in.readShort());
|
|
|
- //移动网号码
|
|
|
- yiTongGPSDevice.setMnc(in.readByte());
|
|
|
- //位置区码
|
|
|
- yiTongGPSDevice.setLac(in.readShort());
|
|
|
- //移动基站Cell Tower ID
|
|
|
- yiTongGPSDevice.setCellId(in.readMedium());
|
|
|
- yiTongGPSDevice.setAcc(in.readByte());
|
|
|
- //数据上报模式 0x00:定时上报,0x01:定距上报,0x02:拐点上传,0x03:ACC状态改变上传,0X08:开机上报位置信息
|
|
|
- yiTongGPSDevice.setReportModel(in.readByte());
|
|
|
- //0x01:实时 0x00:补传
|
|
|
- yiTongGPSDevice.setIsmendMsg(in.readByte());
|
|
|
- double mileage = NumUtil.toFixed2Place((double)in.readInt() / 1000);
|
|
|
- //里程设备默认是关闭的,需要指令,设备端才发送
|
|
|
- yiTongGPSDevice.setDeviceId(deviceId);
|
|
|
- yiTongGPSDevice.setMileage(mileage);
|
|
|
- yiTongGPSDevice.setDataType(1);
|
|
|
- //写文件操作
|
|
|
- String deviceStr = YiTongGPSDevice.buildDeviceStr(yiTongGPSDevice);
|
|
|
- dataStorage(deviceStr);
|
|
|
- }
|
|
|
+ private void resolveLoginMSG(ByteBuf in, Channel channel) {
|
|
|
+ byte[] deviceIdBytes = new byte[8];
|
|
|
+ in.readBytes(deviceIdBytes);
|
|
|
+ String deviceId = DatatypeConverter.printHexBinary(deviceIdBytes);
|
|
|
+ // 回复和链接管理
|
|
|
+ String deviceIdInMap = channelDeviceMap.get(channel);
|
|
|
+ if (!deviceId.equals(deviceIdInMap)) {
|
|
|
+ manageChannel(channel, deviceId);
|
|
|
+ }
|
|
|
+ reply(channel, LOGIN_MSG);
|
|
|
+ }
|
|
|
|
|
|
- private void reply(Channel channel, byte msgType) {
|
|
|
- ByteBuf buffer = Unpooled.buffer();
|
|
|
- byte[] crcBytes = new byte[]{0x05, msgType, 0x00, 0x05};
|
|
|
- int doCrc = CRCUtil.do_crc(65535, crcBytes);
|
|
|
- byte[] intToByte = NumUtil.intToByte(doCrc, 2);
|
|
|
- byte[] bytes = new byte[]{0x78, 0x78, 0x05, msgType, 0x00, 0x05, intToByte[0], intToByte[1], 0x0D, 0x0A};
|
|
|
- buffer.writeBytes(bytes);
|
|
|
- ChannelFuture channelFuture = channel.write(buffer);
|
|
|
- channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
|
|
|
- @Override
|
|
|
- public void operationComplete(Future<? super Void> future) throws Exception {
|
|
|
- logger.info("server reply [{}] to client success", DatatypeConverter.printHexBinary(bytes));
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
+ private void resolveLocationMSG(ByteBuf in, String deviceId) throws Exception {
|
|
|
+ YiTongGPSDevice yiTongGPSDevice = new YiTongGPSDevice();
|
|
|
+ StringBuffer dateTimeStrBuf = new StringBuffer();
|
|
|
+ int indexOfDateTime = 0;
|
|
|
+ while (indexOfDateTime < DATA_SIZE) {
|
|
|
+ byte b = in.readByte();
|
|
|
+ dateTimeStrBuf.append(NumUtil.byte2String(b));
|
|
|
+ indexOfDateTime++;
|
|
|
+ }
|
|
|
+ // 日期
|
|
|
+ yiTongGPSDevice.setDate(dateTimeStrBuf.toString());
|
|
|
+ // gps信息卫星数
|
|
|
+ yiTongGPSDevice.setGpsCount(in.readByte());
|
|
|
+ // 维度
|
|
|
+ yiTongGPSDevice.setLat(in.readInt());
|
|
|
+ // 经度
|
|
|
+ yiTongGPSDevice.setLng(in.readInt());
|
|
|
+ // 速度
|
|
|
+ yiTongGPSDevice.setSpeedbyte(in.readByte());
|
|
|
+ // 航向
|
|
|
+ yiTongGPSDevice.setCourseStatus(in.readShort());
|
|
|
+ // 国家代号
|
|
|
+ yiTongGPSDevice.setMcc(in.readShort());
|
|
|
+ // 移动网号码
|
|
|
+ yiTongGPSDevice.setMnc(in.readByte());
|
|
|
+ // 位置区码
|
|
|
+ yiTongGPSDevice.setLac(in.readShort());
|
|
|
+ // 移动基站Cell Tower ID
|
|
|
+ yiTongGPSDevice.setCellId(in.readMedium());
|
|
|
+ yiTongGPSDevice.setAcc(in.readByte());
|
|
|
+ // 数据上报模式 0x00:定时上报,0x01:定距上报,0x02:拐点上传,0x03:ACC状态改变上传,0X08:开机上报位置信息
|
|
|
+ yiTongGPSDevice.setReportModel(in.readByte());
|
|
|
+ // 0x01:实时 0x00:补传
|
|
|
+ yiTongGPSDevice.setIsmendMsg(in.readByte());
|
|
|
+ double mileage = NumUtil.toFixed2Place((double) in.readInt() / 1000);
|
|
|
+ // 里程设备默认是关闭的,需要指令,设备端才发送
|
|
|
+ yiTongGPSDevice.setDeviceId(deviceId);
|
|
|
+ yiTongGPSDevice.setMileage(mileage);
|
|
|
+ yiTongGPSDevice.setDataType(1);
|
|
|
+ // 写文件操作
|
|
|
+ String deviceStr = YiTongGPSDevice.buildDeviceStr(yiTongGPSDevice);
|
|
|
+ dataStorage(deviceStr);
|
|
|
+ }
|
|
|
|
|
|
- @Override
|
|
|
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
|
|
- cause.printStackTrace();
|
|
|
- ctx.close();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
|
|
- Channel channel = ctx.channel();
|
|
|
- if (!channel.isActive()) {
|
|
|
- String deviceId = channelDeviceMap.get(channel);
|
|
|
- if (deviceId != null) {
|
|
|
- channelDeviceMap.remove(channel);
|
|
|
- deleteLinkFromRedis(deviceId);
|
|
|
- }
|
|
|
- }
|
|
|
- super.channelInactive(ctx);
|
|
|
- ctx.close();
|
|
|
- }
|
|
|
-
|
|
|
- private void deleteLinkFromRedis(String deviceId) {
|
|
|
- String deleteKey = PREFIX_DEVICE + deviceId;
|
|
|
- try(Jedis jedis = jedisPool.getResource()) {
|
|
|
- jedis.select(REDIS_INDEX_LINK);
|
|
|
- String connectMsg = jedis.get(deleteKey);
|
|
|
- if (connectMsg != null) {
|
|
|
- ConnectMsg cmsg = StringUtil.convert2Object(connectMsg, ConnectMsg.class);
|
|
|
- String socketId = cmsg.getSocketId();
|
|
|
- socketyChannelMap.remove(socketId);
|
|
|
- String socketQueryKey = PREFIX_LINK + address;
|
|
|
- jedis.srem(socketQueryKey, socketId);
|
|
|
- jedis.del(deleteKey);
|
|
|
- logger.info("delete link [{}] from redis and memory deviceId is [{}]", socketId, deviceId);
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error(e.getLocalizedMessage());
|
|
|
- }
|
|
|
- }
|
|
|
+ private void reply(Channel channel, byte msgType) {
|
|
|
+ ByteBuf buffer = Unpooled.buffer();
|
|
|
+ byte[] crcBytes = new byte[] { 0x05, msgType, 0x00, 0x05 };
|
|
|
+ int doCrc = CRCUtil.do_crc(65535, crcBytes);
|
|
|
+ byte[] intToByte = NumUtil.intToByte(doCrc, 2);
|
|
|
+ byte[] bytes = new byte[] { 0x78, 0x78, 0x05, msgType, 0x00, 0x05, intToByte[0], intToByte[1], 0x0D, 0x0A };
|
|
|
+ buffer.writeBytes(bytes);
|
|
|
+ ChannelFuture channelFuture = channel.write(buffer);
|
|
|
+ channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
|
|
|
+ @Override
|
|
|
+ public void operationComplete(Future<? super Void> future) throws Exception {
|
|
|
+ logger.info("server reply [{}] to client success", DatatypeConverter.printHexBinary(bytes));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
public void startAcceptor() {
|
|
|
- EventLoopGroup bossGroup = new NioEventLoopGroup();
|
|
|
- EventLoopGroup workerGroup = new NioEventLoopGroup();
|
|
|
- byte[] splitBytes = new byte[]{0x0D, 0x0A};
|
|
|
- try {
|
|
|
- ServerBootstrap b = new ServerBootstrap();
|
|
|
- b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
|
|
|
- .childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
- @Override
|
|
|
- protected void initChannel(SocketChannel ch) throws Exception {
|
|
|
- ch.pipeline().addLast(new DelimiterBasedFrameDecoder(65535, Unpooled.copiedBuffer(splitBytes)));
|
|
|
- ch.pipeline().addLast(this);
|
|
|
- }
|
|
|
- }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
|
|
|
- ChannelFuture f = b.bind(port).sync();
|
|
|
- f.channel().closeFuture().sync();
|
|
|
-
|
|
|
- } catch (InterruptedException e) {
|
|
|
- e.printStackTrace();
|
|
|
- } finally {
|
|
|
- cleanRedisLinkData();
|
|
|
- workerGroup.shutdownGracefully();
|
|
|
- bossGroup.shutdownGracefully();
|
|
|
- }
|
|
|
- }
|
|
|
+ EventLoopGroup bossGroup = new NioEventLoopGroup();
|
|
|
+ EventLoopGroup workerGroup = new NioEventLoopGroup();
|
|
|
+ byte[] splitBytes = new byte[] { 0x0D, 0x0A };
|
|
|
+ try {
|
|
|
+ ServerBootstrap b = new ServerBootstrap();
|
|
|
+ b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
|
|
|
+ .childHandler(new ChannelInitializer<SocketChannel>() {
|
|
|
+ @Override
|
|
|
+ protected void initChannel(SocketChannel ch) throws Exception {
|
|
|
+ ch.pipeline()
|
|
|
+ .addLast(new DelimiterBasedFrameDecoder(65535, Unpooled.copiedBuffer(splitBytes)));
|
|
|
+ ch.pipeline().addLast(this);
|
|
|
+ }
|
|
|
+ }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
|
|
|
+ ChannelFuture f = b.bind(port).sync();
|
|
|
+ f.channel().closeFuture().sync();
|
|
|
|
|
|
- @Override
|
|
|
- public void reply(ChannelHandlerContext ctx, String msg) throws Exception {
|
|
|
- // TODO Auto-generated method stub
|
|
|
-
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ cleanRedisLinkData();
|
|
|
+ workerGroup.shutdownGracefully();
|
|
|
+ bossGroup.shutdownGracefully();
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
}
|