Skip to content

Commit

Permalink
1) VARLEN fields can now be anywhere in a message (not just at the en…
Browse files Browse the repository at this point in the history
…d of it). 2) Fields with the same name but different length are now allowed.
  • Loading branch information
prontog committed Jan 21, 2016
1 parent b5c880e commit 909832e
Showing 1 changed file with 67 additions and 34 deletions.
101 changes: 67 additions & 34 deletions src/ws_dissector_helper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,48 @@ local Field = {}

Field.repo = {}

-- Returns a ProtoField from the Field.repo. If it does not exist,
-- it is first created and added to the repo.
local function createProtoField(abbr, name, desc, len, type)
local len = len or ''
local type = type or ftypes.STRING
local len = len or ''
local type = type or 'STRING'

local ftype = nil
if type == 'NUMERIC' then
ftype = ftypes.FLOAT
else
ftype = ftypes.STRING
end

local repoFieldName = abbr
local f = Field.repo[repoFieldName]

local protoField = Field.repo[abbr .. len]
if not protoField then
--protoField = ProtoField.string(abbr, name, desc)
protoField = ProtoField.new(name, abbr, type, nil, nil, nil, descr)
Field.repo[abbr .. len] = protoField
-- If a field with the same abbr exists in the repo we need to check
-- the type and length as well. All three should much. Otherwise we
-- need to create a new ProtoField.
if f and f.len ~= len then
warn('A field with name ' .. f.name .. ' and different length already exists.')
repoFieldName = repoFieldName .. len
f = Field.repo[repoFieldName]
end

local protoField = nil

if f then
protoField = f.protoField
else
--print(repoFieldName)
protoField = ProtoField.new(name, repoFieldName, ftype, nil, nil, nil, descr)
--print('ok')
Field.repo[repoFieldName] = { name = name,
abbr = abbr,
len = len,
ftype = ftype,
descr = descr,
protoField = protoField }
end

return protoField
end

Expand Down Expand Up @@ -77,7 +109,7 @@ end

function Field.NUMERIC(len, abbr, name, desc, offset)
return {
proto = createProtoField(abbr, name, desc, len, ftypes.FLOAT),
proto = createProtoField(abbr, name, desc, len, 'NUMERIC'),
type = 'NUMERIC',
len = function()
return len
Expand All @@ -104,7 +136,7 @@ end

function Field.VARLEN(lenField, abbr, name, desc, offset)
return {
proto = createProtoField(abbr, name, desc),
proto = createProtoField(abbr, name, desc, lenField.abbr),
type = 'STRING',
lenField = lenField,
len = function(self, tvb)
Expand Down Expand Up @@ -282,36 +314,37 @@ local msgSpecToFieldSpec = function(id, description, msgSpec, header, trailer)
-- Create Field.X object for each field in the spec
local bodyFields = {}
for i, f in ipairs(msgSpec) do
-- Handle simple types.
if tonumber(f.len) then
local newField = nil
-- Handle simple types.
if f.fieldType == 'NUMERIC' then
bodyFields[#bodyFields + 1] = Field.NUMERIC(f.len, f.abbr, f.name, '', f.offset)
elseif f.fieldType == 'REPEATING' then
local lenField = fieldByAbbr(f.len, bodyFields)
assert(lenField, f.len .. ' does not match an existing abbr in message ' .. id)

if f.fieldType == 'NUMERIC' then
newField = Field.NUMERIC(f.len, f.abbr, f.name, '', f.offset)
else
newField = Field.STRING(f.len, f.abbr, f.name, '', f.offset)
local repeatingFields = {}
for ii = i + 1, #msgSpec do
local ff = msgSpec[ii]
if ff.fieldType == 'REPEATING-END' then

end
repeatingFields[#repeatingFields + 1] = Field.STRING(ff.len, ff.abbr, ff.name, '', ff.offset)
end
repeatingFields['title'] = f.name

bodyFields[#bodyFields + 1] = newField
else -- Hanlde complex types
local repeatingComposite = Field.COMPOSITE(repeatingFields)
bodyFields[#bodyFields + 1] = Field.REPEATING(lenField, repeatingComposite)
break
elseif f.fieldType == 'VARLEN' then
local lenField = fieldByAbbr(f.len, bodyFields)
assert(lenField, f.len .. ' does not match an existing abbr in message ' .. id)

if f.fieldType == 'REPEATING' then
local repeatingFields = {}
for ii = i + 1, #msgSpec do
local ff = msgSpec[ii]
repeatingFields[#repeatingFields + 1] = Field.STRING(ff.len, ff.abbr, ff.name, '', ff.offset)
end
repeatingFields['title'] = f.name

local repeatingComposite = Field.COMPOSITE(repeatingFields)
bodyFields[#bodyFields + 1] = Field.REPEATING(lenField, repeatingComposite)
break
elseif f.fieldType == 'VARLEN' then
bodyFields[#bodyFields + 1] = Field.VARLEN(lenField, f.abbr, f.name, '', f.offset)
break
end
bodyFields[#bodyFields + 1] = Field.VARLEN(lenField,
f.abbr,
f.name,
'',
f.offset)
else -- Everything else will become Field.STRING
bodyFields[#bodyFields + 1] = Field.STRING(f.len, f.abbr, f.name, '', f.offset)
end
end
bodyFields['title'] = 'Body'
Expand Down Expand Up @@ -479,9 +512,9 @@ local function createProtoHelper(proto)
msgParsers[v.name] = self:createParser(msgSpecs[v.name])
end

for i, protoField in pairs(Field.repo) do
for i, f in pairs(Field.repo) do
self:trace('Adding ' .. i .. ' to proto.fields')
table.insert(self.protocol.fields, protoField)
table.insert(self.protocol.fields, f.protoField)
end

self.header = header
Expand Down

0 comments on commit 909832e

Please sign in to comment.