-- 创建一个新的解析插件 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)