Files
geedge-jira/attachment/29166/parser_GBT32960_plug.lua
2025-09-14 22:00:20 +00:00

1000 lines
41 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 创建一个新的解析插件
local name = "GBT32960"
local port = 8010
local GBT32960 = Proto(name, "GBT32960 Protocol")
local GBT32960_info = {}
local mt = {__index = function(...) return "unknown" end}
local reply_name_GBT32960 = {
[1] = "Successed",
[2] = "Failed",
[3] = "Vin Repeat",
[0xFE] = "Command",
}
setmetatable(reply_name_GBT32960, mt)
local is_GBT32960 = 0
local is_GBTXXXXX = 1
local is_command = 0
local is_reply = 1
--设置自定义协议头部格式,每个字段的名称,长度,含义
local fields = GBT32960.fields
-- 2byte feature ##
-- 1byte command
fields.command_id = ProtoField.uint8("GBT32960.command_id", "command id", base.HEX, NONE, 0xFF, "command id")
-- 1byte response
fields.reply_id = ProtoField.uint8("GBT32960.reply_id", "reply id", base.HEX, NONE, 0xFF, "reply id")
-- 17byte VIN
fields.vin = ProtoField.string("GBT32960.vin", "vin")
fields.encryption = ProtoField.uint8("GBT32960.encryption", "encryption", base.HEX, NONE, 0xFF, "encryption")
fields.data_unit_len = ProtoField.uint16("GBT32960.data_unit_len", "data unit len", base.DEC, NONE, 65535, "data unit len")
fields.year = ProtoField.uint8("GBT32960.year", "year", base.DEC, NONE, 0xFF, "year")
fields.month = ProtoField.uint8("GBT32960.month", "month", base.DEC, NONE, 0xFF, "month")
fields.day = ProtoField.uint8("GBT32960.day", "day", base.DEC, NONE, 0xFF, "day")
fields.hour = ProtoField.uint8("GBT32960.hour", "hour", base.DEC, NONE, 0xFF, "hour")
fields.mimute = ProtoField.uint8("GBT32960.mimute", "mimute", base.DEC, NONE, 0xFF, "mimute")
fields.second = ProtoField.uint8("GBT32960.second", "second", base.DEC, NONE, 0xFF, "second")
fields.sequence = ProtoField.uint16("GBT32960.sequence", "sequence", base.DEC, NONE, 65535, "sequence")
fields.ICCID = ProtoField.string("GBT32960.ICCID", "ICCID", base.ASCII)
fields.rechargeable_energy_storage_subsystem_num = ProtoField.uint8("GBT32960.rechargeable_energy_storage_subsystem_num", "rechargeable_energy_storage_subsystem_num", base.DEC, NONE, 0xFF, "rechargeable_energy_storage_subsystem_num")
fields.rechargeable_energy_storage_encode_len = ProtoField.uint8("GBT32960.rechargeable_energy_storage_encode_len", "rechargeable_energy_storage_encode_len", base.DEC, NONE, 0xFF, "rechargeable_energy_storage_encode_len")
fields.rechargeable_energy_storage_encode = ProtoField.string("GBT32960.rechargeable_energy_storage_encode", "rechargeable_energy_storage_encode", base.ASCII)
fields.msgtype = ProtoField.uint8("GBT32960.realtimeInformation.messageType", "messageType", base.HEX, NONE, 0xFF, "messageType")
fields.vehicleSatus = ProtoField.uint8("GBT32960.reltimeInformation.vehicleData.vehicleStatus", "vehicle status", base.HEX, NONE, 0xFF, "vehicle status")
fields.chargind = ProtoField.uint8("GBT32960.reltimeInformation.vehicleData.chargind", "chargind", base.HEX, NONE, 0xFF, "chargind")
fields.operatingMode = ProtoField.uint8("GBT32960.reltimeInformation.vehicleData.operatingMode", "operating Mode", base.HEX, NONE, 0xFF, "operating Mode")
fields.speed = ProtoField.uint16("GBT32960.reltimeInformation.vehicleData.speed", "speed", base.DEC, NONE, 0xFFFF, "speed")
fields.accmulatedMileage = ProtoField.uint32("GBT32960.reltimeInformation.vehicleData.accmulatedMileage", "accmulated Mileage", base.DEC, NONE, 0xFFFFFFFF, "accmulated Mileage")
fields.totalVoltage = ProtoField.uint16("GBT32960.reltimeInformation.vehicleData.totalVoltage", "total Voltage", base.DEC, NONE, 0xFFFF, "total Voltage")
fields.totalCurrent = ProtoField.uint16("GBT32960.reltimeInformation.vehicleData.totalCurrent", "total Current", base.DEC, NONE, 0xFFFF, "total Current")
fields.SOC = ProtoField.uint8("GBT32960.reltimeInformation.vehicleData.SOC", "SOC", base.DEC, NONE, 0xFF, "SOC")
fields.DCorDCStatus = ProtoField.uint8("GBT32960.reltimeInformation.vehicleData.DorCDCStatus", "D/DC status", base.HEX, NONE, 0xFF, "D/DC status")
fields.Gear = ProtoField.uint8("GBT32960.reltimeInformation.vehicleData.Gear", "Gear", base.HEX, NONE, 0xFF, "Gear")
fields.InsulationResistance = ProtoField.uint16("GBT32960.reltimeInformation.vehicleData.InsulationResistance", "Insulation Resistance", base.DEC, NONE, 0xFFFF, "Insulation Resistance")
-- fields.acceleratorPedalStrokeValue = ProtoField.uint8("GBT32960.reltimeInformation.vehicleData.acceleratorPedalStrokeValue", "Accelerator Pedal Stroke Value", base.DEC, NONE, 0xFF, "Accelerator Pedal Strok Value")
-- fields.brakePedalStatus = ProtoField.uint8("GBT32960.reltimeInformation.vehicleData.brakePedalStatus", "Brake Pedal Status", base.DEC, NONE, 0xFF, "Brake Pedal Status")
fields.vehicleSatusReserved = ProtoField.uint16("GBT32960.reltimeInformation.engin", "Reserved", base.DEC, NONE, 0xFFFF, "Reserved")
fields.driveMotorNum = ProtoField.uint8("GBT32960.reltimeInformation.driverMotorData.driveMotorNum", "dirve Motor num", base.DEC, NONE, 0xFF, "drive Motor num")
fields.driveMotorSeq = ProtoField.uint8("GBT32960.reltimeInformation.driverMotorData.driveMotorSeq", "dirve Motor Sequence", base.DEC, NONE, 0xFF, "drive Motor Sequence")
fields.driveMotorStatus = ProtoField.uint8("GBT32960.reltimeInformation.driverMotorData.driveMotorStatus", "dirve Motor Status", base.DEC, NONE, 0xFF, "drive Motor Status")
fields.ControllerTemperature = ProtoField.int8("GBT32960.reltimeInformation.driverMotorData.ControllerTemperature", "Controller Temperature", base.DEC, NONE, 0xFF, "Controller Temperature")
fields.driveMotorRotatingSpeed = ProtoField.uint16("GBT32960.reltimeInformation.driverMotorData.driveMotorRotatingSpeed", "dirve Motor Rotating Speed", base.DEC, NONE, 0xFFFF, "drive Motor Rotating Speed")
fields.driveMotorTorque = ProtoField.uint16("GBT32960.reltimeInformation.driverMotorData.driveMotorTorque", "dirve Motor Torque", base.DEC, NONE, 0xFFFF, "drive Motor Torque")
fields.driveMotorTemperature = ProtoField.int8("GBT32960.reltimeInformation.driverMotorData.driveMotorTemperature", "drive Motor Temperature", base.DEC, NONE, 0xFF, "drive Motor Temperature")
fields.ControllerInputVoltage = ProtoField.uint16("GBT32960.reltimeInformation.driverMotorData.ControllerInputVoltage", "Controller Input Voltage", base.DEC, NONE, 0xFF, "Controller Input Voltage")
fields.DCBusCurrent = ProtoField.uint8("GBT32960.reltimeInformation.driverMotorData.DCBusCurrent", "DC Bus Current", base.DEC, NONE, 0xFF, "DC Bus Current")
fields.engineStatus = ProtoField.uint8("GBT32960.reltimeInformation.engineData.engineStatus", "engine status", base.HEX, NONE, 0xFF, "engine status")
fields.crankshaftSpeed = ProtoField.uint16("GBT32960.reltimeInformation.engineData.crankshaftSpeed", "crankshaft speed", base.DEC, NONE, 0xFFFF, "crankshaft speed")
fields.fuelConsumptionRate = ProtoField.uint16("GBT32960.reltimeInformation.engineData.fuelConsumptionRate", "fuel consumption rate", base.DEC, NONE, 0xFFFF, "fuel Consumption Rate")
fields.platformAccount = ProtoField.string("GBT32960.platformLogin.platformAccount", "platform account", base.ASCII)
fields.platformPasswd = ProtoField.string("GBT32960.platformLogin.platformPasswd", "platform account", base.ASCII)
fields.MaxVoltageBatterySubsystemNum = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MaxVoltageBatterySubsystemNum", "Max Voltage Battery Subsystem Num", base.DEC, NONE, 0xFF, "Max Voltage Battery Subsystem Num")
fields.MaxVoltageBatteryCellCode = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MaxVoltageBatteryCellCode", "Max Voltage Battery Cell Code", base.DEC, NONE, 0xFF, "Max Voltage Battery Cell Code")
fields.MaxValueBatteryCellVoltage = ProtoField.uint16("GBT32960.reltimeInformation.extremeData.MaxValueBatteryCellVoltage", "Max Value Battery Cell Voltage", base.DEC, NONE, 0xFFFF, "Max Value Battery Cell Voltage")
fields.MinVoltageBatterySubsystemNum = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MinVoltageBatterySubsystemNum", "Min Voltage Battery Subsystem Num", base.DEC, NONE, 0xFF, "Min Voltage Battery Subsystem Num")
fields.MinVoltageBatteryCellCode = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MinVoltageBatteryCellCode", "Min Voltage Battery Cell Code", base.DEC, NONE, 0xFF, "Min Voltage Battery Cell Code")
fields.MinValueBatteryCellVoltage = ProtoField.uint16("GBT32960.reltimeInformation.extremeData.MinValueBatteryCellVoltage", "Min Value Battery Cell Voltage", base.DEC, NONE, 0xFFFF, "Min Value Battery Cell Voltage")
fields.MaxTemperatureSubsystemNum = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MaxTemperatureSubsystemNum", "Max Temperature Subsystem Num", base.DEC, NONE, 0xFF, "Max Temperature Subsystem Num")
fields.MaxTemperatureProbeSerialNum = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MaxTemperatureProbeSerialNum", "Max Temperature Probe Serial Num", base.DEC, NONE, 0xFF, "Max Temperature Probe Serial Num")
fields.MaxTemperatureValue = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MaxTemperatureValue", "Max Temperature Value", base.DEC, NONE, 0xFF, "Max Temperature Value")
fields.MinTemperatureSubsystemNum = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MinTemperatureSubsystemNum", "Min Temperature Subsystem Num", base.DEC, NONE, 0xFF, "Min Temperature Subsystem Num")
fields.MinTemperatureProbeSerialNum = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MinTemperatureProbeSerialNum", "Min Temperature Probe Serial Num", base.DEC, NONE, 0xFF, "Min Temperature Probe Serial Num")
fields.MinTemperatureValue = ProtoField.uint8("GBT32960.reltimeInformation.extremeData.MinTemperatureValue", "Min Temperature Value", base.DEC, NONE, 0xFF, "Min Temperature Value")
fields.locationStatus = ProtoField.uint8("GBT32960.reltimeInfomation.vehicleLocation.locationStatus", "Location Status", base.HEX, NONE, 0x80, "Location Status")
fields.longitude = ProtoField.uint32("GBT32960.reltimeInfomation.vehicleLocation.longitude", "Longitude", base.DEC, NONE, 0xFFFFFFFF, "Longitude")
fields.latitude = ProtoField.uint32("GBT32960.reltimeInfomation.vehicleLocation.latiitude", "latiitude", base.DEC, NONE, 0xFFFFFFFF, "latiitude")
fields.fuelCellVoltage = ProtoField.uint16("GBT32960.reltimeInfomation.fuelCellData.fuelCellVoltage", "fuel Cell Voltage", base.DEC, NONE, 0xFFFF, "fuel Cell Voltage")
fields.fuelCellCurrent = ProtoField.uint16("GBT32960.reltimeInfomation.fuelCellData.fuelCellCurrent", "fuel Cell Current", base.DEC, NONE, 0xFFFF, "fuel Cell Current")
fields.fuelConsumptionRate = ProtoField.uint16("GBT32960.reltimeInfomation.fuelCellData.fuelConsumptionRate", "fuel Consumption Rate", base.DEC, NONE, 0xFFFF, "fuel Consumption Rate")
fields.fuelCellTempratureProbesNum = ProtoField.uint16("GBT32960.reltimeInfomation.fuelCellData.fuelCellTempratureProbesNum", "fuel Cell Temprature Probes Num", base.DEC, NONE, 0xFFFF, "fuel Cell Temprature ProbesNum")
fields.fuelCellTemperatureProbesValue = ProtoField.uint8("GBT32960.reltimeInfomation.fuelCellData.fuelCellTemperatureProbesValue", "fuel Cell Temperature Probes Value", base.DEC, NONE, 0xFF, "fuel Cell Temperature Probes Value")
fields.MaxTemperatureInHydrogenSystem = ProtoField.uint16("GBT32960.reltimeInfomation.fuelCellData.MaxTemperatureInHydrogenSystem", "Max Temperature In Hydrogen System", base.DEC, NONE, 0xFFFF, "Max Temperature In Hydrogen System")
fields.MaxTemperatureProbeCodeInHydrogenSystem = ProtoField.uint8("GBT32960.reltimeProbeCodeInfomation.fuelCellData.MaxTemperatureProbeCodeInHydrogenSystem", "Max Temperature Probe Code In Hydrogen System", base.DEC, NONE, 0xFF, "Max Temperature Probe Code In Hydrogen System")
fields.MaxHydrogenConcentration = ProtoField.uint16("GBT32960.reltimeInfomation.fuelCellData.MaxHydrogenConcentration", "Max Hydrogen Concentration", base.DEC, NONE, 0xFFFF, "Max Hydrogen Concentration")
fields.MaxHydrogenConcentrationSensorCode = ProtoField.uint8("GBT32960.reltimeInfomationSensorCode.fuelCellData.MaxHydrogenConcentrationSensorCode", "Max Hydrogen Concentration Sensor Code", base.DEC, NONE, 0xFF, "Max Hydrogen Concentration Sensor Code")
fields.MaxHydrogenPressure = ProtoField.uint16("GBT32960.reltimeInfomation.fuelCellData.MaxHydrogenPressure", "Max Hydrogen Pressure", base.DEC, NONE, 0xFFFF, "Max Hydrogen Pressure")
fields.MaxHydrogenPressureSensorCode = ProtoField.uint8("GBT32960.reltimeInfomation.fuelCellData.MaxHydrogenPressureSensorCode", "Max Hydrogen Pressure Sensor Code", base.DEC, NONE, 0xFF, "Max Hydrogen Pressure Sensor Code")
fields.HighVoltageDcOrDCStatus = ProtoField.uint8("GBT32960.reltimeInfomation.fuelCellData.HighVoltageDcOrDCStatus", "High Voltage Dc Or DC Status", base.DEC, NONE, 0xFF, "High Voltage Dc Or DCStatus")
local function get_time (tvb, offset, tree)
local time = {}
time.year = tvb(offset, 1):uint()
time.month = tvb(offset + 1, 1):uint()
time.day = tvb(offset + 2, 1):uint()
time.hour = tvb(offset + 3, 1):uint()
time.mimute = tvb(offset + 4, 1):uint()
time.second = tvb(offset + 5, 1):uint()
tree:add(fields.year, tvb(offset, 1))
tree:add(fields.month, tvb(offset+1, 1))
tree:add(fields.day, tvb(offset+2, 1))
tree:add(fields.hour, tvb(offset+3, 1))
tree:add(fields.mimute, tvb(offset+4, 1))
tree:add(fields.second, tvb(offset+5, 1))
-- return string.format("%d-%d-%d-%d-%d-%d", time.year, time.month, time.day, time.hour, time.mimute, time.hour, time.second)
end
local function vehicle_login(tvb, offset, datatree)
local vehicle_login_info = {}
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 6
if (GBT32960_info.data_unit_len < 0) then
return
end
get_time(tvb, offset, datatree)
offset = offset + 6
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
datatree:add(fields.sequence, tvb(offset, 2))
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 20
if (GBT32960_info.data_unit_len < 0) then
return
end
datatree:add(fields.ICCID, tvb(offset, 20))
offset = offset + 20
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
vehicle_login_info.rechargeable_energy_storage_subsystem_num = tvb(offset, 1):uint()
datatree:add(fields.rechargeable_energy_storage_subsystem_num, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
vehicle_login_info.rechargeable_energy_storage_encode_len = tvb(offset, 1):uint()
datatree:add(fields.rechargeable_energy_storage_encode_len, tvb(offset, 1))
offset = offset + 1
local encode_len = vehicle_login_info.rechargeable_energy_storage_subsystem_num *
vehicle_login_info.rechargeable_energy_storage_encode_len
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - encode_len
if (GBT32960_info.data_unit_len < 0) then
return
end
-- vehicle_login_info.rechargeable_energy_storage_encode = tvb(offset, encode_len):string()
if encode_len > 0 then
datatree:add(fields.rechargeable_energy_storage_encode, tvb(offset, encode_len))
offset = offset + encode_len
end
return vehicle_login_info, offset
end
local function vehicle_data_dissector(tvb, offset, subtree)
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.vehicleSatus, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.chargind, tvb(offset,1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.operatingMode, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.speed, tvb(offset, 2)):append_text("((*0.1)km/h)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 4
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.accmulatedMileage, tvb(offset, 4)):append_text("((* 0.1)km)")
offset = offset + 4
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.totalVoltage, tvb(offset, 2)):append_text("((* 0.1) V)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.totalCurrent, tvb(offset, 2)):append_text("((-1000) A)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.SOC, tvb(offset, 1)):append_text("(%)")
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.DCorDCStatus, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.Gear, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.InsulationResistance, tvb(offset, 2)):append_text("(kΩ)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.vehicleSatusReserved, tvb(offset, 2))
-- subtree:add(fields.acceleratorPedalStrokeValue, tvb(offset, 1)):append_text("(%)")
-- offset = offset + 1
-- subtree:add(fields.brakePedalStatus, tvb(offset, 1)):append_text("(%)")
-- offset = offset + 1
end
local function drive_motor_data_dissector(tvb, offset, subtree)
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
local drive_motor_num = tvb(offset, 1):uint()
subtree:add(fields.driveMotorNum, tvb(offset, 1))
offset = offset + 1
for num = 1, drive_motor_num, 1 do
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
local driveTree = subtree:add(GBT32960, tvb(offset, 10), "drive motor data")
driveTree:add(fields.driveMotorSeq, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
driveTree:add(fields.driveMotorStatus, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
driveTree:add(fields.ControllerTemperature, tvb(offset, 1)):append_text("((-40)℃)")
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
driveTree:add(fields.driveMotorRotatingSpeed, tvb(offset, 2)):append_text("((-20000)r/min)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
driveTree:add(fields.driveMotorTorque, tvb(offset, 2)):append_text("((-20000) (* 0.1) PN · m)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
driveTree:add(fields.driveMotorTemperature, tvb(offset, 1)):append_text("((-40)℃)")
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
driveTree:add(fields.ControllerInputVoltage, tvb(offset, 2)):append_text("((*0.1)V)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
driveTree:add(fields.DCBusCurrent, tvb(offset, 2)):append_text("((-1000) (* 0.1) A)")
offset = offset + 2
end
end
local function fuel_cell_data_dissector(tvb, offset, subtree)
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.fuelCellVoltage, tvb(offset, 2)):append_text("((* 0.1) V)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.fuelCellCurrent, tvb(offset, 2)):append_text("(*0.1) A")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.fuelConsumptionRate, tvb(offset, 2)):append_text("((*0.01)kg/km)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
local fuelCellTemperatureProbesNum = tvb(offset, 2):int()
subtree:add(fields.fuelCellTemperatureProbesNum, tvb(offset, 2))
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
for i = 1, fuelCellTemperatureProbesNum, 1 do
subtree:add(fields.fuelCellTemperatureProbesValue, tvb(offset, 1))
offset = offset + 1
end
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxTemperatureInHydrogenSystem, tvb(offset, 2))
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxTemperatureProbeCodeInHydrogenSystem, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxHydrogenConcentration, tvb(offset, 2))
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxHydrogenConcentrationSensorCode, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxHydrogenPressure, tvb(offset, 2))
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxHydrogenPressureSensorCode, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.HighVoltageDCOrDCStatus, tvb(offset, 1))
offset = offset + 1
end
local function engine_data_dissector(tvb, offset, subtree)
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.engineStatus, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.crankshaftSpeed, tvb(offset, 2)):append_text("(r/min)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.fuelConsumptionRate, tvb(offset, 2)):append_text("((*0.01) L/100km)")
offset = offset + 2
end
local function vehicle_location_data_dissector(tvb, offset, subtree)
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.locationStatus, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 4
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.longitude, tvb(offset, 4)):append_text("((* 10^6)°)")
offset = offset + 4
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 4
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.latitude, tvb(offset, 4)):append_text("((* 10^6)°)")
offset = offset + 4
end
local function extreme_data_dissector(tvb, offset, subtree)
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxVoltageBatterySubsystemNum, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxVoltageBatteryCellCode, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxValueBatteryCellVoltage, tvb(offset, 2)):append_text("(mV)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MinVoltageBatterySubsystemNum, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MinVoltageBatteryCellCode, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MinValueBatteryCellVoltage, tvb(offset, 2)):append_text("(mV)")
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxTemperatureSubsystemNum, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxTemperatureProbeSerialNum, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MaxTemperatureValue, tvb(offset, 1)):append_text("((-40)℃)")
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MinTemperatureSubsystemNum, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MinTemperatureProbeSerialNum, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.MinTemperatureValue, tvb(offset, 1)):append_text("((-40)℃)")
offset = offset + 1
end
local function alarm_data_dissector(tvb, offset, subtree)
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.HighestAlarmLevel, tvb(offset, 1))
offset = offset + 1
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 4
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.GeneralAlarmSign, tvb(offset, 4))
offset = offset + 4
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.rechargeableEnergyStorageDeviceFaultsNum, tvb(offset, 1))
local rechargeableEnergyStorageDeviceFaultsNum = tvb(offset, 1):int()
offset = offset + 1
for i = 1, rechargeableEnergyStorageDeviceFaultsNum, 1 do
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 4
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.rechargeableEnergyStorageDeviceErrorCode, tvb(offset, 4))
offset = offset + 4
end
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.driveMotorFaultsNum, tvb(offset, 1))
local driveMotorFaultsNum = tvb(offset, 1):int()
offset = offset + 1
for i = 1, driveMotorFaultsNum, 1 do
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 4
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.driveMotorFaultsCode, tvb(offset, 4))
offset = offset + 4
end
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.engineFaultsNum, tvb(offset, 1))
local engineFaultsNum = tvb(offset, 1):int()
offset = offset + 1
for i = 1, engineFaultsNum, 1 do
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 4
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.engineFaultsCode, tvb(offset, 4))
offset = offset + 4
end
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.otherFaultsNum, tvb(offset, 1))
local otherFaultsNum = tvb(offset, 1):int()
offset = offset + 1
for i = 1, otherFaultsNum, 1 do
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 4
if (GBT32960_info.data_unit_len < 0) then
return
end
subtree:add(fields.otherFaultsCode, tvb(offset, 4))
offset = offset + 4
end
end
local realtime_mt = {
__index = function(...) return {name = "unkown", dissector = function(...) end}
end
}
local realtime_info_msg_type_dissector =
{
[1] = {name = "vehicle data", dissector = vehicle_data_dissector};
[2] = {name = "drive motor data", dissector = drive_motor_data_dissector};
[3] = {name = "fuel cell data", dissector = fuel_cell_data_dissector};
[4] = {name = "engine data", dissector = engine_data_dissector};
[5] = {name = "vehicle location", dissector = vehicle_location_data_dissector};
[6] = {name = "extreme data", dissector = extreme_data_dissector};
[7] = {name = "alarm data", dissector = alarm_data_dissector};
}
setmetatable(realtime_info_msg_type_dissector, realtime_mt)
local function realtime_information_report(tvb, offset, datatree)
local realtime_info = {}
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 6
if (GBT32960_info.data_unit_len < 0) then
return
end
realtime_info.data_collection_time = get_time(tvb, offset, datatree)
offset = offset + 6
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
realtime_info.msg_type = tvb(offset, 1):uint()
datatree:add(fields.msgtype, tvb(offset, 1)):append_text("("..realtime_info_msg_type_dissector[realtime_info.msg_type].name..")")
offset = offset + 1
local subtree = datatree:add(GBT32960, tvb(offset), realtime_info_msg_type_dissector[realtime_info.msg_type].name)
realtime_info_msg_type_dissector[realtime_info.msg_type].dissector(tvb, offset, subtree)
end
local function Reissue_information_report(tvb, offset, datatree)
realtime_information_report(tvb, offset, datatree)
end
local function vehicle_logout(tvb, offset, datatree)
local vehicle_logout_info = {}
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 6
if (GBT32960_info.data_unit_len < 0) then
return
end
vehicle_logout_info.data_collection_time = get_time(tvb, offset, datatree)
offset = offset + 6
-- vehicle_logout_info.serial_number = tvb(offset, 2)
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
datatree:add(fields.sequence, tvb(offset, 2))
offset = offset + 2
return vehicle_logout_info, offset
end
local function platform_login(tvb, offset, datatree)
local platform_login_info = {}
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 6
if (GBT32960_info.data_unit_len < 0) then
return
end
platform_login_info.data_collection_time = get_time(tvb, offset, datatree)
offset = offset + 6
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
platform_login_info.serial_number = tvb(offset, 2)
datatree:add(fields.sequence, tvb(offset, 2))
offset = offset + 2
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 12
if (GBT32960_info.data_unit_len < 0) then
return
end
platform_login_info.platform_account = tvb(offset, 12)
datatree:add(fields.platformAccount, tvb(offset, 12))
offset = offset + 12
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 20
if (GBT32960_info.data_unit_len < 0) then
return
end
platform_login_info.platform_passwd = tvb(offset, 20)
datatree:add(fields.platformPasswd, tvb(offset, 20))
offset = offset + 20
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 1
if (GBT32960_info.data_unit_len < 0) then
return
end
platform_login_info.encryption = tvb(offset, 1)
datatree:add(fields.encryption, tvb(offset, 1))
offset = offset + 1
return platform_login_info, offset
end
local function platform_logout(tvb, offset, datatree)
local platform_logout_info = {}
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 6
if (GBT32960_info.data_unit_len < 0) then
return
end
platform_logout_info.data_collection_time = get_time(tvb, offset, datatree)
offset = offset + 6
-- platform_logout_info.serial_number = string.byte(tvb, offset) * 256 + string.byte(tvb, offset + 1)
GBT32960_info.data_unit_len = GBT32960_info.data_unit_len - 2
if (GBT32960_info.data_unit_len < 0) then
return
end
datatree:add(fields.sequence, tvb(offset, 2))
offset = offset + 2
return offset
end
local function GBT32960_identify(tvb)
-- 解析 ##
local offset = 0
if tvb(offset, 1):uint() ~= 0x23 or tvb(offset+1, 1):uint() ~= 0x23 then
return false
end
-- 判断长度
local length = tvb:len()
if (length < 25) then
return false
end
offset = offset + 22
local data_unit_len = tvb(offset, 2):uint()
if length < 25 + data_unit_len then
return false
end
return true
end
local function dissector_command_unit(tvb, offset)
-- 解析命令标识
GBT32960_info.command_id = tvb(offset, 1)
offset = offset + 1
-- 解析应答标志
GBT32960_info.reply_id = tvb(offset, 1)
if GBT32960_info.reply_id:uint() ~= 0x01 and GBT32960_info.reply_id:uint() ~= 0x02 and GBT32960_info.reply_id:uint() ~= 0x03 and
GBT32960_info.reply_id:uint() ~= 0xFE then
-- 0x01 响应成功
-- 0x02 响应修改错
-- 0x03 响应VIN重复
-- 0xFE 次数据为命令包而非应答包
-- 非标准协议response_menu在vin之后
print("1st reply id: "..GBT32960_info.reply_id:uint())
GBT32960_info.version = is_GBTXXXXX
GBT32960_info.reply_id = tvb(offset + 17, 1)
-- if GBT32960_info.reply_id:uint() ~= 0x01 and GBT32960_info.reply_id:uint() ~= 0x02 and GBT32960_info.reply_id:uint() ~= 0x03 and
-- GBT32960_info.reply_id:uint() ~= 0xFE then
-- print("2nd reply id: "..GBT32960_info.reply_id:uint())
-- -- 非标准协议response_menu在vin之后的第二个字段
-- GBT32960_info.reply_id = tvb(offset + 18, 1)
-- if GBT32960_info.reply_id:uint() ~= 0x01 and GBT32960_info.reply_id:uint() ~= 0x02 and GBT32960_info.reply_id:uint() ~= 0x03 and
-- GBT32960_info.reply_id:uint() ~= 0xFE then
-- print("3th reply id: "..GBT32960_info.reply_id:uint())
-- return false, offset
-- else
-- GBT32960_info.is_reply_id_rear = 2
-- end
-- else
-- GBT32960_info.is_reply_id_rear = 1
-- end
GBT32960_info.is_reply_id_rear = 1
else
GBT32960_info.version = is_GBT32960
offset = offset + 1
end
if GBT32960_info.reply_id == 0XFE then
GBT32960_info.msg_type = is_command
else
GBT32960_info.msg_type = is_reply
end
if GBT32960_info.command_id:uint() == 3 then
GBT32960_info.version = is_GBT32960
end
return true, offset
end
local function check_vin(data)
-- 根据GB16735
-- VIN 长度是17位
-- VIN 最后3位一定是数字
-- VIN 第9位为校验码 0~9 或者 X
-- VIN 不会出现IO, Q
local data_len = string.len(data)
if data_len ~= 17 then
return false
end
if not tonumber(string.sub(data, -3, -1)) then
return false
end
if string.find(data, "I" or "O" or "Q") then
return false
end
if (string.byte( data, 9 ) > string.byte('9') or string.byte(data, 9) < string.byte('0')) and string.byte(data, 9) ~= string.byte('X') then
return false
end
return true
end
local command_name_mt = {
__index = function(...)
return { name = "Unknown", dissector = function(...) end }
end
}
local command_name_GBT32960 = {
[1] = {name = "Vehicle login", dissector = vehicle_login},
[2] = {name = "Real-time information report", dissector = realtime_information_report},
[3] = {name = "Reissue_information_report", dissector = Reissue_information_report},
[4] = {name = "Vehicle logout", dissector = vehicle_logout},
[5] = {name = "Platform login", dissector = platform_login},
[6] = {name = "Platform logout", dissector = platform_logout}
}
setmetatable(command_name_GBT32960, command_name_mt)
-- local command_name_GBTXXXXX = {
-- [1] = {name = "Vehicle login", dissector = vehicle_login},
-- [2] = {name = "Real-time information report", dissector = realtime_information_report},
-- [4] = {name = "Reissue_information_report", dissector = Reissue_information_report},
-- [5] = {name = "Vehicle_logout", dissector = vehicle_logout},
-- [6] = {name = "Platform_login", dissector = platform_login},
-- [7] = {name = "Platform_logout", dissector = platform_logout}
-- }
-- 解析函数
function GBT32960.dissector(tvb, pinfo, tree)
local offset = 0
if not GBT32960_identify(tvb) then
print("Identify failed...")
return
end
offset = offset + 2
-- 显示协议名称
pinfo.cols.protocol = GBT32960.name
local subtree = tree:add(GBT32960, tvb(), "GBT32960 Protocol")
-- 分别显示出每个字段值
local ret = false
-- command unit
ret, offset = dissector_command_unit(tvb, offset)
if not ret then
print("command unit failed...")
return
end
local cmd_name = ""
-- if GBT32960_info.version == is_GBT32960 then
-- cmd_name = command_name_GBT32960[GBT32960_info.command_id:uint()].name
-- -- else
-- -- cmd_name = command_name_GBTXXXXX[GBT32960_info.command_id:uint()].name
-- end
cmd_name = command_name_GBT32960[GBT32960_info.command_id:uint()].name
local reply_name = reply_name_GBT32960[GBT32960_info.reply_id:uint()]
subtree:add(fields.command_id, GBT32960_info.command_id):append_text("("..cmd_name..")")
subtree:add(fields.reply_id, GBT32960_info.reply_id):append_text("("..reply_name..")")
GBT32960_info.vin = tvb(offset, 17)
ret = check_vin(GBT32960_info.vin:string())
if not ret then
return
end
subtree:add(fields.vin, GBT32960_info.vin)
offset = offset + 17
if GBT32960_info.is_reply_id_rear == 1 then
offset = offset + 1
-- elseif GBT32960_info.is_reply_id_rear == 2 then
-- offset = offset + 2
end
-- 解析加密方式
local encryption = tvb(offset, 1):uint()
if (encryption < 0x01 or encryption > 0x03) and encryption ~= 0xFF then
encryption = tvb(offset+1, 1):uint()
if (encryption < 0x01 or encryption > 0x03) and encryption ~= 0xFF then
return
else
offset = offset + 1
end
end
subtree:add(fields.encryption, tvb(offset, 1))
offset = offset + 1
-- 解析数据单元长度
subtree:add(fields.data_unit_len, tvb(offset, 2))
GBT32960_info.data_unit_len = tvb(offset, 2):uint()
offset = offset + 2
if GBT32960_info.data_unit_len > 0 then
local datatree = subtree:add(GBT32960, tvb(offset), "GBT32960 Data unit")
-- if GBT32960_info.version == is_GBT32960 then
-- command_name_GBT32960[GBT32960_info.command_id:uint()].dissector(tvb, offset, datatree)
-- else
-- command_name_GBTXXXXX[GBT32960_info.command_id:uint()].dissector(tvb, offset, datatree)
-- end
command_name_GBT32960[GBT32960_info.command_id:uint()].dissector(tvb, offset, datatree)
end
end
--dump(DissectorTable.list())
--DissectorTable.get("tcp.port"):add(port, GBT32960)
DissectorTable.get("tcp.port"):add(19006, GBT32960)
DissectorTable.get("tcp.port"):add(35046, GBT32960)
DissectorTable.get("tcp.port"):add(8010, GBT32960)
DissectorTable.get("tcp.port"):add(9002, GBT32960)
DissectorTable.get("tcp.port"):add(1211, GBT32960)
DissectorTable.get("tcp.port"):add(7740, GBT32960)
DissectorTable.get("tcp.port"):add(9005, GBT32960)
DissectorTable.get("tcp.port"):add(4002, GBT32960)
DissectorTable.get("tcp.port"):add(3502, GBT32960)
DissectorTable.get("tcp.port"):add(5102, GBT32960)
DissectorTable.get("tcp.port"):add(8877, GBT32960)
DissectorTable.get("tcp.port"):add(7500, GBT32960)
DissectorTable.get("tcp.port"):add(9102, GBT32960)
DissectorTable.get("tcp.port"):add(8001, GBT32960)
DissectorTable.get("tcp.port"):add(8111, GBT32960)
DissectorTable.get("tcp.port"):add(10013, GBT32960)
DissectorTable.get("tcp.port"):add(9005, GBT32960)
DissectorTable.get("tcp.port"):add(21941, GBT32960)
DissectorTable.get("tcp.port"):add(20500, GBT32960)