import logging import copy from asn1tools import parse_files, compile_dict, ParseError, CompileError from glob import glob from pathlib import Path from pprint import pprint def parseASN1File (asnFile): try: parse_files(asnFile) except ParseError as ex: return [ex] return [] def parseASN1Files (fileList): if len(fileList) == 0: logging.warning ("No files specified") return {} errors = {} logging.info("Parsing files...") for f in fileList: ex = parseASN1File(f) if ex: logging.info (f" {f}: Failed - {ex!r}") else: logging.info (f" {f}: OK") errors[f] = ex return errors def fixDottedReference (dict, importingModule, importingType, importingMember, importedModule, importedType): newName = importedModule + "_" + importedType dict[importedModule]['types'][newName] = copy.deepcopy(dict[importedModule]['types'][importedType]) dict[importingModule]['imports'][importedModule].append(newName) member = [x for x in dict[importingModule]['types'][importingType]['members'] if x is not None and x['name'] == importingMember][0] member['type'] = newName def compileASN1Files (fileList): logging.info("Compiling files...") errors = [] imports = {} #p = re.compile(r"]\s+\S+\.\S+") #for f in fileList: # with open(f) as fh: # s = fh.read() # for match in p.findall(s): # print (f"In {f}: {match}") #exit() try: dr = parse_files(fileList) for modulename, module in dr.items(): # Weird fix because the compiler doesn't like RELATIVE-OID as a type # Not sure if the on-the-wire encoding would be affected or not # but for most checking purposes this doesn't matter module['types']["RELATIVE-OID"] = {'type' : 'OBJECT IDENTIFIER'} for k,v in module['imports'].items(): if not k in imports: imports[k] = [] imports[k].append({ "in" : modulename, "types" : v }) for k,v in imports.items(): if not k in dr.keys(): importers = [i['in'] for i in v] errors.append(f"Unsatisfied import [{k}] for {importers}") fixDottedReference(dr, 'LI-PS-PDU', 'Location', 'umtsHI2Location', 'UmtsHI2Operations', 'Location') fixDottedReference(dr, 'LI-PS-PDU', 'Location', 'epsLocation', 'EpsHI2Operations', 'Location') fixDottedReference(dr, 'LI-PS-PDU', 'Location', 'eTSI671HI2Location', 'HI2Operations', 'Location') fixDottedReference(dr, 'LI-PS-PDU', 'UMTSIRI', 'iRI-Parameters', 'UmtsHI2Operations', 'IRI-Parameters') fixDottedReference(dr, 'LI-PS-PDU', 'UMTSIRI', 'iRI-CS-Parameters', 'UmtsCS-HI2Operations', 'IRI-Parameters') fixDottedReference(dr, 'LI-PS-PDU', 'ETSI671IRI', 'iRI-Parameters', 'HI2Operations', 'IRI-Parameters') fixDottedReference(dr, 'LI-PS-PDU', 'EPSIRI', 'iRI-EPS-Parameters', 'EpsHI2Operations', 'IRI-Parameters') fixDottedReference(dr, 'LI-PS-PDU', 'ConfIRI', 'iRI-Conf-Parameters', 'CONFHI2Operations', 'IRI-Parameters') fixDottedReference(dr, 'LI-PS-PDU', 'ProSeIRI', 'iRI-ProSe-Parameters', 'ProSeHI2Operations', 'IRI-Parameters') fixDottedReference(dr, 'LI-PS-PDU', 'GcseIRI', 'iRI-Gcse-Parameters', 'GCSEHI2Operations', 'IRI-Parameters') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'tTRAFFIC-1', 'TS101909201', 'TTRAFFIC') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'cTTRAFFIC-1', 'TS101909201', 'CTTRAFFIC') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'tTRAFFIC-2', 'TS101909202', 'TTRAFFIC') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'cTTRAFFIC-2', 'TS101909202', 'CTTRAFFIC') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'cCIPPacketHeader', 'CDMA2000CCModule', 'CCIPPacketHeader') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'uMTSCC-CC-PDU', 'Umts-HI3-PS', 'CC-PDU') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'ePSCC-CC-PDU', 'Eps-HI3-PS', 'CC-PDU') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'confCC-CC-PDU', 'CONF-HI3-IMS', 'Conf-CC-PDU') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'voipCC-CC-PDU', 'VoIP-HI3-IMS', 'Voip-CC-PDU') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'gcseCC-CC-PDU', 'GCSE-HI3', 'Gcse-CC-PDU') fixDottedReference(dr, 'LI-PS-PDU', 'CCContents', 'cSvoice-CC-PDU', 'CSvoice-HI3-IP', 'CSvoice-CC-PDU') fixDottedReference(dr, 'LI-PS-PDU', 'IRIContents', 'tARGETACTIVITYMONITOR-1', 'TS101909201', 'TARGETACTIVITYMONITOR-1') fixDottedReference(dr, 'LI-PS-PDU', 'IRIContents', 'tARGETACTIVITYMONITOR-2', 'TS101909202', 'TARGETACTIVITYMONITOR') fixDottedReference(dr, 'LI-PS-PDU', 'IRIContents', 'lAESProtocol', 'Laesp-j-std-025-b', 'LAESProtocol') fixDottedReference(dr, 'LI-PS-PDU', 'IRIContents', 'cDMA2000LAESMessage', 'CDMA2000CIIModule', 'CDMA2000LAESMessage') fixDottedReference(dr, 'LI-PS-PDU', 'HI4Payload', 'threeGPP-LI-Notification', 'TS33128Payloads', 'LINotificationPayload') fixDottedReference(dr, 'ILHIPDU', 'TimestampMapping', 'timeStampQualifier', 'LI-PS-PDU', 'TimeStampQualifier') fixDottedReference(dr, 'ILHIPDU', 'ILHITimestamp', 'qualifiedDateTime', 'Common-Parameters', 'QualifiedDateTime') fixDottedReference(dr, 'ILHIPDU', 'ILHITimestamp', 'qualifiedMicrosecondDateTime', 'Common-Parameters', 'QualifiedMicrosecondDateTime') fixDottedReference(dr, 'ILHIPDU', 'OriginalTimestamp', 'microSecondTimeStamp', 'LI-PS-PDU', 'MicroSecondTimeStamp') fixDottedReference(dr, 'ILHIPDU', 'LocationMapping', 'originalLocation', 'LI-PS-PDU', 'Location') fixDottedReference(dr, 'ILHIPDU', 'GeocodedLocationData', 'wGS84CoordinateDecimal', 'Common-Parameters', 'WGS84CoordinateDecimal') fixDottedReference(dr, 'ILHIPDU', 'GeocodedLocationData', 'wGS84CoordinateAngular', 'Common-Parameters', 'WGS84CoordinateAngular') c = compile_dict(dr) except CompileError as ex: logging.info (f"Compiler error: {ex}") errors.append(ex) return errors, None except ParseError as ex: logging.info (f"Parse error: {ex}") errors.append(ex) return errors, None logging.info ("Compiled OK") return errors, c def validateASN1Files (fileList): parseErrors = parseASN1Files(fileList) errorCount = sum([len(v) for k,v in parseErrors.items()]) if errorCount > 0: logging.info ("Abandoning compile due to parse errors") return parseErrors, [], None compileErrors, parser = compileASN1Files(fileList) return parseErrors, compileErrors, parser def validateAllASN1FilesInPath (path): p = Path(path) fileGlob = [str(f) for f in p.rglob('*.asn')] fileGlob += [str(f) for f in p.rglob('*.asn1')] return validateASN1Files(fileGlob)