Skip to content

Instantly share code, notes, and snippets.

@studentbrad
Last active July 30, 2022 22:37
Show Gist options
  • Save studentbrad/3357811bf5b48ffeddda54255de7775b to your computer and use it in GitHub Desktop.
Save studentbrad/3357811bf5b48ffeddda54255de7775b to your computer and use it in GitHub Desktop.
#!/bin/python3
from copy import deepcopy
from typing import Union
import asn1tools
def hackTemplatedType(memberDict: dict, templatedTypeDict: dict, name: str):
"""
Hack the templated type by replacing it in memberDict.
The final result is stored in memberDict["members"] and memberDict["type"].
"""
asnType = memberDict["type"]
if asnType != name:
raise ValueError(f"Was expecting {name} but got {asnType} instead.")
actualParameterList = deepcopy(memberDict["actual-parameters"])
del memberDict["actual-parameters"]
del memberDict["type"]
memberList = deepcopy(templatedTypeDict["members"])
parameterList = deepcopy(templatedTypeDict["parameters"])
asnType = templatedTypeDict["type"]
for actualParameter, parameter in zip(actualParameterList, parameterList):
for member in memberList:
if member["type"] == parameter:
member["type"] = actualParameter["type"]
memberDict["members"] = memberList
memberDict["type"] = asnType
def hackTemplatedTypes(memberDict: dict, templatedTypeDict: dict, name: str):
"""
Hack the templated type of all nested members of a type or member.
This function is recursive.
The name memberDict is misleading, it can actually be typeDict or memberDict.
The final result is stored in each nested dictionary.
"""
asnType = memberDict["type"]
if asnType == name:
hackTemplatedType(memberDict, templatedTypeDict, name)
if "members" in memberDict:
for member in memberDict["members"]:
if member is None:
continue # this happens where there is three dots in the structure "..."
if isinstance(member, dict):
hackTemplatedTypes(member, templatedTypeDict, name)
elif isinstance(member, list):
for xgroupMember in member:
hackTemplatedTypes(xgroupMember, templatedTypeDict, name)
else:
memberType = type(member)
raise TypeError(f"Expected member of type dict, list but got {memberType} instead.\n")
def modifyAsnDict(asnDict: dict):
"""
Modify the dictionary for all nested members of all types.
This function does the following:
Hacks the templated type SetupRelease by replacing it in the dictionary.
"""
for name, typeDict in asnDict["types"].items():
# Hack the templated type SetupRelease.
asnType = "SetupRelease"
hackTemplatedTypes(typeDict, asnDict["types"][asnType], asnType)
return asnDict
def compileFiles(filenames: Union[list, str],
codec: str = "ber",
encoding: str = "utf-8"):
"""
A new compiler that supports SetupRelease.
"""
# Parse the ASN text using ASN.1 tools.
asnDict = asn1tools.parse_files(filenames, encoding=encoding)
# Hack the templated type SetupRelease.
modifyAsnDict(asnDict["EUTRA-RRC-Definitions"])
return asn1tools.compile_dict(asnDict, codec=codec)
def main():
schema = compileFiles("asn_r16_7.asn1", codec="gser")
message = {"interval-ULHoppingConfigCommonModeA-r13": ("interval-FDD-r13", "int8")}
encoded = schema.encode("FreqHoppingParameters-r13", message)
print(encoded)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment