shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.walker.tcp.coder;
 
import java.util.Arrays;
import java.util.List;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
import com.walker.tcp.msg.MyAbstractMessage;
import com.walker.tcp.msg.MyOEMMessage;
import com.walker.tcp.util.ByteUtils;
 
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
 
/**
 * 描述:(充电)设备解码器,目前只有一种设备
 * @author 时克英
 * @date 2020年8月18日 下午6:24:30
 */
 
public class MessageDecoder extends MessageToMessageDecoder<ByteBuf> {
 
    protected final transient Log logger = LogFactory.getLog(this.getClass());
    
    // 目前只有这一家,开头特征
    private final byte[] feature = new byte[] { (byte) 0xAA, (byte) 0xf5 };
    
    // 不包含业务数据的报文其他字段长度(固定)
    private final int sizeWithoutData = 9;
    
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
        
        // 1-特征(2字节)
        byte[] msgFeature = new byte[2];
        msg.readBytes(msgFeature);
        if(msgFeature[0] != feature[0] || msgFeature[1] != feature[1]){
            logger.warn("未识别的设备请求特征:" + Arrays.toString(msgFeature));
            out.add(null);
            return;
        }
        
        // 2-长度(2字节)
        msg.readBytes(msgFeature);
        int contentSize = ByteUtils.toInt2(msgFeature);
        if(contentSize != msg.capacity()){
            logger.error("请求设备数据长度错误,数据提供长度:" + contentSize + ",实际长度:" +  msg.capacity());
            out.add(null);
            return;
        }
        
        // 这里先实现了一种设备解码,如果后续更多设备,改解码器需要重构。
        MyAbstractMessage message = new MyOEMMessage();
        message.setTotalSize(contentSize);
        
        // 3-信息域(1字节)
        byte info = msg.readByte();
        
        // 4-序列号域(1字节)
        byte serialNum = msg.readByte();
        
        
        // 5-命令字(2字节)
        msg.readBytes(msgFeature);
//        int command = ByteUtils.toInt2(msgFeature);
//        logger.debug("command = " + command);
//        if(command == 106){
//            logger.debug("设备连接签到请求,这里需要判断如果不再命令集合中则丢掉数据");
//        }
        message.setProtocol(ByteUtils.getCommand(msgFeature));
        
        // 6-业务内容
        byte[] data = new byte[contentSize - sizeWithoutData];
        msg.readBytes(data);
        message.setPayload(data);
        
        out.add(message);
    }
 
}