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

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


The following commit(s) were added to refs/heads/master by this push:
     new 801dd1b  TEE Sockets API (#31)
801dd1b is described below

commit 801dd1b37abc4955085ffb05776d0d97b389e745
Author: Mingshen Sun <[email protected]>
AuthorDate: Mon Jul 26 19:23:09 2021 -0700

    TEE Sockets API (#31)
---
 ci/ci.sh                                           |   2 +
 ci/ci.sh => examples/tcp_client/Makefile           |  25 +-
 examples/tcp_client/host/Cargo.lock                | 104 ++++++
 examples/tcp_client/host/Cargo.toml                |  16 +
 ci/ci.sh => examples/tcp_client/host/Makefile      |  42 ++-
 .../lib.rs => examples/tcp_client/host/src/main.rs |  35 +-
 examples/tcp_client/proto/Cargo.toml               |  13 +
 .../lib.rs => examples/tcp_client/proto/build.rs   |  36 +-
 .../tcp_client/proto}/src/lib.rs                   |  31 +-
 examples/tcp_client/ta/Cargo.lock                  | 105 ++++++
 examples/tcp_client/ta/Cargo.toml                  |  21 ++
 examples/tcp_client/ta/Makefile                    |  53 +++
 examples/tcp_client/ta/Xargo.toml                  |   8 +
 examples/tcp_client/ta/build.rs                    |  62 ++++
 examples/tcp_client/ta/src/main.rs                 |  93 ++++++
 examples/tcp_client/ta/ta_aarch64.lds              |  92 ++++++
 examples/tcp_client/ta/ta_arm.lds                  |  91 ++++++
 examples/tcp_client/ta/ta_static.rs                |  98 ++++++
 examples/tcp_client/uuid.txt                       |   1 +
 ci/ci.sh => examples/udp_socket/Makefile           |  25 +-
 examples/udp_socket/host/Cargo.lock                | 104 ++++++
 examples/udp_socket/host/Cargo.toml                |  16 +
 ci/ci.sh => examples/udp_socket/host/Makefile      |  42 ++-
 examples/udp_socket/host/src/main.rs               |  49 +++
 examples/udp_socket/proto/Cargo.toml               |  13 +
 .../lib.rs => examples/udp_socket/proto/build.rs   |  36 +-
 .../udp_socket/proto}/src/lib.rs                   |  31 +-
 examples/udp_socket/ta/Cargo.lock                  | 105 ++++++
 examples/udp_socket/ta/Cargo.toml                  |  21 ++
 examples/udp_socket/ta/Makefile                    |  53 +++
 examples/udp_socket/ta/Xargo.toml                  |   8 +
 examples/udp_socket/ta/build.rs                    |  62 ++++
 examples/udp_socket/ta/src/main.rs                 |  98 ++++++
 examples/udp_socket/ta/ta_aarch64.lds              |  92 ++++++
 examples/udp_socket/ta/ta_arm.lds                  |  91 ++++++
 examples/udp_socket/ta/ta_static.rs                |  98 ++++++
 examples/udp_socket/uuid.txt                       |   1 +
 optee-utee/optee-utee-sys/src/lib.rs               |   8 +
 .../optee-utee-sys/src/{lib.rs => tee_ipsocket.rs} |  25 +-
 optee-utee/optee-utee-sys/src/tee_isocket.rs       |  64 ++++
 .../src/{lib.rs => tee_tcpsocket.rs}               |  37 ++-
 .../src/{lib.rs => tee_udpsocket.rs}               |  35 +-
 optee-utee/src/lib.rs                              |   1 +
 optee-utee/src/net.rs                              | 361 +++++++++++++++++++++
 tests/test_tcp_client.sh                           |  54 +++
 tests/test_udp_socket.sh                           |  54 +++
 46 files changed, 2300 insertions(+), 212 deletions(-)

diff --git a/ci/ci.sh b/ci/ci.sh
index ed3d738..30112bc 100755
--- a/ci/ci.sh
+++ b/ci/ci.sh
@@ -33,5 +33,7 @@ pushd ../tests
 ./test_digest.sh
 ./test_authentication.sh
 ./test_time.sh
+./test_tcp_client.sh
+./test_udp_socket.sh
 
 popd
diff --git a/ci/ci.sh b/examples/tcp_client/Makefile
old mode 100755
new mode 100644
similarity index 74%
copy from ci/ci.sh
copy to examples/tcp_client/Makefile
index ed3d738..09679cd
--- a/ci/ci.sh
+++ b/examples/tcp_client/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,21 +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_serde.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
+all:
+       @make -s -C host
+       @make -s -C ta
 
-popd
+clean:
+       @make -s -C host clean
+       @make -s -C ta clean
diff --git a/examples/tcp_client/host/Cargo.lock 
b/examples/tcp_client/host/Cargo.lock
new file mode 100644
index 0000000..e97c3d6
--- /dev/null
+++ b/examples/tcp_client/host/Cargo.lock
@@ -0,0 +1,104 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "hex"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "libc"
+version = "0.2.95"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "optee-teec"
+version = "0.1.0"
+dependencies = [
+ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.95 (registry+https://github.com/rust-lang/crates.io-index)",
+ "optee-teec-macros 0.1.0",
+ "optee-teec-sys 0.1.0",
+ "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "optee-teec-macros"
+version = "0.1.0"
+dependencies = [
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "optee-teec-sys"
+version = "0.1.0"
+dependencies = [
+ "libc 0.2.95 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "0.4.30"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proto"
+version = "0.1.0"
+dependencies = [
+ "uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "0.6.13"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "0.15.44"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tcp_client"
+version = "0.1.0"
+dependencies = [
+ "libc 0.2.95 (registry+https://github.com/rust-lang/crates.io-index)",
+ "optee-teec 0.1.0",
+ "proto 0.1.0",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "uuid"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[metadata]
+"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
+"checksum libc 0.2.95 (registry+https://github.com/rust-lang/crates.io-index)" 
= "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
+"checksum proc-macro2 0.4.30 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
+"checksum quote 0.6.13 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
+"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" 
= "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
+"checksum unicode-xid 0.1.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+"checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" 
= "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768"
+"checksum uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" 
= "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
diff --git a/examples/tcp_client/host/Cargo.toml 
b/examples/tcp_client/host/Cargo.toml
new file mode 100644
index 0000000..cf359ee
--- /dev/null
+++ b/examples/tcp_client/host/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "tcp_client"
+version = "0.1.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"
+
+[dependencies]
+libc = "0.2.48"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
+
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/examples/tcp_client/host/Makefile
old mode 100755
new mode 100644
similarity index 57%
copy from ci/ci.sh
copy to examples/tcp_client/host/Makefile
index ed3d738..fdf34ce
--- a/ci/ci.sh
+++ b/examples/tcp_client/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,21 +15,31 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
+NAME := tcp_client
+ARCH ?= aarch64
+
+OPTEE_DIR ?= ../../../optee
+
+ifeq ($(ARCH), arm)
+       OPTEE_BIN := $(OPTEE_DIR)/toolchains/aarch32/bin
+       OBJCOPY := $(OPTEE_BIN)/arm-linux-gnueabihf-objcopy
+       TARGET := arm-unknown-linux-gnueabihf
+else
+       OPTEE_BIN := $(OPTEE_DIR)/toolchains/$(ARCH)/bin
+       OBJCOPY := $(OPTEE_BIN)/aarch64-linux-gnu-objcopy
+       TARGET := aarch64-unknown-linux-gnu
+endif
+
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+
+all: host strip
 
-pushd ../tests
+host:
+       @cargo build --target $(TARGET) --release
 
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_serde.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
+strip:
+       @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/$(NAME) $(OUT_DIR)/$(NAME)
 
-popd
+clean:
+       @cargo clean
diff --git a/optee-utee/optee-utee-sys/src/lib.rs 
b/examples/tcp_client/host/src/main.rs
similarity index 58%
copy from optee-utee/optee-utee-sys/src/lib.rs
copy to examples/tcp_client/host/src/main.rs
index ef15d46..9e032dc 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/examples/tcp_client/host/src/main.rs
@@ -15,22 +15,23 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![allow(non_camel_case_types, non_snake_case)]
+use optee_teec::{Context, Operation, Session, Uuid};
+use optee_teec::ParamNone;
+use proto::{UUID, Command};
 
-pub use tee_api::*;
-pub use tee_api_defines::*;
-pub use tee_api_types::*;
-pub use tee_internal_api_extensions::*;
-pub use trace::*;
-pub use user_ta_header::*;
-pub use utee_syscalls::*;
-pub use utee_types::*;
+fn tcp_client(session: &mut Session) -> optee_teec::Result<()> {
+    let mut operation = Operation::new(0, ParamNone, ParamNone, ParamNone, 
ParamNone);
+    session.invoke_command(Command::Start as u32, &mut operation)?;
+    Ok(())
+}
 
-mod tee_api;
-mod tee_api_defines;
-mod tee_api_types;
-mod tee_internal_api_extensions;
-mod trace;
-mod user_ta_header;
-mod utee_syscalls;
-mod utee_types;
+fn main() -> optee_teec::Result<()> {
+    let mut ctx = Context::new()?;
+    let uuid = Uuid::parse_str(UUID).unwrap();
+    let mut session = ctx.open_session(uuid)?;
+
+    tcp_client(&mut session)?;
+
+    println!("Success");
+    Ok(())
+}
diff --git a/examples/tcp_client/proto/Cargo.toml 
b/examples/tcp_client/proto/Cargo.toml
new file mode 100644
index 0000000..00f6bae
--- /dev/null
+++ b/examples/tcp_client/proto/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "proto"
+version = "0.1.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"
+
+[dependencies]
+
+[build_dependencies]
+uuid = { version = "0.8" }
diff --git a/optee-utee/optee-utee-sys/src/lib.rs 
b/examples/tcp_client/proto/build.rs
similarity index 62%
copy from optee-utee/optee-utee-sys/src/lib.rs
copy to examples/tcp_client/proto/build.rs
index ef15d46..b9d0612 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/examples/tcp_client/proto/build.rs
@@ -15,22 +15,22 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![allow(non_camel_case_types, non_snake_case)]
+use std::fs;
+use std::path::PathBuf;
+use std::fs::File;
+use std::env;
+use std::io::Write;
 
-pub use tee_api::*;
-pub use tee_api_defines::*;
-pub use tee_api_types::*;
-pub use tee_internal_api_extensions::*;
-pub use trace::*;
-pub use user_ta_header::*;
-pub use utee_syscalls::*;
-pub use utee_types::*;
-
-mod tee_api;
-mod tee_api_defines;
-mod tee_api_types;
-mod tee_internal_api_extensions;
-mod trace;
-mod user_ta_header;
-mod utee_syscalls;
-mod utee_types;
+fn main() {
+    let uuid = match fs::read_to_string("../uuid.txt") {
+        Ok(u) => {
+            u.trim().to_string()
+        },
+        Err(_) => {
+            panic!("Cannot find uuid.txt");
+        }
+    };
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let mut buffer = File::create(out.join("uuid.txt")).unwrap();
+    write!(buffer, "{}", uuid).unwrap();
+}
diff --git a/optee-utee/optee-utee-sys/src/lib.rs 
b/examples/tcp_client/proto/src/lib.rs
similarity index 66%
copy from optee-utee/optee-utee-sys/src/lib.rs
copy to examples/tcp_client/proto/src/lib.rs
index ef15d46..7679b2d 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/examples/tcp_client/proto/src/lib.rs
@@ -15,22 +15,19 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![allow(non_camel_case_types, non_snake_case)]
+pub enum Command {
+    Start,
+    Unknown,
+}
 
-pub use tee_api::*;
-pub use tee_api_defines::*;
-pub use tee_api_types::*;
-pub use tee_internal_api_extensions::*;
-pub use trace::*;
-pub use user_ta_header::*;
-pub use utee_syscalls::*;
-pub use utee_types::*;
+impl From<u32> for Command {
+    #[inline]
+    fn from(value: u32) -> Command {
+        match value {
+            0 => Command::Start,
+            _ => Command::Unknown,
+        }
+    }
+}
 
-mod tee_api;
-mod tee_api_defines;
-mod tee_api_types;
-mod tee_internal_api_extensions;
-mod trace;
-mod user_ta_header;
-mod utee_syscalls;
-mod utee_types;
+pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/examples/tcp_client/ta/Cargo.lock 
b/examples/tcp_client/ta/Cargo.lock
new file mode 100644
index 0000000..4499911
--- /dev/null
+++ b/examples/tcp_client/ta/Cargo.lock
@@ -0,0 +1,105 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "bitflags"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "hex"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "libc"
+version = "0.2.59"
+
+[[package]]
+name = "optee-utee"
+version = "0.1.0"
+dependencies = [
+ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.59",
+ "optee-utee-macros 0.1.0",
+ "optee-utee-sys 0.1.0",
+ "uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "optee-utee-macros"
+version = "0.1.0"
+dependencies = [
+ "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "optee-utee-sys"
+version = "0.1.0"
+dependencies = [
+ "libc 0.2.59",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "0.4.30"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proto"
+version = "0.1.0"
+dependencies = [
+ "uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "0.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "0.15.39"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ta"
+version = "0.1.0"
+dependencies = [
+ "libc 0.2.59",
+ "optee-utee 0.1.0",
+ "optee-utee-sys 0.1.0",
+ "proto 0.1.0",
+ "uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[metadata]
+"checksum bitflags 1.1.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
+"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
+"checksum proc-macro2 0.4.30 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
+"checksum quote 0.6.12 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
+"checksum syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)" 
= "b4d960b829a55e56db167e861ddb43602c003c7be0bee1d345021703fac2fb7c"
+"checksum unicode-xid 0.1.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+"checksum uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" 
= "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
diff --git a/examples/tcp_client/ta/Cargo.toml 
b/examples/tcp_client/ta/Cargo.toml
new file mode 100644
index 0000000..027e6a3
--- /dev/null
+++ b/examples/tcp_client/ta/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "ta"
+version = "0.1.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"
+
+[dependencies]
+libc = { path = "../../../rust/libc" }
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
+
+[build_dependencies]
+uuid = { version = "0.8" }
+proto = { path = "../proto" }
+
+[profile.release]
+lto = true
diff --git a/examples/tcp_client/ta/Makefile b/examples/tcp_client/ta/Makefile
new file mode 100644
index 0000000..ffee4b2
--- /dev/null
+++ b/examples/tcp_client/ta/Makefile
@@ -0,0 +1,53 @@
+# 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.
+
+OPTEE_DIR ?= ../../../optee
+OPTEE_OS_DIR ?= $(OPTEE_DIR)/optee_os
+UUID ?= $(shell cat "../uuid.txt")
+
+ARCH ?= aarch64
+
+ifeq ($(ARCH), arm)
+       TA_SIGN_KEY ?= 
$(OPTEE_OS_DIR)/out/arm/export-ta_arm32/keys/default_ta.pem
+       SIGN := $(OPTEE_OS_DIR)/out/arm/export-ta_arm32/scripts/sign_encrypt.py
+       OPTEE_BIN := $(OPTEE_DIR)/toolchains/aarch32/bin
+       OBJCOPY := $(OPTEE_BIN)/arm-linux-gnueabihf-objcopy
+       TARGET := arm-unknown-optee-trustzone
+else
+       TA_SIGN_KEY ?= 
$(OPTEE_OS_DIR)/out/arm/export-ta_arm64/keys/default_ta.pem
+       SIGN := $(OPTEE_OS_DIR)/out/arm/export-ta_arm64/scripts/sign_encrypt.py
+       OPTEE_BIN := $(OPTEE_DIR)/toolchains/$(ARCH)/bin
+       OBJCOPY := $(OPTEE_BIN)/aarch64-linux-gnu-objcopy
+       TARGET := aarch64-unknown-optee-trustzone
+endif
+
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+all: ta strip sign
+
+ta:
+       @xargo build --target $(TARGET) --release --verbose
+
+strip:
+       @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/ta $(OUT_DIR)/stripped_ta
+
+sign:
+       @$(SIGN) --uuid $(UUID) --key $(TA_SIGN_KEY) --in 
$(OUT_DIR)/stripped_ta --out $(OUT_DIR)/$(UUID).ta
+       @echo "SIGN =>  ${UUID}"
+
+clean:
+       @xargo clean
diff --git a/examples/tcp_client/ta/Xargo.toml 
b/examples/tcp_client/ta/Xargo.toml
new file mode 100644
index 0000000..c577b24
--- /dev/null
+++ b/examples/tcp_client/ta/Xargo.toml
@@ -0,0 +1,8 @@
+[dependencies.std]
+path = "../../../rust/rust/src/libstd"
+
+[patch.crates-io]
+libc =  { path = "../../../rust/libc" }
+compiler_builtins =  { path = "../../../rust/compiler-builtins" }
+rustc-std-workspace-core = { path = 
"../../../rust/rust/src/tools/rustc-std-workspace-core" }
+rustc-std-workspace-alloc = { path = 
"../../../rust/rust/src/tools/rustc-std-workspace-alloc" }
diff --git a/examples/tcp_client/ta/build.rs b/examples/tcp_client/ta/build.rs
new file mode 100644
index 0000000..33f6cc0
--- /dev/null
+++ b/examples/tcp_client/ta/build.rs
@@ -0,0 +1,62 @@
+// 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 proto;
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::{Path, PathBuf};
+use uuid::Uuid;
+
+fn main() -> std::io::Result<()> {
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
+    buffer.write_all(include_bytes!("ta_static.rs"))?;
+
+    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
+    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = 
tee_uuid.as_fields();
+
+    write!(buffer, "\n")?;
+    write!(
+        buffer,
+        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
+    timeLow: {:#x},
+    timeMid: {:#x},
+    timeHiAndVersion: {:#x},
+    clockSeqAndNode: {:#x?},
+}};",
+        time_low, time_mid, time_hi_and_version, clock_seq_and_node
+    )?;
+    let optee_os_dir = 
env::var("OPTEE_OS_DIR").unwrap_or("../../../optee/optee_os".to_string());
+    let search_path = match env::var("ARCH") {
+        Ok(ref v) if v == "arm" => {
+            
File::create(out.join("ta.lds"))?.write_all(include_bytes!("ta_arm.lds"))?;
+            Path::new(&optee_os_dir).join("out/arm/export-ta_arm32/lib")
+        },
+        _ => {
+            
File::create(out.join("ta.lds"))?.write_all(include_bytes!("ta_aarch64.lds"))?;
+            Path::new(&optee_os_dir).join("out/arm/export-ta_arm64/lib")
+        }
+    };
+    println!("cargo:rustc-link-search={}", out.display());
+    println!("cargo:rerun-if-changed=ta.lds");
+
+    println!("cargo:rustc-link-search={}", search_path.display());
+    println!("cargo:rustc-link-lib=static=utee");
+    Ok(())
+}
diff --git a/examples/tcp_client/ta/src/main.rs 
b/examples/tcp_client/ta/src/main.rs
new file mode 100644
index 0000000..25249ae
--- /dev/null
+++ b/examples/tcp_client/ta/src/main.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.
+
+#![no_main]
+
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters, Result};
+use optee_utee::net::TcpStream;
+use proto::Command;
+use std::io::Read;
+use std::io::Write;
+
+#[ta_create]
+fn create() -> Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA open session");
+    Ok(())
+}
+
+#[ta_close_session]
+fn close_session() {
+    trace_println!("[+] TA close session");
+}
+
+#[ta_destroy]
+fn destroy() {
+    trace_println!("[+] TA destroy");
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA invoke command");
+    match Command::from(cmd_id) {
+        Command::Start => {
+            tcp_client();
+            Ok(())
+        }
+        _ => Err(Error::new(ErrorKind::BadParameters)),
+    }
+}
+
+fn tcp_client() {
+    let mut stream = TcpStream::connect("teaclave.apache.org", 80).unwrap();
+    stream.write_all(b"GET / HTTP/1.0\r\nHost: 
teaclave.apache.org\r\n\r\n").unwrap();
+    let mut response = Vec::new();
+    let mut chunk = [0u8; 1024];
+    loop {
+        match stream.read(&mut chunk) {
+            Ok(0) => break,
+            Ok(n) => response.extend_from_slice(&chunk[..n]),
+            Err(_) => {
+                trace_println!("Error");
+                panic!();
+            }
+        }
+    }
+    trace_println!("{}", String::from_utf8_lossy(&response));
+}
+
+// TA configurations
+const TA_FLAGS: u32 = 0;
+const TA_DATA_SIZE: u32 = 1 * 1024 * 1024;
+const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
+const TA_VERSION: &[u8] = b"0.1\0";
+const TA_DESCRIPTION: &[u8] = b"This is a hello world example.\0";
+const EXT_PROP_VALUE_1: &[u8] = b"Hello World TA\0";
+const EXT_PROP_VALUE_2: u32 = 0x0010;
+const TRACE_LEVEL: i32 = 4;
+const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
+const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/tcp_client/ta/ta_aarch64.lds 
b/examples/tcp_client/ta/ta_aarch64.lds
new file mode 100644
index 0000000..adb7603
--- /dev/null
+++ b/examples/tcp_client/ta/ta_aarch64.lds
@@ -0,0 +1,92 @@
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+PHDRS {
+       /*
+        * Exec and rodata headers are hard coded to RX and RO
+        * respectively. This is needed because the binary is relocatable
+        * and the linker would automatically make any header writeable
+        * that need to be updated during relocation.
+        */
+       exec PT_LOAD FLAGS (5);         /* RX */
+       rodata PT_LOAD FLAGS (4);       /* RO */
+       rwdata PT_LOAD;
+       dyn PT_DYNAMIC;
+}
+
+SECTIONS {
+       .ta_head : {*(.ta_head)} :exec
+       .text : {
+               __text_start = .;
+               *(.text .text.*)
+               *(.stub)
+               *(.glue_7)
+               *(.glue_7t)
+               *(.gnu.linkonce.t.*)
+               /* Workaround for an erratum in ARM's VFP11 coprocessor */
+               *(.vfp11_veneer)
+               PROVIDE(__gnu_mcount_nc = __utee_mcount);
+               __text_end = .;
+       }
+        .plt : { *(.plt) }
+
+       .eh_frame : { *(.eh_frame) } :rodata
+       .rodata : {
+               *(.gnu.linkonce.r.*)
+               *(.rodata .rodata.*)
+       }
+       /* .ARM.exidx is sorted, so has to go in its own output section.  */
+       .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+        .ctors : { *(.ctors) }
+        .dtors : { *(.dtors) }
+       .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+       .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+       .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+       .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+       .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+       .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+       .rel.dyn : { *(.rel.dyn) }
+       .rel.got : { *(.rel.got) }
+       .rela.got : { *(.rela.got) }
+       .rel.ctors : { *(.rel.ctors) }
+       .rela.ctors : { *(.rela.ctors) }
+       .rel.dtors : { *(.rel.dtors) }
+       .rela.dtors : { *(.rela.dtors) }
+       .rel.init : { *(.rel.init) }
+       .rela.init : { *(.rela.init) }
+       .rel.fini : { *(.rel.fini) }
+       .rela.fini : { *(.rela.fini) }
+       .rel.bss : { *(.rel.bss) }
+       .rela.bss : { *(.rela.bss) }
+       .rel.plt : { *(.rel.plt) }
+       .rela.plt : { *(.rela.plt) }
+       .dynamic : { *(.dynamic) } :dyn :rodata
+       .dynsym : { *(.dynsym) } :rodata
+       .dynstr : { *(.dynstr) }
+       .hash : { *(.hash) }
+
+       /* Page align to allow dropping execute bit for RW data */
+       . = ALIGN(4096);
+
+       .data : { *(.data .data.* .gnu.linkonce.d.*) } :rwdata
+       .got : { *(.got.plt) *(.got) }
+       .bss : {
+               *(.bss .bss.* .gnu.linkonce.b.* COMMON)
+
+               /*
+                * TA profiling with gprof
+                * Reserve some space for the profiling buffer, only if the
+                * TA is instrumented (i.e., some files were built with -pg).
+                * Note that PROVIDE() above defines a symbol only if it is
+                * referenced in the object files.
+                * This also provides a way to detect at runtime if the TA is
+                * instrumented or not.
+                */
+               . = ALIGN(8);
+               __gprof_buf_start = .;
+               __gprof_buf_end = .;
+       }
+
+       /DISCARD/ : { *(.interp) }
+}
+
diff --git a/examples/tcp_client/ta/ta_arm.lds 
b/examples/tcp_client/ta/ta_arm.lds
new file mode 100644
index 0000000..e9601b5
--- /dev/null
+++ b/examples/tcp_client/ta/ta_arm.lds
@@ -0,0 +1,91 @@
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+PHDRS {
+       /*
+        * Exec and rodata headers are hard coded to RX and RO
+        * respectively. This is needed because the binary is relocatable
+        * and the linker would automatically make any header writeable
+        * that need to be updated during relocation.
+        */
+       exec PT_LOAD FLAGS (5);         /* RX */
+       rodata PT_LOAD FLAGS (4);       /* RO */
+       rwdata PT_LOAD;
+       dyn PT_DYNAMIC;
+}
+
+SECTIONS {
+       .ta_head : {*(.ta_head)} :exec
+       .text : {
+               __text_start = .;
+               *(.text .text.*)
+               *(.stub)
+               *(.glue_7)
+               *(.glue_7t)
+               *(.gnu.linkonce.t.*)
+               /* Workaround for an erratum in ARM's VFP11 coprocessor */
+               *(.vfp11_veneer)
+               PROVIDE(__gnu_mcount_nc = __utee_mcount);
+               __text_end = .;
+       }
+        .plt : { *(.plt) }
+
+       .eh_frame : { *(.eh_frame) } :rodata
+       .rodata : {
+               *(.gnu.linkonce.r.*)
+               *(.rodata .rodata.*)
+       }
+       /* .ARM.exidx is sorted, so has to go in its own output section.  */
+       .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+        .ctors : { *(.ctors) }
+        .dtors : { *(.dtors) }
+       .got : { *(.got.plt) *(.got) }
+       .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+       .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+       .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+       .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+       .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+       .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+       .rel.dyn : { *(.rel.dyn) }
+       .rel.got : { *(.rel.got) }
+       .rela.got : { *(.rela.got) }
+       .rel.ctors : { *(.rel.ctors) }
+       .rela.ctors : { *(.rela.ctors) }
+       .rel.dtors : { *(.rel.dtors) }
+       .rela.dtors : { *(.rela.dtors) }
+       .rel.init : { *(.rel.init) }
+       .rela.init : { *(.rela.init) }
+       .rel.fini : { *(.rel.fini) }
+       .rela.fini : { *(.rela.fini) }
+       .rel.bss : { *(.rel.bss) }
+       .rela.bss : { *(.rela.bss) }
+       .rel.plt : { *(.rel.plt) }
+       .rela.plt : { *(.rela.plt) }
+       .dynamic : { *(.dynamic) } :dyn :rodata
+       .dynsym : { *(.dynsym) } :rodata
+       .dynstr : { *(.dynstr) }
+       .hash : { *(.hash) }
+
+       /* Page align to allow dropping execute bit for RW data */
+       . = ALIGN(4096);
+
+       .data : { *(.data .data.* .gnu.linkonce.d.*) } :rwdata
+       .bss : {
+               *(.bss .bss.* .gnu.linkonce.b.* COMMON)
+
+               /*
+                * TA profiling with gprof
+                * Reserve some space for the profiling buffer, only if the
+                * TA is instrumented (i.e., some files were built with -pg).
+                * Note that PROVIDE() above defines a symbol only if it is
+                * referenced in the object files.
+                * This also provides a way to detect at runtime if the TA is
+                * instrumented or not.
+                */
+               . = ALIGN(8);
+               __gprof_buf_start = .;
+               __gprof_buf_end = .;
+       }
+
+       /DISCARD/ : { *(.interp) }
+}
diff --git a/examples/tcp_client/ta/ta_static.rs 
b/examples/tcp_client/ta/ta_static.rs
new file mode 100644
index 0000000..b31f8c3
--- /dev/null
+++ b/examples/tcp_client/ta/ta_static.rs
@@ -0,0 +1,98 @@
+// 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_mangle]
+pub static mut trace_level: libc::c_int = TRACE_LEVEL;
+
+#[no_mangle]
+pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
+
+#[no_mangle]
+#[link_section = ".ta_head"]
+pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
+    uuid: TA_UUID,
+    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
+    flags: TA_FLAGS,
+    depr_entry: std::u64::MAX,
+};
+
+#[no_mangle]
+#[link_section = ".bss"]
+pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
+
+#[no_mangle]
+pub static ta_heap_size: libc::size_t = std::mem::size_of::<u8>() * 
TA_DATA_SIZE as usize;
+static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) 
!= 0;
+static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) 
!= 0;
+static FLAG_INSTANCE: bool = (TA_FLAGS & 
optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
+
+#[no_mangle]
+pub static ta_num_props: libc::size_t = 9;
+
+#[no_mangle]
+pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_BOOL as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_MULTI as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_INSTANCE as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_DATA_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_STACK_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_VERSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_VERSION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_DESCRIPTION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.description\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.version\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
+    },
+];
+
+#[no_mangle]
+pub unsafe extern "C" fn tahead_get_trace_level() -> libc::c_int {
+    return trace_level;
+}
diff --git a/examples/tcp_client/uuid.txt b/examples/tcp_client/uuid.txt
new file mode 100644
index 0000000..386e8ab
--- /dev/null
+++ b/examples/tcp_client/uuid.txt
@@ -0,0 +1 @@
+59db8536-e5e6-11eb-8e9b-a316ce7a6568
diff --git a/ci/ci.sh b/examples/udp_socket/Makefile
old mode 100755
new mode 100644
similarity index 74%
copy from ci/ci.sh
copy to examples/udp_socket/Makefile
index ed3d738..09679cd
--- a/ci/ci.sh
+++ b/examples/udp_socket/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,21 +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_serde.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
+all:
+       @make -s -C host
+       @make -s -C ta
 
-popd
+clean:
+       @make -s -C host clean
+       @make -s -C ta clean
diff --git a/examples/udp_socket/host/Cargo.lock 
b/examples/udp_socket/host/Cargo.lock
new file mode 100644
index 0000000..07056d2
--- /dev/null
+++ b/examples/udp_socket/host/Cargo.lock
@@ -0,0 +1,104 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "hex"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "libc"
+version = "0.2.95"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "optee-teec"
+version = "0.1.0"
+dependencies = [
+ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.95 (registry+https://github.com/rust-lang/crates.io-index)",
+ "optee-teec-macros 0.1.0",
+ "optee-teec-sys 0.1.0",
+ "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "optee-teec-macros"
+version = "0.1.0"
+dependencies = [
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "optee-teec-sys"
+version = "0.1.0"
+dependencies = [
+ "libc 0.2.95 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "0.4.30"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proto"
+version = "0.1.0"
+dependencies = [
+ "uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "0.6.13"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "0.15.44"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "udp_socket"
+version = "0.1.0"
+dependencies = [
+ "libc 0.2.95 (registry+https://github.com/rust-lang/crates.io-index)",
+ "optee-teec 0.1.0",
+ "proto 0.1.0",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "uuid"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[metadata]
+"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
+"checksum libc 0.2.95 (registry+https://github.com/rust-lang/crates.io-index)" 
= "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
+"checksum proc-macro2 0.4.30 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
+"checksum quote 0.6.13 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
+"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" 
= "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
+"checksum unicode-xid 0.1.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+"checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" 
= "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768"
+"checksum uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" 
= "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
diff --git a/examples/udp_socket/host/Cargo.toml 
b/examples/udp_socket/host/Cargo.toml
new file mode 100644
index 0000000..de062f2
--- /dev/null
+++ b/examples/udp_socket/host/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "udp_socket"
+version = "0.1.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"
+
+[dependencies]
+libc = "0.2.48"
+proto = { path = "../proto" }
+optee-teec = { path = "../../../optee-teec" }
+
+[profile.release]
+lto = true
diff --git a/ci/ci.sh b/examples/udp_socket/host/Makefile
old mode 100755
new mode 100644
similarity index 57%
copy from ci/ci.sh
copy to examples/udp_socket/host/Makefile
index ed3d738..7e23e0b
--- a/ci/ci.sh
+++ b/examples/udp_socket/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,21 +15,31 @@
 # specific language governing permissions and limitations
 # under the License.
 
-set -xe
+NAME := udp_socket
+ARCH ?= aarch64
+
+OPTEE_DIR ?= ../../../optee
+
+ifeq ($(ARCH), arm)
+       OPTEE_BIN := $(OPTEE_DIR)/toolchains/aarch32/bin
+       OBJCOPY := $(OPTEE_BIN)/arm-linux-gnueabihf-objcopy
+       TARGET := arm-unknown-linux-gnueabihf
+else
+       OPTEE_BIN := $(OPTEE_DIR)/toolchains/$(ARCH)/bin
+       OBJCOPY := $(OPTEE_BIN)/aarch64-linux-gnu-objcopy
+       TARGET := aarch64-unknown-linux-gnu
+endif
+
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+
+all: host strip
 
-pushd ../tests
+host:
+       @cargo build --target $(TARGET) --release
 
-./test_hello_world.sh
-./test_random.sh
-./test_secure_storage.sh
-./test_aes.sh
-./test_serde.sh
-./test_hotp.sh
-./test_acipher.sh
-./test_big_int.sh
-./test_diffie_hellman.sh
-./test_digest.sh
-./test_authentication.sh
-./test_time.sh
+strip:
+       @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/$(NAME) $(OUT_DIR)/$(NAME)
 
-popd
+clean:
+       @cargo clean
diff --git a/examples/udp_socket/host/src/main.rs 
b/examples/udp_socket/host/src/main.rs
new file mode 100644
index 0000000..416ef50
--- /dev/null
+++ b/examples/udp_socket/host/src/main.rs
@@ -0,0 +1,49 @@
+// 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, Operation, Session, Uuid};
+use optee_teec::ParamNone;
+use proto::{UUID, Command};
+use std::thread;
+use std::net::UdpSocket;
+use std::str;
+
+fn udp_socket(session: &mut Session) -> optee_teec::Result<()> {
+    let mut operation = Operation::new(0, ParamNone, ParamNone, ParamNone, 
ParamNone);
+    session.invoke_command(Command::Start as u32, &mut operation)?;
+    Ok(())
+}
+
+fn main() -> optee_teec::Result<()> {
+    let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
+
+    let mut ctx = Context::new()?;
+    let uuid = Uuid::parse_str(UUID).unwrap();
+    let child = thread::spawn(move || {
+        let mut session = ctx.open_session(uuid).unwrap();
+        udp_socket(&mut session).unwrap();
+    });
+
+    let mut buf = [0; 100];
+    let (_, src_addr) = socket.recv_from(&mut buf).unwrap();
+    socket.send_to(b"[Host] Hello, Teaclave!", src_addr).unwrap();
+    println!("{}", str::from_utf8(&buf).unwrap());
+    let _ = child.join();
+
+    println!("Success");
+    Ok(())
+}
diff --git a/examples/udp_socket/proto/Cargo.toml 
b/examples/udp_socket/proto/Cargo.toml
new file mode 100644
index 0000000..00f6bae
--- /dev/null
+++ b/examples/udp_socket/proto/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "proto"
+version = "0.1.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"
+
+[dependencies]
+
+[build_dependencies]
+uuid = { version = "0.8" }
diff --git a/optee-utee/optee-utee-sys/src/lib.rs 
b/examples/udp_socket/proto/build.rs
similarity index 62%
copy from optee-utee/optee-utee-sys/src/lib.rs
copy to examples/udp_socket/proto/build.rs
index ef15d46..b9d0612 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/examples/udp_socket/proto/build.rs
@@ -15,22 +15,22 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![allow(non_camel_case_types, non_snake_case)]
+use std::fs;
+use std::path::PathBuf;
+use std::fs::File;
+use std::env;
+use std::io::Write;
 
-pub use tee_api::*;
-pub use tee_api_defines::*;
-pub use tee_api_types::*;
-pub use tee_internal_api_extensions::*;
-pub use trace::*;
-pub use user_ta_header::*;
-pub use utee_syscalls::*;
-pub use utee_types::*;
-
-mod tee_api;
-mod tee_api_defines;
-mod tee_api_types;
-mod tee_internal_api_extensions;
-mod trace;
-mod user_ta_header;
-mod utee_syscalls;
-mod utee_types;
+fn main() {
+    let uuid = match fs::read_to_string("../uuid.txt") {
+        Ok(u) => {
+            u.trim().to_string()
+        },
+        Err(_) => {
+            panic!("Cannot find uuid.txt");
+        }
+    };
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+    let mut buffer = File::create(out.join("uuid.txt")).unwrap();
+    write!(buffer, "{}", uuid).unwrap();
+}
diff --git a/optee-utee/optee-utee-sys/src/lib.rs 
b/examples/udp_socket/proto/src/lib.rs
similarity index 66%
copy from optee-utee/optee-utee-sys/src/lib.rs
copy to examples/udp_socket/proto/src/lib.rs
index ef15d46..7679b2d 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/examples/udp_socket/proto/src/lib.rs
@@ -15,22 +15,19 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![allow(non_camel_case_types, non_snake_case)]
+pub enum Command {
+    Start,
+    Unknown,
+}
 
-pub use tee_api::*;
-pub use tee_api_defines::*;
-pub use tee_api_types::*;
-pub use tee_internal_api_extensions::*;
-pub use trace::*;
-pub use user_ta_header::*;
-pub use utee_syscalls::*;
-pub use utee_types::*;
+impl From<u32> for Command {
+    #[inline]
+    fn from(value: u32) -> Command {
+        match value {
+            0 => Command::Start,
+            _ => Command::Unknown,
+        }
+    }
+}
 
-mod tee_api;
-mod tee_api_defines;
-mod tee_api_types;
-mod tee_internal_api_extensions;
-mod trace;
-mod user_ta_header;
-mod utee_syscalls;
-mod utee_types;
+pub const UUID: &str = &include_str!(concat!(env!("OUT_DIR"), "/uuid.txt"));
diff --git a/examples/udp_socket/ta/Cargo.lock 
b/examples/udp_socket/ta/Cargo.lock
new file mode 100644
index 0000000..4499911
--- /dev/null
+++ b/examples/udp_socket/ta/Cargo.lock
@@ -0,0 +1,105 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "bitflags"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "hex"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "libc"
+version = "0.2.59"
+
+[[package]]
+name = "optee-utee"
+version = "0.1.0"
+dependencies = [
+ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.59",
+ "optee-utee-macros 0.1.0",
+ "optee-utee-sys 0.1.0",
+ "uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "optee-utee-macros"
+version = "0.1.0"
+dependencies = [
+ "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "optee-utee-sys"
+version = "0.1.0"
+dependencies = [
+ "libc 0.2.59",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "0.4.30"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "proto"
+version = "0.1.0"
+dependencies = [
+ "uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "0.6.12"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "0.15.39"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+dependencies = [
+ "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ta"
+version = "0.1.0"
+dependencies = [
+ "libc 0.2.59",
+ "optee-utee 0.1.0",
+ "optee-utee-sys 0.1.0",
+ "proto 0.1.0",
+ "uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+
+[metadata]
+"checksum bitflags 1.1.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
+"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = 
"805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
+"checksum proc-macro2 0.4.30 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
+"checksum quote 0.6.12 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
+"checksum syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)" 
= "b4d960b829a55e56db167e861ddb43602c003c7be0bee1d345021703fac2fb7c"
+"checksum unicode-xid 0.1.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+"checksum uuid 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" 
= "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
diff --git a/examples/udp_socket/ta/Cargo.toml 
b/examples/udp_socket/ta/Cargo.toml
new file mode 100644
index 0000000..027e6a3
--- /dev/null
+++ b/examples/udp_socket/ta/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "ta"
+version = "0.1.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"
+
+[dependencies]
+libc = { path = "../../../rust/libc" }
+proto = { path = "../proto" }
+optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
+optee-utee = { path = "../../../optee-utee" }
+
+[build_dependencies]
+uuid = { version = "0.8" }
+proto = { path = "../proto" }
+
+[profile.release]
+lto = true
diff --git a/examples/udp_socket/ta/Makefile b/examples/udp_socket/ta/Makefile
new file mode 100644
index 0000000..ffee4b2
--- /dev/null
+++ b/examples/udp_socket/ta/Makefile
@@ -0,0 +1,53 @@
+# 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.
+
+OPTEE_DIR ?= ../../../optee
+OPTEE_OS_DIR ?= $(OPTEE_DIR)/optee_os
+UUID ?= $(shell cat "../uuid.txt")
+
+ARCH ?= aarch64
+
+ifeq ($(ARCH), arm)
+       TA_SIGN_KEY ?= 
$(OPTEE_OS_DIR)/out/arm/export-ta_arm32/keys/default_ta.pem
+       SIGN := $(OPTEE_OS_DIR)/out/arm/export-ta_arm32/scripts/sign_encrypt.py
+       OPTEE_BIN := $(OPTEE_DIR)/toolchains/aarch32/bin
+       OBJCOPY := $(OPTEE_BIN)/arm-linux-gnueabihf-objcopy
+       TARGET := arm-unknown-optee-trustzone
+else
+       TA_SIGN_KEY ?= 
$(OPTEE_OS_DIR)/out/arm/export-ta_arm64/keys/default_ta.pem
+       SIGN := $(OPTEE_OS_DIR)/out/arm/export-ta_arm64/scripts/sign_encrypt.py
+       OPTEE_BIN := $(OPTEE_DIR)/toolchains/$(ARCH)/bin
+       OBJCOPY := $(OPTEE_BIN)/aarch64-linux-gnu-objcopy
+       TARGET := aarch64-unknown-optee-trustzone
+endif
+
+OUT_DIR := $(CURDIR)/target/$(TARGET)/release
+
+all: ta strip sign
+
+ta:
+       @xargo build --target $(TARGET) --release --verbose
+
+strip:
+       @$(OBJCOPY) --strip-unneeded $(OUT_DIR)/ta $(OUT_DIR)/stripped_ta
+
+sign:
+       @$(SIGN) --uuid $(UUID) --key $(TA_SIGN_KEY) --in 
$(OUT_DIR)/stripped_ta --out $(OUT_DIR)/$(UUID).ta
+       @echo "SIGN =>  ${UUID}"
+
+clean:
+       @xargo clean
diff --git a/examples/udp_socket/ta/Xargo.toml 
b/examples/udp_socket/ta/Xargo.toml
new file mode 100644
index 0000000..c577b24
--- /dev/null
+++ b/examples/udp_socket/ta/Xargo.toml
@@ -0,0 +1,8 @@
+[dependencies.std]
+path = "../../../rust/rust/src/libstd"
+
+[patch.crates-io]
+libc =  { path = "../../../rust/libc" }
+compiler_builtins =  { path = "../../../rust/compiler-builtins" }
+rustc-std-workspace-core = { path = 
"../../../rust/rust/src/tools/rustc-std-workspace-core" }
+rustc-std-workspace-alloc = { path = 
"../../../rust/rust/src/tools/rustc-std-workspace-alloc" }
diff --git a/examples/udp_socket/ta/build.rs b/examples/udp_socket/ta/build.rs
new file mode 100644
index 0000000..33f6cc0
--- /dev/null
+++ b/examples/udp_socket/ta/build.rs
@@ -0,0 +1,62 @@
+// 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 proto;
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::{Path, PathBuf};
+use uuid::Uuid;
+
+fn main() -> std::io::Result<()> {
+    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
+
+    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
+    buffer.write_all(include_bytes!("ta_static.rs"))?;
+
+    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
+    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = 
tee_uuid.as_fields();
+
+    write!(buffer, "\n")?;
+    write!(
+        buffer,
+        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
+    timeLow: {:#x},
+    timeMid: {:#x},
+    timeHiAndVersion: {:#x},
+    clockSeqAndNode: {:#x?},
+}};",
+        time_low, time_mid, time_hi_and_version, clock_seq_and_node
+    )?;
+    let optee_os_dir = 
env::var("OPTEE_OS_DIR").unwrap_or("../../../optee/optee_os".to_string());
+    let search_path = match env::var("ARCH") {
+        Ok(ref v) if v == "arm" => {
+            
File::create(out.join("ta.lds"))?.write_all(include_bytes!("ta_arm.lds"))?;
+            Path::new(&optee_os_dir).join("out/arm/export-ta_arm32/lib")
+        },
+        _ => {
+            
File::create(out.join("ta.lds"))?.write_all(include_bytes!("ta_aarch64.lds"))?;
+            Path::new(&optee_os_dir).join("out/arm/export-ta_arm64/lib")
+        }
+    };
+    println!("cargo:rustc-link-search={}", out.display());
+    println!("cargo:rerun-if-changed=ta.lds");
+
+    println!("cargo:rustc-link-search={}", search_path.display());
+    println!("cargo:rustc-link-lib=static=utee");
+    Ok(())
+}
diff --git a/examples/udp_socket/ta/src/main.rs 
b/examples/udp_socket/ta/src/main.rs
new file mode 100644
index 0000000..11defb8
--- /dev/null
+++ b/examples/udp_socket/ta/src/main.rs
@@ -0,0 +1,98 @@
+// 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_main]
+
+use optee_utee::{
+    ta_close_session, ta_create, ta_destroy, ta_invoke_command, 
ta_open_session, trace_println,
+};
+use optee_utee::{Error, ErrorKind, Parameters, Result};
+use optee_utee::net::UdpSocket;
+use proto::Command;
+use std::io::Read;
+use std::io::Write;
+
+#[ta_create]
+fn create() -> Result<()> {
+    trace_println!("[+] TA create");
+    Ok(())
+}
+
+#[ta_open_session]
+fn open_session(_params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA open session");
+    Ok(())
+}
+
+#[ta_close_session]
+fn close_session() {
+    trace_println!("[+] TA close session");
+}
+
+#[ta_destroy]
+fn destroy() {
+    trace_println!("[+] TA destroy");
+}
+
+#[ta_invoke_command]
+fn invoke_command(cmd_id: u32, _params: &mut Parameters) -> Result<()> {
+    trace_println!("[+] TA invoke command");
+    match Command::from(cmd_id) {
+        Command::Start => {
+            udp_socket();
+            Ok(())
+        }
+        _ => Err(Error::new(ErrorKind::BadParameters)),
+    }
+}
+
+fn udp_socket() {
+    let mut stream = UdpSocket::connect("127.0.0.1", 34254).unwrap();
+    stream.write_all(b"[TA]: Hello, Teaclave!").unwrap();
+    let mut response = Vec::new();
+    let mut chunk = [0u8; 1024];
+
+    // Loop until read something.
+    loop {
+        match stream.read(&mut chunk) {
+            Ok(0) => continue,
+            Ok(n) => {
+                response.extend_from_slice(&chunk[..n]);
+                break;
+            }
+            Err(_) => {
+                trace_println!("Error");
+                panic!();
+            }
+        }
+    }
+    trace_println!("{}", String::from_utf8_lossy(&response));
+}
+
+// TA configurations
+const TA_FLAGS: u32 = 0;
+const TA_DATA_SIZE: u32 = 1 * 1024 * 1024;
+const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
+const TA_VERSION: &[u8] = b"0.1\0";
+const TA_DESCRIPTION: &[u8] = b"This is a hello world example.\0";
+const EXT_PROP_VALUE_1: &[u8] = b"Hello World TA\0";
+const EXT_PROP_VALUE_2: u32 = 0x0010;
+const TRACE_LEVEL: i32 = 4;
+const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
+const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
+
+include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/udp_socket/ta/ta_aarch64.lds 
b/examples/udp_socket/ta/ta_aarch64.lds
new file mode 100644
index 0000000..adb7603
--- /dev/null
+++ b/examples/udp_socket/ta/ta_aarch64.lds
@@ -0,0 +1,92 @@
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+
+PHDRS {
+       /*
+        * Exec and rodata headers are hard coded to RX and RO
+        * respectively. This is needed because the binary is relocatable
+        * and the linker would automatically make any header writeable
+        * that need to be updated during relocation.
+        */
+       exec PT_LOAD FLAGS (5);         /* RX */
+       rodata PT_LOAD FLAGS (4);       /* RO */
+       rwdata PT_LOAD;
+       dyn PT_DYNAMIC;
+}
+
+SECTIONS {
+       .ta_head : {*(.ta_head)} :exec
+       .text : {
+               __text_start = .;
+               *(.text .text.*)
+               *(.stub)
+               *(.glue_7)
+               *(.glue_7t)
+               *(.gnu.linkonce.t.*)
+               /* Workaround for an erratum in ARM's VFP11 coprocessor */
+               *(.vfp11_veneer)
+               PROVIDE(__gnu_mcount_nc = __utee_mcount);
+               __text_end = .;
+       }
+        .plt : { *(.plt) }
+
+       .eh_frame : { *(.eh_frame) } :rodata
+       .rodata : {
+               *(.gnu.linkonce.r.*)
+               *(.rodata .rodata.*)
+       }
+       /* .ARM.exidx is sorted, so has to go in its own output section.  */
+       .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+        .ctors : { *(.ctors) }
+        .dtors : { *(.dtors) }
+       .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+       .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+       .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+       .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+       .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+       .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+       .rel.dyn : { *(.rel.dyn) }
+       .rel.got : { *(.rel.got) }
+       .rela.got : { *(.rela.got) }
+       .rel.ctors : { *(.rel.ctors) }
+       .rela.ctors : { *(.rela.ctors) }
+       .rel.dtors : { *(.rel.dtors) }
+       .rela.dtors : { *(.rela.dtors) }
+       .rel.init : { *(.rel.init) }
+       .rela.init : { *(.rela.init) }
+       .rel.fini : { *(.rel.fini) }
+       .rela.fini : { *(.rela.fini) }
+       .rel.bss : { *(.rel.bss) }
+       .rela.bss : { *(.rela.bss) }
+       .rel.plt : { *(.rel.plt) }
+       .rela.plt : { *(.rela.plt) }
+       .dynamic : { *(.dynamic) } :dyn :rodata
+       .dynsym : { *(.dynsym) } :rodata
+       .dynstr : { *(.dynstr) }
+       .hash : { *(.hash) }
+
+       /* Page align to allow dropping execute bit for RW data */
+       . = ALIGN(4096);
+
+       .data : { *(.data .data.* .gnu.linkonce.d.*) } :rwdata
+       .got : { *(.got.plt) *(.got) }
+       .bss : {
+               *(.bss .bss.* .gnu.linkonce.b.* COMMON)
+
+               /*
+                * TA profiling with gprof
+                * Reserve some space for the profiling buffer, only if the
+                * TA is instrumented (i.e., some files were built with -pg).
+                * Note that PROVIDE() above defines a symbol only if it is
+                * referenced in the object files.
+                * This also provides a way to detect at runtime if the TA is
+                * instrumented or not.
+                */
+               . = ALIGN(8);
+               __gprof_buf_start = .;
+               __gprof_buf_end = .;
+       }
+
+       /DISCARD/ : { *(.interp) }
+}
+
diff --git a/examples/udp_socket/ta/ta_arm.lds 
b/examples/udp_socket/ta/ta_arm.lds
new file mode 100644
index 0000000..e9601b5
--- /dev/null
+++ b/examples/udp_socket/ta/ta_arm.lds
@@ -0,0 +1,91 @@
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+PHDRS {
+       /*
+        * Exec and rodata headers are hard coded to RX and RO
+        * respectively. This is needed because the binary is relocatable
+        * and the linker would automatically make any header writeable
+        * that need to be updated during relocation.
+        */
+       exec PT_LOAD FLAGS (5);         /* RX */
+       rodata PT_LOAD FLAGS (4);       /* RO */
+       rwdata PT_LOAD;
+       dyn PT_DYNAMIC;
+}
+
+SECTIONS {
+       .ta_head : {*(.ta_head)} :exec
+       .text : {
+               __text_start = .;
+               *(.text .text.*)
+               *(.stub)
+               *(.glue_7)
+               *(.glue_7t)
+               *(.gnu.linkonce.t.*)
+               /* Workaround for an erratum in ARM's VFP11 coprocessor */
+               *(.vfp11_veneer)
+               PROVIDE(__gnu_mcount_nc = __utee_mcount);
+               __text_end = .;
+       }
+        .plt : { *(.plt) }
+
+       .eh_frame : { *(.eh_frame) } :rodata
+       .rodata : {
+               *(.gnu.linkonce.r.*)
+               *(.rodata .rodata.*)
+       }
+       /* .ARM.exidx is sorted, so has to go in its own output section.  */
+       .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+        .ctors : { *(.ctors) }
+        .dtors : { *(.dtors) }
+       .got : { *(.got.plt) *(.got) }
+       .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+       .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+       .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+       .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+       .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+       .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+       .rel.dyn : { *(.rel.dyn) }
+       .rel.got : { *(.rel.got) }
+       .rela.got : { *(.rela.got) }
+       .rel.ctors : { *(.rel.ctors) }
+       .rela.ctors : { *(.rela.ctors) }
+       .rel.dtors : { *(.rel.dtors) }
+       .rela.dtors : { *(.rela.dtors) }
+       .rel.init : { *(.rel.init) }
+       .rela.init : { *(.rela.init) }
+       .rel.fini : { *(.rel.fini) }
+       .rela.fini : { *(.rela.fini) }
+       .rel.bss : { *(.rel.bss) }
+       .rela.bss : { *(.rela.bss) }
+       .rel.plt : { *(.rel.plt) }
+       .rela.plt : { *(.rela.plt) }
+       .dynamic : { *(.dynamic) } :dyn :rodata
+       .dynsym : { *(.dynsym) } :rodata
+       .dynstr : { *(.dynstr) }
+       .hash : { *(.hash) }
+
+       /* Page align to allow dropping execute bit for RW data */
+       . = ALIGN(4096);
+
+       .data : { *(.data .data.* .gnu.linkonce.d.*) } :rwdata
+       .bss : {
+               *(.bss .bss.* .gnu.linkonce.b.* COMMON)
+
+               /*
+                * TA profiling with gprof
+                * Reserve some space for the profiling buffer, only if the
+                * TA is instrumented (i.e., some files were built with -pg).
+                * Note that PROVIDE() above defines a symbol only if it is
+                * referenced in the object files.
+                * This also provides a way to detect at runtime if the TA is
+                * instrumented or not.
+                */
+               . = ALIGN(8);
+               __gprof_buf_start = .;
+               __gprof_buf_end = .;
+       }
+
+       /DISCARD/ : { *(.interp) }
+}
diff --git a/examples/udp_socket/ta/ta_static.rs 
b/examples/udp_socket/ta/ta_static.rs
new file mode 100644
index 0000000..b31f8c3
--- /dev/null
+++ b/examples/udp_socket/ta/ta_static.rs
@@ -0,0 +1,98 @@
+// 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_mangle]
+pub static mut trace_level: libc::c_int = TRACE_LEVEL;
+
+#[no_mangle]
+pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
+
+#[no_mangle]
+#[link_section = ".ta_head"]
+pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
+    uuid: TA_UUID,
+    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
+    flags: TA_FLAGS,
+    depr_entry: std::u64::MAX,
+};
+
+#[no_mangle]
+#[link_section = ".bss"]
+pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
+
+#[no_mangle]
+pub static ta_heap_size: libc::size_t = std::mem::size_of::<u8>() * 
TA_DATA_SIZE as usize;
+static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) 
!= 0;
+static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) 
!= 0;
+static FLAG_INSTANCE: bool = (TA_FLAGS & 
optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
+
+#[no_mangle]
+pub static ta_num_props: libc::size_t = 9;
+
+#[no_mangle]
+pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_BOOL as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_MULTI as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
+        value: &FLAG_INSTANCE as *const bool as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_DATA_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &TA_STACK_SIZE as *const u32 as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_VERSION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_VERSION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: TA_DESCRIPTION as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.description\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
+        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
+    },
+    optee_utee_sys::user_ta_property {
+        name: "gp.ta.version\0".as_ptr(),
+        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
+        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
+    },
+];
+
+#[no_mangle]
+pub unsafe extern "C" fn tahead_get_trace_level() -> libc::c_int {
+    return trace_level;
+}
diff --git a/examples/udp_socket/uuid.txt b/examples/udp_socket/uuid.txt
new file mode 100644
index 0000000..e91b72f
--- /dev/null
+++ b/examples/udp_socket/uuid.txt
@@ -0,0 +1 @@
+87c2d78e-eb7b-11eb-8d25-df4d5338f285
diff --git a/optee-utee/optee-utee-sys/src/lib.rs 
b/optee-utee/optee-utee-sys/src/lib.rs
index ef15d46..3284a5e 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/optee-utee/optee-utee-sys/src/lib.rs
@@ -21,6 +21,10 @@ pub use tee_api::*;
 pub use tee_api_defines::*;
 pub use tee_api_types::*;
 pub use tee_internal_api_extensions::*;
+pub use tee_isocket::*;
+pub use tee_tcpsocket::*;
+pub use tee_udpsocket::*;
+pub use tee_ipsocket::*;
 pub use trace::*;
 pub use user_ta_header::*;
 pub use utee_syscalls::*;
@@ -30,7 +34,11 @@ mod tee_api;
 mod tee_api_defines;
 mod tee_api_types;
 mod tee_internal_api_extensions;
+mod tee_isocket;
+mod tee_tcpsocket;
+mod tee_udpsocket;
 mod trace;
 mod user_ta_header;
 mod utee_syscalls;
 mod utee_types;
+mod tee_ipsocket;
diff --git a/optee-utee/optee-utee-sys/src/lib.rs 
b/optee-utee/optee-utee-sys/src/tee_ipsocket.rs
similarity index 66%
copy from optee-utee/optee-utee-sys/src/lib.rs
copy to optee-utee/optee-utee-sys/src/tee_ipsocket.rs
index ef15d46..123ceb2 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/optee-utee/optee-utee-sys/src/tee_ipsocket.rs
@@ -15,22 +15,9 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![allow(non_camel_case_types, non_snake_case)]
-
-pub use tee_api::*;
-pub use tee_api_defines::*;
-pub use tee_api_types::*;
-pub use tee_internal_api_extensions::*;
-pub use trace::*;
-pub use user_ta_header::*;
-pub use utee_syscalls::*;
-pub use utee_types::*;
-
-mod tee_api;
-mod tee_api_defines;
-mod tee_api_types;
-mod tee_internal_api_extensions;
-mod trace;
-mod user_ta_header;
-mod utee_syscalls;
-mod utee_types;
+#[repr(C)]
+pub enum TEE_ipSocket_ipVersion {
+    TEE_IP_VERSION_DC = 0,
+    TEE_IP_VERSION_4 = 1,
+    TEE_IP_VERSION_6 = 2,
+}
diff --git a/optee-utee/optee-utee-sys/src/tee_isocket.rs 
b/optee-utee/optee-utee-sys/src/tee_isocket.rs
new file mode 100644
index 0000000..4906711
--- /dev/null
+++ b/optee-utee/optee-utee-sys/src/tee_isocket.rs
@@ -0,0 +1,64 @@
+// 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::*;
+use libc::*;
+
+pub type TEE_iSocketHandle = *mut c_void;
+pub type TEE_iSocket = TEE_iSocket_s;
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct TEE_iSocket_s {
+    pub TEE_iSocketVersion: u32,
+    pub protocolID: u8,
+    pub open: unsafe extern "C" fn(
+        ctx: *mut TEE_iSocketHandle,
+        setup: *mut c_void,
+        protocolError: *mut u32,
+    ) -> TEE_Result,
+    pub close: unsafe extern "C" fn(ctx: TEE_iSocketHandle) -> TEE_Result,
+    pub send: unsafe extern "C" fn(
+        ctx: TEE_iSocketHandle,
+        buf: *const c_void,
+        length: *mut u32,
+        timeout: u32,
+    ) -> TEE_Result,
+    pub recv: unsafe extern "C" fn(
+        ctx: TEE_iSocketHandle,
+        buf: *mut c_void,
+        length: *mut u32,
+        timeout: u32,
+    ) -> TEE_Result,
+    pub error: unsafe extern "C" fn(ctx: TEE_iSocketHandle) -> u32,
+    pub ioctl: unsafe extern "C" fn(
+        ctx: TEE_iSocketHandle,
+        commandCode: u32,
+        buf: *mut c_void,
+        length: *mut u32,
+    ) -> TEE_Result,
+}
+
+pub const TEE_ISOCKET_VERSION: u32 = 0x01000000;
+ 
+pub const TEE_ISOCKET_ERROR_PROTOCOL: u32 = 0xF1007001;
+pub const TEE_ISOCKET_ERROR_REMOTE_CLOSED: u32 = 0xF1007002;
+pub const TEE_ISOCKET_ERROR_TIMEOUT: u32 = 0xF1007003;
+pub const TEE_ISOCKET_ERROR_OUT_OF_RESOURCES: u32 = 0xF1007004;
+pub const TEE_ISOCKET_ERROR_LARGE_BUFFER: u32 = 0xF1007005;
+pub const TEE_ISOCKET_WARNING_PROTOCOL: u32 = 0xF1007006;
+pub const TEE_ISOCKET_ERROR_HOSTNAME: u32 = 0xF1007007;
diff --git a/optee-utee/optee-utee-sys/src/lib.rs 
b/optee-utee/optee-utee-sys/src/tee_tcpsocket.rs
similarity index 59%
copy from optee-utee/optee-utee-sys/src/lib.rs
copy to optee-utee/optee-utee-sys/src/tee_tcpsocket.rs
index ef15d46..a942cd4 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/optee-utee/optee-utee-sys/src/tee_tcpsocket.rs
@@ -15,22 +15,25 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![allow(non_camel_case_types, non_snake_case)]
+use super::*;
+use libc::*;
 
-pub use tee_api::*;
-pub use tee_api_defines::*;
-pub use tee_api_types::*;
-pub use tee_internal_api_extensions::*;
-pub use trace::*;
-pub use user_ta_header::*;
-pub use utee_syscalls::*;
-pub use utee_types::*;
+pub type TEE_tcpSocket_Setup = TEE_tcpSocket_Setup_s;
+#[repr(C)]
+pub struct TEE_tcpSocket_Setup_s {
+    pub ipVersion: TEE_ipSocket_ipVersion,
+    pub server_addr: *const c_char,
+    pub server_port: u16,
+}
 
-mod tee_api;
-mod tee_api_defines;
-mod tee_api_types;
-mod tee_internal_api_extensions;
-mod trace;
-mod user_ta_header;
-mod utee_syscalls;
-mod utee_types;
+extern "C" {
+    #[no_mangle]
+    pub static TEE_tcpSocket: *const TEE_iSocket;
+}
+
+
+pub const TEE_ISOCKET_PROTOCOLID_TCP: u32 = 0x65;
+pub const TEE_ISOCKET_TCP_WARNING_UNKNOWN_OUT_OF_BAND: u32 = 0xF1010002;
+
+pub const TEE_TCP_SET_RECVBUF: u32 = 0x65f00000;
+pub const TEE_TCP_SET_SENDBUF: u32 = 0x65f00001;
diff --git a/optee-utee/optee-utee-sys/src/lib.rs 
b/optee-utee/optee-utee-sys/src/tee_udpsocket.rs
similarity index 60%
copy from optee-utee/optee-utee-sys/src/lib.rs
copy to optee-utee/optee-utee-sys/src/tee_udpsocket.rs
index ef15d46..bea28d3 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/optee-utee/optee-utee-sys/src/tee_udpsocket.rs
@@ -15,22 +15,23 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![allow(non_camel_case_types, non_snake_case)]
+use super::*;
+use libc::*;
 
-pub use tee_api::*;
-pub use tee_api_defines::*;
-pub use tee_api_types::*;
-pub use tee_internal_api_extensions::*;
-pub use trace::*;
-pub use user_ta_header::*;
-pub use utee_syscalls::*;
-pub use utee_types::*;
+pub type TEE_udpSocket_Setup = TEE_udpSocket_Setup_s;
+#[repr(C)]
+pub struct TEE_udpSocket_Setup_s {
+    pub ipVersion: TEE_ipSocket_ipVersion,
+    pub server_addr: *const c_char,
+    pub server_port: u16,
+}
 
-mod tee_api;
-mod tee_api_defines;
-mod tee_api_types;
-mod tee_internal_api_extensions;
-mod trace;
-mod user_ta_header;
-mod utee_syscalls;
-mod utee_types;
+extern "C" {
+    #[no_mangle]
+    pub static TEE_udpSocket: *const TEE_iSocket;
+}
+
+pub const TEE_ISOCKET_PROTOCOLID_UDP: u32 = 0x66;
+pub const TEE_ISOCKET_UDP_WARNING_UNKNOWN_OUT_OF_BAND: u32 = 0xF1020002;
+pub const TEE_UDP_CHANGEADDR: u32 = 0x66000001;
+pub const TEE_UDP_CHANGEPORT: u32 = 0x66000002;
diff --git a/optee-utee/src/lib.rs b/optee-utee/src/lib.rs
index 6de80f6..2893b76 100644
--- a/optee-utee/src/lib.rs
+++ b/optee-utee/src/lib.rs
@@ -38,3 +38,4 @@ pub mod time;
 pub mod arithmetical;
 pub mod extension;
 pub mod uuid;
+pub mod net;
diff --git a/optee-utee/src/net.rs b/optee-utee/src/net.rs
new file mode 100644
index 0000000..ea859b5
--- /dev/null
+++ b/optee-utee/src/net.rs
@@ -0,0 +1,361 @@
+// 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_sys as raw;
+use std::io;
+use std::io::ErrorKind;
+use std::ptr;
+
+pub struct TcpStream {
+    pub handle: raw::TEE_iSocketHandle,
+}
+
+impl TcpStream {
+    fn connect_with_ip_version(
+        address: &str,
+        port: u16,
+        ip_version: raw::TEE_ipSocket_ipVersion,
+    ) -> std::io::Result<Self> {
+        use std::ffi::CString;
+        unsafe {
+            let addr = match CString::new(address) {
+                Ok(addr) => addr,
+                Err(_) => return Err(io::Error::new(ErrorKind::Other, "Invalid 
address")),
+            };
+            let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
+            let mut protocol_error: u32 = 0;
+            let mut setup = raw::TEE_tcpSocket_Setup {
+                ipVersion: ip_version,
+                server_addr: addr.as_ptr() as _,
+                server_port: port,
+            };
+            let ret = ((*raw::TEE_tcpSocket).open)(
+                &mut handle,
+                &mut setup as *mut raw::TEE_tcpSocket_Setup as _,
+                &mut protocol_error,
+            );
+            match ret {
+                raw::TEE_SUCCESS => Ok(Self { handle }),
+                raw::TEE_ERROR_CANCEL => {
+                    Err(io::Error::new(ErrorKind::Interrupted, 
"TEE_ERROR_CANCEL"))
+                }
+                raw::TEE_ERROR_OUT_OF_MEMORY => {
+                    Err(io::Error::new(ErrorKind::Other, 
"TEE_ERROR_OUT_OF_MEMORY"))
+                }
+                raw::TEE_ERROR_BAD_PARAMETERS => {
+                    Err(io::Error::new(ErrorKind::Other, 
"TEE_ERROR_BAD_PARAMETERS"))
+                }
+                raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
+                    ErrorKind::TimedOut,
+                    "TEE_ISOCKET_ERROR_TIMEOUT",
+                )),
+                raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
+                    ErrorKind::ConnectionAborted,
+                    "TEE_ERROR_COMMUNICATION",
+                )),
+                raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
+                    ErrorKind::Other,
+                    "TEE_ISOCKET_ERROR_PROTOCOL",
+                )),
+                raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
+                    ErrorKind::Other,
+                    format!("TEE_ISOCKET_WARNING_PROTOCOL: {}", 
protocol_error),
+                )),
+                _ => panic!("Unexpected return value"),
+            }
+        }
+    }
+
+    pub fn connect_v4(address: &str, port: u16) -> std::io::Result<Self> {
+        Self::connect_with_ip_version(address, port, 
raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
+    }
+
+    pub fn connect_v6(address: &str, port: u16) -> std::io::Result<Self> {
+        Self::connect_with_ip_version(address, port, 
raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
+    }
+
+    pub fn connect(address: &str, port: u16) -> std::io::Result<Self> {
+        Self::connect_v4(address, port)
+    }
+}
+
+impl Drop for TcpStream {
+    fn drop(&mut self) {
+        // Ignore any errors on close.
+        unsafe {
+            ((*raw::TEE_tcpSocket).close)(self.handle);
+        }
+    }
+}
+
+impl std::io::Read for TcpStream {
+    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+        let mut length: u32 = buf.len() as _;
+        let ret = unsafe {
+            ((*raw::TEE_tcpSocket).recv)(
+                self.handle,
+                buf.as_mut_ptr() as _,
+                &mut length,
+                raw::TEE_TIMEOUT_INFINITE,
+            )
+        };
+
+        match ret {
+            raw::TEE_SUCCESS => Ok(length as _),
+            raw::TEE_ERROR_CANCEL => {
+                Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
+            }
+            raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
+                ErrorKind::TimedOut,
+                "TEE_ISOCKET_ERROR_TIMEOUT",
+            )),
+            raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
+                ErrorKind::ConnectionAborted,
+                "TEE_ERROR_COMMUNICATION",
+            )),
+            raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
+                ErrorKind::ConnectionAborted,
+                "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
+            )),
+            raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_ERROR_PROTOCOL",
+            )),
+            raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_WARNING_PROTOCOL",
+            )),
+            _ => panic!("Unexpected return value"),
+        }
+    }
+}
+
+impl std::io::Write for TcpStream {
+    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+        let mut length: u32 = buf.len() as _;
+        let ret = unsafe {
+            ((*raw::TEE_tcpSocket).send)(
+                self.handle,
+                buf.as_ptr() as *const u8 as _,
+                &mut length,
+                raw::TEE_TIMEOUT_INFINITE,
+            )
+        };
+
+        match ret {
+            raw::TEE_SUCCESS => Ok(length as _),
+            raw::TEE_ERROR_CANCEL => {
+                Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
+            }
+            raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
+                ErrorKind::TimedOut,
+                "TEE_ISOCKET_ERROR_TIMEOUT",
+            )),
+            raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
+                ErrorKind::ConnectionAborted,
+                "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
+            )),
+            raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_ERROR_PROTOCOL",
+            )),
+            raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_WARNING_PROTOCOL",
+            )),
+            raw::TEE_ISOCKET_ERROR_LARGE_BUFFER => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_ERROR_LARGE_BUFFER",
+            )),
+            _ => panic!("Unexpected return value"),
+        }
+    }
+
+    fn flush(&mut self) -> std::io::Result<()> {
+        Ok(())
+    }
+}
+
+pub struct UdpSocket {
+    pub handle: raw::TEE_iSocketHandle,
+}
+
+impl UdpSocket {
+    fn connect_with_ip_version(
+        address: &str,
+        port: u16,
+        ip_version: raw::TEE_ipSocket_ipVersion,
+    ) -> std::io::Result<Self> {
+        use std::ffi::CString;
+        unsafe {
+            let addr = match CString::new(address) {
+                Ok(addr) => addr,
+                Err(_) => return Err(io::Error::new(ErrorKind::Other, "Invalid 
address")),
+            };
+            let mut handle: raw::TEE_iSocketHandle = ptr::null_mut();
+            let mut protocol_error: u32 = 0;
+            let mut setup = raw::TEE_udpSocket_Setup {
+                ipVersion: ip_version,
+                server_addr: addr.as_ptr() as _,
+                server_port: port,
+            };
+            let ret = ((*raw::TEE_udpSocket).open)(
+                &mut handle,
+                &mut setup as *mut raw::TEE_udpSocket_Setup as _,
+                &mut protocol_error,
+            );
+            match ret {
+                raw::TEE_SUCCESS => Ok(Self { handle }),
+                raw::TEE_ERROR_CANCEL => {
+                    Err(io::Error::new(ErrorKind::Interrupted, 
"TEE_ERROR_CANCEL"))
+                }
+                raw::TEE_ERROR_OUT_OF_MEMORY => {
+                    Err(io::Error::new(ErrorKind::Other, 
"TEE_ERROR_OUT_OF_MEMORY"))
+                }
+                raw::TEE_ERROR_BAD_PARAMETERS => {
+                    Err(io::Error::new(ErrorKind::Other, 
"TEE_ERROR_BAD_PARAMETERS"))
+                }
+                raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
+                    ErrorKind::TimedOut,
+                    "TEE_ISOCKET_ERROR_TIMEOUT",
+                )),
+                raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
+                    ErrorKind::ConnectionAborted,
+                    "TEE_ERROR_COMMUNICATION",
+                )),
+                raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
+                    ErrorKind::Other,
+                    "TEE_ISOCKET_ERROR_PROTOCOL",
+                )),
+                raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
+                    ErrorKind::Other,
+                    format!("TEE_ISOCKET_WARNING_PROTOCOL: {}", 
protocol_error),
+                )),
+                _ => panic!("Unexpected return value"),
+            }
+        }
+    }
+
+    pub fn connect_v4(address: &str, port: u16) -> std::io::Result<Self> {
+        Self::connect_with_ip_version(address, port, 
raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
+    }
+
+    pub fn connect_v6(address: &str, port: u16) -> std::io::Result<Self> {
+        Self::connect_with_ip_version(address, port, 
raw::TEE_ipSocket_ipVersion::TEE_IP_VERSION_4)
+    }
+
+    pub fn connect(address: &str, port: u16) -> std::io::Result<Self> {
+        Self::connect_v4(address, port)
+    }
+}
+
+impl Drop for UdpSocket {
+    fn drop(&mut self) {
+        // Ignore any errors on close.
+        unsafe {
+            ((*raw::TEE_udpSocket).close)(self.handle);
+        }
+    }
+}
+
+impl std::io::Read for UdpSocket {
+    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
+        let mut length: u32 = buf.len() as _;
+        let ret = unsafe {
+            ((*raw::TEE_udpSocket).recv)(
+                self.handle,
+                buf.as_mut_ptr() as _,
+                &mut length,
+                raw::TEE_TIMEOUT_INFINITE,
+            )
+        };
+
+        match ret {
+            raw::TEE_SUCCESS => Ok(length as _),
+            raw::TEE_ERROR_CANCEL => {
+                Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
+            }
+            raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
+                ErrorKind::TimedOut,
+                "TEE_ISOCKET_ERROR_TIMEOUT",
+            )),
+            raw::TEE_ERROR_COMMUNICATION => Err(io::Error::new(
+                ErrorKind::ConnectionAborted,
+                "TEE_ERROR_COMMUNICATION",
+            )),
+            raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
+                ErrorKind::ConnectionAborted,
+                "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
+            )),
+            raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_ERROR_PROTOCOL",
+            )),
+            raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_WARNING_PROTOCOL",
+            )),
+            _ => panic!("Unexpected return value"),
+        }
+    }
+}
+
+impl std::io::Write for UdpSocket {
+    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+        let mut length: u32 = buf.len() as _;
+        let ret = unsafe {
+            ((*raw::TEE_udpSocket).send)(
+                self.handle,
+                buf.as_ptr() as *const u8 as _,
+                &mut length,
+                raw::TEE_TIMEOUT_INFINITE,
+            )
+        };
+
+        match ret {
+            raw::TEE_SUCCESS => Ok(length as _),
+            raw::TEE_ERROR_CANCEL => {
+                Err(io::Error::new(ErrorKind::Interrupted, "TEE_ERROR_CANCEL"))
+            }
+            raw::TEE_ISOCKET_ERROR_TIMEOUT => Err(io::Error::new(
+                ErrorKind::TimedOut,
+                "TEE_ISOCKET_ERROR_TIMEOUT",
+            )),
+            raw::TEE_ISOCKET_ERROR_REMOTE_CLOSED => Err(io::Error::new(
+                ErrorKind::ConnectionAborted,
+                "TEE_ISOCKET_ERROR_REMOTE_CLOSED",
+            )),
+            raw::TEE_ISOCKET_ERROR_PROTOCOL => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_ERROR_PROTOCOL",
+            )),
+            raw::TEE_ISOCKET_WARNING_PROTOCOL => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_WARNING_PROTOCOL",
+            )),
+            raw::TEE_ISOCKET_ERROR_LARGE_BUFFER => Err(io::Error::new(
+                ErrorKind::Other,
+                "TEE_ISOCKET_ERROR_LARGE_BUFFER",
+            )),
+            _ => panic!("Unexpected return value"),
+        }
+    }
+
+    fn flush(&mut self) -> std::io::Result<()> {
+        Ok(())
+    }
+}
diff --git a/tests/test_tcp_client.sh b/tests/test_tcp_client.sh
new file mode 100755
index 0000000..7180e81
--- /dev/null
+++ b/tests/test_tcp_client.sh
@@ -0,0 +1,54 @@
+#!/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
+# 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.
+
+set -xe
+
+rm -rf screenlog.0
+rm -rf optee-qemuv8-3.13.0
+rm -rf shared
+
+curl http://mesalock-linux.org/assets/optee-qemuv8-3.13.0.tar.gz | tar zxv
+mkdir shared
+cp 
../examples/tcp_client/ta/target/aarch64-unknown-optee-trustzone/release/*.ta 
shared
+cp 
../examples/tcp_client/host/target/aarch64-unknown-linux-gnu/release/tcp_client 
shared
+
+screen -L -d -m -S qemu_screen ./optee-qemuv8.sh
+sleep 30
+screen -S qemu_screen -p 0 -X stuff "root\n"
+sleep 5
+screen -S qemu_screen -p 0 -X stuff "mkdir shared && mount -t 9p -o 
trans=virtio host shared && cd shared\n"
+sleep 5
+screen -S qemu_screen -p 0 -X stuff "cp *.ta /lib/optee_armtz/\n"
+sleep 5
+screen -S qemu_screen -p 0 -X stuff "./tcp_client\n"
+sleep 5
+screen -S qemu_screen -p 0 -X stuff "^C"
+sleep 5
+
+{
+       grep -q "Success" screenlog.0
+} || {
+       cat -v screenlog.0
+       cat -v /tmp/serial.log
+        false
+}
+
+rm -rf screenlog.0
+rm -rf optee-qemuv8-3.13.0
+rm -rf shared
diff --git a/tests/test_udp_socket.sh b/tests/test_udp_socket.sh
new file mode 100755
index 0000000..aa3a7f1
--- /dev/null
+++ b/tests/test_udp_socket.sh
@@ -0,0 +1,54 @@
+#!/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
+# 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.
+
+set -xe
+
+rm -rf screenlog.0
+rm -rf optee-qemuv8-3.13.0
+rm -rf shared
+
+curl http://mesalock-linux.org/assets/optee-qemuv8-3.13.0.tar.gz | tar zxv
+mkdir shared
+cp 
../examples/udp_socket/ta/target/aarch64-unknown-optee-trustzone/release/*.ta 
shared
+cp 
../examples/udp_socket/host/target/aarch64-unknown-linux-gnu/release/udp_socket 
shared
+
+screen -L -d -m -S qemu_screen ./optee-qemuv8.sh
+sleep 30
+screen -S qemu_screen -p 0 -X stuff "root\n"
+sleep 5
+screen -S qemu_screen -p 0 -X stuff "mkdir shared && mount -t 9p -o 
trans=virtio host shared && cd shared\n"
+sleep 5
+screen -S qemu_screen -p 0 -X stuff "cp *.ta /lib/optee_armtz/\n"
+sleep 5
+screen -S qemu_screen -p 0 -X stuff "./udp_socket\n"
+sleep 5
+screen -S qemu_screen -p 0 -X stuff "^C"
+sleep 5
+
+{
+       grep -q "Success" screenlog.0
+} || {
+       cat -v screenlog.0
+       cat -v /tmp/serial.log
+        false
+}
+
+rm -rf screenlog.0
+rm -rf optee-qemuv8-3.13.0
+rm -rf shared

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

Reply via email to