1# Development with Cargo 2 3Although this library are built by Android build system officially, we can also 4build and test the library by cargo. 5 6## Building `uwb_uci_packets` package 7 8The `uwb_uci_packets` package depends on `pdlc and thus simply using `cargo 9build` will fail. Follow the steps below before using cargo. 10 111. Enter Android environment by `source build/make/rbesetup.sh; lunch <target>` 122. Run `m pdlc` to compile the `pdlc` Rust binary. 13 14After that, we could build or test the package by `cargo test --features proto`. 15 16## Enable logging for a certain test case of uwb\_core library 17 18When debugging a certain test case, we could enable the logging and run the 19single test case. 20 211. Add `crate::utils::init_test_logging();` at the beginning of the test case 222. Run the single test case by: 23``` 24RUST_LOG=debug cargo test -p uwb_core <test_case_name> -- --nocapture 25``` 26 27# Code Architecture 28 29This section describes the main modules of this library. The modules below are 30listed in reversed topological order. 31 32## The uwb\_uci\_packets crate 33 34The `uwb_uci_packets` crate is aimed for encoding and decoding the UCI packets. 35All the details of the UCI packet format should be encapsulated here. That 36means, the client of this crate should not be aware of how the UCI messages are 37constructed to or parsed from raw byte buffers. 38 39The crate is mainly generated from the PDL file. However, in the case where a 40UCI feature cannot be achieved using PDL alone, a workaround should be created 41inside this crate to complete this feature (i.e. define structs and implement 42the parsing methods manually) to encapsulate the details of UCI packet format. 43 44Note that the interface of the workaround should be as close to PDL-generated 45code as possible. 46 47 48## params 49 50The params modules defines the parameters types, including UCI, FiRa, and CCC 51specification. 52 53This module depends on the `uwb_uci_packets` crate. To prevent the client of 54this module directly depending on the `uwb_uci_packets` crate, we re-expose all 55the needed enums and structs at `params/uci_packets.rs`. 56 57## UCI 58 59The `uci` module is aimed to provide a rust-idiomatic way that implements the 60UCI interface, such as: 61- Declare meaningful arguments types 62- Create a public method for each UCI command, and wait for its corresponding 63 response 64- Create a callback method for each UCI notification 65 66According to the asynchronous nature of the UCI interface, the `UciManager` 67struct provides asynchronous methods using the actor model. For easier usage, 68the `UciManagerSync` struct works as a thin synchronous wrapper. 69 70This module depends on the `params` module. 71 72## Session 73 74The `session` module implements the ranging session-related logic. We support 75the FiRa and CCC specification here. 76 77This module depends on the `params` and `UCI` modules. 78 79## service 80 81The `service` module is aimed to provide a "top-shim", the main entry of this 82library. Similar to the `UciManagerSync`, the `UwbService` struct provides a 83simple synchronous interface to the client of the library. `examples/main.rs` is 84a simple example for using the `UwbService` struct. 85 86If we want to provide the UWB across the process or language boundary, then 87`ProtoUwbService` provices a simple wrapper that converts all the arguments and 88responses to protobuf-encoded byte buffers. 89 90The `service` module depends on `params`, `uci`, and `session` modules. 91