906 lines
37 KiB
Lua
906 lines
37 KiB
Lua
-- создаем описание нового протокола
|
||
local egts_proto = Proto("egts", "EGTS")
|
||
|
||
-- настройки плагина
|
||
local default_settings = {
|
||
port = 5020
|
||
}
|
||
|
||
local EGTS_PT_RESPONSE = "EGTS_PT_RESPONSE"
|
||
local EGTS_PT_APPDATA = "EGTS_PT_APPDATA"
|
||
local EGTS_PT_SIGNED_APPDATA = "EGTS_PT_SIGNED_APPDATA"
|
||
|
||
local egts_packet_type = {
|
||
[0] = EGTS_PT_RESPONSE,
|
||
[1] = EGTS_PT_APPDATA,
|
||
[2] = EGTS_PT_SIGNED_APPDATA,
|
||
}
|
||
|
||
local egts_subrecord_type = {
|
||
[0] = "EGTS_SR_RECORD_RESPONSE",
|
||
[1] = "EGTS_SR_TERM_IDENTITY",
|
||
[9] = "EGTS_SR_RESULT_CODE",
|
||
[15] = "EGTS_SR_EGTSPLUS_DATA",
|
||
[16] = "EGTS_SR_POS_DATA",
|
||
[17] = "EGTS_SR_EXT_POS_DATA",
|
||
[18] = "EGTS_SR_AD_SENSORS_DATA",
|
||
[19] = "EGTS_SR_COUNTERS_DATA",
|
||
[20] = "EGTS_SR_STATE_DATA",
|
||
[22] = "EGTS_SR_LOOPIN_DATA",
|
||
[23] = "EGTS_SR_ABS_DIG_SENS_DATA",
|
||
[24] = "EGTS_SR_ABS_AN_SENS_DATA",
|
||
[25] = "EGTS_SR_ABS_CNTR_DATA",
|
||
[26] = "EGTS_SR_ABS_LOOPIN_DATA",
|
||
[27] = "EGTS_SR_LIQUID_LEVEL_SENSOR",
|
||
|
||
-- Список подзаписей сервиса EGTS_ECALL_SERVICE
|
||
--[20] = "EGTS_SR_ACCEL_DATA",
|
||
[40] = "EGTS_SR_RAW_MSD_DATA",
|
||
[62] = "EGTS_SR_TRACK_DATA",
|
||
|
||
-- Описание подзаписей сервиса EGTS_COMMAND_SERVICE
|
||
[51] = "EGTS_SR_COMМAND_DАТА",
|
||
}
|
||
|
||
local result_code = {
|
||
[0] = "EGTS_PC_OK",
|
||
[1] = "EGTS_PC_IN_PROGRESS",
|
||
[128] = "EGTS_PC_UNS_PROTOCOL",
|
||
[129] = "EGTS_PC_DECRYPT_ERROR",
|
||
[130] = "EGTS_PC_PROC_DENIED",
|
||
[131] = "EGTS_PC_INC_HEADERFORM",
|
||
[132] = "EGTS_PC_INC_DATAFORM",
|
||
[133] = "EGTS_PC_UNS_TYPE",
|
||
[134] = "EGTS_PC_NOTEN_PARAMS",
|
||
[135] = "EGTS_PC_DBL_PROC",
|
||
[136] = "EGTS_PC_PROC_SRC_DENIED",
|
||
[137] = "EGTS_PC_HEADERCRC_ERROR",
|
||
[138] = "EGTS_PC_DATACRC_ERROR",
|
||
[139] = "EGTS_PC_INVDATALEN",
|
||
[140] = "EGTS_PC_ROUTE_NFOUND",
|
||
[141] = "EGTS_PC_ROUTE_CLOSED",
|
||
[142] = "EGTS_PC_ROUTE_DENIED",
|
||
[143] = "EGTS_PC_INVADDR",
|
||
[144] = "EGTS_PC_TTLEXPIRED",
|
||
[145] = "EGTS_PC_NO_ACK",
|
||
[146] = "EGTS_PC_OBJ_NFOUND",
|
||
[147] = "EGTS_PC_EVNT_NFOUND",
|
||
[148] = "EGTS_PC_SRVC_NFOUND",
|
||
[149] = "EGTS_PC_SRVC_DENIED",
|
||
[150] = "EGTS_PC_SRVC_UNKN",
|
||
[151] = "EGTS_PC_AUTH_DENIED",
|
||
[152] = "EGTS_PC_ALREADY_EXISTS",
|
||
[153] = "EGTS_PC_ID_NFOUND",
|
||
[154] = "EGTS_PC_INC_DATETIME",
|
||
[155] = "EGTS_PC_IO_ERROR",
|
||
[156] = "EGTS_PC_NO_RES_AVAIL",
|
||
[157] = "EGTS_PC_MODULE_FAULT",
|
||
[158] = "EGTS_PC_MODULE_PWR_FLT",
|
||
[159] = "EGTS_PC_MODULE_PROC_FLT",
|
||
[160] = "EGTS_PC_MODULE_SW_FLT",
|
||
[161] = "EGTS_PC_MODULE_FW_FLT",
|
||
[162] = "EGTS_PC_MODULE_IO_FLT",
|
||
[163] = "EGTS_PC_MODULE_MEM_FLT",
|
||
[164] = "EGTS_PC_TEST_FAILED",
|
||
}
|
||
local command_srv_command_type = {
|
||
[0001] = "СT_COMCONF",
|
||
[0010] = "CT_MSGCONF",
|
||
[0011] = "CT_MSGFROM",
|
||
[0100] = "CT_MSGTO",
|
||
[0101] = "CT_COM",
|
||
[0110] = "CT_DELCOM",
|
||
[0111] = "CT_SUBREQ",
|
||
[1000] = "CT_DELIV",
|
||
}
|
||
local command_srv_command_confirmation_type = {
|
||
[0000] = "CC_OK",
|
||
[0001] = "CC_ERROR",
|
||
[0010] = "CC_ILL",
|
||
[0011] = "CC_DEL",
|
||
[0100] = "CC_NFOUND",
|
||
[0101] = "CC_NCONF",
|
||
[0110] = "CC_INPROG",
|
||
}
|
||
|
||
local command_srv_command_code = {
|
||
[0x0000] = "EGTS_RAW_DATA",
|
||
[0x0001] = "EGTS_TEST_MODE",
|
||
[0x0006] = "EGTS_CONFIG_RESET",
|
||
[0x0007] = "EGTS_SET_AUTH_CODE",
|
||
[0x0108] = "EGTS_RESTART",
|
||
[0x020D] = "EGTS_ECALL_TEST_NUMBER",
|
||
[0x0223] = "EGTS_ECALL_SMS_FALLBACK_NUMBER",
|
||
}
|
||
|
||
local header = {
|
||
|
||
prv = ProtoField.new("ProtocolVersion", "egts.prv", ftypes.UINT8, nil, base.DEC),
|
||
skid = ProtoField.new("SecurityKeyID", "egts.skid", ftypes.UINT8, nil, base.DEC),
|
||
prf = ProtoField.new("Prefix", "egts.prf", ftypes.UINT8, nil, base.DEC, 0xc0),
|
||
rte = ProtoField.new("Route", "egts.rte", ftypes.UINT8, nil, base.DEC, 0x20),
|
||
ena = ProtoField.new("Encryption alg", "egts.ena", ftypes.UINT8, nil, base.DEC, 0x18),
|
||
cmp = ProtoField.new("Compression", "egts.cmp", ftypes.UINT8, nil, base.DEC, 0x4),
|
||
prt = ProtoField.new("Priority", "egts.prt", ftypes.UINT8, nil, base.DEC, 0x3),
|
||
hl = ProtoField.new("Header length", "egts.hl", ftypes.UINT8, nil, base.DEC),
|
||
he = ProtoField.new("Header encoding", "egts.he", ftypes.UINT8, nil, base.DEC),
|
||
fdl = ProtoField.new("Frame data length", "egts.fdl", ftypes.UINT16, nil, base.DEC),
|
||
pid = ProtoField.new("Packet identifier", "egts.pid", ftypes.UINT16, nil, base.DEC),
|
||
pt = ProtoField.new("Packet type", "egts.pt", ftypes.UINT8, egts_packet_type, base.DEC),
|
||
pra = ProtoField.new("Peer address", "egts.pra", ftypes.UINT16, nil, base.DEC),
|
||
rca = ProtoField.new("Recipient address", "egts.rca", ftypes.UINT16, nil, base.DEC),
|
||
ttl = ProtoField.new("Time to live", "egts.ttl", ftypes.UINT8, nil, base.DEC),
|
||
hcs = ProtoField.new("Header checksum", "egts.hcs", ftypes.UINT8, nil, base.HEX),
|
||
sfrd = ProtoField.new("Services frame data", "egts.sfrd", ftypes.BYTES),
|
||
rpid = ProtoField.new("Response packetID", "egts.rpid", ftypes.UINT16, nil, base.DEC),
|
||
pr = ProtoField.new("Processing result", "egts.pr", ftypes.UINT8, nil, base.DEC),
|
||
rl = ProtoField.new("Record length", "egts.rl", ftypes.UINT16, nil, base.DEC),
|
||
rn = ProtoField.new("Record number", "egts.rn", ftypes.UINT16, nil, base.DEC),
|
||
ssod = ProtoField.new("Source service on device", "egts.ssod", ftypes.UINT8, nil, base.DEC, 0x80),
|
||
rsod = ProtoField.new("Recipient service on device", "egts.rsod", ftypes.UINT8, nil, base.DEC, 0x40),
|
||
grp = ProtoField.new("Group", "egts.grp", ftypes.UINT8, nil, base.DEC, 0x20),
|
||
rpr = ProtoField.new("Record processing priority", "egts.rpr", ftypes.UINT8, nil, base.DEC, 0x18),
|
||
tmfe = ProtoField.new("Time field exists", "egts.tmfe", ftypes.UINT8, nil, base.DEC, 0x4),
|
||
evfe = ProtoField.new("Event ID field exists", "egts.evfe", ftypes.UINT8, nil, base.DEC, 0x2),
|
||
obfe = ProtoField.new("Object ID field exists", "egts.obfe", ftypes.UINT8, nil, base.DEC, 0x1),
|
||
oid = ProtoField.new("Object identifier", "egts.oid", ftypes.UINT32, nil, base.DEC),
|
||
evid = ProtoField.new("Event identifier", "egts.evid", ftypes.UINT32, nil, base.DEC),
|
||
tm = ProtoField.new("Time", "egts.tm", ftypes.UINT32, nil, base.DEC),
|
||
sst = ProtoField.new("Source service type", "egts.sst", ftypes.UINT8, nil, base.DEC),
|
||
rst = ProtoField.new("Recipient service type", "egts.rst", ftypes.UINT8, nil, base.DEC),
|
||
rd = ProtoField.new("Record data", "egts.rd", ftypes.BYTES),
|
||
srt = ProtoField.new("Subrecord type", "egts.srt", ftypes.UINT8, egts_subrecord_type, base.DEC),
|
||
srl = ProtoField.new("Subrecord length", "egts.srl", ftypes.UINT16, nil, base.DEC),
|
||
srd = ProtoField.new("Subrecord data", "egts.srd", ftypes.STRING),
|
||
crn = ProtoField.new("Confirmed record number", "egts.crn", ftypes.UINT16, nil, base.DEC),
|
||
rs = ProtoField.new("Record status", "egts.rs", ftypes.UINT8, result_code, base.DEC),
|
||
tid = ProtoField.new("Terminal identifier", "egts.tid", ftypes.UINT32, nil, base.DEC),
|
||
mne = ProtoField.new("MNE", "egts.mne", ftypes.UINT8, nil, base.DEC, 0x80),
|
||
bse = ProtoField.new("BSE", "egts.bse", ftypes.UINT8, nil, base.DEC, 0x40),
|
||
nide = ProtoField.new("NIDE", "egts.nide", ftypes.UINT8, nil, base.DEC, 0x20),
|
||
ssra = ProtoField.new("SSRA", "egts.ssra", ftypes.UINT8, nil, base.DEC, 0x10),
|
||
lngce = ProtoField.new("LNGCE", "egts.lngce", ftypes.UINT8, nil, base.DEC, 0x8),
|
||
imsie = ProtoField.new("IMSIE", "egts.imsie", ftypes.UINT8, nil, base.DEC, 0x4),
|
||
imeie = ProtoField.new("IMEIE", "egts.imeie", ftypes.UINT8, nil, base.DEC, 0x2),
|
||
hdide = ProtoField.new("HDIDE", "egts.hdide", ftypes.UINT8, nil, base.DEC, 0x1),
|
||
hdid = ProtoField.new("Home dispatcher identifier", "egts.hdid", ftypes.UINT16, nil, base.DEC),
|
||
imei = ProtoField.new("International mobile equipment identity", "egts.imei", ftypes.STRING),
|
||
imsi = ProtoField.new("International mobile subscriber identity", "egts.imsi", ftypes.STRING),
|
||
lngc = ProtoField.new("Language code", "egts.lngc", ftypes.STRING),
|
||
nid = ProtoField.new("Network identifier", "egts.nid", ftypes.UINT32, nil, base.DEC),
|
||
bs = ProtoField.new("Buffer size", "egts.bs", ftypes.UINT32, nil, base.DEC),
|
||
msisdn = ProtoField.new("Mobile station integrated services digital network number", "egts.msisdn", ftypes.STRING),
|
||
ntm = ProtoField.new("Navigation time", "egts.ntm", ftypes.ABSOLUTE_TIME),
|
||
lat = ProtoField.new("Latitude", "egts.lat", ftypes.DOUBLE),
|
||
long = ProtoField.new("Longitude", "egts.long", ftypes.DOUBLE),
|
||
alte = ProtoField.new("ALTE", "egts.alte", ftypes.UINT8, nil, base.DEC, 0x80),
|
||
lohs = ProtoField.new("LONS", "egts.lohs", ftypes.UINT8, nil, base.DEC, 0x40),
|
||
lahs = ProtoField.new("LAHS", "egts.lahs", ftypes.UINT8, nil, base.DEC, 0x20),
|
||
mv = ProtoField.new("MV", "egts.mv", ftypes.UINT8, nil, base.DEC, 0x10),
|
||
bb = ProtoField.new("BB", "egts.bb", ftypes.UINT8, nil, base.DEC, 0x8),
|
||
cs = ProtoField.new("CS", "egts.cs", ftypes.UINT8, nil, base.DEC, 0x4),
|
||
fix = ProtoField.new("FIX", "egts.fix", ftypes.UINT8, nil, base.DEC, 0x2),
|
||
vld = ProtoField.new("VLD", "egts.vld", ftypes.UINT8, nil, base.DEC, 0x1),
|
||
dirh = ProtoField.new("Direction the Highest bit", "egts.dirh", ftypes.UINT16, nil, base.DEC, 0x8000),
|
||
alts = ProtoField.new("Altitude sign", "egts.alts", ftypes.UINT16, nil, base.DEC, 0x4000),
|
||
spd = ProtoField.new("Speed", "egts.spd", ftypes.UINT16, nil, base.DEC, 0x3fff),
|
||
dir = ProtoField.new("Direction", "egts.dir", ftypes.UINT8, nil, base.DEC),
|
||
odm = ProtoField.new("Odometer", "egts.odm", ftypes.UINT32, nil, base.DEC),
|
||
din = ProtoField.new("Digital inputs", "egts.din", ftypes.UINT8, nil, base.DEC),
|
||
src = ProtoField.new("Source", "egts.src", ftypes.UINT8, nil, base.DEC),
|
||
alt = ProtoField.new("Altitude", "egts.alt", ftypes.UINT32, nil, base.DEC),
|
||
srcd = ProtoField.new("Source data", "egts.srcd", ftypes.UINT16, nil, base.DEC),
|
||
nsfe = ProtoField.new("NSFE", "egts.nsfe", ftypes.UINT8, nil, base.DEC, 0x10),
|
||
sfe = ProtoField.new("SFE", "egts.sfe", ftypes.UINT8, nil, base.DEC, 0x8),
|
||
pfe = ProtoField.new("PFE", "egts.pfe", ftypes.UINT8, nil, base.DEC, 0x4),
|
||
hfe = ProtoField.new("HFE", "egts.hfe", ftypes.UINT8, nil, base.DEC, 0x2),
|
||
vfe = ProtoField.new("VFE", "egts.vfe", ftypes.UINT8, nil, base.DEC, 0x1),
|
||
vdop = ProtoField.new("Vertical dilution of precision", "egts.vdop", ftypes.UINT16, nil, base.DEC),
|
||
hdop = ProtoField.new("Horizontal dilution of precision", "egts.hdop", ftypes.UINT16, nil, base.DEC),
|
||
pdop = ProtoField.new("Position dilution of precision", "egts.pdop", ftypes.UINT16, nil, base.DEC),
|
||
sat = ProtoField.new("Satellites", "egts.sat", ftypes.UINT8, nil, base.DEC),
|
||
ns = ProtoField.new("Navigation system", "egts.ns", ftypes.UINT16, nil, base.DEC),
|
||
st = ProtoField.new("State", "egts.ns", ftypes.UINT8, nil, base.DEC),
|
||
mpsv = ProtoField.new("Main power source voltage", "egts.mpsv", ftypes.UINT8, nil, base.DEC),
|
||
bbv = ProtoField.new("Back up battery voltage", "egts.bbv", ftypes.UINT8, nil, base.DEC),
|
||
ibv = ProtoField.new("Internal battery voltage", "egts.ibv", ftypes.UINT8, nil, base.DEC),
|
||
nms = ProtoField.new("NMS", "egts.nms", ftypes.UINT8, nil, base.DEC, 0x4),
|
||
ibu = ProtoField.new("IBU", "egts.ibu", ftypes.UINT8, nil, base.DEC, 0x2),
|
||
bbu = ProtoField.new("BBU", "egts.bbu", ftypes.UINT8, nil, base.DEC, 0x1),
|
||
sfrcs = ProtoField.new("Services frame data checksum", "egts.sfrcs", ftypes.UINT16, nil, base.HEX),
|
||
llsef = ProtoField.new("Liquid Level Sensor Error Flag", "egts.llsef", ftypes.UINT8, nil, base.DEC, 0x40),
|
||
llsvu = ProtoField.new("Liquid Level Sensor Value Unit", "egts.llsvu", ftypes.UINT8, nil, base.DEC, 0x30),
|
||
rdf = ProtoField.new("Raw Data Flag", "egts.rdf", ftypes.UINT8, nil, base.DEC, 0x8),
|
||
llsn = ProtoField.new("Liquid Level Sensor Number", "egts.llsn", ftypes.UINT8, nil, base.DEC, 0x7),
|
||
maddr = ProtoField.new("Module address", "egts.maddr", ftypes.UINT16, nil, base.DEC),
|
||
llsd = ProtoField.new("Liquid Level Sensor Data", "egts.llsd", ftypes.UINT32, nil, base.DEC),
|
||
llsdraw = ProtoField.new("Liquid Level Sensor Data bytes", "egts.llsdraw", ftypes.STRING),
|
||
dioe1 = ProtoField.new("Digital Inputs Octet Exists 1", "egts.dioe1", ftypes.UINT8, nil, base.DEC, 0x1),
|
||
dioe2 = ProtoField.new("Digital Inputs Octet Exists 2", "egts.dioe2", ftypes.UINT8, nil, base.DEC, 0x2),
|
||
dioe3 = ProtoField.new("Digital Inputs Octet Exists 3", "egts.dioe3", ftypes.UINT8, nil, base.DEC, 0x4),
|
||
dioe4 = ProtoField.new("Digital Inputs Octet Exists 4", "egts.dioe4", ftypes.UINT8, nil, base.DEC, 0x8),
|
||
dioe5 = ProtoField.new("Digital Inputs Octet Exists 5", "egts.dioe5", ftypes.UINT8, nil, base.DEC, 0x10),
|
||
dioe6 = ProtoField.new("Digital Inputs Octet Exists 6", "egts.dioe6", ftypes.UINT8, nil, base.DEC, 0x20),
|
||
dioe7 = ProtoField.new("Digital Inputs Octet Exists 7", "egts.dioe7", ftypes.UINT8, nil, base.DEC, 0x40),
|
||
dioe8 = ProtoField.new("Digital Inputs Octet Exists 8", "egts.dioe8", ftypes.UINT8, nil, base.DEC, 0x80),
|
||
dout = ProtoField.new("Digital Outputs", "egts.dout", ftypes.UINT8, nil, base.DEC),
|
||
asfe1 = ProtoField.new("Analog Sensor Fields Exist 1", "egts.asfe1", ftypes.UINT8, nil, base.DEC, 0x1),
|
||
asfe2 = ProtoField.new("Analog Sensor Fields Exist 2", "egts.asfe2", ftypes.UINT8, nil, base.DEC, 0x2),
|
||
asfe3 = ProtoField.new("Analog Sensor Fields Exist 3", "egts.asfe3", ftypes.UINT8, nil, base.DEC, 0x4),
|
||
asfe4 = ProtoField.new("Analog Sensor Fields Exist 4", "egts.asfe4", ftypes.UINT8, nil, base.DEC, 0x8),
|
||
asfe5 = ProtoField.new("Analog Sensor Fields Exist 5", "egts.asfe5", ftypes.UINT8, nil, base.DEC, 0x10),
|
||
asfe6 = ProtoField.new("Analog Sensor Fields Exist 6", "egts.asfe6", ftypes.UINT8, nil, base.DEC, 0x20),
|
||
asfe7 = ProtoField.new("Analog Sensor Fields Exist 7", "egts.asfe7", ftypes.UINT8, nil, base.DEC, 0x40),
|
||
asfe8 = ProtoField.new("Analog Sensor Fields Exist 8", "egts.asfe8", ftypes.UINT8, nil, base.DEC, 0x80),
|
||
adio1 = ProtoField.new("Additional Digital Inputs Octet 1", "egts.adio1", ftypes.UINT8, nil, base.DEC),
|
||
adio2 = ProtoField.new("Additional Digital Inputs Octet 2", "egts.adio2", ftypes.UINT8, nil, base.DEC),
|
||
adio3 = ProtoField.new("Additional Digital Inputs Octet 3", "egts.adio3", ftypes.UINT8, nil, base.DEC),
|
||
adio4 = ProtoField.new("Additional Digital Inputs Octet 4", "egts.adio4", ftypes.UINT8, nil, base.DEC),
|
||
adio5 = ProtoField.new("Additional Digital Inputs Octet 5", "egts.adio5", ftypes.UINT8, nil, base.DEC),
|
||
adio6 = ProtoField.new("Additional Digital Inputs Octet 6", "egts.adio6", ftypes.UINT8, nil, base.DEC),
|
||
adio7 = ProtoField.new("Additional Digital Inputs Octet 7", "egts.adio7", ftypes.UINT8, nil, base.DEC),
|
||
adio8 = ProtoField.new("Additional Digital Inputs Octet 8", "egts.adio8", ftypes.UINT8, nil, base.DEC),
|
||
ans1 = ProtoField.new("Analog Sensor 1", "egts.ans1", ftypes.UINT16, nil, base.DEC),
|
||
ans2 = ProtoField.new("Analog Sensor 2", "egts.ans2", ftypes.UINT16, nil, base.DEC),
|
||
ans3 = ProtoField.new("Analog Sensor 3", "egts.ans3", ftypes.UINT16, nil, base.DEC),
|
||
ans4 = ProtoField.new("Analog Sensor 4", "egts.ans4", ftypes.UINT16, nil, base.DEC),
|
||
ans5 = ProtoField.new("Analog Sensor 5", "egts.ans5", ftypes.UINT16, nil, base.DEC),
|
||
ans6 = ProtoField.new("Analog Sensor 6", "egts.ans6", ftypes.UINT16, nil, base.DEC),
|
||
ans7 = ProtoField.new("Analog Sensor 7", "egts.ans7", ftypes.UINT16, nil, base.DEC),
|
||
ans8 = ProtoField.new("Analog Sensor 8", "egts.ans8", ftypes.UINT16, nil, base.DEC),
|
||
cn = ProtoField.new("Counter Number", "egts.cn", ftypes.UINT8, nil, base.DEC),
|
||
cnv = ProtoField.new("Counter Value", "egts.cnv", ftypes.UINT16, nil, base.DEC),
|
||
-- EGTS_SR_COMMAND_DATA
|
||
CT = ProtoField.new("Command Type", "egts.CT", ftypes.UINT8, command_srv_command_type, base.DEC, 0xF0),
|
||
CCT = ProtoField.new("Command Confirmation Type", "egts.CCT", ftypes.UINT8, command_srv_command_confirmation_type, base.DEC, 0x0F),
|
||
CID = ProtoField.new("Command Identifier", "egts.CID", ftypes.UINT32, nil, base.DEC),
|
||
SID = ProtoField.new("Source Identifier", "egts.SID", ftypes.UINT32, nil, base.DEC),
|
||
|
||
ACFE = ProtoField.new("Authorization Code Field Exist", "egts.ACFE", ftypes.UINT8, nil, base.DEC, 0x02),
|
||
CHSFE = ProtoField.new("Charset Field Exists", "egts.CHSFE", ftypes.UINT8, nil, base.DEC, 0x01),
|
||
|
||
CHS = ProtoField.new("Charset", "egts.CHS", ftypes.UINT8, nil, base.DEC),
|
||
ACL = ProtoField.new("Authorization Code Length", "egts.ACL", ftypes.UINT8, nil, base.DEC),
|
||
AC = ProtoField.new("Authorization Code", "egts.AC", ftypes.STRING),
|
||
|
||
ADR = ProtoField.new("Address", "egts.ADR", ftypes.UINT16, nil, base.DEC),
|
||
|
||
SZ = ProtoField.new("Size", "egts.SZ", ftypes.UINT8, nil, base.DEC, 0xF0),
|
||
ACT = ProtoField.new("Action", "egts.ACT", ftypes.UINT8, nil, base.DEC, 0x0F),
|
||
|
||
CCD = ProtoField.new("Command Code", "egts.CCD", ftypes.UINT16, command_srv_command_code, base.HEX),
|
||
|
||
DT = ProtoField.new("Data", "egts.DT", ftypes.STRING),
|
||
}
|
||
|
||
|
||
|
||
-- регистрация полей протокола
|
||
egts_proto.fields = header
|
||
|
||
local function parse_sr_command_data_body(buf, tree)
|
||
local cur_offset = 0
|
||
|
||
tree:add(header.ADR, buf:range(cur_offset, 2):le_uint())
|
||
cur_offset = cur_offset + 2
|
||
|
||
local sub = buf:range(cur_offset, 1):le_uint()
|
||
tree:add(header.SZ, sub)
|
||
tree:add(header.ACT, sub)
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.CCD, buf:range(cur_offset, 2):le_uint())
|
||
cur_offset = cur_offset + 2
|
||
|
||
if cur_offset < buf:len() then
|
||
tree:add(header.DT, buf:range(cur_offset))
|
||
end
|
||
|
||
end
|
||
|
||
local function parse_sr_command_data(buf, tree)
|
||
local cur_offset = 0
|
||
|
||
local types = buf:range(cur_offset, 1):le_uint()
|
||
tree:add(header.CT, types)
|
||
tree:add(header.CCT, types)
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.CID, buf:range(cur_offset, 4):le_uint())
|
||
cur_offset = cur_offset + 4
|
||
|
||
tree:add(header.SID, buf:range(cur_offset, 4):le_uint())
|
||
cur_offset = cur_offset + 4
|
||
|
||
local flags = buf:range(cur_offset, 1):le_uint()
|
||
tree:add(header.ACFE, flags)
|
||
tree:add(header.CHSFE, flags)
|
||
cur_offset = cur_offset + 1
|
||
|
||
if bit.band(flags, 0x1) ~= 0 then
|
||
tree:add(header.CHS, buf:range(cur_offset, 1):le_uint())
|
||
cur_offset = cur_offset + 1
|
||
end
|
||
|
||
if bit.band(flags, 0x2) ~= 0 then
|
||
local len = buf:range(cur_offset, 1):le_uint();
|
||
tree:add(header.ACL, len)
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.AC, buf:range(cur_offset, len))
|
||
cur_offset = cur_offset + len
|
||
|
||
end
|
||
|
||
--tree:add(header.srd, buf:range(cur_offset):bytes():tohex())
|
||
|
||
local cmd_data = buf:range(cur_offset)
|
||
|
||
local cmd = tree:add(egts_proto, cmd_data, "Subrecord data")
|
||
|
||
parse_sr_command_data_body(cmd_data, cmd);
|
||
|
||
return buf:len()
|
||
end
|
||
|
||
local MIN_HEADE_LENGHT = 11
|
||
|
||
local function get_packet_type(type_id)
|
||
return egts_packet_type[type_id]
|
||
end
|
||
|
||
local function get_egts_length(tvbuf, pktinfo, offset)
|
||
local header_len = tvbuf:range(offset + 3, 1):uint()
|
||
local data_len = tvbuf:range(offset + 5, 2):le_uint()
|
||
|
||
return header_len + data_len + 2
|
||
end
|
||
|
||
local function parse_sr_response(buf, tree)
|
||
local cur_offset = 0
|
||
|
||
tree:add(header.crn, buf:range(cur_offset, 2):le_uint())
|
||
cur_offset = cur_offset + 2
|
||
|
||
tree:add(header.rs, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
return buf:len()
|
||
end
|
||
|
||
local function parse_sr_term_identity(buf, tree)
|
||
local cur_offset = 0
|
||
|
||
tree:add(header.tid, buf:range(cur_offset, 4):le_uint())
|
||
cur_offset = cur_offset + 4
|
||
|
||
local flags = buf:range(cur_offset, 1):le_uint()
|
||
tree:add(header.mne, flags)
|
||
tree:add(header.bse, flags)
|
||
tree:add(header.nide, flags)
|
||
tree:add(header.ssra, flags)
|
||
tree:add(header.lngce, flags)
|
||
tree:add(header.imsie, flags)
|
||
tree:add(header.imeie, flags)
|
||
tree:add(header.hdide, flags)
|
||
cur_offset = cur_offset + 1
|
||
|
||
if bit.band(flags, 0x1) ~= 0 then
|
||
tree:add(header.hdid, buf:range(cur_offset, 2):uint())
|
||
cur_offset = cur_offset + 2
|
||
end
|
||
|
||
if bit.band(flags, 0x2) ~= 0 then
|
||
tree:add(header.imei, buf:range(cur_offset, 15):string())
|
||
cur_offset = cur_offset + 15
|
||
end
|
||
|
||
if bit.band(flags, 0x4) ~= 0 then
|
||
tree:add(header.imsi, buf:range(cur_offset, 16):string())
|
||
cur_offset = cur_offset + 16
|
||
end
|
||
|
||
if bit.band(flags, 0x8) ~= 0 then
|
||
tree:add(header.lngc, buf:range(cur_offset, 3):string())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
if bit.band(flags, 0x20) ~= 0 then
|
||
tree:add(header.nid, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
if bit.band(flags, 0x40) ~= 0 then
|
||
tree:add(header.bs, buf:range(cur_offset, 2):le_uint())
|
||
cur_offset = cur_offset + 2
|
||
end
|
||
|
||
if bit.band(flags, 0x80) ~= 0 then
|
||
tree:add(header.msisdn, buf:range(cur_offset, 15):le_uint())
|
||
cur_offset = cur_offset + 15
|
||
end
|
||
|
||
return cur_offset
|
||
end
|
||
|
||
local function parse_sr_pos_data(buf, tree)
|
||
local cur_offset = 0
|
||
|
||
local ntm = buf:range(cur_offset, 4):le_uint()
|
||
local offset_time = os.time { year = 2010, month = 1, day = 1, hour = 0 }
|
||
ntm = ntm + offset_time
|
||
|
||
tree:add(header.ntm, NSTime.new(ntm))
|
||
cur_offset = cur_offset + 4
|
||
|
||
tree:add(header.lat, buf:range(cur_offset, 4):le_uint() * 90 / 0xFFFFFFFF)
|
||
cur_offset = cur_offset + 4
|
||
|
||
tree:add(header.long, buf:range(cur_offset, 4):le_uint() * 180 / 0xFFFFFFFF)
|
||
cur_offset = cur_offset + 4
|
||
|
||
local flg = buf:range(cur_offset, 1):uint()
|
||
tree:add(header.alte, flg)
|
||
tree:add(header.lohs, flg)
|
||
tree:add(header.lahs, flg)
|
||
tree:add(header.mv, flg)
|
||
tree:add(header.bb, flg)
|
||
tree:add(header.cs, flg)
|
||
tree:add(header.fix, flg)
|
||
tree:add(header.vld, flg)
|
||
cur_offset = cur_offset + 1
|
||
|
||
local spd = buf:range(cur_offset, 2):le_uint()
|
||
tree:add(header.dirh, spd)
|
||
tree:add(header.alts, spd)
|
||
tree:add(header.spd, spd)
|
||
cur_offset = cur_offset + 2
|
||
|
||
tree:add(header.dir, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.odm, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
|
||
tree:add(header.din, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.src, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
if bit.band(flg, 0x80) ~= 0 then
|
||
tree:add(header.alt, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
-- TODO: разобраться с разбором SourceData
|
||
return buf:len()
|
||
end
|
||
|
||
local function parse_sr_ext_pos_data(buf, tree)
|
||
local cur_offset = 0
|
||
local flags = buf:range(cur_offset, 1):uint()
|
||
tree:add(header.nsfe, flags)
|
||
tree:add(header.sfe, flags)
|
||
tree:add(header.pfe, flags)
|
||
tree:add(header.hfe, flags)
|
||
tree:add(header.vfe, flags)
|
||
cur_offset = cur_offset + 1
|
||
|
||
if bit.band(flags, 0x1) ~= 0 then
|
||
-- если флаг VFE установлен, то есть поле снижение точности в вертикальной плоскости
|
||
tree:add(header.vdop, buf:range(cur_offset, 2):le_uint())
|
||
cur_offset = cur_offset + 2
|
||
end
|
||
|
||
if bit.band(flags, 0x2) ~= 0 then
|
||
-- если флаг HFE установлен, то есть поле снижение точности в горизонтальной плоскости
|
||
tree:add(header.hdop, buf:range(cur_offset, 2):le_uint())
|
||
cur_offset = cur_offset + 2
|
||
end
|
||
|
||
if bit.band(flags, 0x4) ~= 0 then
|
||
-- если флаг HFE установлен, то есть поле снижение точности по местоположению
|
||
tree:add(header.pdop, buf:range(cur_offset, 2):le_uint())
|
||
cur_offset = cur_offset + 2
|
||
end
|
||
|
||
local sectionLen = buf:len()
|
||
if bit.band(flags, 0x8) ~= 0 then
|
||
-- если флаг SFE установлен, то есть поле c данными о текущем количестве видимых спутников и типе используемой навигационной спутниковой системы
|
||
tree:add(header.sat, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
if cur_offset < sectionLen then
|
||
tree:add(header.ns, buf:range(cur_offset, 2):le_uint())
|
||
cur_offset = cur_offset + 2
|
||
end
|
||
end
|
||
|
||
return sectionLen
|
||
end
|
||
|
||
local function parse_sr_state_data(buf, tree)
|
||
local cur_offset = 0
|
||
|
||
tree:add(header.st, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.mpsv, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.bbv, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.ibv, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
local flags = buf:range(cur_offset, 1):uint()
|
||
tree:add(header.nms, flags)
|
||
tree:add(header.ibu, flags)
|
||
tree:add(header.bbu, flags)
|
||
cur_offset = cur_offset + 1
|
||
|
||
return cur_offset
|
||
end
|
||
|
||
local function parse_sr_liquid_level_sensor(buf, tree)
|
||
local cur_offset = 0
|
||
|
||
local flags = buf:range(cur_offset, 1):uint()
|
||
tree:add(header.llsef, flags)
|
||
tree:add(header.llsvu, flags)
|
||
tree:add(header.rdf, flags)
|
||
tree:add(header.llsn, flags)
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.maddr, buf:range(cur_offset, 2):le_uint())
|
||
cur_offset = cur_offset + 2
|
||
|
||
if bit.band(flags, 0x8) == 0 then
|
||
-- если флаг RDF флаг установлен, то значение имеет длину 4 байта
|
||
tree:add(header.llsd, buf:range(cur_offset, 4):le_uint())
|
||
cur_offset = cur_offset + 4
|
||
else
|
||
tree:add(header.llsdraw, buf:bytes():tohex())
|
||
end
|
||
|
||
return cur_offset
|
||
end
|
||
|
||
local function parse_sr_ad_sensors_data(buf, tree)
|
||
local cur_offset = 0
|
||
local sectionLen = buf:len()
|
||
|
||
local diflg = buf:range(cur_offset, 1):uint()
|
||
tree:add(header.dioe1, diflg)
|
||
tree:add(header.dioe2, diflg)
|
||
tree:add(header.dioe3, diflg)
|
||
tree:add(header.dioe4, diflg)
|
||
tree:add(header.dioe5, diflg)
|
||
tree:add(header.dioe6, diflg)
|
||
tree:add(header.dioe7, diflg)
|
||
tree:add(header.dioe8, diflg)
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.dout, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
local ansflg = buf:range(cur_offset, 1):uint()
|
||
tree:add(header.asfe1, ansflg)
|
||
tree:add(header.asfe2, ansflg)
|
||
tree:add(header.asfe3, ansflg)
|
||
tree:add(header.asfe4, ansflg)
|
||
tree:add(header.asfe5, ansflg)
|
||
tree:add(header.asfe6, ansflg)
|
||
tree:add(header.asfe7, ansflg)
|
||
tree:add(header.asfe8, ansflg)
|
||
cur_offset = cur_offset + 1
|
||
|
||
if bit.band(diflg, 0x1) ~= 0 then
|
||
tree:add(header.adio1, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
end
|
||
|
||
if bit.band(diflg, 0x2) ~= 0 then
|
||
tree:add(header.adio2, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
end
|
||
|
||
if bit.band(diflg, 0x4) ~= 0 then
|
||
tree:add(header.adio3, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
end
|
||
|
||
if bit.band(diflg, 0x8) ~= 0 then
|
||
tree:add(header.adio4, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
end
|
||
|
||
if bit.band(diflg, 0x10) ~= 0 then
|
||
tree:add(header.adio5, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
end
|
||
|
||
if bit.band(diflg, 0x20) ~= 0 then
|
||
tree:add(header.adio6, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
end
|
||
|
||
if bit.band(diflg, 0x40) ~= 0 then
|
||
tree:add(header.adio7, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
end
|
||
|
||
if bit.band(diflg, 0x80) ~= 0 then
|
||
tree:add(header.adio8, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
end
|
||
|
||
if bit.band(ansflg, 0x1) ~= 0 then
|
||
tree:add(header.ans1, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
if bit.band(ansflg, 0x2) ~= 0 then
|
||
tree:add(header.ans2, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
if bit.band(ansflg, 0x4) ~= 0 then
|
||
tree:add(header.ans3, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
if bit.band(ansflg, 0x8) ~= 0 then
|
||
tree:add(header.ans4, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
if bit.band(ansflg, 0x10) ~= 0 then
|
||
tree:add(header.ans5, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
if bit.band(ansflg, 0x20) ~= 0 then
|
||
tree:add(header.ans6, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
if bit.band(ansflg, 0x40) ~= 0 then
|
||
tree:add(header.ans7, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
if bit.band(ansflg, 0x80) ~= 0 then
|
||
tree:add(header.ans8, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
end
|
||
|
||
return sectionLen
|
||
end
|
||
|
||
local function parse_sr_abs_cntr_data(buf, tree)
|
||
local cur_offset = 0
|
||
|
||
tree:add(header.cnv, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
tree:add(header.cnv, buf:range(cur_offset, 3):le_uint())
|
||
cur_offset = cur_offset + 3
|
||
|
||
return offset
|
||
end
|
||
|
||
local function parse_sr_result_code(buf, tree)
|
||
local cur_offset = 0
|
||
|
||
tree:add(header.rs, buf:range(cur_offset, 1):uint())
|
||
cur_offset = cur_offset + 1
|
||
|
||
return buf:len()
|
||
end
|
||
|
||
local function parse_subrecord(buf, tree)
|
||
local subrecords = tree:add(egts_proto, buf, "Record data")
|
||
local current_offset = 0
|
||
while current_offset < buf:len() do
|
||
local subrecord = subrecords:add(egts_proto, buf, "Subrecord")
|
||
|
||
local subrecord_type = buf:range(current_offset, 1):uint()
|
||
subrecord:add(header.srt, subrecord_type)
|
||
current_offset = current_offset + 1
|
||
|
||
local subrecord_data_len = buf:range(current_offset, 2):le_uint()
|
||
subrecord:add(header.srl, subrecord_data_len)
|
||
current_offset = current_offset + 2
|
||
|
||
local sr_data = buf:range(current_offset, subrecord_data_len)
|
||
|
||
local srd = subrecord:add(egts_proto, sr_data, "Subrecord data")
|
||
|
||
if subrecord_type == 0 then
|
||
parse_sr_response(sr_data, srd)
|
||
elseif subrecord_type == 1 then
|
||
parse_sr_term_identity(sr_data, srd)
|
||
elseif subrecord_type == 9 then
|
||
parse_sr_result_code(sr_data, srd)
|
||
elseif subrecord_type == 16 then
|
||
parse_sr_pos_data(sr_data, srd)
|
||
elseif subrecord_type == 17 then
|
||
parse_sr_ext_pos_data(sr_data, srd)
|
||
elseif subrecord_type == 20 then
|
||
parse_sr_state_data(sr_data, srd)
|
||
elseif subrecord_type == 27 then
|
||
parse_sr_liquid_level_sensor(sr_data, srd)
|
||
elseif subrecord_type == 18 then
|
||
parse_sr_ad_sensors_data(sr_data, srd)
|
||
elseif subrecord_type == 25 then
|
||
parse_sr_abs_cntr_data(sr_data, srd)
|
||
elseif subrecord_type == 51 then
|
||
parse_sr_command_data(sr_data, srd)
|
||
else
|
||
subrecord:add(header.srd, sr_data:bytes():tohex())
|
||
end
|
||
|
||
current_offset = current_offset + subrecord_data_len
|
||
end
|
||
|
||
return current_offset
|
||
end
|
||
|
||
local function parse_sdr(buf, tree)
|
||
local current_offset = 0
|
||
local sdr_len = 0
|
||
while (current_offset < buf:len()) do
|
||
sdr_len = buf:range(current_offset, 2):le_uint()
|
||
local service_data_record = tree:add(egts_proto, buf, "Service Data Record")
|
||
current_offset = current_offset + 2
|
||
|
||
service_data_record:add(header.rl, sdr_len)
|
||
service_data_record:add(header.rn, buf:range(current_offset, 2):le_uint())
|
||
current_offset = current_offset + 2
|
||
|
||
local rfl = buf:range(current_offset, 1):uint()
|
||
service_data_record:add(header.ssod, rfl)
|
||
service_data_record:add(header.rsod, rfl)
|
||
service_data_record:add(header.grp, rfl)
|
||
service_data_record:add(header.rpr, rfl)
|
||
service_data_record:add(header.tmfe, rfl)
|
||
service_data_record:add(header.evfe, rfl)
|
||
service_data_record:add(header.obfe, rfl)
|
||
current_offset = current_offset + 1
|
||
|
||
if bit.band(rfl, 0x1) ~= 0 then
|
||
-- если флаг OBFE установлен, то значит есть поле с id объекта и его надо заполнить
|
||
service_data_record:add(header.oid, buf:range(current_offset, 4):le_uint())
|
||
current_offset = current_offset + 4
|
||
end
|
||
|
||
if bit.band(rfl, 0x2) ~= 0 then
|
||
-- если флаг EVFE установлен, то значит присутствует поле с id события
|
||
service_data_record:add(header.evid, buf:range(current_offset, 4):le_uint())
|
||
current_offset = current_offset + 4
|
||
end
|
||
|
||
if bit.band(rfl, 0x4) ~= 0 then
|
||
-- если флаг TMFE установлен, то есть поле со временем, которое нужно разобрать
|
||
service_data_record:add(header.tm, buf:range(current_offset, 4):le_uint())
|
||
current_offset = current_offset + 4
|
||
end
|
||
|
||
service_data_record:add(header.sst, buf:range(current_offset, 1):uint())
|
||
current_offset = current_offset + 1
|
||
|
||
service_data_record:add(header.rst, buf:range(current_offset, 1):uint())
|
||
current_offset = current_offset + 1
|
||
|
||
local computed_bytes = parse_subrecord(buf:range(current_offset, sdr_len), service_data_record)
|
||
current_offset = current_offset + computed_bytes
|
||
end
|
||
|
||
return current_offset
|
||
end
|
||
|
||
local function parse_pt_response (buf, tree)
|
||
local current_offset = 0
|
||
tree:add(header.rpid, buf:range(current_offset, 2):le_uint())
|
||
current_offset = current_offset + 2
|
||
|
||
tree:add(header.pr, buf:range(current_offset, 1):uint())
|
||
current_offset = current_offset + 1
|
||
|
||
if buf:len() - current_offset > 0 then
|
||
local computed_bytes = parse_sdr(buf:range(current_offset), tree)
|
||
current_offset = current_offset + computed_bytes
|
||
end
|
||
|
||
return buf:len()
|
||
end
|
||
|
||
local function parse_pt_appdata (buf, tree)
|
||
local current_offset = 0
|
||
local computed_bytes = 0
|
||
while (current_offset < buf:len()) do
|
||
computed_bytes = parse_sdr(buf:range(current_offset), tree)
|
||
current_offset = current_offset + computed_bytes
|
||
end
|
||
|
||
return current_offset
|
||
end
|
||
|
||
local function parse_pt_signed_appdata (buf, tree)
|
||
tree:add(header.sfrd, buf:raw())
|
||
return buf:len()
|
||
end
|
||
|
||
local function dissect_egts_pdu(tvbuf, pktinfo, root)
|
||
local header_len = tvbuf:range(3, 1):uint()
|
||
local data_len = tvbuf:range(5, 2):le_uint()
|
||
local msglen = header_len + data_len + 2
|
||
|
||
pktinfo.cols.protocol:set("EGTS")
|
||
|
||
-- Начинаем заполнения дерева в отображении
|
||
local tree = root:add(egts_proto, tvbuf:range(0, msglen))
|
||
|
||
tree:add(header.prv, tvbuf:range(0, 1):uint())
|
||
tree:add(header.skid, tvbuf:range(1, 1):uint())
|
||
|
||
local prf_tvbr = tvbuf:range(2, 1):uint()
|
||
tree:add(header.prf, prf_tvbr)
|
||
tree:add(header.rte, prf_tvbr)
|
||
tree:add(header.ena, prf_tvbr)
|
||
tree:add(header.cmp, prf_tvbr)
|
||
tree:add(header.prt, prf_tvbr)
|
||
|
||
tree:add(header.hl, header_len)
|
||
tree:add(header.he, tvbuf:range(4, 1):uint())
|
||
|
||
tree:add(header.fdl, data_len)
|
||
tree:add(header.pid, tvbuf:range(7, 2):le_uint())
|
||
|
||
local packet_type_id = tvbuf:range(9, 1):uint()
|
||
tree:add(header.pt, packet_type_id)
|
||
|
||
local field_offset = 10;
|
||
|
||
if bit.band(prf_tvbr, 0x20) ~= 0 then
|
||
-- если RTE флаг присутствует, то заполняем не обязательные поля
|
||
|
||
tree:add(header.pra, tvbuf:range(field_offset, 2):le_uint())
|
||
field_offset = field_offset + 2
|
||
tree:add(header.rca, tvbuf:range(field_offset, 2):le_uint())
|
||
field_offset = field_offset + 2
|
||
tree:add(header.ttl, tvbuf:range(field_offset, 1):uint())
|
||
field_offset = field_offset + 1
|
||
end
|
||
tree:add(header.hcs, tvbuf:range(field_offset, 1):uint())
|
||
field_offset = field_offset + 1
|
||
|
||
local subtree = tree:add(egts_proto, tvbuf, "Services frame data")
|
||
if get_packet_type(packet_type_id) == EGTS_PT_RESPONSE then
|
||
parse_pt_response(tvbuf:range(field_offset, data_len), subtree)
|
||
elseif get_packet_type(packet_type_id) == EGTS_PT_APPDATA then
|
||
parse_pt_appdata(tvbuf:range(field_offset, data_len), subtree)
|
||
else
|
||
parse_pt_signed_appdata(tvbuf:range(field_offset, data_len), subtree)
|
||
end
|
||
|
||
tree:add(header.sfrcs, tvbuf:range(field_offset + data_len, 2):le_uint())
|
||
|
||
return msglen
|
||
end
|
||
|
||
-- задаем функию обработки, которая получает на вход данные tvbuf (объект Tvb), информацию о пакете
|
||
-- pktinfo (объект Pinfo) и root дерево распарсенного объекта.
|
||
function egts_proto.dissector(tvbuf, pktinfo, root)
|
||
dissect_tcp_pdus(tvbuf, root, MIN_HEADE_LENGHT, get_egts_length, dissect_egts_pdu)
|
||
local bytes_consumed = tvbuf:len()
|
||
return bytes_consumed
|
||
|
||
end
|
||
|
||
-- добавляем парсер в таблицу
|
||
DissectorTable.get("tcp.port"):add(default_settings.port, egts_proto)
|