compile_asn.py 7.11 KB
Newer Older
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)
canterburym's avatar
canterburym committed
        return errors, None
    except ParseError as ex:
        logging.info (f"Parse error: {ex}")
        errors.append(ex)
canterburym's avatar
canterburym committed
        return errors, None
    logging.info ("Compiled OK")
    return errors, c


def validateASN1Files (fileList):
    parseErrors = parseASN1Files(fileList)
canterburym's avatar
canterburym committed
    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)