From 1413aa9105b362190be6ae245e14eb465733f6d7 Mon Sep 17 00:00:00 2001 From: Erik Moqvist Date: Sun, 6 Aug 2017 00:18:39 +0200 Subject: [PATCH] Various compiler and schema changes. --- asn1tools/compiler.py | 356 ++++++++++++++++++++++++++++----- asn1tools/schema.py | 82 +++++--- tests/test_asn1tools.py | 425 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 771 insertions(+), 92 deletions(-) diff --git a/asn1tools/compiler.py b/asn1tools/compiler.py index 31ebee7c..022faff6 100644 --- a/asn1tools/compiler.py +++ b/asn1tools/compiler.py @@ -1,10 +1,21 @@ +import logging +from collections import OrderedDict + from pyparsing import \ Literal, Keyword, Word, ZeroOrMore, Regex, printables, delimitedList, \ - Group, Optional, Forward, StringEnd, OneOrMore + Group, Optional, Forward, StringEnd, OneOrMore, alphanums from .codecs import ber from .schema import \ - Module, Sequence, Integer, Boolean, IA5String + Module, Sequence, Integer, Boolean, IA5String, Enumerated, \ + BitString, Choice, SequenceOf, OctetString + + +LOGGER = logging.getLogger(__name__) + + +class CompilerError(Exception): + pass class Type(object): @@ -41,8 +52,8 @@ def __str__(self): class Schema(object): - def __init__(self, schema, codec): - self._schema = schema + def __init__(self, modules, codec): + self._modules = modules self._codec = codec def encode(self, name, data): @@ -54,9 +65,14 @@ def encode(self, name, data): """ - item = self._schema.get_item_by_name(name) + for module in self._modules: + try: + return self._codec.encode(data, + module.get_type_by_name(name)) + except LookupError: + pass - return self._codec.encode(data, item) + raise LookupError("Type '{}' not found.".format(name)) def decode(self, name, data): """Decode given bytes object `data` as given type `name` and return @@ -67,9 +83,14 @@ def decode(self, name, data): """ - item = self._schema.get_item_by_name(name) + for module in self._modules: + try: + return self._codec.decode(data, + module.get_type_by_name(name)) + except LookupError: + pass - return self._codec.decode(data, item) + raise LookupError("Type '{}' not found.".format(name)) def get_type(self, name): """Return a :class:`Type` object of type with given name `name`. The @@ -78,10 +99,214 @@ def get_type(self, name): """ - return Type(self._schema.get_item_by_name(name), self._codec) + for module in self._modules: + try: + return Type(module.get_type_by_name(name), self._codec) + except LookupError: + pass + + raise LookupError("Type '{}' not found.".format(name)) + + def get_type_names(self): + """Returns a dictionary of lists of all type names per module. + + """ + + types = {} + + for module in self._modules: + types[module.name] = [type_.name for type_ in module.types] + + return types def __str__(self): - return str(self._schema) + return str(self._modules) + + +def _convert_type_tokens_to_sequence(name, value, module, modules): + """Recursively convert tokens to classes. + + """ + + items = [] + + for member in value[4]: + # Ignore '...'. + if member == ['...']: + continue + + item, _ = member + + if item[1] == 'INTEGER': + item = Integer(item[0]) + elif item[1] == 'BOOLEAN': + item = Boolean(item[0]) + elif item[1] == 'IA5String': + item = IA5String(item[0]) + elif item[1] == 'ENUMERATED': + item = Enumerated(item[0], {i: v for i, v in enumerate(item[3])}) + elif item[1] == 'CHOICE': + item = Choice(item[0], []) + elif item[1:3] == ['BIT', 'STRING']: + item = BitString(item[0]) + elif item[1:3] == ['OCTET', 'STRING']: + item = OctetString(item[0]) + elif item[1:3] == ['SEQUENCE', '{']: + item = Sequence(item[0], []) + elif item[1] == 'SEQUENCE' and item[3] == 'OF': + item = SequenceOf(item[0], []) + else: + # User defined type. + type_name = item[1] + + if type_name in module['types']: + _convert_type_tokens_to_class(type_name, + module['types'][type_name], + module, + modules) + item = module['types'][type_name] + else: + item = None + + for from_module, import_types in module['import'].items(): + if type_name in import_types: + _convert_type_tokens_to_class( + type_name, + modules[from_module]['types'][type_name], + modules[from_module], + modules) + item = modules[from_module]['types'][type_name] + break + + if item is None: + raise CompilerError('Type {} not found.'.format( + type_name)) + + items.append(item) + + module['types'][name] = Sequence(name, items) + + +def _convert_type_tokens_to_choice(name, value, module, modules): + """Recursively convert tokens to classes. + + """ + + module['types'][name] = Choice(name, []) + + +def _convert_type_tokens_to_integer(name, value, module, modules): + """Recursively convert tokens to classes. + + """ + + module['types'][name] = Integer(name) + + +def _convert_type_tokens_to_boolean(name, value, module, modules): + """Recursively convert tokens to classes. + + """ + + module['types'][name] = Boolean(name) + + +def _convert_type_tokens_to_sequence_of(name, value, module, modules): + """Recursively convert tokens to classes. + + """ + + module['types'][name] = SequenceOf(name, []) + + +def _convert_type_tokens_to_bit_string(name, value, module, modules): + """Recursively convert tokens to classes. + + """ + + module['types'][name] = BitString(name) + + +def _convert_type_tokens_to_octet_string(name, value, module, modules): + """Recursively convert tokens to classes. + + """ + + module['types'][name] = OctetString(name) + + +def _convert_type_tokens_to_enumerated(name, value, module, modules): + """Recursively convert tokens to classes. + + """ + + module['types'][name] = Enumerated(name, + {i: v + for i, v in enumerate(value[4])}) + + +def _convert_type_tokens_to_user_type(name, value, module, modules): + """Recursively convert tokens to classes. + + """ + + type_name = value[2] + + if type_name in module['types']: + _convert_type_tokens_to_class(type_name, + module['types'][type_name], + module, + modules) + item = module['types'][type_name] + else: + item = None + + for from_module, import_types in module['import'].items(): + if type_name in import_types: + _convert_type_tokens_to_class( + type_name, + modules[from_module]['types'][type_name], + modules[from_module], + modules) + item = modules[from_module]['types'][type_name] + break + + if item is None: + raise CompilerError('Type {} not found.'.format( + type_name)) + + module['types'][name] = item + + +def _convert_type_tokens_to_class(name, value, module, modules): + """Recursively convert type tokens to classes. + + """ + + # Return immediately if the type is already converted to a class. + if not isinstance(value, list): + return + + if value[1:4] == ['::=', 'SEQUENCE', '{']: + _convert_type_tokens_to_sequence(name, value, module, modules) + elif value[1:4] == ['::=', 'CHOICE', '{']: + _convert_type_tokens_to_choice(name, value, module, modules) + elif value[1:3] == ['::=', 'INTEGER']: + _convert_type_tokens_to_integer(name, value, module, modules) + elif value[1:3] == ['::=', 'BOOLEAN']: + _convert_type_tokens_to_boolean(name, value, module, modules) + elif value[1:3] == ['::=', 'SEQUENCE'] and value[4] == 'OF': + _convert_type_tokens_to_sequence_of(name, value, module, modules) + elif value[1:4] == ['::=', 'BIT', 'STRING']: + _convert_type_tokens_to_bit_string(name, value, module, modules) + elif value[1:4] == ['::=', 'OCTET', 'STRING']: + _convert_type_tokens_to_octet_string(name, value, module, modules) + elif value[1:4] == ['::=', 'ENUMERATED', '{']: + _convert_type_tokens_to_enumerated(name, value, module, modules) + elif len(value) == 3: + _convert_type_tokens_to_user_type(name, value, module, modules) + else: + raise NotImplementedError(value) def compile_string(string, codec=None): @@ -99,33 +324,53 @@ def compile_string(string, codec=None): codec = ber grammar = _create_grammar() - tokens = grammar.parseString(string) + tokens = grammar.parseString(string).asList() - #print(tokens) + modules = OrderedDict() - definitions = [] + # Put tokens into dictionaries. + for module in tokens: + module_name = module[0][0] - for definition in tokens[2]: - if definition[2] == 'SEQUENCE': - items = [] + LOGGER.debug("Found module '%s'.", module_name) - for item in definition[4]: - if item[1] == 'INTEGER': - items.append(Integer(item[0])) - elif item[1] == 'BOOLEAN': - items.append(Boolean(item[0])) - elif item[1] == 'IA5String': - items.append(IA5String(item[0])) - else: - raise NotImplementedError(item[1]) + import_tokens = OrderedDict() + types_tokens = OrderedDict() + values_tokens = OrderedDict() - definitions.append(Sequence(definition[0], items)) - else: - raise NotImplementedError(definition[2]) + if module[1]: + from_name = module[1][-2] + LOGGER.debug("Found imports from '%s'.", from_name) + import_tokens[from_name] = module[1][1] + + for definition in module[2]: + name = definition[0] + + if name[0].isupper(): + LOGGER.debug("Found type '%s'.", name) + types_tokens[name] = definition + else: + LOGGER.debug("Found value '%s'.", name) + values_tokens[name] = definition + + modules[module_name] = { + 'import': import_tokens, + 'types': types_tokens, + 'values': values_tokens + } - schema = Module(tokens[0][0], definitions) + # Recursively convert token lists to schema classes and their + # instances. + for module in modules.values(): + for name, value in module['types'].items(): + _convert_type_tokens_to_class(name, value, module, modules) - return Schema(schema, codec) + return Schema([Module(name, + [v for v in values['types'].values()], + values['import'], + values['values']) + for name, values in modules.items()], + codec) def compile_file(filename, codec=None): @@ -165,6 +410,8 @@ def _create_grammar(): # Various literals. word = Word(printables, excludeChars=',(){}.:=;') + type_name = Regex(r'[A-Z][a-zA-Z0-9-]*') + value_name = Word(alphanums + '-') assignment = Literal('::=') lparen = Literal('(') rparen = Literal(')') @@ -192,17 +439,20 @@ def _create_grammar(): | enumerated | sequence_of | word) - item = Group(word + type_) + item = Group(value_name + type_) # Type definitions. sequence << (SEQUENCE + lbrace - + Group(Optional(delimitedList((item - + Optional(OPTIONAL) - + Optional(DEFAULT + word)) - | dotx3))) + + Group(Optional(delimitedList( + Group((item + + Group(Optional(OPTIONAL) + + Optional(DEFAULT + word))) + | dotx3)))) + rbrace) sequence_of << (SEQUENCE - + lparen + SIZE + lparen + (range_ | word) + rparen + rparen + + Group(lparen + SIZE + lparen + + (range_ | word) + + rparen + rparen) + OF + type_) choice << (CHOICE + lbrace @@ -228,27 +478,27 @@ def _create_grammar(): + rparen)) # Top level definitions. - definition = Group((word + assignment + (sequence - | choice - | enumerated - | sequence_of - | integer - | bit_string - | octet_string - | word)) + definition = Group((type_name + assignment + (sequence + | choice + | enumerated + | sequence_of + | integer + | bit_string + | octet_string + | word)) | (word + INTEGER + assignment + word)) module_body = (Group(Optional(IMPORTS - + delimitedList(word) + + Group(delimitedList(word)) + FROM + word + scolon)) + Group(ZeroOrMore(definition))) - module = (Group(word - + DEFINITIONS - + Optional(AUTOMATIC) - + Optional(TAGS) - + assignment - + BEGIN) - + module_body - + END) + module = Group(Group(word + + DEFINITIONS + + Optional(AUTOMATIC) + + Optional(TAGS) + + assignment + + BEGIN) + + module_body + + END) # The whole specification. specification = OneOrMore(module) + StringEnd() diff --git a/asn1tools/schema.py b/asn1tools/schema.py index 82bf8a77..1e829eb3 100644 --- a/asn1tools/schema.py +++ b/asn1tools/schema.py @@ -2,6 +2,7 @@ """ + class Item(object): """Abstract base class of an item. All ASN.1 type definitions should subclass this class. @@ -12,13 +13,11 @@ def __init__(self, name=None, default=None, tag=None, - optional=False, - values=None): + optional=False): self._name = name self._default = default self._tag = tag self._optional = optional - self._values = values @property def name(self): @@ -52,14 +51,6 @@ def optional(self): return self._optional - @property - def values(self): - """The values of the item, or None is unavailable. - - """ - - return self._values - def dump_lines(self, assignment=False): raise NotImplementedError() @@ -86,22 +77,52 @@ class Module(Item): """ - def __init__(self, name, items, **kwargs): + def __init__(self, name, types=None, imports=None, values=None, **kwargs): super(Module, self).__init__(name, **kwargs) - self.items = items - def get_item_by_name(self, name): - for item in self.items: - if item.name == name: - return item + if types is None: + types = [] + self.types = types + + if imports is None: + imports = [] + self.imports = imports + + if values is None: + values = [] + self.values = values + + def get_imports_by_module(self, name): + for import_ in self.imports: + if import_.name == name: + return import_ - raise LookupError("No item with name '{}'.".format(name)) + raise LookupError("Imports '{}' not found.".format(name)) + + def get_type_by_name(self, name): + for type_ in self.types: + if type_.name == name: + return type_ + + raise LookupError("Type '{}' not found.".format(name)) + + def get_value_by_name(self, name): + for value in self.values: + if value.name == name: + return value + + raise LookupError("Value '{}' not found.".format(name)) def dump_lines(self, assignment=False): return ([self.name + ' DEFINITIONS ::= BEGIN'] - + _indent_lines(_dump_list_lines(self.items, assignment=True)) + + _indent_lines(_dump_list_lines(self.types, assignment=True)) + ['END']) + def __repr__(self): + return '{} (imports={}, types={}, values={})'.format(self.name, + self.imports, + self.types, + self.values) class Sequence(Item): """The ASN.1 SEQUENCE type. @@ -163,8 +184,9 @@ def __init__(self, name=None, values=None, **kwargs): def dump_lines(self, assignment=False): return ([self.name + ' ENUMERATED {'] - + _indent_lines(['{}({})'.format(value, key) - for key, value in self.values.items()]) + + _indent_lines(_delimited_lines( + ['{}({})'.format(value, key) + for key, value in self.values.items()])) + ['}' + self.dump_qualifiers()]) @@ -182,6 +204,15 @@ class Integer(Item): """ + def __init__(self, name=None, values=None, **kwargs): + super(Integer, self).__init__(name, **kwargs) + + if values is None: + if hasattr(self.__class__, 'values'): + values = getattr(self.__class__, 'values') + + self.values = values + def dump_lines(self, assignment=False): return [self.name + ' INTEGER' + self.dump_qualifiers()] @@ -218,9 +249,7 @@ def __init__(self, name=None, item=None, **kwargs): self.item = item def dump_lines(self, assignment=False): - return ([self.name + ' SEQUENCE OF'] - + _indent_lines(self.item.dump_lines()) - + [self.dump_qualifiers()]) + return [self.name + ' SEQUENCE OF'] class BitString(Item): @@ -257,3 +286,8 @@ def _dump_list_lines(items, assignment=False): lines += item_lines return lines + + +def _delimited_lines(lines): + return [line + (',' if i < len(lines) else '') + for i, line in enumerate(lines, 1)] diff --git a/tests/test_asn1tools.py b/tests/test_asn1tools.py index 55f517b6..b8508af3 100644 --- a/tests/test_asn1tools.py +++ b/tests/test_asn1tools.py @@ -1,3 +1,4 @@ +import logging import unittest import asn1tools @@ -9,35 +10,35 @@ class Asn1ToolsTest(unittest.TestCase): def test_str(self): module = Module( - 'Sequence', + 'Foo', [ Sequence( - 'Foo', + 'Bar', [ Integer('foo', optional=True), Integer('bar', default=5), Sequence( - 'Fie', + 'fie', [ + Integer('fum'), Integer('foo'), - Integer('bar'), ]) ]), - Sequence('Bar', []) + Sequence('Fie', []) ]) self.assertEqual( str(module), - """Sequence DEFINITIONS ::= BEGIN - Foo ::= SEQUENCE { + """Foo DEFINITIONS ::= BEGIN + Bar ::= SEQUENCE { foo INTEGER OPTIONAL, bar INTEGER DEFAULT 5, - Fie SEQUENCE { - foo INTEGER, - bar INTEGER + fie SEQUENCE { + fum INTEGER, + foo INTEGER } }, - Bar ::= SEQUENCE { + Fie ::= SEQUENCE { } END""") @@ -107,6 +108,9 @@ def test_sequence(self): def test_compile_file(self): foo = asn1tools.compile_file('tests/files/foo.asn') + # Get a list of all types. + self.assertEqual(foo.get_type_names(), {'Foo': ['Question', 'Answer']}) + # Encode a question. encoded = foo.encode('Question', {'id': 1, 'question': 'Is 1+1=3?'}) @@ -120,7 +124,7 @@ def test_compile_file(self): with self.assertRaises(LookupError) as cm: foo.get_type('Bar') - self.assertEqual(str(cm.exception), "No item with name 'Bar'.") + self.assertEqual(str(cm.exception), "Type 'Bar' not found.") # Get the answer type from the schema. answer = foo.get_type('Answer') @@ -134,9 +138,400 @@ def test_compile_file(self): self.assertEqual(decoded, {'id': 1, 'answer': False}) def test_rrc_8_6_0(self): - with self.assertRaises(NotImplementedError): - rrc = asn1tools.compile_file('tests/files/rrc_8.6.0.asn') - print(rrc) + rrc = asn1tools.compile_file('tests/files/rrc_8.6.0.asn') + self.assertEqual(rrc.get_type_names(), + { + 'EUTRA-InterNodeDefinitions': [ + 'HandoverCommand', + 'HandoverCommand-r8-IEs', + 'HandoverPreparationInformation', + 'HandoverPreparationInformation-r8-IEs', + 'UERadioAccessCapabilityInformation', + 'UERadioAccessCapabilityInformation-r8-IEs', + 'AS-Config', + 'AS-Context', + 'ReestablishmentInfo', + 'AdditionalReestabInfoList', + 'AdditionalReestabInfo', + 'Key-eNodeB-Star', + 'RRM-Config' + ], + 'EUTRA-RRC-Definitions': [ + 'BCCH-BCH-Message', + 'MasterInformationBlock', + 'BCCH-DL-SCH-Message', + 'BCCH-DL-SCH-MessageType', + 'PCCH-Message', + 'PCCH-MessageType', + 'DL-CCCH-Message', + 'DL-CCCH-MessageType', + 'DL-DCCH-Message', + 'DL-DCCH-MessageType', + 'UL-CCCH-Message', + 'UL-CCCH-MessageType', + 'UL-DCCH-Message', + 'UL-DCCH-MessageType', + 'CounterCheck', + 'CounterCheck-r8-IEs', + 'DRB-CountMSB-InfoList', + 'DRB-CountMSB-Info', + 'CounterCheckResponse', + 'CounterCheckResponse-r8-IEs', + 'DRB-CountInfoList', + 'DRB-CountInfo', + 'CSFBParametersRequestCDMA2000', + 'CSFBParametersRequestCDMA2000-r8-IEs', + 'CSFBParametersResponseCDMA2000', + 'CSFBParametersResponseCDMA2000-r8-IEs', + 'DLInformationTransfer', + 'DLInformationTransfer-r8-IEs', + 'HandoverFromEUTRAPreparationRequest', + 'HandoverFromEUTRAPreparationRequest-r8-IEs', + 'MasterInformationBlock', + 'MeasurementReport', + 'MeasurementReport-r8-IEs', + 'MobilityFromEUTRACommand', + 'MobilityFromEUTRACommand-r8-IEs', + 'Handover', + 'CellChangeOrder', + 'SI-OrPSI-GERAN', + 'SystemInfoListGERAN', + 'Paging', + 'PagingRecordList', + 'PagingRecord', + 'PagingUE-Identity', + 'IMSI', + 'IMSI-Digit', + 'RRCConnectionReconfiguration', + 'RRCConnectionReconfiguration-r8-IEs', + 'SecurityConfigHO', + 'RRCConnectionReconfigurationComplete', + 'RRCConnectionReconfigurationComplete-r8-IEs', + 'RRCConnectionReestablishment', + 'RRCConnectionReestablishment-r8-IEs', + 'RRCConnectionReestablishmentComplete', + 'RRCConnectionReestablishmentComplete-r8-IEs', + 'RRCConnectionReestablishmentReject', + 'RRCConnectionReestablishmentReject-r8-IEs', + 'RRCConnectionReestablishmentRequest', + 'RRCConnectionReestablishmentRequest-r8-IEs', + 'ReestabUE-Identity', + 'ReestablishmentCause', + 'RRCConnectionReject', + 'RRCConnectionReject-r8-IEs', + 'RRCConnectionRelease', + 'RRCConnectionRelease-r8-IEs', + 'ReleaseCause', + 'RedirectedCarrierInfo', + 'IdleModeMobilityControlInfo', + 'FreqPriorityListEUTRA', + 'FreqPriorityEUTRA', + 'FreqsPriorityListGERAN', + 'FreqsPriorityGERAN', + 'FreqPriorityListUTRA-FDD', + 'FreqPriorityUTRA-FDD', + 'FreqPriorityListUTRA-TDD', + 'FreqPriorityUTRA-TDD', + 'BandClassPriorityListHRPD', + 'BandClassPriorityHRPD', + 'BandClassPriorityList1XRTT', + 'BandClassPriority1XRTT', + 'RRCConnectionRequest', + 'RRCConnectionRequest-r8-IEs', + 'InitialUE-Identity', + 'EstablishmentCause', + 'RRCConnectionSetup', + 'RRCConnectionSetup-r8-IEs', + 'RRCConnectionSetupComplete', + 'RRCConnectionSetupComplete-r8-IEs', + 'RegisteredMME', + 'SecurityModeCommand', + 'SecurityModeCommand-r8-IEs', + 'SecurityConfigSMC', + 'SecurityModeComplete', + 'SecurityModeComplete-r8-IEs', + 'SecurityModeFailure', + 'SecurityModeFailure-r8-IEs', + 'SystemInformation', + 'SystemInformation-r8-IEs', + 'SystemInformationBlockType1', + 'PLMN-IdentityList', + 'PLMN-IdentityInfo', + 'SchedulingInfoList', + 'SchedulingInfo', + 'SIB-MappingInfo', + 'SIB-Type', + 'UECapabilityEnquiry', + 'UECapabilityEnquiry-r8-IEs', + 'UE-CapabilityRequest', + 'UECapabilityInformation', + 'UECapabilityInformation-r8-IEs', + 'ULHandoverPreparationTransfer', + 'ULHandoverPreparationTransfer-r8-IEs', + 'ULInformationTransfer', + 'ULInformationTransfer-r8-IEs', + 'SystemInformationBlockType2', + 'AC-BarringConfig', + 'MBSFN-SubframeConfigList', + 'MBSFN-SubframeConfig', + 'SystemInformationBlockType3', + 'SystemInformationBlockType4', + 'IntraFreqNeighCellList', + 'IntraFreqNeighCellInfo', + 'IntraFreqBlackCellList', + 'SystemInformationBlockType5', + 'InterFreqCarrierFreqList', + 'InterFreqCarrierFreqInfo', + 'InterFreqNeighCellList', + 'InterFreqNeighCellInfo', + 'InterFreqBlackCellList', + 'SystemInformationBlockType6', + 'CarrierFreqListUTRA-FDD', + 'CarrierFreqUTRA-FDD', + 'CarrierFreqListUTRA-TDD', + 'CarrierFreqUTRA-TDD', + 'SystemInformationBlockType7', + 'CarrierFreqsInfoListGERAN', + 'CarrierFreqsInfoGERAN', + 'SystemInformationBlockType8', + 'CellReselectionParametersCDMA2000', + 'NeighCellListCDMA2000', + 'NeighCellCDMA2000', + 'NeighCellsPerBandclassListCDMA2000', + 'NeighCellsPerBandclassCDMA2000', + 'PhysCellIdListCDMA2000', + 'BandClassListCDMA2000', + 'BandClassInfoCDMA2000', + 'SystemInformationBlockType9', + 'SystemInformationBlockType10', + 'SystemInformationBlockType11', + 'AntennaInfoCommon', + 'AntennaInfoDedicated', + 'CQI-ReportConfig', + 'CQI-ReportPeriodic', + 'DRB-Identity', + 'LogicalChannelConfig', + 'MAC-MainConfig', + 'DRX-Config', + 'PDCP-Config', + 'PDSCH-ConfigCommon', + 'PDSCH-ConfigDedicated', + 'PHICH-Config', + 'PhysicalConfigDedicated', + 'P-Max', + 'PRACH-ConfigSIB', + 'PRACH-Config', + 'PRACH-ConfigInfo', + 'PresenceAntennaPort1', + 'PUCCH-ConfigCommon', + 'PUCCH-ConfigDedicated', + 'PUSCH-ConfigCommon', + 'PUSCH-ConfigDedicated', + 'UL-ReferenceSignalsPUSCH', + 'RACH-ConfigCommon', + 'RACH-ConfigDedicated', + 'RadioResourceConfigCommonSIB', + 'RadioResourceConfigCommon', + 'BCCH-Config', + 'PCCH-Config', + 'UL-CyclicPrefixLength', + 'RadioResourceConfigDedicated', + 'SRB-ToAddModList', + 'SRB-ToAddMod', + 'DRB-ToAddModList', + 'DRB-ToAddMod', + 'DRB-ToReleaseList', + 'RLC-Config', + 'UL-AM-RLC', + 'DL-AM-RLC', + 'UL-UM-RLC', + 'DL-UM-RLC', + 'SN-FieldLength', + 'T-PollRetransmit', + 'PollPDU', + 'PollByte', + 'T-Reordering', + 'T-StatusProhibit', + 'SchedulingRequestConfig', + 'SoundingRS-UL-ConfigCommon', + 'SoundingRS-UL-ConfigDedicated', + 'SPS-Config', + 'SPS-ConfigDL', + 'SPS-ConfigUL', + 'N1-PUCCH-AN-PersistentList', + 'TDD-Config', + 'TimeAlignmentTimer', + 'TPC-PDCCH-Config', + 'TPC-Index', + 'UplinkPowerControlCommon', + 'UplinkPowerControlDedicated', + 'DeltaFList-PUCCH', + 'NextHopChainingCount', + 'SecurityAlgorithmConfig', + 'ShortMAC-I', + 'AdditionalSpectrumEmission', + 'ARFCN-ValueCDMA2000', + 'ARFCN-ValueEUTRA', + 'ARFCN-ValueGERAN', + 'ARFCN-ValueUTRA', + 'BandclassCDMA2000', + 'BandIndicatorGERAN', + 'CarrierFreqCDMA2000', + 'CarrierFreqGERAN', + 'CarrierFreqsGERAN', + 'ExplicitListOfARFCNs', + 'CDMA2000-Type', + 'CellIdentity', + 'CellIndexList', + 'CellIndex', + 'CellReselectionPriority', + 'CSFB-RegistrationParam1XRTT', + 'CellGlobalIdEUTRA', + 'CellGlobalIdUTRA', + 'CellGlobalIdGERAN', + 'CellGlobalIdCDMA2000', + 'MobilityControlInfo', + 'CarrierBandwidthEUTRA', + 'CarrierFreqEUTRA', + 'MobilityParametersCDMA2000', + 'MobilityStateParameters', + 'PhysCellId', + 'PhysCellIdRange', + 'PhysCellIdCDMA2000', + 'PhysCellIdGERAN', + 'PhysCellIdUTRA-FDD', + 'PhysCellIdUTRA-TDD', + 'PLMN-Identity', + 'MCC', + 'MNC', + 'MCC-MNC-Digit', + 'PreRegistrationInfoHRPD', + 'SecondaryPreRegistrationZoneIdListHRPD', + 'PreRegistrationZoneIdHRPD', + 'Q-RxLevMin', + 'Q-OffsetRange', + 'Q-OffsetRangeInterRAT', + 'ReselectionThreshold', + 'SpeedStateScaleFactors', + 'SystemTimeInfoCDMA2000', + 'TrackingAreaCode', + 'T-Reselection', + 'AllowedMeasBandwidth', + 'Hysteresis', + 'MeasConfig', + 'MeasIdToRemoveList', + 'MeasObjectToRemoveList', + 'ReportConfigToRemoveList', + 'MeasGapConfig', + 'MeasId', + 'MeasIdToAddModList', + 'MeasIdToAddMod', + 'MeasObjectCDMA2000', + 'CellsToAddModListCDMA2000', + 'CellsToAddModCDMA2000', + 'MeasObjectEUTRA', + 'CellsToAddModList', + 'CellsToAddMod', + 'BlackCellsToAddModList', + 'BlackCellsToAddMod', + 'MeasObjectGERAN', + 'MeasObjectId', + 'MeasObjectToAddModList', + 'MeasObjectToAddMod', + 'MeasObjectUTRA', + 'CellsToAddModListUTRA-FDD', + 'CellsToAddModUTRA-FDD', + 'CellsToAddModListUTRA-TDD', + 'CellsToAddModUTRA-TDD', + 'MeasResults', + 'MeasResultListEUTRA', + 'MeasResultEUTRA', + 'MeasResultListUTRA', + 'MeasResultUTRA', + 'MeasResultListGERAN', + 'MeasResultGERAN', + 'MeasResultsCDMA2000', + 'MeasResultListCDMA2000', + 'MeasResultCDMA2000', + 'PLMN-IdentityList2', + 'QuantityConfig', + 'QuantityConfigEUTRA', + 'QuantityConfigUTRA', + 'QuantityConfigGERAN', + 'QuantityConfigCDMA2000', + 'ReportConfigEUTRA', + 'ThresholdEUTRA', + 'ReportConfigId', + 'ReportConfigInterRAT', + 'ThresholdUTRA', + 'ThresholdGERAN', + 'ThresholdCDMA2000', + 'ReportConfigToAddModList', + 'ReportConfigToAddMod', + 'ReportInterval', + 'RSRP-Range', + 'RSRQ-Range', + 'TimeToTrigger', + 'C-RNTI', + 'DedicatedInfoCDMA2000', + 'DedicatedInfoNAS', + 'FilterCoefficient', + 'MMEC', + 'NeighCellConfig', + 'RAND-CDMA2000', + 'RAT-Type', + 'RRC-TransactionIdentifier', + 'S-TMSI', + 'UE-CapabilityRAT-ContainerList', + 'UE-CapabilityRAT-Container', + 'UE-EUTRA-Capability', + 'AccessStratumRelease', + 'PDCP-Parameters', + 'PhyLayerParameters', + 'RF-Parameters', + 'SupportedBandListEUTRA', + 'SupportedBandEUTRA', + 'MeasParameters', + 'BandListEUTRA', + 'BandInfoEUTRA', + 'InterFreqBandList', + 'InterFreqBandInfo', + 'InterRAT-BandList', + 'InterRAT-BandInfo', + 'IRAT-ParametersUTRA-FDD', + 'SupportedBandListUTRA-FDD', + 'SupportedBandUTRA-FDD', + 'IRAT-ParametersUTRA-TDD128', + 'SupportedBandListUTRA-TDD128', + 'SupportedBandUTRA-TDD128', + 'IRAT-ParametersUTRA-TDD384', + 'SupportedBandListUTRA-TDD384', + 'SupportedBandUTRA-TDD384', + 'IRAT-ParametersUTRA-TDD768', + 'SupportedBandListUTRA-TDD768', + 'SupportedBandUTRA-TDD768', + 'IRAT-ParametersGERAN', + 'SupportedBandListGERAN', + 'SupportedBandGERAN', + 'IRAT-ParametersCDMA2000-HRPD', + 'SupportedBandListHRPD', + 'IRAT-ParametersCDMA2000-1XRTT', + 'SupportedBandList1XRTT', + 'UE-TimersAndConstants' + ], + 'EUTRA-UE-Variables': [ + 'VarMeasConfig', + 'VarMeasReportList', + 'VarMeasReport', + 'CellsTriggeredList', + 'VarShortMAC-Input' + ] + }) + + +# This file is not '__main__' when executed via 'python setup.py +# test'. +logging.basicConfig(level=logging.DEBUG) if __name__ == '__main__':