MAVInspect
==========

Rust library for parsing [MAVLink](https://mavlink.io/en/) XML definitions. A part of
[`Mavka`](https://mavka.gitlab.io/home/) initiative.

[`repository`](https://gitlab.com/mavka/libs/mavinspect)
[`crates.io`](https://crates.io/crates/mavinspect)
[`API docs`](https://docs.rs/mavinspect/latest/mavinspect/)
[`issues`](https://gitlab.com/mavka/spec/libs/mavinspect/-/issues)

MAVLink is a lightweight open protocol for communicating between drones, onboard components and ground control stations.
It is used by such autopilots like [PX4](https://px4.io) or [ArduPilot](https://ardupilot.org/#). MAVLink has simple and
compact serialization model. The basic abstraction is `message` which can be sent through the link (UDP, TCP, UNIX
socket, UART, whatever) and deserialized into a struct with fields of primitive types or arrays of primitive types.
Such fields can be additionally restricted by `enum` variants, annotated with metadata like units of measurements,
default or invalid values. There are several MAVLink dialects. Official dialect definitions are XML whiles that can be
found in the MAVlink [repository](https://github.com/mavlink/mavlink/tree/master/message_definitions/v1.0). Based on
`message` abstractions, MAVLink defines so-called [`microservices`](https://mavlink.io/en/services/) that specify how
clients should respond on a particular message under certain conditions or how they should initiate a particular action.

This library is a building block for other MAVLink-related tools (code generators, telemetry collectors, IO, etc.). We
intentionally moved everything which is not related to protocol inspection to other [Mavka](https://mavka.gitlab.io/home/)
project such as:

* [MAVSpec](https://gitlab.com/mavka/libs/mavspec) that responsible for code generation.
* [Mavio](https://gitlab.com/mavka/libs/mavio), a minimalistic library for transport-agnostic MAVLink communication 
  written in Rust. It supports `no-std` (and `no-alloc`) targets and focuses on stateless parts of MAVLink protocol.
* [Maviola](https://gitlab.com/mavka/libs/maviola) (WIP), an elaborated MAVLink communication library based on `Mavio`
  that takes care about stateful features: sequencing, message time-stamping, automatic heartbeats, simplifies message
  signing, and so on.

This library respects [`semantic versioning`](https://semver.org).

Usage
-----

Parse standard and custom XML definitions from [`./message_definitions`](./message_definitions):

```rust
use std::env;

use mavinspect::parser::XMLInspector;

fn main() {
    // Instantiate inspector and load list of XML definitions
    let inspector = XMLInspector::builder()
        .set_sources(vec![
            "./message_definitions/standard".to_string(),
            "./message_definitions/extra".to_string(),
        ])
        .build()
        .unwrap();
    
    // Parse all XML definitions
    let protocol = inspector.parse().unwrap();
    
    // Get `crazyflight` custom dialect
    let crazyflight = protocol.dialects().get("crazy_flight").unwrap();
    
    // Get `DUMMYFLIGHT_OUTCRY` message
    let outcry_message = crazyflight.messages().get(&54000u32).unwrap();
    assert_eq!(outcry_message.name(), "CRAZYFLIGHT_OUTCRY");
    println!("\n`CRAZYFLIGHT_OUTCRY` message: {:#?}", outcry_message);
}
```

See [examples](#examples) and [`API documentation`](https://docs.rs/mavinspect/latest/mavinspect/) for advanced usage.

Examples
--------

- [`parser`](./examples/parser.rs) — parse XML definitions.
  ```shell
  cargo run --example parser --features=serde
  ```

Roadmap
-------

API is considered relatively stable but certain advanced features are yet to be developed. However, most of these
features are nice to have, rather than something necessary to consider this library complete. Which means that such
features will prioritized only in the case of articulated demand from community.

- [x] Add standalone examples.
- [x] Accept multiple folders with XML definitions.
- [x] Implement `CRC_EXTRA` calculation.
- [x] Add more utility functions for fields management.
- [ ] Add more examples to docs.
- [ ] Create abstractions for [MAVLink commands](https://mavlink.io/en/services/command.html).
- [ ] Implement conversion to [Protobuf](https://gitlab.com/mavka/libs/mavinspect/-/issues) letting non-Rust
  clients to use this library. WIP specification can be found
  [here](https://gitlab.com/mavka/spec/protocols/mavlink/message-definitions-v1-proto).
- [ ] Create [gRPC](https://grpc.io) server and client to serve MAVLink specifications for non-rust clients. Service
  definition is under development [here](https://gitlab.com/mavka/spec/libs/mavinspect).

[Propositions](https://gitlab.com/mavka/spec/libs/mavinspect/-/issues) and
[pull-requests](https://gitlab.com/mavka/spec/libs/mavinspect/-/merge_requests) are welcomed.

Other MAVLink Tools
-------------------

First of all, there is an official MAVLink client for Rust worth mentioning:
[`rust-mavlink`](https://github.com/mavlink/rust-mavlink).

Also I was personally inspired by [`gomavlib`](https://github.com/bluenviron/gomavlib) library for MAVLink. I like the
way it is written, and its source code helped me in several cases when official MAVLink documentation wasn't clear
enough.

If you want to autogenerate language bindings and prefer Python, you might be interested in the official
[`mavgen`](https://mavlink.io/en/getting_started/generate_libraries.html#mavgen) code-generation tool. If you are
looking for a router for MAVLink messages, then we suggest [`mavp2p`](https://github.com/bluenviron/mavp2p). If
you want a solution that supports MAVLink microservices, then it worth checking [`MAVSDK`](https://github.com/mavlink/MAVSDK)
that uses Protobuf.

MAVLink is almost 15 years old, but the ecosystem around this protocol is still dynamic and developing. Some projects are
stable and robust, while others are nice and feature-rich but incomplete.

Acknowledgements
----------------

I've used images from [Flaticon](https://www.flaticon.com) to create project avatars.

License
-------

> Here we simply comply with the suggested dual licensing according to
> [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/about.html) (C-PERMISSIVE).

Licensed under either of

* Apache License, Version 2.0
  ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
  ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

Contribution
------------

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.
