blf_asc 0.2.0

Read/write Vector BLF and ASC (CAN log) files.
Documentation
  • Coverage
  • 0%
    0 out of 45 items documented0 out of 29 items with examples
  • Size
  • Source code size: 85.74 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 7.53 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 21s Average build duration of successful builds.
  • all releases: 22s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • chirikoro/blf_asc
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • chirikoro

blf_asc

A small Rust library for reading and writing Vector BLF and ASC (CAN log) files, modeled after python-can behavior.

crates.io docs.rs license

Documentation: docs.rs/blf_asc

Features

  • BLF reader with Iterator<Item = Message>
  • BLF writer with on_message_received (python-can-like)
  • ASC (Vector) reader/writer
  • Supports CAN classic, CAN FD, and error frames
  • Zlib compression for BLF (default level = -1, same intent as python-can)

Installation

[dependencies]
blf_asc = "0.2"

Usage

Read BLF

use blf_asc::{BlfReader, Result};

fn main() -> Result<()> {
    let mut reader = BlfReader::open("input.blf")?;
    for msg in reader.by_ref() {
        // msg: Message
        println!("id={} dlc={} data={:?}", msg.arbitration_id, msg.dlc, msg.data);
    }
    if let Some(err) = reader.take_error() {
        eprintln!("reader error: {err}");
    }
    Ok(())
}

Note: msg.data is DataBytes (hex-friendly). println!("{:?}", msg.data) prints hex. The helper msg.data_hex() returns a hex string, and msg.arbitration_id_hex() prints the ID as hex.

Write BLF (python-can style)

use blf_asc::{BlfWriter, Message, Result};

fn main() -> Result<()> {
    let mut writer = BlfWriter::create("output.blf")?; // default compression level = -1

    let msg = Message {
        timestamp: 0.0,
        arbitration_id: 0x123.into(),
        is_extended_id: false,
        is_remote_frame: false,
        is_rx: true,
        is_error_frame: false,
        is_fd: false,
        bitrate_switch: false,
        error_state_indicator: false,
        dlc: 3,
        data: vec![0x11, 0x22, 0x33].into(),
        channel: 0, // 0-based (channel 1 in BLF/ASC)
    };

    writer.on_message_received(&msg)?;
    writer.finish()?;
    Ok(())
}

Read ASC

use blf_asc::{AscReader, Result};

fn main() -> Result<()> {
    let mut reader = AscReader::open("input.asc")?; // default: base hex, relative timestamps
    for msg in reader.by_ref() {
        println!("id={} dlc={} data={:?}", msg.arbitration_id, msg.dlc, msg.data);
    }
    if let Some(err) = reader.take_error() {
        eprintln!("reader error: {err}");
    }
    Ok(())
}

Write ASC

use blf_asc::{AscWriter, Message, Result};

fn main() -> Result<()> {
    let mut writer = AscWriter::create("output.asc")?;

    let msg = Message {
        timestamp: 1710000000.123,
        arbitration_id: 0x123.into(),
        is_extended_id: false,
        is_remote_frame: false,
        is_rx: true,
        is_error_frame: false,
        is_fd: false,
        bitrate_switch: false,
        error_state_indicator: false,
        dlc: 3,
        data: vec![0x11, 0x22, 0x33].into(),
        channel: 0,
    };

    writer.on_message_received(&msg)?;
    writer.finish()?;
    Ok(())
}

Convert BLF <-> ASC

use blf_asc::{AscReader, AscWriter, BlfReader, BlfWriter, Result};

fn blf_to_asc(input: &str, output: &str) -> Result<()> {
    let reader = BlfReader::open(input)?;
    let mut writer = AscWriter::create(output)?;
    for msg in reader {
        writer.on_message_received(&msg)?;
    }
    writer.finish()?;
    Ok(())
}

fn asc_to_blf(input: &str, output: &str) -> Result<()> {
    // Use absolute timestamps from ASC header/triggerblock.
    let reader = AscReader::open_with_options(input, "hex", false)?;
    let mut writer = BlfWriter::create(output)?;
    for msg in reader {
        writer.on_message_received(&msg)?;
    }
    writer.finish()?;
    Ok(())
}

Notes

  • Message::channel is 0-based. It is serialized as channel+1 in BLF/ASC, matching python-can conventions.
  • BLF object types supported: CAN_MESSAGE, CAN_MESSAGE2, CAN_ERROR_EXT, CAN_FD_MESSAGE, CAN_FD_MESSAGE_64.
  • ASC timestamp precision is milliseconds. A BLF -> ASC -> BLF roundtrip will lose sub-millisecond precision.

License

Licensed under either of

  • Apache License, Version 2.0
  • MIT license

at your option.

Release

This repo includes release.toml for cargo-release.

Typical flow:

  1. cargo release patch