ASN编码中会出现形如结构体嵌套的数据结构,例如某ASN文件结构为:
–=================================================
– OperationID: BigDataDriving (0x0001)
–=================================================
OpBigDataSrvSrvForDriving-NotificationCyclic ::= SEQUENCE {
prkgEmgyBrkSysSts PrkgEmgyBrkSysSts OPTIONAL,
vehSpdLgt VehSpdLgt OPTIONAL,
……
}
……
PrkgEmgyBrkSysSts ::= ENUMERATED{
pEBSysSts-Off (0),
pEBSysSts-Standby (1),
……
}
……
VehSpdLgt ::= SEQUENCE{
vehSpdLgtA INTEGER(0…31970),
……
}
其中OpBigDataSrvSrvForSmartDriving-NotificationCyclic是一个Operation,类似一个结构体,结构体成员有可能是基本数据类型,如PrkgEmgyBrkSysSts 为枚举型,也有可能是嵌套了另一个结构体,如VehSpdLgt 。
ASN的注释是以“–”开头的,需要忽略。
当需要对ASN Operation进行编码时需要对Operation(可以理解为结构体)的所有成员进行赋值,并以字典形式作为编码的输入。字典格式为:
dictType = {“prkgEmgyBrkSysSts ”:enumValue, “VehSpdLgt”:{“vehSpdLgtA ”:intValue , …}, …}
从ASN文件输入到打印出字典,需要python对文本进行处理,Python源代码如下:
BaseFunc.py:
import re
import random
def getRandEnum(lineList, LineIndex):
lineStr = ""
EnumStrList = []
while('}' not in lineStr):
LineIndex = LineIndex + 1
lineStr = lineList[LineIndex]
EnumStr = ((lineStr.strip()).split(' '))[0]
EnumStrList.append(EnumStr)
EnumStrList.pop()
return random.choice(EnumStrList)
# # uinit test start
# lineList = [\
# "--=================================================",\
# "MemPosnFromTelm ::= ENUMERATED {",\
# "memPosn-ProfPosn (0),",\
# "memPosn-MemBnk1 (1),",\
# "memPosn-MemBnk2 (2),",\
# "memPosn-MemBnk3 (3)",\
# "}",\
# "--================================================="]
# print("---------------test Func getRandEnum----------------")
# print(getRandEnum(lineList, 1))
# # uinit test end
def isEnumTypeAndGetEnumValue(keyTypeStr, inputFileClass):
for i in range(0, inputFileClass.lineNum - 2):
line = inputFileClass.lineList[i]
if (re.search(keyTypeStr + '\s*::= ENUMERATED', line)):
randEnum = getRandEnum(inputFileClass.lineList, i)
return True, randEnum
return False, "Dumy"
# # uinit test start
# print("-----------test Func isEnumTypeAndGetEnumValue-------------")
# isEnumTypeAndGetEnumValue("ProfPenGidSts", inputFileObj)
# # uinit test end
def isBaseTypeAndReturnValue(keyTypeStr, inputFileObj):
if ("INTEGER" in keyTypeStr):
result = re.split(r'[\.\(\)]', keyTypeStr, 10)
while '' in result:
result.remove('')
low = int(result[1])
up = int(result[2])
value = random.randint(low,up)
#print (value)
return True, value
elif ("BOOLEAN" in keyTypeStr):
listBoolean = ["True", "False"]
value = random.choice(listBoolean)
#print (value)
return True, value
elif ("PrintableString(SIZE(16))" in keyTypeStr):
return True, "1234567890ABCDEF"
isEnumType, randEnumValue = isEnumTypeAndGetEnumValue(keyTypeStr, inputFileObj)
if (isEnumType):
return True, randEnumValue
else:
return False, keyTypeStr
BuildDict.py:
import re
import BaseFunc
filePath = "D:/BDU/IPRouting_Test/asn/0xB3_V028.asn"
OpName = "OpPersonalSettingReq-SetRequestNoReturn"
class inputFileClass():
def __init__(self, filePath, OpName):
self.filePath = filePath
self.OpName = OpName
with open(filePath, 'r') as fileHandle:
self.lineList = fileHandle.readlines()
self.lineNum = len(self.lineList)
inputFileObj = inputFileClass(filePath, OpName)
class TreeNode():
def __init__(self, value = {}):
self.SigValue = value
SigName = ""
SigType = ""
class OpTree:
def __init__(self, node):
self.node = node
self.children = []
def addChild(self, child):
self.children.append(child)
def getChildren(self):
return self.children
lineList = inputFileObj.lineList
lineNum = inputFileObj.lineNum
root_key = "OpBigDataSrvSrvForSmartDriving-NotificationCyclic"
rootNode = TreeNode()
rootNode.SigName = "Dummy"
rootNode.SigType = root_key
rootTree = OpTree(rootNode) # init tree, add root tree Node
def CreatTree(Tree):
father = Tree
for i in range(0, lineNum):
if re.search("^--", lineList[i].strip()): #ignore comments
continue
if (re.search(father.node.SigType + '\s*::=\s*SEQUENCE\s*{', lineList[i])):
startLine = i + 1
for j in range(startLine, lineNum): # after find startline, find endline immediately
if ('}' in lineList[j]):
endLine = j
break
for k in range(startLine, endLine):
genNode = TreeNode()
genNode.SigName = (re.split(',*\s+', ((lineList[k].strip()).strip(','))))[0]
genNode.SigType = (re.split(',*\s+', ((lineList[k].strip()).strip(','))))[1]
isBaseType, Value = BaseFunc.isBaseTypeAndReturnValue(genNode.SigType, inputFileObj)
if (isBaseType):
genNode.SigValue = Value
child = OpTree(genNode)
father.addChild(child)
CreatTree(child)
CreatTree(rootTree)
resultDict = {}
def depthFirstByRecursion(tree):
tempDict = {}
children = tree.getChildren()
for child in children:
name = child.node.SigName
if (child.children == []):
value = child.node.SigValue
else:
value = depthFirstByRecursion(child)
tempDict[name] = value
return tempDict
resultDict = depthFirstByRecursion(rootTree)
print(resultDict)
右边的写法是错误的children