#cbor #no-std #sen-ml

no-std senml-deser

Library for serialization and deserialization using SenML specifications

1 unstable release

0.2.1 Feb 16, 2024

#443 in Embedded development

49 downloads per month

OLFL-1.3

56KB
1K SLoC

SenML DeSer

SenML De-serialization and Serialization [no_std]

Sensor Measurement Lists (SenML) implementation (needs neither std nor alloc). For detailed information about SenML refer to REF8428.

Currently, the only supported serialization format is CBOR.

Usage

Serialization is done with the help of the Record structure and the Pack that can hold multiple Record instances. For successful serialization, make sure to have the base_name or name fields set.

use senml_deser::{
    content::{record::Record, record::Values, pack::Pack},
    deser::ser::Encoder,
    Cbor
};

fn main() {
    // creating the pack
    let mut pack = Pack::<Cbor>::new();

    // Create a common Record that can hold any SenML fields
    let record = Record::<Cbor>{
        base_name: Some("device/instance0/"),
        name: Some("manufacturer"),
        value: Some(Values::StringValue("Fraunhofer-IML")),
        ..Default::default()
    };

    pack.add_record(record).unwrap();

    // Use convenience function to directly add common name/value records
    pack.add_string_value_record("version", "1.0").unwrap();
    pack.add_value_record("battery_level", 42_f64).unwrap();

    // Crate the encoder and encode the pack
    let mut buf = [0_u8; 1024];
    let mut encoder = Encoder::new(&mut buf);

    // Get the encoded bytes
    if let Ok(encoded_data) = encoder.cbor_encode(pack) {
        println!(
            "encoded:\n{:02x?}\nlength: {}\n",
            encoded_data,
            encoded_data.len()
        );
    }
}

Deserialization works similar:

use senml_deser::{content::pack::Pack, deser::de::Decoder};

fn main() {
    // Have the encoded data
    let encoded_data: &[u8] = &[
        0x83, 0xa3, 0x21, 0x71, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x69, 0x6e, 0x73, 0x74,
        0x61, 0x6e, 0x63, 0x65, 0x30, 0x2f, 0x00, 0x6c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63,
        0x74, 0x75, 0x72, 0x65, 0x72, 0x03, 0x6e, 0x46, 0x72, 0x61, 0x75, 0x6e, 0x68, 0x6f, 0x66,
        0x65, 0x72, 0x2d, 0x49, 0x4d, 0x4c, 0xa2, 0x00, 0x67, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
        0x6e, 0x03, 0x63, 0x31, 0x2e, 0x30, 0xa2, 0x00, 0x6d, 0x62, 0x61, 0x74, 0x74, 0x65, 0x72,
        0x79, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x02, 0x18, 0x2a,
    ];
    // Create the Decoder
    let mut decoder = Decoder::new();
    // We need to provide a scratch array for the decoder
    let mut scratch = [0_u8; 1024];
    // Deserialize the data
    let decoded_record_list= decoder.decode_cbor(encoded_data, &mut scratch).unwrap();
    // The Package supplies a EntryIterator to iterate over the decoded entries
    for record in decoded_record_list.records_iter() {
        // Note that the decoded entries will always have the full path/name (base_name + name)
        println!("{record:?}");
    }
}

License

Open Logistics Foundation License Version 1.3, January 2023

See the LICENSE file in the top directory.

Contact Information

Fraunhofer IML Embedded Rust Group - embedded-rust@iml.fraunhofer.de

Dependencies

~1.4–2MB
~44K SLoC