ystero-dev / hampi

Rust ASN.1 Toolkit
Other
43 stars 18 forks source link

Decoding an S1AP message #76

Closed ghost closed 1 year ago

ghost commented 1 year ago

Hello Is there an example that shows how to decode a message encoded with APER codec? For example, take the following message (which is an S1AP message) and return its Information Elements such as MME-UE-S1AP-ID or Cause.

msg = "0004001A00000300000005C0098134A200080004800411EA000240020000"

gabhijit commented 1 year ago

I believe something like this can be used -

    use asn1_codecs::{aper::AperCodec, PerCodecData};

    let decode_str = "0004001A00000300000005C0098134A200080004800411EA000240020000";
    let decode_hex = hex::decode(decode_str).unwrap();
    let mut codec_data = PerCodecData::from_slice_aper(&decode_hex);
    let s1ap_pdu = s1ap::S1AP_PDU::aper_decode(&mut codec_data);

    eprintln!("s1ap_pdu: {:#?}", s1ap_pdu.unwrap());

This is the generated output -

s1ap_pdu: InitiatingMessage(
    InitiatingMessage {
        procedure_code: ProcedureCode(
            4,
        ),
        criticality: Criticality(
            0,
        ),
        value: Id_HandoverCancel(
            HandoverCancel {
                protocol_i_es: HandoverCancelProtocolIEs(
                    [
                        HandoverCancelProtocolIEs_Entry {
                            id: ProtocolIE_ID(
                                0,
                            ),
                            criticality: Criticality(
                                0,
                            ),
                            value: Id_MME_UE_S1AP_ID(
                                MME_UE_S1AP_ID(
                                    159462562,
                                ),
                            ),
                        },
                        HandoverCancelProtocolIEs_Entry {
                            id: ProtocolIE_ID(
                                8,
                            ),
                            criticality: Criticality(
                                0,
                            ),
                            value: Id_eNB_UE_S1AP_ID(
                                ENB_UE_S1AP_ID(
                                    266730,
                                ),
                            ),
                        },
                        HandoverCancelProtocolIEs_Entry {
                            id: ProtocolIE_ID(
                                2,
                            ),
                            criticality: Criticality(
                                1,
                            ),
                            value: Id_Cause(
                                RadioNetwork(
                                    CauseRadioNetwork(
                                        0,
                                    ),
                                ),
                            ),
                        },
                    ],
                ),
            },
        ),
    },
)

You can look at examples/tests/13-ngap.rs for some of this usage. Maybe I will I use this as a test for s1ap decode in examples/tests/12-s1ap.rs.

gabhijit commented 1 year ago

Added example for decoding S1AP message in #77 . Once this is merged, will close the issue. Hope that is fine.

ghost commented 1 year ago

Excellent. thank you

ghost commented 1 year ago

Using the hampi-rs-asn1c tool, I generate the s1ap.rs file. How do I use this file in my project? (like the example you mentioned above). My project directory structure is as follows:

Cargo.lock Cargo.toml src --- main.rs

Cargo.toml: [dependencies] asn1-codecs = "0.5.5" hex = "0.4.3"

main.rs

use asn1_codecs::{aper::AperCodec, PerCodecData};
use hex;

fn main() {
    let decode_str = "0004001A00000300000005C0098134A200080004800411EA000240020000";
    let decode_hex = hex::decode(decode_str).unwrap();
    let mut codec_data = PerCodecData::from_slice_aper(&decode_hex);
    let s1ap_pdu = s1ap::S1AP_PDU::aper_decode(&mut codec_data); // ?

    eprintln!("s1ap_pdu: {:#?}", s1ap_pdu.unwrap());
}
gabhijit commented 1 year ago

One of the simplest ways of using this is using the build.rs mechanism. If you take a look at the build.rs in examples directory and how it is used, it should give you an idea. But before that you will need to have s1ap ASN.1 specifications. You can of course use the ones from the examples/specs directory, but those are files mainly used as examples/ and may not be suitable for your use-case.

The way this works is as follows -

  1. Get the ASN.1 spec file (.asn file). You can use the examples/specs/parse_spec.py file for this. This is also explained in the README.md file (I believe it is a bit difficult to find out.)
  2. Place this file in some path and use the build.rs mechanism or hampi-rs-asn1c CLI tool to generate s1ap.rs file.
  3. Place the file in right path (build.rs is more automated.) Hope this helps