pycrate-org / pycrate

A Python library to ease the development of encoders and decoders for various protocols and file formats, especially telecom ones. Provides an ASN.1 compiler and a CSN.1 runtime.
https://github.com/pycrate-org/pycrate
GNU Lesser General Public License v2.1
39 stars 9 forks source link

How to set IEs in PFCP messages #12

Closed x0ul closed 2 months ago

x0ul commented 3 months ago

Hello, this is more of a question than an issue. I can't seem to figure out how to set an IE in a PFCP message correctly. I have some code like this:

def build_recovery_timestamp(ts: datetime) -> RecoveryTimeStamp:
    pass

Which returns a pycrate PFCP RecoveryTimeStamp IE object. I want to put this recovery time stamp IE into a PFCP heartbeat request message.

This code doesn't work, but it should convey the basic idea of what I'm trying to accomplish: building up a message with pre-created IEs made by other helper functions. How can I accomplish this?

def build_heartbeat_req(seq_num: int, start_time: datetime) -> PFCPHeartbeatReq:
    ts = build_recovery_timestamp(start_time)
    req = PFCPHeartbeatReq(
        val={
            "Hdr": {
                "SeqNum": seq_num,
            },
            "PFCPHeartbeatReqIEs": [ts],
        }
    )

    return req
x0ul commented 3 months ago

After a lot more messing around, I have something that works but still feels like there's room for improvement. I wish I didn't have to specify "Type" and "Data" and call get_val_d on everything. Any thoughts on how to improve this?

def build_heartbeat_req(seq_num: int, start_time: datetime) -> PFCPHeartbeatReq:
    ts = build_recovery_timestamp(start_time)
    ies = PFCPHeartbeatReqIEs(val=[{"Type": PFCPIEType.RecoveryTimeStamp, "Data": ts.get_val_d()}])
    req = PFCPHeartbeatReq(
        val=({"SeqNum": seq_num}, ies.get_val_d())
    )
    return req
mitshell commented 2 months ago

You can assign the value of the whole PFCP message in a single call, like this:

m = PFCPHeartbeatReq(val={
    'Hdr': {'SeqNum': 10},
    'PFCPHeartbeatReqIEs': [
        {'Type': PFCPIEType.RecoveryTimeStamp,  'Data': {'Val': 0x1234}}
        ]})

Generally speaking, PFCP is implemented quite similarly as GTPC. See https://github.com/pycrate-org/pycrate/wiki/Working-with-GTPC.

x0ul commented 2 months ago

Ok, thanks. This is the approach that I've taken. Pity I can't keep things in pycrate data types, but this works.