rainbow954 há 7 anos atrás
pai
commit
4901822a81

+ 160 - 24
src/main/java/com/tidecloud/dataacceptance/entity/YiTongGPSDevice.java

@@ -17,22 +17,49 @@ public class YiTongGPSDevice implements Serializable{
     
     private String deviceId;
     private String date;
-    private String lat;
-    private String lng;
+    private Byte gpsCount;
+    private Integer lat;
+    private Integer lng;
+    private Byte speedbyte;
     private String speed;
-    private String mileage;
-    
-    private Integer oil;
-    
+    private Short courseStatus;
+    private Short mcc;
+    private Byte mnc;
+    private Short lac;
+    private Integer cellId;
+    private Byte acc;
+    private Double mileage;
+    private Byte reportModel;
+    private Byte ismendMsg;
+    private Double voltage;
+    private Integer dataType;
    
-    public Integer getOil() {
-        return oil;
-    }
-    public void setOil(Integer oil) {
-        this.oil = oil;
-    }
     public YiTongGPSDevice() {
     }
+    public YiTongGPSDevice(String deviceId, String date, Byte gpsCount, Integer lat, Integer lng, Byte speedbyte,
+            String speed, Short courseStatus, Short mcc, Byte mnc, Short lac, Integer cellId, Byte acc, Double mileage,
+            Byte reportModel, Byte ismendMsg, Double voltage, Integer dataType) {
+        super();
+        this.deviceId = deviceId;
+        this.date = date;
+        this.gpsCount = gpsCount;
+        this.lat = lat;
+        this.lng = lng;
+        this.speedbyte = speedbyte;
+        this.speed = speed;
+        this.courseStatus = courseStatus;
+        this.mcc = mcc;
+        this.mnc = mnc;
+        this.lac = lac;
+        this.cellId = cellId;
+        this.acc = acc;
+        this.mileage = mileage;
+        this.reportModel = reportModel;
+        this.ismendMsg = ismendMsg;
+        this.voltage = voltage;
+        this.dataType = dataType;
+    }
+
     public String getDeviceId() {
         return deviceId;
     }
@@ -49,32 +76,134 @@ public class YiTongGPSDevice implements Serializable{
         this.date = date;
     }
 
-    public String getSpeed() {
-        return speed;
+    public Byte getGpsCount() {
+        return gpsCount;
     }
 
-    public void setSpeed(String speed) {
-        this.speed = speed;
+    public void setGpsCount(Byte gpsCount) {
+        this.gpsCount = gpsCount;
     }
 
-    public String getLat() {
+    public Integer getLat() {
         return lat;
     }
-    public void setLat(String lat) {
+
+    public void setLat(Integer lat) {
         this.lat = lat;
     }
-    public String getLng() {
+
+    public Integer getLng() {
         return lng;
     }
-    public void setLng(String lng) {
+
+    public void setLng(Integer lng) {
         this.lng = lng;
     }
-    public String getMileage() {
+
+    public Byte getSpeedbyte() {
+        return speedbyte;
+    }
+
+    public void setSpeedbyte(Byte speedbyte) {
+        this.speedbyte = speedbyte;
+    }
+
+    public String getSpeed() {
+        return speed;
+    }
+
+    public void setSpeed(String speed) {
+        this.speed = speed;
+    }
+
+    public Short getCourseStatus() {
+        return courseStatus;
+    }
+
+    public void setCourseStatus(Short courseStatus) {
+        this.courseStatus = courseStatus;
+    }
+
+    public Short getMcc() {
+        return mcc;
+    }
+
+    public void setMcc(Short mcc) {
+        this.mcc = mcc;
+    }
+
+    public Byte getMnc() {
+        return mnc;
+    }
+
+    public void setMnc(Byte mnc) {
+        this.mnc = mnc;
+    }
+
+    public Short getLac() {
+        return lac;
+    }
+
+    public void setLac(Short lac) {
+        this.lac = lac;
+    }
+
+    public Integer getCellId() {
+        return cellId;
+    }
+
+    public void setCellId(Integer cellId) {
+        this.cellId = cellId;
+    }
+
+    public Byte getAcc() {
+        return acc;
+    }
+
+    public void setAcc(Byte acc) {
+        this.acc = acc;
+    }
+
+    public Double getMileage() {
         return mileage;
     }
-    public void setMileage(String mileage) {
+
+    public void setMileage(Double mileage) {
         this.mileage = mileage;
     }
+
+    public Byte getReportModel() {
+        return reportModel;
+    }
+
+    public void setReportModel(Byte reportModel) {
+        this.reportModel = reportModel;
+    }
+
+    public Byte getIsmendMsg() {
+        return ismendMsg;
+    }
+
+    public void setIsmendMsg(Byte ismendMsg) {
+        this.ismendMsg = ismendMsg;
+    }
+
+    public Double getVoltage() {
+        return voltage;
+    }
+
+    public void setVoltage(Double voltage) {
+        this.voltage = voltage;
+    }
+
+    public Integer getDataType() {
+        return dataType;
+    }
+
+    public void setDataType(Integer dataType) {
+        this.dataType = dataType;
+    }
+
     public static String buildDeviceStr(YiTongGPSDevice device){
         // [设备号] [日期] [gpsCount] [经度] [维度] [速度] [里程] [是否补传] [数据上报模式] [移动基站] [LAC] [MCC] [信息类型 1代表location, 0代表电压] [电压]
         SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
@@ -89,11 +218,18 @@ public class YiTongGPSDevice implements Serializable{
         StringBuilder builder = new StringBuilder();
         builder.append(checkoutNullObject(device.getDeviceId())).append(",");
         builder.append(checkoutNullObject(dateStr)).append(",");
+        builder.append(checkoutNullObject(device.getGpsCount())).append(",");
         builder.append(checkoutNullObject(device.getLng())).append(",");
         builder.append(checkoutNullObject(device.getLat())).append(",");
-        builder.append(checkoutNullObject(device.getSpeed())).append(",");
+        builder.append(checkoutNullObject(device.getSpeedbyte())).append(",");
         builder.append(checkoutNullObject(device.getMileage())).append(",");
-        builder.append(checkoutNullObject(device.getOil()));
+        builder.append(checkoutNullObject(device.getIsmendMsg())).append(",");
+        builder.append(checkoutNullObject(device.getReportModel())).append(",");
+        builder.append(checkoutNullObject(device.getAcc())).append(",");
+        builder.append(checkoutNullObject(device.getLac())).append(",");
+        builder.append(checkoutNullObject(device.getMcc())).append(",");
+        builder.append(checkoutNullObject(device.getDataType())).append(",");
+        builder.append(checkoutNullObject(device.getVoltage()));
         return builder.toString();
     }
     

+ 87 - 0
src/main/java/com/tidecloud/dataacceptance/entity/YiTongGpsForWarnDevice.java

@@ -0,0 +1,87 @@
+package com.tidecloud.dataacceptance.entity;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.tidecloud.dataacceptance.common.DateUtil;
+
+/**   
+ * @author: chudk 
+ * @date:   2018年1月23日 下午2:12:24   
+ */
+public class YiTongGpsForWarnDevice extends YiTongGPSDevice {
+
+    private static final long serialVersionUID = -9157286369663317479L;
+    
+    /**@see: 电压等级,0x00:无电  0x01:电量极低(不足以打电话发短信) 0x02:电量很低(低电报警) 0x03:电量底(可正常使用)
+     * 0x04:电量中  0x05:电量高  0x06:电量极高
+     * */
+    private Integer electric;
+    
+    /** @see: GSM信号等级, 0x00:无信号  0x01:信号极弱  0x02:信号较弱  0x03:信号良好  0x04:信号强*/
+    private Integer gmsSign;
+    
+    /** @see: 报警原因, 0x00:正常报警  0x01:SOS求救  0x03:震动报警  等 */
+    private Integer warningReason;
+
+    /** @see: 终端信息详解*/
+    private Integer terminalMsg;
+    
+    public Integer getTerminalMsg() {
+        return terminalMsg;
+    }
+    public void setTerminalMsg(Integer terminalMsg) {
+        this.terminalMsg = terminalMsg;
+    }
+    public Integer getElectric() {
+        return electric;
+    }
+    public void setElectric(Integer electric) {
+        this.electric = electric;
+    }
+    public Integer getGmsSign() {
+        return gmsSign;
+    }
+    public void setGmsSign(Integer gmsSign) {
+        this.gmsSign = gmsSign;
+    }
+    public Integer getWarningReason() {
+        return warningReason;
+    }
+    public void setWarningReason(Integer warningReason) {
+        this.warningReason = warningReason;
+    }
+    
+    public String buildDeviceStr(){
+        // [设备号] [日期] [gpsCount] [经度] [维度] [速度] [电压等级] [GSM信号等级] [报警原因] [终端信息详解] [] [] [数据类型]
+        SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
+        Date date = new Date();
+        try {
+            date = sdf.parse(this.getDate());
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        date = DateUtil.calculateByHour(date, 8);
+        String dateStr = sdf.format(date);
+        StringBuilder builder = new StringBuilder();
+        builder.append(checkoutNullObject(this.getDeviceId())).append(",");
+        builder.append(checkoutNullObject(dateStr)).append(",");
+        builder.append(checkoutNullObject(this.getGpsCount())).append(",");
+        builder.append(checkoutNullObject(this.getLng())).append(",");
+        builder.append(checkoutNullObject(this.getLat())).append(",");
+        builder.append(checkoutNullObject(this.getSpeedbyte())).append(",");
+        builder.append(checkoutNullObject(this.getElectric())).append(",");
+        builder.append(checkoutNullObject(this.getGmsSign())).append(",");
+        builder.append(checkoutNullObject(this.getWarningReason())).append(",");
+        builder.append(checkoutNullObject(this.getTerminalMsg())).append(',').append(',').append(',').append(3);
+        return builder.toString();
+    }
+    
+    private static String checkoutNullObject(Object t){
+        if (t == null) {
+            return "";
+        }
+        return String.valueOf(t);
+    }
+}

+ 5 - 5
src/main/java/com/tidecloud/dataacceptance/service/AcceptanceDeviceService.java

@@ -30,7 +30,7 @@ import com.smartsanitation.common.util.StringUtil;
 import com.tidecloud.dataacceptance.config.AcceptanceDeviceConfig;
 import com.tidecloud.dataacceptance.config.DeviceConfig;
 import com.tidecloud.dataacceptance.entity.ConnectMsg;
-import com.tidecloud.dataacceptance.service.impl.YiTongGpsServerHandler;
+import com.tidecloud.dataacceptance.service.impl.BingShuiGpsServerHandler;
 
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.ChannelFuture;
@@ -108,14 +108,14 @@ public class AcceptanceDeviceService implements ApplicationContextAware {
 	private void cleanRedisLinkData(String address) {
 
 		try (Jedis jedis = jedisPool.getResource()) {
-			jedis.select(YiTongGpsServerHandler.REDIS_INDEX_LINK);
+			jedis.select(BingShuiGpsServerHandler.REDIS_INDEX_LINK);
 			String addressStr = ConnectMsg.ipToLong(address);
-			String selectKey = YiTongGpsServerHandler.PREFIX_LINK_BACK + addressStr;
+			String selectKey = BingShuiGpsServerHandler.PREFIX_LINK_BACK + addressStr;
 			Set<String> values = jedis.smembers(selectKey);
 
 			for (String deviceId : values) {
-				String deleteKeyOfDevice = YiTongGpsServerHandler.PREFIX_DEVICE + deviceId;
-				String deleteKeyOfLink = YiTongGpsServerHandler.PREFIX_LINK + addressStr;
+				String deleteKeyOfDevice = BingShuiGpsServerHandler.PREFIX_DEVICE + deviceId;
+				String deleteKeyOfLink = BingShuiGpsServerHandler.PREFIX_LINK + addressStr;
 				String connectMsgStr = jedis.get(deleteKeyOfDevice);
 				if (connectMsgStr != null) {
 					ConnectMsg connectMsg = StringUtil.convert2Object(connectMsgStr, ConnectMsg.class);

+ 31 - 0
src/main/java/com/tidecloud/dataacceptance/service/AcceptanceInboundHandlerAdapter.java

@@ -14,6 +14,7 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -32,6 +33,7 @@ import org.springframework.util.concurrent.SuccessCallback;
 import com.smartsanitation.common.util.StringUtil;
 import com.tidecloud.dataacceptance.common.NumUtil;
 import com.tidecloud.dataacceptance.entity.ConnectMsg;
+import com.tidecloud.dataacceptance.service.impl.YiTongGpsServerHandler;
 
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.buffer.ByteBuf;
@@ -322,11 +324,40 @@ public abstract class AcceptanceInboundHandlerAdapter extends ChannelInboundHand
 		} catch (Exception e) {
 			logger.error(e.getMessage());
 		} finally {
+			cleanRedisLinkData();
 			workerGroup.shutdownGracefully();
 			bossGroup.shutdownGracefully();
 		}
 	}
 	
+	
+	   protected void cleanRedisLinkData() {
+	        
+	        try(Jedis jedis = jedisPool.getResource()){
+	            jedis.select(YiTongGpsServerHandler.REDIS_INDEX_LINK);
+	            String addressStr = ConnectMsg.ipToLong(this.ip);
+	            String selectKey = YiTongGpsServerHandler.PREFIX_LINK_BACK + addressStr;
+	            Set<String> values = jedis.smembers(selectKey);
+	            
+	            for (String deviceId : values) {
+	                String deleteKeyOfDevice = YiTongGpsServerHandler.PREFIX_DEVICE + deviceId;
+	                String deleteKeyOfLink = YiTongGpsServerHandler.PREFIX_LINK + addressStr;
+	                String connectMsgStr = jedis.get(deleteKeyOfDevice);
+	                if (connectMsgStr != null) {
+	                    ConnectMsg connectMsg = StringUtil.convert2Object(connectMsgStr, ConnectMsg.class);
+	                    String socketId = connectMsg.getSocketId();
+	                    jedis.del(deleteKeyOfDevice);
+	                    jedis.srem(deleteKeyOfLink, socketId);
+	                }else {
+	                	logger.error("error deviceId [{}] in select [{}] key [{}]", deviceId, 15, deleteKeyOfDevice);
+	                }
+	            }
+	            jedis.del(selectKey);
+	        } catch (Exception e) {
+	        	logger.error(e.getLocalizedMessage());
+	        }
+	    }
+	
 	public String getDataPath() {
 		return dataPath;
 	}

+ 1 - 0
src/main/java/com/tidecloud/dataacceptance/service/impl/BSJGpsServerHandler.java

@@ -323,6 +323,7 @@ public class BSJGpsServerHandler extends AcceptanceInboundHandlerAdapter {
 		} catch (Exception e) {
 			logger.error(e.getMessage());
 		} finally {
+			cleanRedisLinkData();
 			workerGroup.shutdownGracefully();
 			bossGroup.shutdownGracefully();
 		}

+ 78 - 0
src/main/java/com/tidecloud/dataacceptance/service/impl/BingShuiGpsServerHandler.java

@@ -0,0 +1,78 @@
+package com.tidecloud.dataacceptance.service.impl;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import com.tidecloud.dataacceptance.service.AcceptanceInboundHandlerAdapter;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
+
+/**
+ * @author cdk
+ */
+@Component
+@ChannelHandler.Sharable
+public class BingShuiGpsServerHandler extends AcceptanceInboundHandlerAdapter {
+
+	private static final Logger logger = LoggerFactory.getLogger(BingShuiGpsServerHandler.class);
+
+	public void reply(ChannelHandlerContext ctx, String oringalData) {
+		Map<String, String> dataMap = new HashMap<>();
+
+		String[] dataArray = oringalData.split("\\s+");
+		String phone = dataArray[0];
+		String deviceData = dataArray[1];
+		if (deviceData.endsWith("]") && deviceData.startsWith("[")) {
+			String subDeviceData = deviceData.substring(1, deviceData.length() - 1);
+			String[] subDataArray = subDeviceData.split(";");
+			try {
+				for (int i = 0; i < subDataArray.length; i++) {
+					String subData = subDataArray[i];
+					String[] datas = subData.split(":");
+					if (datas[0].contains("S") && !datas[0].contains("G")) {
+						dataMap.put("S", datas[1]);
+					} else {
+						dataMap.put(datas[0], datas[1]);
+					}
+				}
+			} catch (Exception e) {
+				logger.error(e.getMessage(), e);
+			}
+		}
+		Channel channel = ctx.channel();
+		
+		receiveMsg(oringalData,phone,channel);
+
+
+		String serialStr = dataMap.get("S");
+		Integer serialId = Integer.valueOf(serialStr) + 1;
+		Date now = new Date();
+		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+		String dataStr = simpleDateFormat.format(now);
+		String replyMsg = "[" + "S:" + serialId + ";R" + "1" + ";" + "ST:" + dataStr + "]";
+		ByteBuf buffer = Unpooled.buffer(replyMsg.getBytes().length);
+		buffer.writeBytes(replyMsg.getBytes());
+
+		ChannelFuture channelFuture = channel.writeAndFlush(buffer);
+		channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
+			@Override
+			public void operationComplete(Future<? super Void> future) throws Exception {
+				logger.info("回复设备: [{}] 成功", replyMsg);
+			}
+		});
+	}
+
+}

+ 366 - 47
src/main/java/com/tidecloud/dataacceptance/service/impl/YiTongGpsServerHandler.java

@@ -1,24 +1,53 @@
 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 io.netty.bootstrap.ServerBootstrap;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+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
@@ -27,52 +56,342 @@ import io.netty.util.concurrent.GenericFutureListener;
 @ChannelHandler.Sharable
 public class YiTongGpsServerHandler extends AcceptanceInboundHandlerAdapter {
 
-	private static final Logger logger = LoggerFactory.getLogger(YiTongGpsServerHandler.class);
-
-	public void reply(ChannelHandlerContext ctx, String oringalData) {
-		Map<String, String> dataMap = new HashMap<>();
-
-		String[] dataArray = oringalData.split("\\s+");
-		String phone = dataArray[0];
-		String deviceData = dataArray[1];
-		if (deviceData.endsWith("]") && deviceData.startsWith("[")) {
-			String subDeviceData = deviceData.substring(1, deviceData.length() - 1);
-			String[] subDataArray = subDeviceData.split(";");
-			try {
-				for (int i = 0; i < subDataArray.length; i++) {
-					String subData = subDataArray[i];
-					String[] datas = subData.split(":");
-					if (datas[0].contains("S") && !datas[0].contains("G")) {
-						dataMap.put("S", datas[1]);
-					} else {
-						dataMap.put(datas[0], datas[1]);
-					}
-				}
-			} catch (Exception e) {
-				logger.error(e.getMessage(), e);
-			}
-		}
-		Channel channel = ctx.channel();
-		
-		receiveMsg(oringalData,phone,channel);
-
-
-		String serialStr = dataMap.get("S");
-		Integer serialId = Integer.valueOf(serialStr) + 1;
-		Date now = new Date();
-		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
-		String dataStr = simpleDateFormat.format(now);
-		String replyMsg = "[" + "S:" + serialId + ";R" + "1" + ";" + "ST:" + dataStr + "]";
-		ByteBuf buffer = Unpooled.buffer(replyMsg.getBytes().length);
-		buffer.writeBytes(replyMsg.getBytes());
-
-		ChannelFuture channelFuture = channel.writeAndFlush(buffer);
-		channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
-			@Override
-			public void operationComplete(Future<? super Void> future) throws Exception {
-				logger.info("回复设备: [{}] 成功", replyMsg);
-			}
-		});
+    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;
+
+    private static final Integer TEN_M = 10485760;
+
+    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;
+
+
+    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 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 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 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 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 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 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 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 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));
+            }
+        });
+    }
+
+    @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());
+        } 
+    }
+
+    
+	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();
+         }
 	}
 
+	@Override
+	public void reply(ChannelHandlerContext ctx, String msg) throws Exception {
+		// TODO Auto-generated method stub
+		
+	}
 }

+ 4 - 4
src/main/java/com/tidecloud/dataacceptance/web/DeviceController.java

@@ -16,7 +16,7 @@ import com.smartsanitation.common.util.StringUtil;
 import com.tidecloud.dataacceptance.common.CRCUtil;
 import com.tidecloud.dataacceptance.common.NumUtil;
 import com.tidecloud.dataacceptance.entity.ConnectMsg;
-import com.tidecloud.dataacceptance.service.impl.YiTongGpsServerHandler;
+import com.tidecloud.dataacceptance.service.impl.BingShuiGpsServerHandler;
 
 import io.netty.channel.Channel;
 import redis.clients.jedis.Jedis;
@@ -41,7 +41,7 @@ public class DeviceController {
             return ResultWrapper.ok();
         }
         try {
-            Map<String, Channel> channelMap = YiTongGpsServerHandler.socketyChannelMap;
+            Map<String, Channel> channelMap = BingShuiGpsServerHandler.socketyChannelMap;
             if (channelMap.isEmpty()) {
                 return ResultWrapper.ok();
             }
@@ -88,9 +88,9 @@ public class DeviceController {
         Map<String, ConnectMsg> deviceIdSocketIdMap = new HashMap<String, ConnectMsg>();
         String[] deviceIdsArray = deviceIds.split(",");
         try (Jedis jedis = jedisPool.getResource()) {
-            jedis.select(YiTongGpsServerHandler.REDIS_INDEX_LINK);
+            jedis.select(BingShuiGpsServerHandler.REDIS_INDEX_LINK);
             for (String deviceId : deviceIdsArray) {
-                String selectKey = YiTongGpsServerHandler.PREFIX_DEVICE + deviceId;
+                String selectKey = BingShuiGpsServerHandler.PREFIX_DEVICE + deviceId;
                 String result = jedis.get(selectKey);
                 if (result != null) {
                     ConnectMsg connectMsg = StringUtil.convert2Object(result, ConnectMsg.class);

+ 12 - 2
src/main/resources/application.yml

@@ -39,7 +39,7 @@ acceptance:
     ip: 10.27.118.76
     port: 7510
     dataFileDir: /home/service/collector_7510/rawdata/
-    handlerClass: com.tidecloud.dataacceptance.service.impl.YiTongGpsServerHandler
+    handlerClass: com.tidecloud.dataacceptance.service.impl.BingShuiGpsServerHandler
     enable: true
     
    -
@@ -50,7 +50,17 @@ acceptance:
     dataFileDir: /home/service/collector_6707/rawdata/
     handlerClass: com.tidecloud.dataacceptance.service.impl.BSJGpsServerHandler
     enable: true
-          
+    
+   -
+    name: yitong
+    topic: device-yitong-bingshui
+    ip: 10.27.118.76
+    port: 7011
+    dataFileDir: /home/service/collector_yitong/rawdata-car/
+    handlerClass: com.tidecloud.dataacceptance.service.impl.YiTongGpsServerHandler
+    enable: true    
+    
+      
 logging:
   config:
     classpath: logback.xml