pycrate icon indicating copy to clipboard operation
pycrate copied to clipboard

Update the 3GPP LTE and NR ASN.1 specs to Rel.18

Open frankist opened this issue 5 months ago • 3 comments

Hi there,

Could you give some tips on how to convert the 3GPP TS docs/pdfs to asn files? Is there any tool that you recommend?

I would be particularly interested in bumping the versions of the E1AP (now in 37.483), F1AP, NGAP and NR RRC.

frankist avatar Jul 18 '25 11:07 frankist

Ok, I wrote a script that seems to work for the E1AP, in case anyone is interested:

from docx import Document
import argparse
import os


def docx_to_txt(input_path, output_path):
    print(f'Converting "{input_path}" to "{output_path}..."')
    doc = Document(input_path)
    with open(output_path, 'w', encoding='utf-8') as f:
        for para in doc.paragraphs:
            f.write(para.text + '\n')


def extract_asn1_blocks(input_path):
    print(f'Extracting ASN1 code from {input_path}...')
    blocks = {}
    OUTSIDE_BLOCK = 1
    INSIDE_BLOCK = 2
    mode = OUTSIDE_BLOCK
    mod_name = None
    cur_block = []
    with open(input_path, 'r') as f:
        for l in f:
            if l.startswith('-- ASN1START'):
                assert mode != INSIDE_BLOCK
                mode = INSIDE_BLOCK
            elif l.startswith('-- ASN1STOP'):
                assert mode != OUTSIDE_BLOCK
                assert len(cur_block) > 0 and mod_name is not None
                mode = OUTSIDE_BLOCK
                blocks[mod_name] = cur_block
                mod_name = None
                cur_block = []
            elif mode == INSIDE_BLOCK:
                cur_block.append(l)
                if mod_name is None and '{' in l:
                    mod_name = l.split()[0]
    return blocks


def write_asn1_blocks(blocks, output_dir):
    for name, lines in blocks.items():
        fname = os.path.join(output_dir, name) + '.asn'
        with open(fname, 'w') as f:
            for l in lines:
                f.write(l)


def main():
    parser = argparse.ArgumentParser(description="Extract ASN.1 from a DOCX file.")
    parser.add_argument('-i', '--docx', required=True, help="Path to input docx")
    parser.add_argument('-o', '--dir', required=True, help="Path to output directory")

    args = parser.parse_args()
    
    # Convert docx to txt
    txt_file = os.path.splitext(os.path.basename(args.docx))[0] + '.txt'
    txt_file = os.path.join(args.dir, txt_file)
    docx_to_txt(args.docx, txt_file)

    # Extract ASN1 blocks
    blocks = extract_asn1_blocks(txt_file)

    # Write ASN blocks to respective files
    write_asn1_blocks(blocks, args.dir)


if __name__ == '__main__':
    main()

frankist avatar Jul 18 '25 13:07 frankist

Thanks for submitting this script. In terms of maintenance of this project: I want to bump all the 4G and 5G RAN specs at once, to keep consistency. This requires some time and attention, even when ASN.1 extraction is automated. Currently, the lib is aligned to a Rel.17 from ~2 years ago.

mitshell avatar Aug 11 '25 20:08 mitshell

The 3GPP Rel.18 stage 3 is frozen since almost a year. This may be a good opportunity for me to update those specs.

mitshell avatar Aug 11 '25 20:08 mitshell