1000 lines
41 KiB
Lua
1000 lines
41 KiB
Lua
-- 创建一个新的解析插件
|
||
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 不会出现I,O, 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)
|