This is an automated email from the ASF dual-hosted git repository.

ivila pushed a commit to branch main
in repository 
https://gitbox.apache.org/repos/asf/incubator-teaclave-trustzone-sdk.git

commit 4069aacc76185374d7c9bf21240064a2bbbf6102
Author: ivila <[email protected]>
AuthorDate: Tue Mar 25 11:18:14 2025 +0800

    examples: add client_pool-rs
    
    Signed-off-by: Zehui Chen <[email protected]>
    Reviewed-by: Yuan Zhuang <[email protected]>
---
 ci/ci.sh                                           |  1 +
 docs/overview-of-optee-rust-examples.md            |  1 +
 ci/ci.sh => examples/client_pool-rs/Makefile       | 50 ++++--------
 .../client_pool-rs/host/Cargo.toml                 | 54 +++++-------
 ci/ci.sh => examples/client_pool-rs/host/Makefile  | 56 +++++--------
 examples/client_pool-rs/host/src/main.rs           | 48 +++++++++++
 .../client_pool-rs/host/src/pool/connection.rs     | 94 +++++++++++++++++++++
 examples/client_pool-rs/host/src/pool/mobc_pool.rs | 93 +++++++++++++++++++++
 examples/client_pool-rs/host/src/pool/mod.rs       | 44 ++++++++++
 examples/client_pool-rs/host/src/pool/r2d2_pool.rs | 95 ++++++++++++++++++++++
 .../client_pool-rs/proto/Cargo.toml                | 45 +++-------
 examples/client_pool-rs/proto/src/lib.rs           | 36 ++++++++
 ci/ci.sh => examples/client_pool-rs/ta/Cargo.toml  | 53 +++++-------
 examples/client_pool-rs/ta/Makefile                | 45 ++++++++++
 ci/ci.sh => examples/client_pool-rs/ta/Xargo.toml  | 41 ++--------
 examples/client_pool-rs/ta/build.rs                | 23 ++++++
 examples/client_pool-rs/ta/src/main.rs             | 81 ++++++++++++++++++
 examples/client_pool-rs/uuid.txt                   |  1 +
 ci/ci.sh => tests/test_client_pool.sh              | 50 +++++-------
 19 files changed, 677 insertions(+), 234 deletions(-)

diff --git a/ci/ci.sh b/ci/ci.sh
index 8281081..6016891 100755
--- a/ci/ci.sh
+++ b/ci/ci.sh
@@ -37,6 +37,7 @@ pushd ../tests
 ./test_error_handling.sh
 ./test_tcp_client.sh
 ./test_udp_socket.sh
+./test_client_pool.sh
 
 # Run std only tests
 if [ "$STD" ]; then
diff --git a/docs/overview-of-optee-rust-examples.md 
b/docs/overview-of-optee-rust-examples.md
index e731cb7..c440eb2 100644
--- a/docs/overview-of-optee-rust-examples.md
+++ b/docs/overview-of-optee-rust-examples.md
@@ -36,3 +36,4 @@ To compile one of the examples, run `make -C 
examples/EXAMPLE_DIR`.
 | tls_server-rs                | `69547de6-f47e-11eb-994e-f34e88d5c2b4` | Set 
up the TLS server in Trusted Application.                |
 | secure_db_abstraction-rs     | `e55291e1-521c-4dca-aa24-51e34ab32ad9` | An 
abstraction of database base on Secure Storage.           |
 | mnist-rs                     | Train: `1b5f5b74-e9cf-4e62-8c3e-7e41da6d76f6` 
<br/> Infer: `ff09aa8a-fbb9-4734-ae8c-d7cd1a3f6744` | Training and Performing 
Inference in Trusted Application. |
+| client_pool-rs               | `c9d73f40-ba45-4315-92c4-cf1255958729` | 
Generic Client Session Pool.                                 |
diff --git a/ci/ci.sh b/examples/client_pool-rs/Makefile
old mode 100755
new mode 100644
similarity index 56%
copy from ci/ci.sh
copy to examples/client_pool-rs/Makefile
index 8281081..a7a3dec
--- a/ci/ci.sh
+++ b/examples/client_pool-rs/Makefile
@@ -1,5 +1,3 @@
-#!/bin/bash
-
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,37 +15,25 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
+# If _HOST or _TA specific compiler/target are not specified, then use common
+# compiler/target for both
+CROSS_COMPILE_HOST ?= aarch64-linux-gnu-
+CROSS_COMPILE_TA ?= aarch64-linux-gnu-
+TARGET_HOST ?= aarch64-unknown-linux-gnu
+TARGET_TA ?= aarch64-unknown-linux-gnu
+
+.PHONY: host ta all clean
 
-pushd ../tests
+all: host ta
 
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
-./test_tcp_client.sh
-./test_udp_socket.sh
+host:
+       $(q)make -C host TARGET=$(TARGET_HOST) \
+               CROSS_COMPILE=$(CROSS_COMPILE_HOST)
 
-# Run std only tests
-if [ "$STD" ]; then
-    ./test_serde.sh
-    ./test_message_passing_interface.sh
-    ./test_tls_client.sh
-    ./test_tls_server.sh
-    ./test_eth_wallet.sh
-    ./test_secure_db_abstraction.sh
-else
-    ./test_mnist_rs.sh
-fi
+ta:
+       $(q)make -C ta TARGET=$(TARGET_TA) \
+               CROSS_COMPILE=$(CROSS_COMPILE_TA)
 
-popd
+clean:
+       $(q)make -C host clean
+       $(q)make -C ta clean
diff --git a/ci/ci.sh b/examples/client_pool-rs/host/Cargo.toml
old mode 100755
new mode 100644
similarity index 54%
copy from ci/ci.sh
copy to examples/client_pool-rs/host/Cargo.toml
index 8281081..2da4c9c
--- a/ci/ci.sh
+++ b/examples/client_pool-rs/host/Cargo.toml
@@ -1,5 +1,3 @@
-#!/bin/bash
-
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,37 +15,25 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
-
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
-./test_tcp_client.sh
-./test_udp_socket.sh
+[package]
+name = "client_pool-rs"
+version = "0.4.0"
+authors = ["Teaclave Contributors <[email protected]>"]
+license = "Apache-2.0"
+repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git";
+description = "An example of Rust OP-TEE TrustZone SDK."
+edition = "2018"
 
-# Run std only tests
-if [ "$STD" ]; then
-    ./test_serde.sh
-    ./test_message_passing_interface.sh
-    ./test_tls_client.sh
-    ./test_tls_server.sh
-    ./test_eth_wallet.sh
-    ./test_secure_db_abstraction.sh
-else
-    ./test_mnist_rs.sh
-fi
+[dependencies]
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
+r2d2 = "0.8.10"
+clap = { version = "4.5.32", features = ["derive"] }
+anyhow = "1.0.97"
+hex = "0.4.3"
+mobc = "0.8.5"
+tokio = { version = "1.44.1", features = ["rt-multi-thread", "sync"] }
+strum = { version = "0.27.1", features = ["derive"] }
 
-popd
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/examples/client_pool-rs/host/Makefile
old mode 100755
new mode 100644
similarity index 56%
copy from ci/ci.sh
copy to examples/client_pool-rs/host/Makefile
index 8281081..9f5117f
--- a/ci/ci.sh
+++ b/examples/client_pool-rs/host/Makefile
@@ -1,5 +1,3 @@
-#!/bin/bash
-
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,37 +15,23 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
-
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
-./test_tcp_client.sh
-./test_udp_socket.sh
-
-# Run std only tests
-if [ "$STD" ]; then
-    ./test_serde.sh
-    ./test_message_passing_interface.sh
-    ./test_tls_client.sh
-    ./test_tls_server.sh
-    ./test_eth_wallet.sh
-    ./test_secure_db_abstraction.sh
-else
-    ./test_mnist_rs.sh
-fi
-
-popd
+NAME := client_pool-rs
+
+TARGET ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE)objcopy
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
+
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+
+all: host strip
+
+host:
+       @cargo build --target $(TARGET_HOST) --release --config $(LINKER_CFG)
+
+strip: host
+       @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/$(NAME) $(OUT_DIR)/$(NAME)
+
+clean:
+       @cargo clean
diff --git a/examples/client_pool-rs/host/src/main.rs 
b/examples/client_pool-rs/host/src/main.rs
new file mode 100644
index 0000000..2abccff
--- /dev/null
+++ b/examples/client_pool-rs/host/src/main.rs
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+mod pool;
+
+use clap::{Parser, Subcommand};
+
+/// A program that demonstrates the TEEC_Session pool in both threading and
+/// async scenarios.
+#[derive(Parser)]
+#[command(version, long_about)]
+struct Cli {
+    #[command(subcommand)]
+    command: Commands,
+}
+
+#[derive(Subcommand)]
+enum Commands {
+    /// Test an r2d2 connection pool with each task running in its own thread.
+    #[command(long_about)]
+    Thread(pool::Args),
+    /// Test a mobc connection pool with each task running in a Tokio async
+    /// task.
+    #[command(long_about)]
+    Async(pool::Args),
+}
+
+fn main() -> anyhow::Result<()> {
+    let args = Cli::parse();
+    match args.command {
+        Commands::Thread(args) => pool::r2d2_pool::run(args),
+        Commands::Async(args) => pool::mobc_pool::run(args),
+    }
+}
diff --git a/examples/client_pool-rs/host/src/pool/connection.rs 
b/examples/client_pool-rs/host/src/pool/connection.rs
new file mode 100644
index 0000000..2e604a4
--- /dev/null
+++ b/examples/client_pool-rs/host/src/pool/connection.rs
@@ -0,0 +1,94 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use optee_teec::{Context, Error, ErrorKind, ErrorOrigin, Operation, Param, 
Session, Uuid};
+use optee_teec::{ParamNone, ParamTmpRef, ParamType, ParamValue};
+use proto::Command;
+
+pub struct Connection {
+    session: Session,
+    identity: [u8; proto::IDENTITY_SIZE],
+    last_err: Option<Error>,
+}
+
+impl Connection {
+    pub fn new(ctx: &mut Context, uuid: Uuid) -> optee_teec::Result<Self> {
+        let mut identity = [0_u8; proto::IDENTITY_SIZE];
+        let session = {
+            let mut operation = Operation::new(
+                0,
+                ParamTmpRef::new_output(&mut identity),
+                ParamNone,
+                ParamNone,
+                ParamNone,
+            );
+            ctx.open_session_with_operation(uuid, &mut operation)?
+        };
+        Ok(Connection {
+            session,
+            identity,
+            last_err: None,
+        })
+    }
+
+    pub fn invoke_command<A: Param, B: Param, C: Param, D: Param>(
+        &mut self,
+        command_id: u32,
+        operation: &mut Operation<A, B, C, D>,
+    ) -> optee_teec::Result<()> {
+        let result = self.session.invoke_command(command_id, operation);
+        self.last_err = result.clone().err();
+        result
+    }
+
+    pub fn identity(&self) -> &[u8] {
+        &self.identity
+    }
+
+    // Check if this session still valid.
+    // We currently consider the session valid unless it is marked as dead.
+    // So if the command returns ErrorKind::TargetDead and ErrorOrigin is not
+    // the TA, the session is not valid anymore.
+    //
+    // One of the scenario is:
+    // Refer to "TEE Internal Core API Specification – Public Release v1.3.1"
+    // - From the client’s point of view, when a Trusted Application
+    //   panics, the client commands SHALL return the error
+    //   TEE_ERROR_TARGET_DEAD with an origin value of TEE_ORIGIN_TEE
+    //   until the session is closed.
+    pub fn valid(&self) -> optee_teec::Result<()> {
+        if let Some(err) = self.last_err.as_ref() {
+            if err.kind() == ErrorKind::TargetDead
+                && err.origin().is_some_and(|x| x != ErrorOrigin::TA)
+            {
+                return Err(err.clone());
+            }
+        }
+        Ok(())
+    }
+}
+
+pub fn tee_wait(session: &mut Connection, milliseconds: u32) -> 
optee_teec::Result<()> {
+    let mut operation = Operation::new(
+        Command::Sleep as u32,
+        ParamValue::new(milliseconds, 0, ParamType::ValueInput),
+        ParamNone,
+        ParamNone,
+        ParamNone,
+    );
+    session.invoke_command(0, &mut operation)
+}
diff --git a/examples/client_pool-rs/host/src/pool/mobc_pool.rs 
b/examples/client_pool-rs/host/src/pool/mobc_pool.rs
new file mode 100644
index 0000000..3dc8206
--- /dev/null
+++ b/examples/client_pool-rs/host/src/pool/mobc_pool.rs
@@ -0,0 +1,93 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use super::{
+    connection::{tee_wait, Connection},
+    Args,
+};
+use optee_teec::{Context, ErrorKind, Uuid};
+use std::{
+    sync::{atomic, Arc, Mutex},
+    time::Duration,
+};
+
+struct Manager {
+    ctx: Arc<Mutex<Context>>,
+    uuid: Uuid,
+}
+
+#[mobc::async_trait]
+impl mobc::Manager for Manager {
+    type Error = optee_teec::Error;
+    type Connection = Connection;
+
+    async fn connect(&self) -> Result<Self::Connection, Self::Error> {
+        let mut guard = self.ctx.lock().map_err(|err| {
+            eprintln!("mobc: cannot acquire lock due to {:#?}", err);
+            ErrorKind::BadState
+        })?;
+        Connection::new(&mut guard, self.uuid.clone())
+    }
+
+    async fn check(&self, conn: Self::Connection) -> Result<Self::Connection, 
Self::Error> {
+        conn.valid().map(|_| conn)
+    }
+}
+
+fn new_pool(args: &Args) -> anyhow::Result<mobc::Pool<Manager>> {
+    let manager = Manager {
+        ctx: Arc::new(Mutex::new(Context::new()?)),
+        uuid: Uuid::parse_str(proto::UUID)?,
+    };
+    Ok(mobc::Builder::new()
+        .max_idle(0)
+        .max_open(args.pool_capacity as u64)
+        .build(manager))
+}
+
+pub fn run(args: Args) -> anyhow::Result<()> {
+    let pool = new_pool(&args)?;
+    let runtime = tokio::runtime::Runtime::new()?;
+    let finish_counter = Arc::new(atomic::AtomicU64::new(0));
+
+    for i in 0..args.concurrency {
+        let pool = pool.clone();
+        let finish_counter = finish_counter.clone();
+        let ta_wait_timeout = args.ta_wait_timeout;
+
+        let _task: tokio::task::JoinHandle<anyhow::Result<()>> = 
runtime.spawn(async move {
+            let mut session = pool.get().await?;
+            tee_wait(&mut session, ta_wait_timeout)?;
+            finish_counter.fetch_add(1, atomic::Ordering::Relaxed);
+            println!(
+                "mobc: {}: {} finish",
+                i,
+                hex::encode_upper(session.identity())
+            );
+            Ok(())
+        });
+    }
+
+    std::thread::sleep(Duration::from_millis(args.execution_timeout as u64));
+    println!(
+        "mobc: total tasks: {}, total finish: {}",
+        args.concurrency,
+        finish_counter.load(atomic::Ordering::Relaxed)
+    );
+
+    Ok(())
+}
diff --git a/examples/client_pool-rs/host/src/pool/mod.rs 
b/examples/client_pool-rs/host/src/pool/mod.rs
new file mode 100644
index 0000000..f4ea8fc
--- /dev/null
+++ b/examples/client_pool-rs/host/src/pool/mod.rs
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+mod connection;
+pub mod mobc_pool;
+pub mod r2d2_pool;
+
+use clap::Parser;
+
+#[derive(Debug, Parser)]
+#[command(about = None, long_about)]
+pub struct Args {
+    /// The duration of the REE wait time, which the REE waits for all tasks to
+    /// complete.
+    #[arg(short, long, default_value_t = 1500)]
+    execution_timeout: u32,
+
+    /// The duration of the TEE wait time, which a TEEC_Session is holding.
+    #[arg(short, long, default_value_t = 1000)]
+    ta_wait_timeout: u32,
+
+    /// The capacity of the TEEC_Session pool.
+    #[arg(short, long, default_value_t = 10)]
+    pool_capacity: u32,
+
+    /// The total number of tasks running concurrently, with each task holding 
a
+    /// TEEC_Session for approximately ${ta_wait_timeout}.
+    #[arg(short, long, default_value_t = 10)]
+    concurrency: u64,
+}
diff --git a/examples/client_pool-rs/host/src/pool/r2d2_pool.rs 
b/examples/client_pool-rs/host/src/pool/r2d2_pool.rs
new file mode 100644
index 0000000..22bef95
--- /dev/null
+++ b/examples/client_pool-rs/host/src/pool/r2d2_pool.rs
@@ -0,0 +1,95 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use super::{
+    connection::{tee_wait, Connection},
+    Args,
+};
+use optee_teec::{Context, ErrorKind, Uuid};
+use std::{
+    sync::{atomic, Arc, Mutex},
+    thread,
+    time::Duration,
+};
+
+struct Manager {
+    ctx: Mutex<Context>,
+    uuid: Uuid,
+}
+
+impl r2d2::ManageConnection for Manager {
+    type Error = optee_teec::Error;
+    type Connection = Connection;
+
+    fn connect(&self) -> Result<Self::Connection, Self::Error> {
+        let mut guard = self.ctx.lock().map_err(|err| {
+            eprintln!("r2d2: cannot acquire lock due to {:#?}", err);
+            ErrorKind::BadState
+        })?;
+        Connection::new(&mut guard, self.uuid.clone())
+    }
+
+    fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error> 
{
+        conn.valid()
+    }
+
+    fn has_broken(&self, conn: &mut Self::Connection) -> bool {
+        conn.valid().is_err()
+    }
+}
+
+fn new_pool(args: &Args) -> Result<r2d2::Pool<Manager>, anyhow::Error> {
+    let manager = Manager {
+        ctx: Mutex::new(Context::new()?),
+        uuid: Uuid::parse_str(proto::UUID)?,
+    };
+
+    Ok(r2d2::Pool::builder()
+        .max_size(args.pool_capacity)
+        .build(manager)?)
+}
+
+pub fn run(args: Args) -> anyhow::Result<()> {
+    let pool = new_pool(&args)?;
+    let finish_counter = Arc::new(atomic::AtomicU64::new(0));
+
+    for i in 0..args.concurrency {
+        let pool = pool.clone();
+        let finish_counter = finish_counter.clone();
+        let ta_wait_timeout = args.ta_wait_timeout;
+        thread::spawn(move || -> anyhow::Result<()> {
+            let mut session = pool.get()?;
+            tee_wait(&mut session, ta_wait_timeout)?;
+            finish_counter.fetch_add(1, atomic::Ordering::Relaxed);
+            println!(
+                "r2d2: {}: {} finish",
+                i,
+                hex::encode_upper(session.identity())
+            );
+            Ok(())
+        });
+    }
+
+    thread::sleep(Duration::from_millis(args.execution_timeout as u64));
+    println!(
+        "r2d2: total tasks: {}, total finish: {}",
+        args.concurrency,
+        finish_counter.load(atomic::Ordering::Relaxed)
+    );
+
+    Ok(())
+}
diff --git a/ci/ci.sh b/examples/client_pool-rs/proto/Cargo.toml
old mode 100755
new mode 100644
similarity index 55%
copy from ci/ci.sh
copy to examples/client_pool-rs/proto/Cargo.toml
index 8281081..91066a3
--- a/ci/ci.sh
+++ b/examples/client_pool-rs/proto/Cargo.toml
@@ -1,5 +1,3 @@
-#!/bin/bash
-
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,37 +15,14 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
-
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
-./test_tcp_client.sh
-./test_udp_socket.sh
-
-# Run std only tests
-if [ "$STD" ]; then
-    ./test_serde.sh
-    ./test_message_passing_interface.sh
-    ./test_tls_client.sh
-    ./test_tls_server.sh
-    ./test_eth_wallet.sh
-    ./test_secure_db_abstraction.sh
-else
-    ./test_mnist_rs.sh
-fi
+[package]
+name = "proto"
+version = "0.4.0"
+authors = ["Teaclave Contributors <[email protected]>"]
+license = "Apache-2.0"
+repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git";
+description = "Data structures and functions shared by host and TA."
+edition = "2018"
 
-popd
+[dependencies]
+num_enum = { version = "0.7.3", default-features = false }
diff --git a/examples/client_pool-rs/proto/src/lib.rs 
b/examples/client_pool-rs/proto/src/lib.rs
new file mode 100644
index 0000000..19debb3
--- /dev/null
+++ b/examples/client_pool-rs/proto/src/lib.rs
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#![no_std]
+
+use num_enum::{FromPrimitive, IntoPrimitive};
+
+#[derive(FromPrimitive, IntoPrimitive)]
+#[repr(u32)]
+pub enum Command {
+    Sleep,
+    #[default]
+    Unknown,
+}
+
+// If Uuid::parse_str() returns an InvalidLength error, there may be an extra
+// newline in your uuid.txt file. You can remove it by running
+// `truncate -s 36 uuid.txt`.
+pub const UUID: &str = include_str!("../../uuid.txt");
+
+// the size of the identity bytes;
+pub const IDENTITY_SIZE: usize = 32;
diff --git a/ci/ci.sh b/examples/client_pool-rs/ta/Cargo.toml
old mode 100755
new mode 100644
similarity index 54%
copy from ci/ci.sh
copy to examples/client_pool-rs/ta/Cargo.toml
index 8281081..3ecfc6e
--- a/ci/ci.sh
+++ b/examples/client_pool-rs/ta/Cargo.toml
@@ -1,5 +1,3 @@
-#!/bin/bash
-
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,37 +15,26 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
+[package]
+name = "ta"
+version = "0.4.0"
+authors = ["Teaclave Contributors <[email protected]>"]
+license = "Apache-2.0"
+repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git";
+description = "An example of Rust OP-TEE TrustZone SDK."
+edition = "2018"
 
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
-./test_tcp_client.sh
-./test_udp_socket.sh
+[dependencies]
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
+hex = { version = "0.4.3", default-features = false }
 
-# Run std only tests
-if [ "$STD" ]; then
-    ./test_serde.sh
-    ./test_message_passing_interface.sh
-    ./test_tls_client.sh
-    ./test_tls_server.sh
-    ./test_eth_wallet.sh
-    ./test_secure_db_abstraction.sh
-else
-    ./test_mnist_rs.sh
-fi
+[build-dependencies]
+proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
-popd
+[profile.release]
+panic = "abort"
+lto = true
+opt-level = 1
diff --git a/examples/client_pool-rs/ta/Makefile 
b/examples/client_pool-rs/ta/Makefile
new file mode 100644
index 0000000..029e66d
--- /dev/null
+++ b/examples/client_pool-rs/ta/Makefile
@@ -0,0 +1,45 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+UUID ?= $(shell cat "../uuid.txt")
+
+TARGET ?= aarch64-unknown-linux-gnu
+CROSS_COMPILE ?= aarch64-linux-gnu-
+OBJCOPY := $(CROSS_COMPILE)objcopy
+# Configure the linker to use GCC, which works on both cross-compilation and 
ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
+
+TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
+SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+BUILDER = $(if $(STD),xargo,cargo)
+
+all: ta strip sign
+
+ta:
+       @$(BUILDER) build --target $(TARGET) --release --config $(LINKER_CFG)
+
+strip: ta
+       @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/ta $(OUT_DIR)/stripped_ta
+
+sign: strip
+       @$(SIGN) --uuid $(UUID) --key $(TA_SIGN_KEY) --in 
$(OUT_DIR)/stripped_ta --out $(OUT_DIR)/$(UUID).ta
+       @echo "SIGN =>  ${UUID}"
+
+clean:
+       @cargo clean
diff --git a/ci/ci.sh b/examples/client_pool-rs/ta/Xargo.toml
old mode 100755
new mode 100644
similarity index 55%
copy from ci/ci.sh
copy to examples/client_pool-rs/ta/Xargo.toml
index 8281081..1b1a113
--- a/ci/ci.sh
+++ b/examples/client_pool-rs/ta/Xargo.toml
@@ -1,5 +1,3 @@
-#!/bin/bash
-
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,37 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
-
-pushd ../tests
-
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
-./test_tcp_client.sh
-./test_udp_socket.sh
-
-# Run std only tests
-if [ "$STD" ]; then
-    ./test_serde.sh
-    ./test_message_passing_interface.sh
-    ./test_tls_client.sh
-    ./test_tls_server.sh
-    ./test_eth_wallet.sh
-    ./test_secure_db_abstraction.sh
-else
-    ./test_mnist_rs.sh
-fi
+[dependencies.std]
+path = "../../../rust/rust/library/std"
 
-popd
+[patch.crates-io]
+libc =  { path = "../../../rust/libc" }
+rustc-std-workspace-core = { path = 
"../../../rust/rust/library/rustc-std-workspace-core" }
+rustc-std-workspace-alloc = { path = 
"../../../rust/rust/library/rustc-std-workspace-alloc" }
diff --git a/examples/client_pool-rs/ta/build.rs 
b/examples/client_pool-rs/ta/build.rs
new file mode 100644
index 0000000..1337f93
--- /dev/null
+++ b/examples/client_pool-rs/ta/build.rs
@@ -0,0 +1,23 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use optee_utee_build::{Error, RustEdition, TaConfig};
+
+fn main() -> Result<(), Error> {
+    let config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, config)
+}
diff --git a/examples/client_pool-rs/ta/src/main.rs 
b/examples/client_pool-rs/ta/src/main.rs
new file mode 100644
index 0000000..66bcb0a
--- /dev/null
+++ b/examples/client_pool-rs/ta/src/main.rs
@@ -0,0 +1,81 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#![no_std]
+#![no_main]
+extern crate alloc;
+
+use alloc::{boxed::Box, string::String};
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
+};
+use optee_utee::{ErrorKind, Parameters, Result};
+use proto::Command;
+
+#[ta_create]
+fn create() -> Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(params: &mut Parameters, ctx: &mut String) -> Result<()> {
+    let mut p0 = unsafe { params.0.as_memref()? };
+
+    let mut buffer = [0_u8; proto::IDENTITY_SIZE];
+    optee_utee::Random::generate(&mut buffer);
+    *ctx = hex::encode(buffer).to_uppercase();
+
+    trace_println!("[+] TA open session, identity: {}", ctx);
+    p0.buffer().copy_from_slice(&buffer);
+
+    Ok(())
+}
+
+#[ta_close_session]
+fn close_session(ctx: &mut String) {
+    trace_println!("[+] TA close session, identity: {}", ctx);
+}
+
+#[ta_destroy]
+fn destroy() {
+    trace_println!("[+] TA destroy");
+}
+
+#[ta_invoke_command]
+fn invoke_command(ctx: &mut String, cmd_id: u32, params: &mut Parameters) -> 
Result<()> {
+    match Command::from(cmd_id) {
+        Command::Sleep => {
+            let values = unsafe { params.0.as_value()? };
+
+            let milliseconds = values.a();
+            let mut now = optee_utee::Time::new();
+            now.system_time();
+            // this would cause messy output in the console when running 
concurrently.
+            trace_println!(
+                "[+] TA {} wait for {} milliseconds at {}",
+                ctx,
+                milliseconds,
+                now.seconds * 1000 + now.millis
+            );
+            optee_utee::Time::wait(milliseconds)
+        }
+        Command::Unknown => Err(ErrorKind::BadParameters.into()),
+    }
+}
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/client_pool-rs/uuid.txt b/examples/client_pool-rs/uuid.txt
new file mode 100644
index 0000000..1f96819
--- /dev/null
+++ b/examples/client_pool-rs/uuid.txt
@@ -0,0 +1 @@
+c9d73f40-ba45-4315-92c4-cf1255958729
\ No newline at end of file
diff --git a/ci/ci.sh b/tests/test_client_pool.sh
similarity index 55%
copy from ci/ci.sh
copy to tests/test_client_pool.sh
index 8281081..0569d2b 100755
--- a/ci/ci.sh
+++ b/tests/test_client_pool.sh
@@ -19,35 +19,27 @@
 
 set -xe
 
-pushd ../tests
+# Include base script
+source setup.sh
 
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
-./test_signature_verification.sh
-./test_supp_plugin.sh
-./test_error_handling.sh
-./test_tcp_client.sh
-./test_udp_socket.sh
+# Copy TA and host binary
+cp ../examples/client_pool-rs/ta/target/$TARGET_TA/release/*.ta shared
+cp ../examples/client_pool-rs/host/target/$TARGET_HOST/release/client_pool-rs 
shared
 
-# Run std only tests
-if [ "$STD" ]; then
-    ./test_serde.sh
-    ./test_message_passing_interface.sh
-    ./test_tls_client.sh
-    ./test_tls_server.sh
-    ./test_eth_wallet.sh
-    ./test_secure_db_abstraction.sh
-else
-    ./test_mnist_rs.sh
-fi
+# Run script specific commands in QEMU
+run_in_qemu "cp *.ta /lib/optee_armtz/\n"
+run_in_qemu "./client_pool-rs thread -p 2 -c 2\n"
+run_in_qemu "./client_pool-rs async -p 2 -c 2\n"
+run_in_qemu "^C"
 
-popd
+# Script specific checks
+{
+    grep -q "r2d2: total tasks: 2, total finish: 2" screenlog.0 &&
+    grep -q "mobc: total tasks: 2, total finish: 2" screenlog.0
+} || {
+    cat -v screenlog.0
+    cat -v /tmp/serial.log
+    false
+}
+
+rm screenlog.0


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to