Build support for Rust via Cargo

ChromeOS is missing support for mixing C++ and Rust in GN so we compile
Rust in a separate step using Cargo. Currently, only the direct code
portions were copied to the Cargo.toml and tests are still missing. The
final output from the Rust build is the libbt_shim_ffi staticlib.

Some BUILD.gn rules for rust libraries were also added (to try to make
it work with an experimental Rust toolchain in GN) but was abandonded
because dependencies couldn't be built. Leaving this in since it will be
useful when GN supports building Rust as well on ChromeOS.

Bug: 176847256
Tag: #floss
Test: atest --host bluetooth_test_gd
Change-Id: I4d1ab599309b153b2304cb87c4526bc476dc2637
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..2b60ccb
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,58 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_shim_ffi"
+version = "0.0.1"
+edition = "2018"
+
+[dependencies]
+# BT dependencies
+bt_common = { path = "gd/rust/common" }
+bt_facade_helpers = { path = "gd/rust/facade" }
+bt_hal = { path = "gd/rust/hal" }
+bt_hci = { path = "gd/rust/hci" }
+bt_main = { path = "gd/rust/main" }
+bt_packets = { path = "gd/rust/packets" }
+
+# All external dependencies. Keep all versions at build/rust/Cargo.toml
+bindgen = "0.51"
+bytes = "1.0"
+cxx = { version = "0.5.9", features = ["c++17"] }
+env_logger = "0.8"
+futures = "0.3"
+grpcio = { version = "0.7", features = ["protobuf", "protobuf-codec", "openssl"] }
+grpcio-sys = { version = "*", features = ["openssl"] }
+lazy_static = "1.4"
+log = "0.4"
+nix = "0.19"
+num-derive = "0.3"
+num-traits = "0.2"
+paste = "1.0"
+proc-macro2 = "1.0.24"
+protobuf = "2.0"
+protoc-grpcio = "2.0"
+protoc-rust = "2.0"
+quote = "1.0.8"
+thiserror = "1.0"
+syn = { version = "1.0.58", features = ['default', 'full'] }
+tokio = { version = "1.0", features = ['bytes', 'fs', 'io-util', 'libc', 'macros', 'memchr', 'mio', 'net', 'num_cpus', 'rt', 'rt-multi-thread', 'sync', 'time', 'tokio-macros'] }
+tokio-stream = "0.1"
+walkdir = "2.2"
+
+
+[lib]
+path = "gd/rust/shim/src/lib.rs"
+crate-type = ["staticlib"]
diff --git a/system/gd/rust/common/BUILD.gn b/system/gd/rust/common/BUILD.gn
index 35b14c8..13ea113 100644
--- a/system/gd/rust/common/BUILD.gn
+++ b/system/gd/rust/common/BUILD.gn
@@ -13,12 +13,17 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-rust("libbt_common") {
+import("//common-mk/cxxbridge.gni")
+
+rust_library("libbt_common") {
   crate_name = "bt_common"
 
   sources = [ "src/lib.rs" ]
 
-  configs += [ "//bt/gd:gd_rust_defaults" ]
+  configs = [
+    "//bt/gd/rust/shim:rust_libs",
+    "//bt/gd:rust_defaults",
+  ]
 }
 
 cxxbridge_cc("libbt_common_sys_prop_bridge_code") {
diff --git a/system/gd/rust/common/Cargo.toml b/system/gd/rust/common/Cargo.toml
new file mode 100644
index 0000000..33a4039
--- /dev/null
+++ b/system/gd/rust/common/Cargo.toml
@@ -0,0 +1,34 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_common"
+version = "0.0.1"
+edition = "2018"
+
+[dependencies]
+cxx = "*"
+env_logger = "*"
+grpcio = "*"
+lazy_static = "*"
+log = "*"
+nix = "*"
+tokio = { version = "*", features = ['bytes', 'net'] }
+
+# Proc Macro dependency
+paste = "*"
+
+[lib]
+crate-type = ["rlib"]
diff --git a/system/gd/rust/facade/BUILD.gn b/system/gd/rust/facade/BUILD.gn
new file mode 100644
index 0000000..0140825
--- /dev/null
+++ b/system/gd/rust/facade/BUILD.gn
@@ -0,0 +1,26 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+rust_library("libbt_facade_helpers") {
+  crate_name = "bt_facade_helpers"
+  sources = [
+    "helpers/lib.rs",
+  ]
+
+  configs = [
+    "//bt/gd/rust/shim:rust_libs",
+    "//bt/gd:rust_defaults",
+  ]
+}
diff --git a/system/gd/rust/facade/Cargo.toml b/system/gd/rust/facade/Cargo.toml
new file mode 100644
index 0000000..ee8f2ad
--- /dev/null
+++ b/system/gd/rust/facade/Cargo.toml
@@ -0,0 +1,37 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_facade_helpers"
+version = "0.0.1"
+edition = "2018"
+
+[dependencies]
+# GD bluetooth deps
+bt_facade_proto = { path = "../facade_proto" }
+bt_packets = { path = "../packets" }
+
+# External deps
+bytes = "*"
+cxx = "*"
+futures = "*"
+grpcio = "*"
+log = "*"
+protobuf = "*"
+tokio = "*"
+
+[lib]
+path = "helpers/lib.rs"
+crate-type = ["rlib"]
diff --git a/system/gd/rust/facade_proto/Cargo.toml b/system/gd/rust/facade_proto/Cargo.toml
new file mode 100644
index 0000000..c69c869
--- /dev/null
+++ b/system/gd/rust/facade_proto/Cargo.toml
@@ -0,0 +1,34 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_facade_proto"
+version = "0.0.1"
+edition = "2018"
+build = "build.rs"
+
+[dependencies]
+bt_hci_custom_types = { path = "../hci/custom_types" }
+futures = "*"
+grpcio = "*"
+protobuf = "*"
+
+[build-dependencies]
+protoc-rust = "*"
+protoc-grpcio = "*"
+protobuf-codegen = "*"
+
+[lib]
+crate-types = ["rlib"]
diff --git a/system/gd/rust/facade_proto/build.rs b/system/gd/rust/facade_proto/build.rs
new file mode 100644
index 0000000..fdb7b56
--- /dev/null
+++ b/system/gd/rust/facade_proto/build.rs
@@ -0,0 +1,108 @@
+//
+//  Copyright 2021 Google, Inc.
+//
+//  Licensed 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.
+
+extern crate protobuf_codegen;
+extern crate protoc_grpcio;
+extern crate protoc_rust;
+
+use std::env;
+use std::fs;
+use std::io::Write;
+use std::path::{Path, PathBuf};
+
+fn paths_to_strs<P: AsRef<Path>>(paths: &[P]) -> Vec<&str> {
+    paths.iter().map(|p| p.as_ref().as_os_str().to_str().unwrap()).collect()
+}
+
+// Generate mod.rs files for given input files.
+fn gen_mod_rs<P: AsRef<Path>>(out_dir: PathBuf, inputs: &[P], grpc: bool) {
+    // Will panic if file doesn't exist or it can't create it
+    let mut f = fs::File::create(out_dir.join("mod.rs")).unwrap();
+
+    f.write_all(b"// Generated by build.rs\n\n").unwrap();
+
+    for i in 0..inputs.len() {
+        let stem = inputs[i].as_ref().file_stem().unwrap();
+        f.write_all(format!("pub mod {}; \n", stem.to_str().unwrap()).as_bytes()).unwrap();
+        if grpc {
+            f.write_all(format!("pub mod {}_grpc;\n", stem.to_str().unwrap()).as_bytes()).unwrap();
+        }
+    }
+}
+
+fn main() {
+    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
+    let proto_out_dir = out_dir.join("proto_out");
+    let grpc_out_dir = out_dir.join("grpc_out");
+
+    // Make sure to create the output directories before using it
+    match fs::create_dir(proto_out_dir.as_os_str().to_str().unwrap()) {
+        Err(e) => println!("Proto dir failed to be created: {}", e),
+        _ => (),
+    };
+
+    match fs::create_dir(grpc_out_dir.as_os_str().to_str().unwrap()) {
+        Err(e) => println!("Grpc dir failed to be created: {}", e),
+        _ => (),
+    }
+
+    // Proto root is //platform2/bt/gd
+    let proto_root = match env::var("PLATFORM_SUBDIR") {
+        Ok(dir) => PathBuf::from(dir).join("bt/gd"),
+        // Currently at //platform2/gd/rust/facade_proto
+        Err(_) => PathBuf::from(env::current_dir().unwrap()).join("../..").canonicalize().unwrap(),
+    };
+
+    //
+    // Generate protobuf output
+    //
+    let facade_dir = proto_root.join("facade");
+    let proto_input_files = [facade_dir.join("common.proto")];
+    let proto_include_dirs = [facade_dir];
+
+    protoc_rust::Codegen::new()
+        .out_dir(proto_out_dir.as_os_str().to_str().unwrap())
+        .inputs(&paths_to_strs(&proto_input_files))
+        .includes(&paths_to_strs(&proto_include_dirs))
+        .customize(Default::default())
+        .run()
+        .expect("protoc");
+
+    //
+    // Generate grpc output
+    //
+    let grpc_proto_input_files = [
+        proto_root.join("hci/facade/hci_facade.proto"),
+        proto_root.join("hal/hal_facade.proto"),
+        proto_root.join("facade/rootservice.proto"),
+    ];
+    let grpc_proto_include_dirs = [
+        proto_root.join("hci/facade"),
+        proto_root.join("hal"),
+        proto_root.join("facade"),
+        proto_root,
+    ];
+
+    protoc_grpcio::compile_grpc_protos(
+        &grpc_proto_input_files,
+        &grpc_proto_include_dirs,
+        &grpc_out_dir,
+        None,
+    )
+    .expect("Failed to compile gRPC definitions");
+
+    gen_mod_rs(proto_out_dir, &proto_input_files, false);
+    gen_mod_rs(grpc_out_dir, &grpc_proto_input_files, true);
+}
diff --git a/system/gd/rust/facade_proto/src/common.rs b/system/gd/rust/facade_proto/src/common.rs
new file mode 100644
index 0000000..e1a6f76
--- /dev/null
+++ b/system/gd/rust/facade_proto/src/common.rs
@@ -0,0 +1,20 @@
+//
+//  Copyright 2021 Google, Inc.
+//
+//  Licensed 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.
+
+// We are not directly including due to bugs with inner and outer attributes.
+//include!(concat!(env!("OUT_DIR"), "/common.rs"));
+
+#[path = concat!(env!("OUT_DIR", "/common.rs"))]
+pub mod common;
diff --git a/system/gd/rust/facade_proto/src/lib.rs b/system/gd/rust/facade_proto/src/lib.rs
new file mode 100644
index 0000000..56f7f70
--- /dev/null
+++ b/system/gd/rust/facade_proto/src/lib.rs
@@ -0,0 +1,25 @@
+//
+//  Copyright 2021 Google, Inc.
+//
+//  Licensed 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.
+
+// protoc-rust and protoc-grpcio generates all modules and exports them in mod.rs
+// We have to include them all here to make them available for crate export.
+include!(concat!(env!("OUT_DIR"), "/proto_out/mod.rs"));
+include!(concat!(env!("OUT_DIR"), "/grpc_out/mod.rs"));
+
+// empty.proto is missing so add a workaround
+// See github.com/stepancheg/grpc-rust/issues/156
+pub mod empty {
+    pub use protobuf::well_known_types::Empty;
+}
diff --git a/system/gd/rust/gddi/Cargo.toml b/system/gd/rust/gddi/Cargo.toml
new file mode 100644
index 0000000..9e43a14
--- /dev/null
+++ b/system/gd/rust/gddi/Cargo.toml
@@ -0,0 +1,31 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "gddi"
+version = "0.0.1"
+edition = "2018"
+
+[dependencies]
+gddi_macros = { path = "macros" }
+
+tokio = { version = "*", features = ['bytes', 'net', 'sync'] }
+quote = "*"
+syn = { version = "*", features = ['default', 'full'] }
+
+[lib]
+path = "src/lib.rs"
+crate-type = ["rlib"]
+
diff --git a/system/gd/rust/gddi/macros/Cargo.toml b/system/gd/rust/gddi/macros/Cargo.toml
new file mode 100644
index 0000000..4038b0c
--- /dev/null
+++ b/system/gd/rust/gddi/macros/Cargo.toml
@@ -0,0 +1,28 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "gddi_macros"
+version = "0.0.1"
+edition = "2018"
+
+[dependencies]
+proc-macro2 = "*"
+quote = "*"
+syn = "*"
+
+[lib]
+proc-macro = true
+path = "lib.rs"
diff --git a/system/gd/rust/hal/BUILD.gn b/system/gd/rust/hal/BUILD.gn
new file mode 100644
index 0000000..cce2f7b
--- /dev/null
+++ b/system/gd/rust/hal/BUILD.gn
@@ -0,0 +1,27 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+rust_library("libbt_hal") {
+  crate_name = "bt_hal"
+
+  sources = [
+    "src/lib.rs"
+  ]
+
+  configs = [
+    "//bt/gd/rust/shim:rust_libs",
+    "//bt/gd:rust_defaults",
+  ]
+}
diff --git a/system/gd/rust/hal/Cargo.toml b/system/gd/rust/hal/Cargo.toml
new file mode 100644
index 0000000..9963e7a
--- /dev/null
+++ b/system/gd/rust/hal/Cargo.toml
@@ -0,0 +1,46 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_hal"
+version = "0.0.1"
+edition = "2018"
+
+[dependencies]
+# BT dependencies
+bt_common = { path = "../common" }
+bt_facade_helpers = { path = "../facade" }
+bt_facade_proto = { path = "../facade_proto" }
+bt_packets = { path = "../packets" }
+gddi = { path = "../gddi" }
+
+# External dependencies
+bytes = "*"
+cxx = "*"
+futures = "*"
+grpcio = "*"
+lazy_static = "*"
+log = "*"
+nix = "*"
+num-traits = "*"
+protobuf = "*"
+thiserror = "*"
+tokio = "*"
+
+# Macro dependencies
+num-derive = "*"
+
+[lib]
+crate-type = ["rlib"]
diff --git a/system/gd/rust/hci/BUILD.gn b/system/gd/rust/hci/BUILD.gn
new file mode 100644
index 0000000..e120b27
--- /dev/null
+++ b/system/gd/rust/hci/BUILD.gn
@@ -0,0 +1,27 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+rust_library("libbt_hci") {
+  crate_name = "bt_hci"
+
+  sources = [
+    "src/lib.rs"
+  ]
+
+  configs = [
+    "//bt/gd/rust/shim:rust_libs",
+    "//bt/gd:rust_defaults",
+  ]
+}
diff --git a/system/gd/rust/hci/Cargo.toml b/system/gd/rust/hci/Cargo.toml
new file mode 100644
index 0000000..14ccc92
--- /dev/null
+++ b/system/gd/rust/hci/Cargo.toml
@@ -0,0 +1,45 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_hci"
+version = "0.0.1"
+edition = "2018"
+
+[dependencies]
+# bt deps
+bt_common = { path = "../common" }
+bt_hci_custom_types = { path = "custom_types" }
+bt_hal = { path = "../hal" }
+bt_facade_helpers = { path = "../facade" }
+bt_facade_proto = { path = "../facade_proto" }
+bt_packets = { path = "../packets" }
+gddi = { path = "../gddi" }
+
+# external deps
+bytes = "*"
+futures = "*"
+grpcio = "*"
+log = "*"
+num-traits = "*"
+protobuf = "*"
+thiserror = "*"
+tokio = { version = "*", features = ['bytes', 'net'] }
+
+# macro deps
+num-derive = "*"
+
+[lib]
+crate-type = ["rlib"]
diff --git a/system/gd/rust/hci/custom_types/Cargo.toml b/system/gd/rust/hci/custom_types/Cargo.toml
new file mode 100644
index 0000000..3e9c5e1
--- /dev/null
+++ b/system/gd/rust/hci/custom_types/Cargo.toml
@@ -0,0 +1,23 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_hci_custom_types"
+version = "0.0.1"
+edition = "2018"
+
+[lib]
+crate-type = ["rlib"]
+path = "lib.rs"
diff --git a/system/gd/rust/link/Cargo.toml b/system/gd/rust/link/Cargo.toml
new file mode 100644
index 0000000..1bde4aa
--- /dev/null
+++ b/system/gd/rust/link/Cargo.toml
@@ -0,0 +1,46 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_link"
+version = "0.0.1"
+edition = "2018"
+
+[dependencies]
+# bt deps
+bt_common = { path = "../common" }
+bt_hci = { path = "../hci" }
+bt_hci_custom_types = { path = "../hci/custom_types" }
+bt_hal = { path = "../hal" }
+bt_facade_proto = { path = "../facade_proto" }
+bt_packets = { path = "../packets" }
+gddi = { path = "../gddi" }
+
+# external deps
+bytes = "*"
+futures = "*"
+grpcio = "*"
+log = "*"
+num-traits = "*"
+protobuf = "*"
+thiserror = "*"
+tokio = { version = "*", features = ['bytes', 'net'] }
+tokio-stream = "*"
+
+# macro deps
+num-derive = "*"
+
+[lib]
+crate-type = ["rlib"]
diff --git a/system/gd/rust/main/Cargo.toml b/system/gd/rust/main/Cargo.toml
new file mode 100644
index 0000000..3a1e81e
--- /dev/null
+++ b/system/gd/rust/main/Cargo.toml
@@ -0,0 +1,33 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_main"
+version = "0.0.1"
+edition = "2018"
+
+[dependencies]
+# bt deps
+bt_common = { path = "../common" }
+bt_hal = { path = "../hal" }
+bt_hci = { path = "../hci" }
+gddi = { path = "../gddi" }
+
+# external deps
+tokio = { version = "*", features = ['bytes', 'net'] }
+grpcio = "*"
+
+[lib]
+crate-types = ["rlib"]
diff --git a/system/gd/rust/packets/Cargo.toml b/system/gd/rust/packets/Cargo.toml
new file mode 100644
index 0000000..3e31024
--- /dev/null
+++ b/system/gd/rust/packets/Cargo.toml
@@ -0,0 +1,34 @@
+#
+#  Copyright 2021 Google, Inc.
+#
+#  Licensed 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.
+
+[package]
+name = "bt_packets"
+version = "0.0.1"
+edition = "2018"
+build = "build.rs"
+
+[dependencies]
+bt_hci_custom_types = { path = "../hci/custom_types" }
+
+bindgen = "*"
+bytes = "*"
+num-derive = "*"
+num-traits = "*"
+thiserror = "*"
+walkdir = "*"
+
+[lib]
+path = "lib.rs"
+crate-types = ["rlib"]
diff --git a/system/gd/rust/packets/build.rs b/system/gd/rust/packets/build.rs
new file mode 100644
index 0000000..ddaf981
--- /dev/null
+++ b/system/gd/rust/packets/build.rs
@@ -0,0 +1,60 @@
+//
+//  Copyright 2021 Google, Inc.
+//
+//  Licensed 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 std::env;
+use std::path::PathBuf;
+use std::process::Command;
+
+fn main() {
+    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
+
+    let gd_root = match env::var("PLATFORM_SUBDIR") {
+        Ok(dir) => PathBuf::from(dir).join("bt/gd"),
+        // Currently at //platform2/gd/rust/rust/packets
+        Err(_) => PathBuf::from(env::current_dir().unwrap()).join("../..").canonicalize().unwrap(),
+    };
+
+    let input_files = [gd_root.join("hci/hci_packets.pdl")];
+    let outputted = [out_dir.join("../../hci/hci_packets.rs")];
+
+    // Find the packetgen tool. Expecting it at CARGO_HOME/bin
+    let packetgen =
+        PathBuf::from(env::var("CARGO_HOME").unwrap()).join("bin").join("bluetooth_packetgen");
+
+    for i in 0..input_files.len() {
+        let output = Command::new(packetgen.as_os_str().to_str().unwrap())
+            .arg("--source_root=".to_owned() + gd_root.as_os_str().to_str().unwrap())
+            .arg("--out=".to_owned() + out_dir.as_os_str().to_str().unwrap())
+            .arg("--include=bt/gd")
+            .arg("--rust")
+            .arg(input_files[i].as_os_str().to_str().unwrap())
+            .output()
+            .unwrap();
+
+        println!(
+            "Status: {}, stdout: {}, stderr: {}",
+            output.status,
+            String::from_utf8_lossy(output.stdout.as_slice()),
+            String::from_utf8_lossy(output.stderr.as_slice())
+        );
+
+        // File will be at ${OUT_DIR}/../../${input_files[i].strip('.pdl')}.rs
+        std::fs::rename(
+            outputted[i].as_os_str().to_str().unwrap(),
+            out_dir.join(outputted[i].file_name().unwrap()).as_os_str().to_str().unwrap(),
+        )
+        .unwrap();
+    }
+}
diff --git a/system/gd/rust/shim/src/stack.rs b/system/gd/rust/shim/src/stack.rs
index 7dab8b9..2dc77d2 100644
--- a/system/gd/rust/shim/src/stack.rs
+++ b/system/gd/rust/shim/src/stack.rs
@@ -21,6 +21,9 @@
 #[cxx::bridge(namespace = bluetooth::shim::rust)]
 mod ffi {
     extern "Rust" {
+        // TODO(abps) - https://github.com/dtolnay/cxx/issues/496
+        // Externing non-local types results in E0117 errors and that breaks
+        // building with CXX > 1.0.
         type Stack;
         type Hci;
         type Controller;