Implement EmulatedChip trait for Bluetooth, BleBeacon, Wifi, and Mocked.

This is a starter code for EmulatedChip trait, which is not being
invoked by other modules yet. Next step is to migrate
handle_packet_response, and progressively replace the original code.

Test: atest --host-unit-test-only libnetsim_daemon_tests
Bug: 307963660
Change-Id: I42c43fd8b767f685dbda22ab9fd618256a93bb8f
diff --git a/rust/daemon/src/echip/ble_beacon.rs b/rust/daemon/src/echip/ble_beacon.rs
new file mode 100644
index 0000000..436df9e
--- /dev/null
+++ b/rust/daemon/src/echip/ble_beacon.rs
@@ -0,0 +1,72 @@
+// Copyright 2023 Google LLC
+//
+// 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
+//
+//     https://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 crate::devices::chip::{ChipIdentifier, FacadeIdentifier};
+use crate::devices::device::DeviceIdentifier;
+use crate::echip::EmulatedChip;
+
+use netsim_proto::common::ChipKind as ProtoChipKind;
+use netsim_proto::model::Chip as ProtoChip;
+use netsim_proto::model::ChipCreate as ChipCreateProto;
+
+use std::rc::Rc;
+
+/// Parameters for creating BleBeacon chips
+pub struct CreateParams {
+    device_id: DeviceIdentifier,
+    device_name: String,
+    chip_id: ChipIdentifier,
+    chip_proto: ChipCreateProto,
+}
+
+/// BleBeacon struct will keep track of facade_id
+pub struct BleBeacon {
+    facade_id: FacadeIdentifier,
+}
+
+impl EmulatedChip for BleBeacon {
+    fn handle_request(&self, packet: &[u8]) {
+        todo!();
+    }
+
+    fn reset(&self) {
+        todo!();
+    }
+
+    fn get(&self) -> ProtoChip {
+        todo!();
+    }
+
+    fn patch(&self, chip: ProtoChip) {
+        todo!();
+    }
+
+    fn get_kind(&self) -> ProtoChipKind {
+        ProtoChipKind::BLUETOOTH_BEACON
+    }
+}
+
+impl Drop for BleBeacon {
+    /// At drop, Remove the emulated chip from the virtual device. No further calls will
+    /// be made on this emulated chip. This is called when the packet stream from
+    /// the virtual device closes.
+    fn drop(&mut self) {
+        todo!();
+    }
+}
+
+/// Create a new Emulated BleBeacon Chip
+pub fn new(params: CreateParams) -> Rc<dyn EmulatedChip> {
+    todo!();
+}
diff --git a/rust/daemon/src/echip/bluetooth.rs b/rust/daemon/src/echip/bluetooth.rs
new file mode 100644
index 0000000..509d566
--- /dev/null
+++ b/rust/daemon/src/echip/bluetooth.rs
@@ -0,0 +1,101 @@
+// Copyright 2023 Google LLC
+//
+// 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
+//
+//     https://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 crate::devices::chip::FacadeIdentifier;
+use crate::ffi::ffi_bluetooth;
+use crate::{devices::device::DeviceIdentifier, echip::EmulatedChip};
+
+use cxx::let_cxx_string;
+use netsim_proto::common::ChipKind as ProtoChipKind;
+use netsim_proto::config::Bluetooth as BluetoothConfig;
+use netsim_proto::configuration::Controller as RootcanalController;
+use netsim_proto::model::chip::Bluetooth as ProtoBluetooth;
+use netsim_proto::model::Chip as ProtoChip;
+use protobuf::{Message, MessageField};
+
+use std::rc::Rc;
+
+/// Parameters for creating Bluetooth chips
+pub struct CreateParams {
+    device_id: DeviceIdentifier,
+    address: String,
+    bt_properties: MessageField<RootcanalController>,
+}
+
+/// Bluetooth struct will keep track of facade_id
+pub struct Bluetooth {
+    facade_id: FacadeIdentifier,
+}
+
+impl EmulatedChip for Bluetooth {
+    fn handle_request(&self, packet: &[u8]) {
+        ffi_bluetooth::handle_bt_request(self.facade_id, packet[0], &packet[1..].to_vec())
+    }
+
+    fn reset(&self) {
+        ffi_bluetooth::bluetooth_reset(self.facade_id);
+    }
+
+    fn get(&self) -> ProtoChip {
+        let bluetooth_bytes = ffi_bluetooth::bluetooth_get_cxx(self.facade_id);
+        let bt_proto = ProtoBluetooth::parse_from_bytes(&bluetooth_bytes).unwrap();
+        let mut chip_proto = ProtoChip::new();
+        chip_proto.mut_bt().clone_from(&bt_proto);
+        chip_proto
+    }
+
+    fn patch(&self, chip: ProtoChip) {
+        let bluetooth_bytes = chip.bt().write_to_bytes().unwrap();
+        ffi_bluetooth::bluetooth_patch_cxx(self.facade_id, &bluetooth_bytes);
+    }
+
+    fn get_kind(&self) -> ProtoChipKind {
+        ProtoChipKind::BLUETOOTH
+    }
+}
+
+impl Drop for Bluetooth {
+    /// At drop, Remove the emulated chip from the virtual device. No further calls will
+    /// be made on this emulated chip. This is called when the packet stream from
+    /// the virtual device closes.
+    fn drop(&mut self) {
+        ffi_bluetooth::bluetooth_remove(self.facade_id);
+    }
+}
+
+/// Create a new Emulated Bluetooth Chip
+pub fn new(create_params: CreateParams) -> Rc<dyn EmulatedChip> {
+    let_cxx_string!(cxx_address = create_params.address);
+    let proto_bytes =
+        create_params.bt_properties.as_ref().unwrap_or_default().write_to_bytes().unwrap();
+    let facade_id =
+        ffi_bluetooth::bluetooth_add(create_params.device_id, &cxx_address, &proto_bytes);
+    let echip = Bluetooth { facade_id };
+    Rc::new(echip)
+}
+
+/// Starts the Bluetooth service.
+pub fn bluetooth_start(
+    config: &MessageField<BluetoothConfig>,
+    instance_num: u16,
+    disable_address_reuse: bool,
+) {
+    let proto_bytes = config.as_ref().unwrap_or_default().write_to_bytes().unwrap();
+    ffi_bluetooth::bluetooth_start(&proto_bytes, instance_num, disable_address_reuse);
+}
+
+/// Stops the Bluetooth service.
+pub fn bluetooth_stop() {
+    ffi_bluetooth::bluetooth_stop();
+}
diff --git a/rust/daemon/src/echip/emulated_chip.rs b/rust/daemon/src/echip/emulated_chip.rs
new file mode 100644
index 0000000..01c6023
--- /dev/null
+++ b/rust/daemon/src/echip/emulated_chip.rs
@@ -0,0 +1,84 @@
+// Copyright 2023 Google LLC
+//
+// 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
+//
+//     https://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 netsim_proto::common::ChipKind as ProtoChipKind;
+use netsim_proto::model::Chip as ProtoChip;
+
+use crate::echip::{ble_beacon, bluetooth, mocked, wifi};
+
+use std::rc::Rc;
+
+/// Parameter for each constructor of Emulated Chips
+pub enum CreateParam {
+    BleBeacon(ble_beacon::CreateParams),
+    Bluetooth(bluetooth::CreateParams),
+    Wifi(wifi::CreateParams),
+    Mock(mocked::CreateParams),
+}
+
+// TODO: Factory trait to include start, stop, and add
+/// EmulatedChip is a trait that provides interface between the generic Chip
+/// and Radio specific library (rootcanal, libslirp, pica).
+pub trait EmulatedChip {
+    /// This is the main entry for incoming host-to-controller packets
+    /// from virtual devices called by the transport module. The format of the
+    /// packet depends on the emulated chip kind:
+    /// * Bluetooth - packet is H4 HCI format
+    /// * Wi-Fi - packet is Radiotap format
+    /// * UWB - packet is UCI format
+    /// * NFC - packet is NCI format
+    fn handle_request(&self, packet: &[u8]);
+
+    /// Reset the internal state of the emulated chip for the virtual device.
+    /// The transmitted and received packet count will be set to 0 and the chip
+    /// shall be in the enabled state following a call to this function.
+    fn reset(&self);
+
+    /// Return the Chip model protobuf from the emulated chip. This is part of
+    /// the Frontend API.
+    fn get(&self) -> ProtoChip;
+
+    /// Patch the state of the emulated chip. For example enable/disable the
+    /// chip's host-to-controller packet processing. This is part of the
+    /// Frontend API
+    fn patch(&self, chip: ProtoChip);
+
+    /// Returns the kind of the emulated chip.
+    fn get_kind(&self) -> ProtoChipKind;
+}
+
+/// This is called when the transport module receives a new packet stream
+/// connection from a virtual device.
+pub fn new(create_param: CreateParam) -> Rc<dyn EmulatedChip> {
+    match create_param {
+        CreateParam::BleBeacon(params) => ble_beacon::new(params),
+        CreateParam::Bluetooth(params) => bluetooth::new(params),
+        CreateParam::Wifi(params) => wifi::new(params),
+        CreateParam::Mock(params) => mocked::new(params),
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+
+    #[test]
+    fn test_echip_new() {
+        let mock_param = CreateParam::Mock(mocked::CreateParams {});
+        let echip = new(mock_param);
+        assert_eq!(echip.get_kind(), ProtoChipKind::UNSPECIFIED);
+        assert_eq!(echip.get(), ProtoChip::new());
+    }
+}
diff --git a/rust/daemon/src/echip/mocked.rs b/rust/daemon/src/echip/mocked.rs
new file mode 100644
index 0000000..a74aef0
--- /dev/null
+++ b/rust/daemon/src/echip/mocked.rs
@@ -0,0 +1,47 @@
+// Copyright 2023 Google LLC
+//
+// 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
+//
+//     https://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 crate::echip::EmulatedChip;
+
+use netsim_proto::common::ChipKind as ProtoChipKind;
+use netsim_proto::model::Chip as ProtoChip;
+
+use std::rc::Rc;
+
+/// Parameters for creating Mocked chips
+pub struct CreateParams {}
+
+/// Mock struct is remained empty.
+pub struct Mock {}
+
+impl EmulatedChip for Mock {
+    fn handle_request(&self, packet: &[u8]) {}
+
+    fn reset(&self) {}
+
+    fn get(&self) -> ProtoChip {
+        ProtoChip::new()
+    }
+
+    fn patch(&self, chip: ProtoChip) {}
+
+    fn get_kind(&self) -> ProtoChipKind {
+        ProtoChipKind::UNSPECIFIED
+    }
+}
+
+/// Create a new MockedChip
+pub fn new(create_params: CreateParams) -> Rc<dyn EmulatedChip> {
+    Rc::new(Mock {})
+}
diff --git a/rust/daemon/src/echip/mod.rs b/rust/daemon/src/echip/mod.rs
new file mode 100644
index 0000000..aab7ff8
--- /dev/null
+++ b/rust/daemon/src/echip/mod.rs
@@ -0,0 +1,21 @@
+// Copyright 2023 Google LLC
+//
+// 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
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+mod ble_beacon;
+mod bluetooth;
+mod emulated_chip;
+mod mocked;
+mod wifi;
+
+use crate::echip::emulated_chip::EmulatedChip;
diff --git a/rust/daemon/src/echip/wifi.rs b/rust/daemon/src/echip/wifi.rs
new file mode 100644
index 0000000..00bba9c
--- /dev/null
+++ b/rust/daemon/src/echip/wifi.rs
@@ -0,0 +1,89 @@
+// Copyright 2023 Google LLC
+//
+// 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
+//
+//     https://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 crate::devices::chip::FacadeIdentifier;
+use crate::ffi::ffi_wifi;
+use crate::{devices::device::DeviceIdentifier, echip::EmulatedChip};
+
+use netsim_proto::common::ChipKind as ProtoChipKind;
+use netsim_proto::config::WiFi as WiFiConfig;
+use netsim_proto::model::chip::Radio;
+use netsim_proto::model::Chip as ProtoChip;
+use protobuf::{Message, MessageField};
+
+use std::rc::Rc;
+
+/// Parameters for creating Wifi chips
+pub struct CreateParams {
+    device_id: DeviceIdentifier,
+}
+
+/// Wifi struct will keep track of facade_id
+pub struct Wifi {
+    facade_id: FacadeIdentifier,
+}
+
+impl EmulatedChip for Wifi {
+    fn handle_request(&self, packet: &[u8]) {
+        ffi_wifi::handle_wifi_request(self.facade_id, &packet.to_vec());
+    }
+
+    fn reset(&self) {
+        ffi_wifi::wifi_reset(self.facade_id);
+    }
+
+    fn get(&self) -> ProtoChip {
+        let radio_bytes = ffi_wifi::wifi_get_cxx(self.facade_id);
+        let wifi_proto = Radio::parse_from_bytes(&radio_bytes).unwrap();
+        let mut chip_proto = ProtoChip::new();
+        chip_proto.mut_wifi().clone_from(&wifi_proto);
+        chip_proto
+    }
+
+    fn patch(&self, chip: ProtoChip) {
+        let radio_bytes = chip.wifi().write_to_bytes().unwrap();
+        ffi_wifi::wifi_patch_cxx(self.facade_id, &radio_bytes);
+    }
+
+    fn get_kind(&self) -> ProtoChipKind {
+        ProtoChipKind::WIFI
+    }
+}
+
+impl Drop for Wifi {
+    /// At drop, Remove the emulated chip from the virtual device. No further calls will
+    /// be made on this emulated chip. This is called when the packet stream from
+    /// the virtual device closes.
+    fn drop(&mut self) {
+        ffi_wifi::wifi_remove(self.facade_id);
+    }
+}
+
+/// Create a new Emulated Wifi Chip
+pub fn new(params: CreateParams) -> Rc<dyn EmulatedChip> {
+    let facade_id = ffi_wifi::wifi_add(params.device_id);
+    let echip = Wifi { facade_id };
+    Rc::new(echip)
+}
+
+/// Starts the WiFi service.
+pub fn wifi_start(config: &MessageField<WiFiConfig>) {
+    let proto_bytes = config.as_ref().unwrap_or_default().write_to_bytes().unwrap();
+    ffi_wifi::wifi_start(&proto_bytes);
+}
+
+/// Stops the WiFi service.
+pub fn wifi_stop() {
+    ffi_wifi::wifi_stop();
+}
diff --git a/rust/daemon/src/lib.rs b/rust/daemon/src/lib.rs
index e655a63..a41e9ee 100644
--- a/rust/daemon/src/lib.rs
+++ b/rust/daemon/src/lib.rs
@@ -34,6 +34,10 @@
 mod version;
 mod wifi;
 
+// TODO(b/307145892): EmulatedChip Trait is actively being implemented.
+#[allow(dead_code, unused_variables)]
+mod echip;
+
 // This feature is enabled only for CMake builds
 #[cfg(feature = "local_ssl")]
 mod openssl;