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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package com.flightfeather.obd.socket
 
import com.flightfeather.obd.common.utils.FileUtil
import com.flightfeather.obd.repository.*
import com.flightfeather.obd.socket.bean.ObdPackageData
import com.flightfeather.obd.socket.decoder.VehicleDataDecoder
import com.flightfeather.obd.socket.decoder.impl.DataPackageDecoderImpl
import com.flightfeather.obd.socket.eunm.ObdCommandUnit
import io.netty.channel.ChannelHandlerContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.text.SimpleDateFormat
import java.util.*
import javax.annotation.PostConstruct
 
/**
 * 处理socket接收的消息
 * Date: 2019.8.27
 * @author riku
 */
 
@Component
class MessageManager{
 
    companion object{
        private lateinit var instance: MessageManager
    }
 
    @Autowired
    lateinit var obdDataRepository: ObdDataRepository
    @Autowired
    lateinit var originDataRepository: OriginDataRepository
    @Autowired
    lateinit var obdInfoRepository: ObdInfoRepository
    @Autowired
    lateinit var dataStreamRepository: DataStreamRepository
    @Autowired
    lateinit var carLogoutRepository: CarLogoutRepository
    @Autowired
    lateinit var carLoginRepository: CarLoginRepository
 
    val vehicleDataDecoder = VehicleDataDecoder()
    val dataPackageDecoder = DataPackageDecoderImpl()
 
    @PostConstruct
    fun init() {
        instance = this
        instance.obdDataRepository = this.obdDataRepository
        instance.originDataRepository = this.originDataRepository
        instance.obdInfoRepository = this.obdInfoRepository
        instance.dataStreamRepository = this.dataStreamRepository
        instance.carLogoutRepository = this.carLogoutRepository
        instance.carLoginRepository = this.carLoginRepository
    }
 
    fun dealStringMsg(msg: String, ctx: ChannelHandlerContext?) {
        saveToTxt(msg)
 
        if (bccCheck(msg)) {
            //解包
            val packageData = vehicleDataDecoder.decode(msg)
            //保存
            DeviceSession.saveDevice(packageData.deviceCode, ctx)
            saveToDataBase(packageData, msg)
        } else {
            println("------数据BCC校验失败,舍弃 [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]")
        }
    }
 
    /**
     * 保存至txt文本
     */
    fun saveToTxt(msg: String) {
        val data = "[${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]data=> $msg"
        FileUtil.instance?.saveObdData(data)
    }
 
    /**
     * 保存至数据库
     */
    fun saveToDataBase(packageData: ObdPackageData, msg: String) {
        instance.obdDataRepository.saveObdData(packageData)
        instance.originDataRepository.saveOriginData(packageData, msg)
        when (packageData.commandUnit) {
            ObdCommandUnit.CarRegister.value -> instance.carLoginRepository.saveCarLogin(packageData)
            ObdCommandUnit.RealTimeData.value,
            ObdCommandUnit.ReplacementData.value -> instance.dataStreamRepository.saveDataStream(packageData)
            ObdCommandUnit.CarLogOut.value-> instance.carLogoutRepository.saveCarLogout(packageData)
        }
    }
 
    /**
     * BCC(异或校验)
     */
    fun bccCheck(msg: String):Boolean {
        val list = mutableListOf<String>().apply {
            addAll(dataPackageDecoder.toStringList(msg))
            //去除2 位起始符
            removeAt(0)
            removeAt(0)
        }
        //取得数据包中的bcc校验结果
        val oldBcc = list[list.size - 1].toInt(16)
 
        //去除校验结果
        list.removeAt(list.size-1)
 
        //计算bcc校验结果
        var newBcc = 0x00
        list.forEach {
            newBcc = newBcc.xor(it.toInt(16))
        }
 
        //返回校验结果是否正确
        return oldBcc == newBcc
    }
}