Last active
July 30, 2022 22:37
-
-
Save studentbrad/3357811bf5b48ffeddda54255de7775b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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