Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into fix-licensekey-remo…
Browse files Browse the repository at this point in the history
…ve-clone

* upstream/main:
  chore: Document status of all C API bindings (#162)
  feat: Add parameter wrapper and example (#161)
  fix(mdb)!: Give callbacks references to errors (#116)
  refactor(axevent): Wrap borrowed `KeyValueSet` in `ManuallyDrop` (#159)
  fix(axevent): Allow undeclaring without callback (#157)
  fix(axevent): Free `KeyValueSet` when creating `Event` (#156)
  fix(axevent)!: Take ownership of returned value in `get_string` (#149)
  chore: Document how to use address sanitizer (#152)
  refactor(mdb): Move error to separate module (#155)
  feat(mdb): Improve ergonomics for consumer (#115)
  chore: Update acap-native-sdk to 12.1.0 (#154)
  chore: Run FFI patterns under Miri (#140)
  • Loading branch information
apljungquist committed Dec 18, 2024
2 parents b534a9e + eb36c7d commit 3ddf08f
Show file tree
Hide file tree
Showing 36 changed files with 1,864 additions and 256 deletions.
5 changes: 3 additions & 2 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
ARG REPO=axisecp
ARG SDK=acap-native-sdk
ARG UBUNTU_VERSION=22.04
# Keep in sync with `install-sdk.sh` and `on-host-workflow.yml`.
ARG UBUNTU_VERSION=24.04
# Keep in sync with `install-sdk.sh`.
ARG VERSION=1.15
ARG VERSION=12.1.0
ARG BASE_IMAGE=debian:bookworm-20240423

FROM --platform=linux/amd64 ${REPO}/${SDK}:${VERSION}-aarch64-ubuntu${UBUNTU_VERSION} AS sdk-aarch64
Expand Down
4 changes: 2 additions & 2 deletions .devhost/install-sdk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set -eux
DIRECTORY="${1}"

# Keep version in sync with `Dockerfile`.
docker run axisecp/acap-native-sdk:1.15-armv7hf-ubuntu22.04 tar \
docker run axisecp/acap-native-sdk:12.1.0-armv7hf-ubuntu24.04 tar \
--create \
--directory /opt/ \
--file - \
Expand All @@ -18,7 +18,7 @@ docker run axisecp/acap-native-sdk:1.15-armv7hf-ubuntu22.04 tar \
--strip-components 1

# Keep version in sync with `Dockerfile`.
docker run axisecp/acap-native-sdk:1.15-aarch64-ubuntu22.04 tar \
docker run axisecp/acap-native-sdk:12.1.0-aarch64-ubuntu24.04 tar \
--create \
--directory /opt/ \
--file - \
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:

jobs:
build:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -21,3 +21,5 @@ jobs:
run: devcontainer exec --remote-env ACAP_BUILD_IMPL=equivalent --workspace-folder . make check_generated_files_container
- name: Run other checks
run: devcontainer exec --workspace-folder . make check_other
- name: Run miri check
run: devcontainer exec --workspace-folder . make check_miri
6 changes: 3 additions & 3 deletions .github/workflows/on-host-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ on:

jobs:
debian_and_ubuntu:
runs-on: ubuntu-22.04
# This procedure should work on:
runs-on: ubuntu-24.04
# Additionally, this procedure should work on:
# - Debian 12 on desktop.
# - Ubuntu 22.04 on desktop.
#
Expand Down Expand Up @@ -56,7 +56,7 @@ jobs:
export ACAP_BUILD_IMPL=equivalent
make check_generated_files
debian_and_ubuntu_no_sdk:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
# If the sysroots from the ACAP Native SDK are not needed, then the Rust implementation of
# `acap-build` can be used for an easier setup:
steps:
Expand Down
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ acap-ssh-utils = { path = "crates/acap-ssh-utils" }
acap-vapix = { path = "crates/acap-vapix" }
axevent = { path = "crates/axevent" }
axevent-sys = { path = "crates/axevent-sys" }
axparameter = { path = "crates/axparameter" }
axparameter-sys = { path = "crates/axparameter-sys" }
axstorage = { path = "crates/axstorage" }
axstorage-sys = { path = "crates/axstorage-sys" }
bbox = { path = "crates/bbox" }
Expand Down
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,14 @@ check_lint:
-Dwarnings
.PHONY: check_lint

## Check that risky FFI patterns are sound using miri
check_miri:
rustup +nightly component add miri
cargo +nightly miri test \
--package ffi_patterns \
--target aarch64-unknown-linux-gnu \
--target thumbv7neon-unknown-linux-gnueabihf

## _
check_tests:
cargo test \
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,24 +124,37 @@ grouped in a similar way as in the ACAP Native SDK APIs documentation.
### ACAP Native API bindings

These are idiomatic and safe bindings for the C APIs.
These are idiomatic and safe bindings for the [C APIs](https://axiscommunications.github.io/acap-documentation/docs/api/native-sdk-api.html#native-sdk-api).
Each crate has a corresponding `*-sys`, which is omitted for brevity.

- `axparameter`: Bindings for the Parameter API.
- Status: ⚠️ Alpha
- Documentation: [Source code](crates/axparameter/src/lib.rs)
- `axevent`: Bindings for the Event API.
- Status: ⚠️ Alpha
- Documentation: [Source code](crates/axevent/src/lib.rs)
- `axoverlay`: Bindings for the Overlay API
- Status: 📄 Not started
- `axserialport`: Bindings for the Serial Port API
- Status: 📄 Not started
- `axstorage`: Bindings for the Edge Storage API.
- Status: ⚠️ Alpha
- Documentation: [Source code](crates/axstorage/src/lib.rs)
- `bbox`: Bindings for the Bounding Box API.
- Status: ⚠️ Alpha
- Documentation: [Source code](crates/bbox/src/lib.rs)
- `larod`: Bindings for the Machine Learning API.
- Status: 💡 Started
- Documentation: [Pull request](https://github.com/AxisCommunications/acap-rs/pull/120)
- `licensekey`: Bindings for the License Key API.
- Status: ⚠️ Alpha
- Documentation: [Source code](crates/licensekey/src/lib.rs)
- `mdb`: Bindings for the Message Broker API.
- Status: ⚠️ Alpha
- Documentation: [Source code](crates/mdb/src/lib.rs)
- `vdo`: Bindings for the Video Capture API.
- Status: 💡 Started
- Documentation: [Pull request](https://github.com/AxisCommunications/acap-rs/pull/153)

### VAPIX API bindings

Expand Down Expand Up @@ -171,6 +184,9 @@ by this project.

### Example applications

- `axparameter_example`: Creates, reads, updates, deletes, and subscribes to parameters.
- Status: ⚠️ Alpha
- [Source code](apps/axparameter_example/src/main.rs)
- `axstorage_example`: Writes data to files on all connected storages.
- Status: ⚠️ Alpha
- [Source code](apps/axstorage_example/src/main.rs)
Expand Down
5 changes: 3 additions & 2 deletions apps-aarch64.checksum
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
9d66c3ff02cf209762e13cd5d7cd5d91b6da23c2 target-aarch64/acap/Challenge_Build_Tools_1_0_0_all.eap
1fe87dc90ee1fefce2c3bd8f4d6d9ecfdc82b84b target-aarch64/acap/axparameter_example_0_0_0_aarch64.eap
12a30609c7fa463e1e8d0405665d2aa17d4349c4 target-aarch64/acap/axstorage_example_0_0_0_aarch64.eap
6db963922ca2ceb25715bbdb6445b504c307d432 target-aarch64/acap/bounding_box_example_0_0_0_aarch64.eap
f99e344e5bf6fc4cd59715b9a4b784a83df27342 target-aarch64/acap/consume_analytics_metadata_0_0_0_aarch64.eap
893f45edfd097fe6f6ffc4ba2210160a32600a6d target-aarch64/acap/consume_analytics_metadata_0_0_0_aarch64.eap
ad1142937ed6e2d4f2a1f4cb0fdae721a0744750 target-aarch64/acap/embedded_web_page_0_0_0_aarch64.eap
f47872232e0f2cd4ace9e2e77b07cafb431cbe73 target-aarch64/acap/hello_world_0_0_0_aarch64.eap
75818664787ff2ff7dbdd32fadfe20c23974c867 target-aarch64/acap/inspect_env_0_0_0_aarch64.eap
9d205dbde1b7144d30fb4c5a45fcaef93cb12810 target-aarch64/acap/licensekey_handler_0_0_0_aarch64.eap
ed84b4b9ae09256dcef1a7287cd802e39c8b6a92 target-aarch64/acap/reverse_proxy_0_0_0_aarch64.eap
aee472d1e21f50694fc495c3483ba3dc7bae21e7 target-aarch64/acap/send_event_1_0_0_aarch64.eap
6d3ebfbd5a42e864faf970c7595309c78b0a00c9 target-aarch64/acap/send_event_1_0_0_aarch64.eap
e8bfb22e1b1416bff9d33980839ccbc8ce4b9d16 target-aarch64/acap/using_a_build_script_0_0_0_aarch64.eap
5a533b71d01edb65d15751dd93fa153f5ef343ea target-aarch64/acap/vapix_access_0_0_0_aarch64.eap
3 changes: 2 additions & 1 deletion apps-aarch64.filesize
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
859 target-aarch64/acap/Challenge_Build_Tools_1_0_0_all.eap
3628 target-aarch64/acap/axparameter_example_0_0_0_aarch64.eap
3698 target-aarch64/acap/axstorage_example_0_0_0_aarch64.eap
2213 target-aarch64/acap/bounding_box_example_0_0_0_aarch64.eap
2083 target-aarch64/acap/consume_analytics_metadata_0_0_0_aarch64.eap
Expand All @@ -7,6 +8,6 @@
2136 target-aarch64/acap/inspect_env_0_0_0_aarch64.eap
2060 target-aarch64/acap/licensekey_handler_0_0_0_aarch64.eap
10425 target-aarch64/acap/reverse_proxy_0_0_0_aarch64.eap
4087 target-aarch64/acap/send_event_1_0_0_aarch64.eap
4089 target-aarch64/acap/send_event_1_0_0_aarch64.eap
859 target-aarch64/acap/using_a_build_script_0_0_0_aarch64.eap
11361 target-aarch64/acap/vapix_access_0_0_0_aarch64.eap
12 changes: 12 additions & 0 deletions apps/axparameter_example/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "axparameter_example"
version = "0.0.0"
edition.workspace = true
publish = false

[dependencies]
glib = { workspace = true }
log = { workspace = true }

acap-logging = { workspace = true }
axparameter = { workspace = true }
26 changes: 26 additions & 0 deletions apps/axparameter_example/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"schemaVersion": "1.7.0",
"acapPackageConf": {
"setup": {
"appName": "axparameter_example",
"embeddedSdkVersion": "2.0",
"vendor": "Axis Communications",
"runMode": "never",
"version": "0.0.0"
},
"configuration": {
"paramConfig": [
{
"name": "TestParameter",
"default": "TestValue2",
"type": "string"
},
{
"name": "w",
"default": "initial_value",
"type": "string"
}
]
}
}
}
110 changes: 110 additions & 0 deletions apps/axparameter_example/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use axparameter::{error::ParameterError, parameter::Parameter, types::ControlWord};
use log::{error, info};

const APP_NAME: &str = "axparameter_example";

fn main() {
acap_logging::init_logger();

let main_loop = glib::MainLoop::new(None, false);
glib::unix_signal_add_once(15, {
let main_loop = main_loop.clone();
move || main_loop.quit()
});
glib::unix_signal_add_once(2, {
let main_loop = main_loop.clone();
move || main_loop.quit()
});

info!("Starting {APP_NAME}");

let parameter = Parameter::new(APP_NAME).unwrap();

if let Err(err) = parameter.add("Parameter", None, "param".to_string()) {
if !err.matches::<ParameterError>(ParameterError::ParamAdded) {
error!("Failed {}", err);
return;
}
}

if let Err(err) = parameter.add("ParameterTwo", None, "param_two".to_string()) {
if !err.matches::<ParameterError>(ParameterError::ParamAdded) {
error!("Failed {}", err);
return;
}
}

if let Err(err) = parameter.add("ParameterThree", None, "param_three".to_string()) {
if !err.matches::<ParameterError>(ParameterError::ParamAdded) {
error!("Failed {}", err);
return;
}
}

if let Err(err) = parameter.add(
"ParameterFour",
Some(ControlWord::ReadOnly),
"param_four".to_string(),
) {
if !err.matches::<ParameterError>(ParameterError::ParamAdded) {
error!("Failed {}", err);
return;
}
}

let value: String = match parameter.get("Parameter") {
Ok(value) => value,
Err(err) => {
error!("Failed {}", err);
return;
}
};

info!("The value of \"Parameter\" is \"{}\"", value);

let value: String = match parameter.get("ParameterFour") {
Ok(value) => value,
Err(err) => {
error!("Failed {}", err);
return;
}
};

info!("The value of \"ParameterFour\" is \"{}\"", value);

if let Err(err) = parameter.remove("ParameterThree") {
error!("Failed {}", err);
return;
}

if let Err(err) = parameter.set("Parameter", "param_set".to_string(), true) {
error!("Failed {}", err);
return;
}

if let Ok(()) = parameter.set("ParameterFour", "param_four_set".to_string(), true) {
error!("Failed ParameterFour should be ReadOnly");
return;
}

if let Ok(list) = parameter.list() {
for param in list {
info!("Parameter in list: \"{}\"", param);
}
} else {
error!("Failed {}", value);
return;
}

if let Err(err) = parameter.register_callback("Parameter", |_name, _value| {
info!("In Parameter callback");
}) {
error!("Failed {}", err);
return;
}

main_loop.run();
}

#[cfg(test)]
mod tests;
Loading

0 comments on commit 3ddf08f

Please sign in to comment.