riku
2019-09-19 58a16c3340f92a1ec0362565020f31de56faaf3e
1. 增加远程查看版本指令逻辑
已修改5个文件
100 ■■■■ 文件已修改
src/main/kotlin/com/flightfeather/obd/socket/DeviceSession.kt 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/obd/socket/MessageManager.kt 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/obd/socket/ServerHandler.kt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/obd/socket/SocketServerClient.kt 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdCommandUnit.kt 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/obd/socket/DeviceSession.kt
@@ -20,7 +20,10 @@
        }
        fun getDevice(deviceCode: String?): ChannelHandlerContext? {
            return if (deviceMap.contains(deviceCode)) deviceMap[deviceCode] else null
            return if (deviceMap.containsKey(deviceCode))
                deviceMap[deviceCode]
            else
                null
        }
    }
}
src/main/kotlin/com/flightfeather/obd/socket/MessageManager.kt
@@ -9,6 +9,7 @@
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.buffer.Unpooled
import io.netty.channel.ChannelHandlerContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
@@ -57,16 +58,23 @@
    }
    fun dealStringMsg(msg: String, ctx: ChannelHandlerContext?) {
        //解包
        val packageData = vehicleDataDecoder.decode(msg)
        saveToTxt(msg)
        if (bccCheck(msg)) {
            //解包
            val packageData = vehicleDataDecoder.decode(msg)
            //保存
            DeviceSession.saveDevice(packageData.deviceCode, ctx)
            saveToDataBase(packageData, msg)
        val isCommand = command(packageData, ctx)
        if (isCommand) {
            println("------远程控制指令 [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]")
        } else {
            println("------数据BCC校验失败,舍弃 [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]")
            if (bccCheck(msg)) {
                //保存
                DeviceSession.saveDevice(packageData.deviceCode, ctx)
                saveToDataBase(packageData, msg)
            } else {
                println("------数据BCC校验失败,舍弃 [${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())}]")
            }
        }
    }
@@ -130,4 +138,68 @@
        //返回校验结果是否正确
        return oldBcc == newBcc
    }
    /**
     * 远程指令
     */
    fun command(packageData: ObdPackageData, ctx: ChannelHandlerContext?): Boolean {
        if (packageData.commandUnit == ObdCommandUnit.Update.value) {
            val channel = DeviceSession.getDevice(packageData.deviceCode)
            if (channel != null) {
                val s = getDataPackage(packageData.deviceCode)
                if (s == null) {
                    ctx?.writeAndFlush("[${packageData.deviceCode}] 设备编号为空")
                } else {
                    val bytes = encodeToBytes(s)
                    channel.writeAndFlush(Unpooled.copiedBuffer(bytes))
                    ctx?.writeAndFlush("[${packageData.deviceCode}] 指令发送成功")
                }
            } else {
                ctx?.writeAndFlush("[${packageData.deviceCode}] 设备未连接或不存在")
            }
            return true
        } else if (packageData.commandUnit != ObdCommandUnit.CarRegister.value
                && packageData.commandUnit != ObdCommandUnit.RealTimeData.value
                && packageData.commandUnit != ObdCommandUnit.ReplacementData.value
                && packageData.commandUnit != ObdCommandUnit.CarLogOut.value
                && packageData.commandUnit != ObdCommandUnit.TimeCalibration.value) {
            ctx?.writeAndFlush("[${packageData.deviceCode}] 命令不存在")
            return true
        } else {
            return false
        }
    }
    fun encodeToBytes(msg:String): ByteArray {
        val list = msg.split(" ")
        val bytes = ByteArray(list.size)
        for (i in 0 until list.size) {
            bytes[i]=list[i].toInt(16).toByte()
        }
        return bytes
    }
    fun getDataPackage(deviceCode: String?): String? {
        if (deviceCode == null) return null
        //23 23 7f 31 37 36 39 31 35 33 31 39 30 39 31 32 30 30 31 31 01 01 00 00 39
        val sb = StringBuilder("23 23 10 ")
        deviceCode.forEach {
            sb.append(it.toInt().toString(16)).append(" ")
        }
        sb.append("01 01 00 00 00 0A 41 54 2B 56 45 52 53 49 4F 4E")
        val list = sb.split(" ")
        //计算bcc校验结果
        var bcc = 0x00
        list.forEach {
            bcc = bcc.xor(it.toInt(16))
        }
        sb.append(" ").append(bcc.toString(16))
        return sb.toString()
    }
}
src/main/kotlin/com/flightfeather/obd/socket/ServerHandler.kt
@@ -40,7 +40,7 @@
                } else {
                    a.toString(16)
                }
                print(s)
                print("$s ")
                sb.append(s).append(" ")
            }
            sb.deleteCharAt(sb.length - 1)
src/main/kotlin/com/flightfeather/obd/socket/SocketServerClient.kt
@@ -13,6 +13,7 @@
import io.netty.handler.codec.bytes.ByteArrayEncoder
import io.netty.handler.codec.string.StringDecoder
import io.netty.handler.codec.string.StringEncoder
import java.nio.charset.Charset
/**
 * socket长连接服务端
@@ -46,8 +47,8 @@
                        override fun initChannel(p0: NioSocketChannel?) {
                            p0?.pipeline()
//                                    ?.addLast("decoder", StringDecoder())
//                                    ?.addLast("encoder", StringEncoder())
                                    ?.addLast(ObdByteDataDecoder())
                                    ?.addLast("encoder", StringEncoder(Charset.forName("UTF-8")))
                                    ?.addLast(ServerHandler())
                        }
                    })
src/main/kotlin/com/flightfeather/obd/socket/eunm/ObdCommandUnit.kt
@@ -15,11 +15,13 @@
 * 0x04            车辆登出                    上行 @see [CarLogOutData]
 * 0x05            终端校时                    上行 @see [TimeCalibrationData]
 * 0x06~0x7F 上行数据系统预留      上行
 * 0x7F            固件远程更新
 */
enum class ObdCommandUnit constructor(val value: Int) {
    CarRegister(1),
    RealTimeData(2),
    ReplacementData(3),
    CarLogOut(4),
    TimeCalibration(5)
    TimeCalibration(5),
    Update(127)
}