Getting rid of facade_id from capture and transport module

1. Propagate chip_id into *facade.cc
2. Removed all facade_key generation
3. grpc_server now has chip_id_to_transport table
4. facade_id --> rootcanal_id for Bluetooth
5. facade_id --> chip_id for WiFi
6. capture_handlers no longer needs chip_kind

Test: m netsimd
Bug: 314155554
Bug: 311692480
Change-Id: Id617e29c6137fafb4efb01373298c6ccd94d33bc
diff --git a/rust/daemon/src/captures/captures_handler.rs b/rust/daemon/src/captures/captures_handler.rs
index f480448..13fda91 100644
--- a/rust/daemon/src/captures/captures_handler.rs
+++ b/rust/daemon/src/captures/captures_handler.rs
@@ -43,12 +43,10 @@
 use crate::ffi::CxxServerResponseWriterWrapper;
 use crate::http_server::server_response::ResponseWritable;
 use crate::resource::clone_captures;
-use crate::util::int_to_chip_kind;
 use crate::wifi::radiotap;
 
 use anyhow::anyhow;
 
-use super::capture::CaptureInfo;
 use super::pcap_util::{append_record, wrap_bt_packet, PacketDirection};
 use super::PCAP_MIME_TYPE;
 
@@ -230,24 +228,23 @@
 
 /// A common code for handle_request and handle_response methods.
 fn handle_packet(
-    kind: u32,
-    facade_id: u32,
+    chip_id: ChipIdentifier,
     packet: &[u8],
     packet_type: u32,
     direction: PacketDirection,
 ) {
     let captures_arc = clone_captures();
     let captures = captures_arc.write().unwrap();
-    let facade_key = CaptureInfo::new_facade_key(int_to_chip_kind(kind), facade_id);
     if let Some(mut capture) = captures
-        .facade_key_to_capture
-        .get(&facade_key)
+        .chip_id_to_capture
+        .get(&chip_id)
         .map(|arc_capture| arc_capture.lock().expect("Failed to acquire lock on CaptureInfo"))
     {
+        let chip_kind = capture.chip_kind;
         if let Some(ref mut file) = capture.file {
             let timestamp =
                 SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards");
-            let packet_buf = match int_to_chip_kind(kind) {
+            let packet_buf = match chip_kind {
                 ChipKind::BLUETOOTH => wrap_bt_packet(direction, packet_type, packet),
                 ChipKind::WIFI => match radiotap::into_pcap(packet) {
                     Ok(buffer) => buffer,
@@ -275,13 +272,13 @@
 }
 
 /// Method for dispatcher to invoke (Host to Controller Packet Flow)
-pub fn handle_packet_request(kind: u32, facade_id: u32, packet: &[u8], packet_type: u32) {
-    handle_packet(kind, facade_id, packet, packet_type, PacketDirection::HostToController)
+pub fn handle_packet_request(chip_id: u32, packet: &[u8], packet_type: u32) {
+    handle_packet(chip_id, packet, packet_type, PacketDirection::HostToController)
 }
 
 /// Method for dispatcher to invoke (Controller to Host Packet Flow)
-pub fn handle_packet_response(kind: u32, facade_id: u32, packet: &[u8], packet_type: u32) {
-    handle_packet(kind, facade_id, packet, packet_type, PacketDirection::ControllerToHost)
+pub fn handle_packet_response(chip_id: u32, packet: &[u8], packet_type: u32) {
+    handle_packet(chip_id, packet, packet_type, PacketDirection::ControllerToHost)
 }
 
 /// Method for clearing pcap files in temp directory
diff --git a/rust/daemon/src/echip/bluetooth.rs b/rust/daemon/src/echip/bluetooth.rs
index 8b52c8a..bc5d605 100644
--- a/rust/daemon/src/echip/bluetooth.rs
+++ b/rust/daemon/src/echip/bluetooth.rs
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use crate::devices::chip::FacadeIdentifier;
+use crate::devices::chip::ChipIdentifier;
 use crate::ffi::ffi_bluetooth;
 use crate::{
     devices::device::DeviceIdentifier,
@@ -32,30 +32,32 @@
 
 static ECHIP_BT_MUTEX: Mutex<()> = Mutex::new(());
 
+pub type RootcanalIdentifier = u32;
+
 /// Parameters for creating Bluetooth chips
 pub struct CreateParams {
     pub address: String,
     pub bt_properties: Option<MessageField<RootcanalController>>,
 }
 
-/// Bluetooth struct will keep track of facade_id
+/// Bluetooth struct will keep track of rootcanal_id
 pub struct Bluetooth {
-    facade_id: FacadeIdentifier,
+    rootcanal_id: RootcanalIdentifier,
 }
 
 impl EmulatedChip for Bluetooth {
     fn handle_request(&self, packet: &[u8]) {
         // Lock to protect device_to_transport_ table in C++
         let _unused = ECHIP_BT_MUTEX.lock().expect("Failed to acquire lock on ECHIP_BT_MUTEX");
-        ffi_bluetooth::handle_bt_request(self.facade_id, packet[0], &packet[1..].to_vec())
+        ffi_bluetooth::handle_bt_request(self.rootcanal_id, packet[0], &packet[1..].to_vec())
     }
 
     fn reset(&self) {
-        ffi_bluetooth::bluetooth_reset(self.facade_id);
+        ffi_bluetooth::bluetooth_reset(self.rootcanal_id);
     }
 
     fn get(&self) -> ProtoChip {
-        let bluetooth_bytes = ffi_bluetooth::bluetooth_get_cxx(self.facade_id);
+        let bluetooth_bytes = ffi_bluetooth::bluetooth_get_cxx(self.rootcanal_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);
@@ -64,13 +66,13 @@
 
     fn patch(&self, chip: &ProtoChip) {
         let bluetooth_bytes = chip.bt().write_to_bytes().unwrap();
-        ffi_bluetooth::bluetooth_patch_cxx(self.facade_id, &bluetooth_bytes);
+        ffi_bluetooth::bluetooth_patch_cxx(self.rootcanal_id, &bluetooth_bytes);
     }
 
     fn remove(&self) {
         // Lock to protect id_to_chip_info_ table in C++
         let _unused = ECHIP_BT_MUTEX.lock().expect("Failed to acquire lock on ECHIP_BT_MUTEX");
-        ffi_bluetooth::bluetooth_remove(self.facade_id);
+        ffi_bluetooth::bluetooth_remove(self.rootcanal_id);
     }
 
     fn get_stats(&self, duration_secs: u64) -> Vec<ProtoRadioStats> {
@@ -98,13 +100,17 @@
         ProtoChipKind::BLUETOOTH
     }
 
-    fn get_facade_id(&self) -> FacadeIdentifier {
-        self.facade_id
+    fn get_facade_id(&self) -> RootcanalIdentifier {
+        self.rootcanal_id
     }
 }
 
 /// Create a new Emulated Bluetooth Chip
-pub fn new(create_params: &CreateParams, device_id: DeviceIdentifier) -> SharedEmulatedChip {
+pub fn new(
+    create_params: &CreateParams,
+    device_id: DeviceIdentifier,
+    chip_id: ChipIdentifier,
+) -> SharedEmulatedChip {
     // Lock to protect id_to_chip_info_ table in C++
     let _unused = ECHIP_BT_MUTEX.lock().expect("Failed to acquire lock on ECHIP_BT_MUTEX");
     let_cxx_string!(cxx_address = create_params.address.clone());
@@ -112,8 +118,8 @@
         Some(properties) => properties.write_to_bytes().unwrap(),
         None => Vec::new(),
     };
-    let facade_id = ffi_bluetooth::bluetooth_add(device_id, &cxx_address, &proto_bytes);
-    let echip = Bluetooth { facade_id };
+    let rootcanal_id = ffi_bluetooth::bluetooth_add(device_id, chip_id, &cxx_address, &proto_bytes);
+    let echip = Bluetooth { rootcanal_id };
     Arc::new(Box::new(echip))
 }
 
diff --git a/rust/daemon/src/echip/emulated_chip.rs b/rust/daemon/src/echip/emulated_chip.rs
index 5d2fe00..a2cd532 100644
--- a/rust/daemon/src/echip/emulated_chip.rs
+++ b/rust/daemon/src/echip/emulated_chip.rs
@@ -93,7 +93,7 @@
     /// Returns the kind of the emulated chip.
     fn get_kind(&self) -> ProtoChipKind;
 
-    // TODO: Remove this method and get rid of facade_id in devices crate.
+    // TODO(b/311480905): Remove this method and get rid of facade_id in devices crate.
     /// Returns Facade Identifier.
     fn get_facade_id(&self) -> FacadeIdentifier;
 }
@@ -125,9 +125,9 @@
     let shared_echip = match create_param {
         CreateParam::BleBeacon(params) => ble_beacon::new(params, device_id, chip_id),
         #[cfg(not(test))]
-        CreateParam::Bluetooth(params) => bluetooth::new(params, device_id),
+        CreateParam::Bluetooth(params) => bluetooth::new(params, device_id, chip_id),
         #[cfg(not(test))]
-        CreateParam::Wifi(params) => wifi::new(params, device_id),
+        CreateParam::Wifi(params) => wifi::new(params, device_id, chip_id),
         #[cfg(not(test))]
         CreateParam::Uwb => todo!(),
         CreateParam::Mock(params) => mocked::new(params, device_id),
diff --git a/rust/daemon/src/echip/packet.rs b/rust/daemon/src/echip/packet.rs
index ec6bc76..6a45a76 100644
--- a/rust/daemon/src/echip/packet.rs
+++ b/rust/daemon/src/echip/packet.rs
@@ -53,36 +53,27 @@
 // (kind,facade_id) to responder queue.
 
 lazy_static! {
-    static ref SENDERS: Arc<Mutex<HashMap<String, Sender<ResponsePacket>>>> =
+    static ref SENDERS: Arc<Mutex<HashMap<ChipIdentifier, Sender<ResponsePacket>>>> =
         Arc::new(Mutex::new(HashMap::new()));
 }
 
-fn get_key(kind: u32, facade_id: u32) -> String {
-    format!("{}/{}", kind, facade_id)
-}
-
 /// Register a chip controller instance to a transport manager.
-pub fn register_transport(kind: u32, facade_id: u32, mut responder: Box<dyn Response + Send>) {
-    let key = get_key(kind, facade_id);
+pub fn register_transport(chip_id: ChipIdentifier, mut responder: Box<dyn Response + Send>) {
     let (tx, rx) = channel::<ResponsePacket>();
-    match SENDERS.lock() {
-        Ok(mut map) => {
-            if map.contains_key(&key) {
-                error!("register_transport: key already present for chip_kind/facade_id: {key}");
-            }
-            map.insert(key.clone(), tx);
-        }
-        Err(_) => panic!("register_transport: poisoned lock"),
+    let mut map = SENDERS.lock().expect("register_transport: poisoned lock");
+    if map.contains_key(&chip_id) {
+        error!("register_transport: key already present for chip_id: {chip_id}");
     }
-    let _ = thread::Builder::new().name("transport_writer_{key}".to_string()).spawn(move || {
-        info!("register_transport: started thread chip_kind/facade_id: {key}");
+    map.insert(chip_id, tx);
+    let _ = thread::Builder::new().name(format!("transport_writer_{chip_id}")).spawn(move || {
+        info!("register_transport: started thread chip_id: {chip_id}");
         loop {
             match rx.recv() {
                 Ok(ResponsePacket { packet, packet_type }) => {
                     responder.response(packet, packet_type);
                 }
                 Err(_) => {
-                    info!("register_transport: finished thread chip_kind/facade_id: {key}");
+                    info!("register_transport: finished thread chip_id: {chip_id}");
                     break;
                 }
             }
@@ -91,45 +82,37 @@
 }
 
 /// Unregister a chip controller instance.
-pub fn unregister_transport(kind: u32, facade_id: u32) {
-    let key = get_key(kind, facade_id);
+pub fn unregister_transport(chip_id: ChipIdentifier) {
     // Shuts down the responder thread, because sender is dropped.
-    SENDERS.lock().expect("unregister_transport: poisoned lock").remove(&key);
+    SENDERS.lock().expect("unregister_transport: poisoned lock").remove(&chip_id);
 }
 
 // Handle response from facades.
 //
 // Queue the response packet to be handled by the responder thread.
 //
-pub fn handle_response(kind: u32, facade_id: u32, packet: &cxx::CxxVector<u8>, packet_type: u8) {
+pub fn handle_response(chip_id: ChipIdentifier, packet: &cxx::CxxVector<u8>, packet_type: u8) {
     // TODO(b/314840701):
     // 1. Per EChip Struct should contain private field of channel & facade_id
     // 2. Lookup from ECHIPS with given chip_id
     // 3. Call echips.handle_response
     let packet_vec = packet.as_slice().to_vec();
-    captures_handler::handle_packet_response(kind, facade_id, &packet_vec, packet_type.into());
+    captures_handler::handle_packet_response(chip_id, &packet_vec, packet_type.into());
 
-    let key = get_key(kind, facade_id);
     let mut binding = SENDERS.lock().expect("Failed to acquire lock on SENDERS");
-    if let Some(responder) = binding.get(&key) {
+    if let Some(responder) = binding.get(&chip_id) {
         if responder.send(ResponsePacket { packet: packet_vec, packet_type }).is_err() {
-            warn!("handle_response: send failed for chip_kind/facade_id: {key}");
-            binding.remove(&key);
+            warn!("handle_response: send failed for chip_id: {chip_id}");
+            binding.remove(&chip_id);
         }
     } else {
-        warn!("handle_response: unknown chip_kind: {kind} facade_id: {facade_id}");
+        warn!("handle_response: unknown chip_id: {chip_id}");
     };
 }
 
 /// Handle requests from transports.
-pub fn handle_request(
-    kind: u32,
-    facade_id: u32,
-    chip_id: ChipIdentifier,
-    packet: &mut Vec<u8>,
-    packet_type: u8,
-) {
-    captures_handler::handle_packet_request(kind, facade_id, packet, packet_type.into());
+pub fn handle_request(chip_id: ChipIdentifier, packet: &mut Vec<u8>, packet_type: u8) {
+    captures_handler::handle_packet_request(chip_id, packet, packet_type.into());
 
     // Prepend packet_type to packet if specified
     if PacketType::HCI_PACKET_UNSPECIFIED.value()
@@ -146,28 +129,15 @@
 }
 
 /// Handle requests from transports in C++.
-pub fn handle_request_cxx(
-    kind: u32,
-    facade_id: u32,
-    chip_id: u32,
-    packet: &cxx::CxxVector<u8>,
-    packet_type: u8,
-) {
+pub fn handle_request_cxx(chip_id: u32, packet: &cxx::CxxVector<u8>, packet_type: u8) {
     let mut packet_vec = packet.as_slice().to_vec();
-    handle_request(kind, facade_id, chip_id, &mut packet_vec, packet_type);
+    handle_request(chip_id, &mut packet_vec, packet_type);
 }
 
 #[cfg(test)]
 mod tests {
     use super::*;
 
-    #[test]
-    fn test_get_key() {
-        assert_eq!("0/0", get_key(0, 0));
-        assert_eq!("42/21", get_key(42, 21));
-        assert_eq!("666/1234", get_key(666, 1234));
-    }
-
     struct TestTransport {}
     impl Response for TestTransport {
         fn response(&mut self, _packet: Vec<u8>, _packet_type: u8) {}
@@ -176,20 +146,19 @@
     #[test]
     fn test_register_transport() {
         let val: Box<dyn Response + Send> = Box::new(TestTransport {});
-        register_transport(0, 0, val);
-        let key = get_key(0, 0);
+        register_transport(0, val);
         {
             let binding = SENDERS.lock().unwrap();
-            assert!(binding.contains_key(&key));
+            assert!(binding.contains_key(&0));
         }
 
-        SENDERS.lock().unwrap().remove(&key);
+        SENDERS.lock().unwrap().remove(&0);
     }
 
     #[test]
     fn test_unregister_transport() {
-        register_transport(0, 1, Box::new(TestTransport {}));
-        unregister_transport(0, 1);
-        assert!(SENDERS.lock().unwrap().get(&get_key(0, 1)).is_none());
+        register_transport(1, Box::new(TestTransport {}));
+        unregister_transport(1);
+        assert!(SENDERS.lock().unwrap().get(&1).is_none());
     }
 }
diff --git a/rust/daemon/src/echip/wifi.rs b/rust/daemon/src/echip/wifi.rs
index e276abd..a73c76a 100644
--- a/rust/daemon/src/echip/wifi.rs
+++ b/rust/daemon/src/echip/wifi.rs
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use crate::devices::chip::FacadeIdentifier;
+use crate::devices::chip::{ChipIdentifier, FacadeIdentifier};
 use crate::ffi::ffi_wifi;
 use crate::wifi::medium;
 use crate::{
@@ -33,7 +33,7 @@
 
 /// Wifi struct will keep track of facade_id
 pub struct Wifi {
-    facade_id: FacadeIdentifier,
+    chip_id: ChipIdentifier,
 }
 
 impl EmulatedChip for Wifi {
@@ -41,15 +41,15 @@
         if crate::config::get_dev() {
             let _ = medium::parse_hwsim_cmd(packet);
         }
-        ffi_wifi::handle_wifi_request(self.facade_id, &packet.to_vec());
+        ffi_wifi::handle_wifi_request(self.chip_id, &packet.to_vec());
     }
 
     fn reset(&self) {
-        ffi_wifi::wifi_reset(self.facade_id);
+        ffi_wifi::wifi_reset(self.chip_id);
     }
 
     fn get(&self) -> ProtoChip {
-        let radio_bytes = ffi_wifi::wifi_get_cxx(self.facade_id);
+        let radio_bytes = ffi_wifi::wifi_get_cxx(self.chip_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);
@@ -58,11 +58,11 @@
 
     fn patch(&self, chip: &ProtoChip) {
         let radio_bytes = chip.wifi().write_to_bytes().unwrap();
-        ffi_wifi::wifi_patch_cxx(self.facade_id, &radio_bytes);
+        ffi_wifi::wifi_patch_cxx(self.chip_id, &radio_bytes);
     }
 
     fn remove(&self) {
-        ffi_wifi::wifi_remove(self.facade_id);
+        ffi_wifi::wifi_remove(self.chip_id);
     }
 
     fn get_stats(&self, duration_secs: u64) -> Vec<ProtoRadioStats> {
@@ -82,14 +82,18 @@
     }
 
     fn get_facade_id(&self) -> FacadeIdentifier {
-        self.facade_id
+        self.chip_id
     }
 }
 
 /// Create a new Emulated Wifi Chip
-pub fn new(_params: &CreateParams, device_id: DeviceIdentifier) -> SharedEmulatedChip {
-    let facade_id = ffi_wifi::wifi_add(device_id);
-    let echip = Wifi { facade_id };
+pub fn new(
+    _params: &CreateParams,
+    _device_id: DeviceIdentifier,
+    chip_id: ChipIdentifier,
+) -> SharedEmulatedChip {
+    ffi_wifi::wifi_add(chip_id);
+    let echip = Wifi { chip_id };
     Arc::new(Box::new(echip))
 }
 
diff --git a/rust/daemon/src/ffi.rs b/rust/daemon/src/ffi.rs
index 0e08b93..b33c145 100644
--- a/rust/daemon/src/ffi.rs
+++ b/rust/daemon/src/ffi.rs
@@ -38,16 +38,10 @@
 pub mod ffi_echip {
     extern "Rust" {
         #[cxx_name = HandleRequestCxx]
-        fn handle_request_cxx(
-            kind: u32,
-            facade_id: u32,
-            chip_id: u32,
-            packet: &CxxVector<u8>,
-            packet_type: u8,
-        );
+        fn handle_request_cxx(chip_id: u32, packet: &CxxVector<u8>, packet_type: u8);
 
         #[cxx_name = HandleResponse]
-        fn handle_response(kind: u32, facade_id: u32, packet: &CxxVector<u8>, packet_type: u8);
+        fn handle_response(chip_id: u32, packet: &CxxVector<u8>, packet_type: u8);
     }
 }
 
@@ -56,10 +50,10 @@
 pub mod ffi_transport {
     extern "Rust" {
         #[cxx_name = RegisterGrpcTransport]
-        fn register_grpc_transport(kind: u32, facade_id: u32);
+        fn register_grpc_transport(chip_id: u32);
 
         #[cxx_name = UnregisterGrpcTransport]
-        fn unregister_grpc_transport(kind: u32, facade_id: u32);
+        fn unregister_grpc_transport(chip_id: u32);
     }
 
     unsafe extern "C++" {
@@ -68,7 +62,7 @@
 
         #[rust_name = handle_grpc_response]
         #[namespace = "netsim::backend"]
-        fn HandleResponseCxx(kind: u32, facade_id: u32, packet: &Vec<u8>, packet_type: u8);
+        fn HandleResponseCxx(chip_id: u32, packet: &Vec<u8>, packet_type: u8);
 
         include!("core/server.h");
 
@@ -160,7 +154,7 @@
 
         #[rust_name = handle_bt_request]
         #[namespace = "netsim::hci"]
-        fn HandleBtRequestCxx(facade_id: u32, packet_type: u8, packet: &Vec<u8>);
+        fn HandleBtRequestCxx(rootcanal_id: u32, packet_type: u8, packet: &Vec<u8>);
 
         // Rust Bluetooth device.
         include!("hci/rust_device.h");
@@ -175,23 +169,28 @@
 
         #[rust_name = bluetooth_patch_cxx]
         #[namespace = "netsim::hci::facade"]
-        pub fn PatchCxx(facade_id: u32, proto_bytes: &[u8]);
+        pub fn PatchCxx(rootcanal_id: u32, proto_bytes: &[u8]);
 
         #[rust_name = bluetooth_get_cxx]
         #[namespace = "netsim::hci::facade"]
-        pub fn GetCxx(facade_id: u32) -> Vec<u8>;
+        pub fn GetCxx(rootcanal_id: u32) -> Vec<u8>;
 
         #[rust_name = bluetooth_reset]
         #[namespace = "netsim::hci::facade"]
-        pub fn Reset(facade_id: u32);
+        pub fn Reset(rootcanal_id: u32);
 
         #[rust_name = bluetooth_remove]
         #[namespace = "netsim::hci::facade"]
-        pub fn Remove(facade_id: u32);
+        pub fn Remove(rootcanal_id: u32);
 
         #[rust_name = bluetooth_add]
         #[namespace = "netsim::hci::facade"]
-        pub fn Add(_chip_id: u32, address: &CxxString, controller_proto_bytes: &[u8]) -> u32;
+        pub fn Add(
+            device_id: u32,
+            chip_id: u32,
+            address: &CxxString,
+            controller_proto_bytes: &[u8],
+        ) -> u32;
 
         /*
         From https://cxx.rs/binding/box.html#restrictions,
@@ -216,11 +215,11 @@
         /// The provided address must be 6 bytes in length
         #[rust_name = bluetooth_set_rust_device_address]
         #[namespace = "netsim::hci::facade"]
-        pub fn SetRustDeviceAddress(facade_id: u32, address: [u8; 6]);
+        pub fn SetRustDeviceAddress(rootcanal_id: u32, address: [u8; 6]);
 
         #[rust_name = bluetooth_remove_rust_device]
         #[namespace = "netsim::hci::facade"]
-        pub fn RemoveRustDevice(facade_id: u32);
+        pub fn RemoveRustDevice(rootcanal_id: u32);
 
         #[rust_name = bluetooth_start]
         #[namespace = "netsim::hci::facade"]
@@ -241,24 +240,24 @@
 
         #[rust_name = handle_wifi_request]
         #[namespace = "netsim::wifi"]
-        fn HandleWifiRequestCxx(facade_id: u32, packet: &Vec<u8>);
+        fn HandleWifiRequestCxx(chip_id: u32, packet: &Vec<u8>);
 
         include!("wifi/wifi_facade.h");
 
         #[rust_name = wifi_patch_cxx]
-        pub fn PatchCxx(facade_id: u32, proto_bytes: &[u8]);
+        pub fn PatchCxx(chip_id: u32, proto_bytes: &[u8]);
 
         #[rust_name = wifi_get_cxx]
-        pub fn GetCxx(facade_id: u32) -> Vec<u8>;
+        pub fn GetCxx(chip_id: u32) -> Vec<u8>;
 
         #[rust_name = wifi_reset]
-        pub fn Reset(facade_id: u32);
+        pub fn Reset(chip_id: u32);
 
         #[rust_name = wifi_remove]
-        pub fn Remove(facade_id: u32);
+        pub fn Remove(chip_id: u32);
 
         #[rust_name = wifi_add]
-        pub fn Add(_chip_id: u32) -> u32;
+        pub fn Add(chip_id: u32);
 
         #[rust_name = wifi_start]
         pub fn Start(proto_bytes: &[u8]);
diff --git a/rust/daemon/src/lib.rs b/rust/daemon/src/lib.rs
index 58bbbcf..a55106a 100644
--- a/rust/daemon/src/lib.rs
+++ b/rust/daemon/src/lib.rs
@@ -29,7 +29,6 @@
 mod service;
 mod session;
 mod transport;
-mod util;
 mod version;
 mod wifi;
 
diff --git a/rust/daemon/src/transport/fd.rs b/rust/daemon/src/transport/fd.rs
index 7cdbb1b..9175e8e 100644
--- a/rust/daemon/src/transport/fd.rs
+++ b/rust/daemon/src/transport/fd.rs
@@ -122,12 +122,12 @@
                             break;
                         }
                         Ok(uci::Packet { mut payload }) => {
-                            echip::handle_request(kind as u32, facade_id, chip_id, &mut payload, 0);
+                            echip::handle_request(chip_id, &mut payload, 0);
                         }
                     },
                     ChipKindEnum::BLUETOOTH => match h4::read_h4_packet(&mut rx) {
                         Ok(h4::Packet { h4_type, mut payload }) => {
-                            echip::handle_request(kind as u32, facade_id, chip_id, &mut payload, h4_type);
+                            echip::handle_request(chip_id, &mut payload, h4_type);
                         }
                         Err(PacketError::IoError(e))
                             if e.kind() == ErrorKind::UnexpectedEof =>
@@ -150,7 +150,7 @@
             // unregister before remove_chip because facade may re-use facade_id
             // on an intertwining create_chip and the unregister here might remove
             // the recently added chip creating a disconnected transport.
-            unregister_transport(kind as u32, facade_id);
+            unregister_transport(chip_id);
 
             if let Err(err) = remove_chip(device_id, chip_id) {
                 warn!("{err}");
@@ -253,11 +253,7 @@
                     // and open.
                     let file_in = unsafe { File::from_raw_fd(chip.fd_in as i32) };
 
-                    register_transport(
-                        chip.kind as u32,
-                        result.facade_id,
-                        Box::new(FdTransport { file: file_in }),
-                    );
+                    register_transport(result.chip_id, Box::new(FdTransport { file: file_in }));
                     // TODO: switch to runtime.spawn once FIFOs are available in Tokio
                     // SAFETY: Our caller promises that the file descriptors in the JSON are valid
                     // and open.
diff --git a/rust/daemon/src/transport/grpc.rs b/rust/daemon/src/transport/grpc.rs
index 4835d59..0ada43e 100644
--- a/rust/daemon/src/transport/grpc.rs
+++ b/rust/daemon/src/transport/grpc.rs
@@ -21,22 +21,21 @@
 /// provides a higher-level API that is easier to use from Rust.
 
 struct GrpcTransport {
-    kind: u32,
-    facade_id: u32,
+    chip_id: u32,
 }
 
 impl Response for GrpcTransport {
     fn response(&mut self, packet: Vec<u8>, packet_type: u8) {
-        handle_grpc_response(self.kind, self.facade_id, &packet, packet_type)
+        handle_grpc_response(self.chip_id, &packet, packet_type)
     }
 }
 
 // for grpc server in C++
-pub fn register_grpc_transport(kind: u32, facade_id: u32) {
-    register_transport(kind, facade_id, Box::new(GrpcTransport { kind, facade_id }));
+pub fn register_grpc_transport(chip_id: u32) {
+    register_transport(chip_id, Box::new(GrpcTransport { chip_id }));
 }
 
 // for grpc server in C++
-pub fn unregister_grpc_transport(kind: u32, facade_id: u32) {
-    unregister_transport(kind, facade_id);
+pub fn unregister_grpc_transport(chip_id: u32) {
+    unregister_transport(chip_id);
 }
diff --git a/rust/daemon/src/transport/socket.rs b/rust/daemon/src/transport/socket.rs
index 7d7b689..8e30a75 100644
--- a/rust/daemon/src/transport/socket.rs
+++ b/rust/daemon/src/transport/socket.rs
@@ -109,18 +109,14 @@
         }
     };
     let tcp_rx = stream.try_clone().unwrap();
-    register_transport(
-        ChipKind::BLUETOOTH as u32,
-        result.facade_id,
-        Box::new(SocketTransport { stream }),
-    );
+    register_transport(result.chip_id, Box::new(SocketTransport { stream }));
 
-    let _ = reader(tcp_rx, ChipKind::BLUETOOTH, result.facade_id, result.chip_id);
+    let _ = reader(tcp_rx, ChipKind::BLUETOOTH, result.chip_id);
 
     // unregister before remove_chip because facade may re-use facade_id
     // on an intertwining create_chip and the unregister here might remove
     // the recently added chip creating a disconnected transport.
-    unregister_transport(ChipKind::BLUETOOTH as u32, result.facade_id);
+    unregister_transport(result.chip_id);
 
     if let Err(err) = remove_chip(result.device_id, result.chip_id) {
         warn!("{err}");
@@ -130,24 +126,12 @@
 
 /// read from the socket and pass to the packet hub.
 ///
-fn reader(
-    mut tcp_rx: TcpStream,
-    kind: ChipKind,
-    facade_id: u32,
-    chip_id: ChipIdentifier,
-) -> std::io::Result<()> {
+fn reader(mut tcp_rx: TcpStream, kind: ChipKind, chip_id: ChipIdentifier) -> std::io::Result<()> {
     loop {
         if let ChipKind::BLUETOOTH = kind {
             match h4::read_h4_packet(&mut tcp_rx) {
                 Ok(mut packet) => {
-                    let kind: u32 = kind as u32;
-                    echip::handle_request(
-                        kind,
-                        facade_id,
-                        chip_id,
-                        &mut packet.payload,
-                        packet.h4_type,
-                    );
+                    echip::handle_request(chip_id, &mut packet.payload, packet.h4_type);
                 }
                 Err(PacketError::IoError(e)) if e.kind() == ErrorKind::UnexpectedEof => {
                     info!("End socket reader connection with {}.", &tcp_rx.peer_addr().unwrap());
diff --git a/rust/daemon/src/transport/websocket.rs b/rust/daemon/src/transport/websocket.rs
index f445e6f..6ef1df8 100644
--- a/rust/daemon/src/transport/websocket.rs
+++ b/rust/daemon/src/transport/websocket.rs
@@ -131,8 +131,7 @@
 
     // Sending cloned websocket into packet dispatcher
     register_transport(
-        ChipKind::BLUETOOTH as u32,
-        result.facade_id,
+        result.chip_id,
         Box::new(WebSocketTransport { websocket_writer: websocket_writer.clone() }),
     );
 
@@ -150,14 +149,7 @@
             let mut cursor = Cursor::new(packet_msg.into_data());
             match h4::read_h4_packet(&mut cursor) {
                 Ok(mut packet) => {
-                    let kind = ChipKind::BLUETOOTH as u32;
-                    echip::handle_request(
-                        kind,
-                        result.facade_id,
-                        result.chip_id,
-                        &mut packet.payload,
-                        packet.h4_type,
-                    );
+                    echip::handle_request(result.chip_id, &mut packet.payload, packet.h4_type);
                 }
                 Err(error) => {
                     error!(
@@ -194,7 +186,7 @@
     // unregister before remove_chip because facade may re-use facade_id
     // on an intertwining create_chip and the unregister here might remove
     // the recently added chip creating a disconnected transport.
-    unregister_transport(ChipKind::BLUETOOTH as u32, result.facade_id);
+    unregister_transport(result.chip_id);
 
     if let Err(err) = remove_chip(result.device_id, result.chip_id) {
         warn!("{err}");
diff --git a/rust/daemon/src/util.rs b/rust/daemon/src/util.rs
deleted file mode 100644
index a85da70..0000000
--- a/rust/daemon/src/util.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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;
-
-/// Helper function for translating u32 representation of ChipKind
-pub(crate) fn int_to_chip_kind(kind: u32) -> ChipKind {
-    match kind {
-        1 => ChipKind::BLUETOOTH,
-        2 => ChipKind::WIFI,
-        3 => ChipKind::UWB,
-        _ => ChipKind::UNSPECIFIED,
-    }
-}
diff --git a/src/backend/backend_packet_hub.h b/src/backend/backend_packet_hub.h
index 9934cfc..5637484 100644
--- a/src/backend/backend_packet_hub.h
+++ b/src/backend/backend_packet_hub.h
@@ -31,12 +31,10 @@
 
 /* Handle packet responses for the backend. */
 
-void HandleResponse(ChipKind kind, uint32_t facade_id,
-                    const std::vector<uint8_t> &packet,
+void HandleResponse(uint32_t chip_id, const std::vector<uint8_t> &packet,
                     /* optional */ packet::HCIPacket_PacketType packet_type);
 
-void HandleResponseCxx(uint32_t kind, uint32_t facade_id,
-                       const rust::Vec<rust::u8> &packet,
+void HandleResponseCxx(uint32_t chip_id, const rust::Vec<rust::u8> &packet,
                        /* optional */ uint8_t packet_type);
 
 }  // namespace backend
diff --git a/src/backend/grpc_server.cc b/src/backend/grpc_server.cc
index 57136da..d995156 100644
--- a/src/backend/grpc_server.cc
+++ b/src/backend/grpc_server.cc
@@ -48,11 +48,8 @@
 using netsim::startup::Chip;
 
 // Mapping from <chip kind, facade id> to streams.
-std::unordered_map<std::string, Stream *> facade_to_stream;
+std::unordered_map<uint32_t, Stream *> chip_id_to_stream;
 
-std::string ChipFacade(ChipKind chip_kind, uint32_t facade_id) {
-  return std::to_string(chip_kind) + "/" + std::to_string(facade_id);
-}
 // Libslirp is not thread safe. Use a lock to prevent concurrent access to
 // libslirp.
 std::mutex gSlirpMutex;
@@ -117,28 +114,30 @@
     }
     uint32_t device_id = result->GetDeviceId();
     uint32_t chip_id = result->GetChipId();
-    uint32_t facade_id = result->GetFacadeId();
+    uint32_t rootcanal_id = result->GetFacadeId();
 
     BtsLogInfo(
-        "grpc_server: adding chip - chip_id: %d, facade_id: %d, device_name: "
+        "grpc_server: adding chip - chip_id: %d, rootcanal_id: %d, "
+        "device_name: "
         "%s",
-        chip_id, facade_id, device_name.c_str());
+        chip_id, rootcanal_id, device_name.c_str());
     // connect packet responses from chip facade to the peer
-    facade_to_stream[ChipFacade(chip_kind, facade_id)] = stream;
-    netsim::transport::RegisterGrpcTransport(chip_kind, facade_id);
-    this->ProcessRequests(stream, chip_id, chip_kind, facade_id);
+    chip_id_to_stream[chip_id] = stream;
+    netsim::transport::RegisterGrpcTransport(chip_id);
+    this->ProcessRequests(stream, chip_id, chip_kind);
 
     // no longer able to send responses to peer
-    netsim::transport::UnregisterGrpcTransport(chip_kind, facade_id);
-    facade_to_stream.erase(ChipFacade(chip_kind, facade_id));
+    netsim::transport::UnregisterGrpcTransport(chip_id);
+    chip_id_to_stream.erase(chip_id);
 
     // Remove the chip from the device
     netsim::device::RemoveChipCxx(device_id, chip_id);
 
     BtsLogInfo(
-        "grpc_server: removing chip - chip_id: %d, facade_id: %d, device_name: "
+        "grpc_server: removing chip - chip_id: %d, rootcanal_id: %d, "
+        "device_name: "
         "%s",
-        chip_id, facade_id, device_name.c_str());
+        chip_id, rootcanal_id, device_name.c_str());
 
     return ::grpc::Status::OK;
   }
@@ -156,35 +155,34 @@
   // Process requests in a loop forwarding packets to the packet_hub and
   // returning when the channel is closed.
   void ProcessRequests(Stream *stream, uint32_t chip_id,
-                       common::ChipKind chip_kind, uint32_t facade_id) {
+                       common::ChipKind chip_kind) {
     packet::PacketRequest request;
     while (true) {
       if (!stream->Read(&request)) {
-        BtsLogWarn("grpc_server: reading stopped - facade_id: %d", facade_id);
+        BtsLogWarn("grpc_server: reading stopped - chip_id: %d", chip_id);
         break;
       }
       // All kinds possible (bt, uwb, wifi), but each rpc only streames one.
       if (chip_kind == common::ChipKind::BLUETOOTH) {
         if (!request.has_hci_packet()) {
-          BtsLogWarn("grpc_server: unknown packet type from facade_id: %d",
-                     facade_id);
+          BtsLogWarn("grpc_server: unknown packet type from chip_id: %d",
+                     chip_id);
           continue;
         }
         auto packet_type = request.hci_packet().packet_type();
         auto packet =
             ToSharedVec(request.mutable_hci_packet()->mutable_packet());
-        echip::HandleRequestCxx(chip_kind, facade_id, chip_id, *packet,
-                                packet_type);
+        echip::HandleRequestCxx(chip_id, *packet, packet_type);
       } else if (chip_kind == common::ChipKind::WIFI) {
         if (!request.has_packet()) {
-          BtsLogWarn("grpc_server: unknown packet type from facade_id: %d",
-                     facade_id);
+          BtsLogWarn("grpc_server: unknown packet type from chip_id: %d",
+                     chip_id);
           continue;
         }
         auto packet = ToSharedVec(request.mutable_packet());
         {
           std::lock_guard<std::mutex> guard(gSlirpMutex);
-          echip::HandleRequestCxx(chip_kind, facade_id, chip_id, *packet,
+          echip::HandleRequestCxx(chip_id, *packet,
                                   packet::HCIPacket::HCI_PACKET_UNSPECIFIED);
         }
 #ifdef NETSIM_ANDROID_EMULATOR
@@ -207,40 +205,37 @@
 }  // namespace
 
 // handle_response is called by packet_hub to forward a response to the gRPC
-// stream associated with chip_kind and facade_id.
+// stream associated with chip_id.
 //
 // When writing, the packet is copied because is borrowed from a shared_ptr and
 // grpc++ doesn't know about smart pointers.
-void HandleResponse(ChipKind kind, uint32_t facade_id,
-                    const std::vector<uint8_t> &packet,
+void HandleResponse(uint32_t chip_id, const std::vector<uint8_t> &packet,
                     packet::HCIPacket_PacketType packet_type) {
-  auto stream = facade_to_stream[ChipFacade(kind, facade_id)];
+  auto stream = chip_id_to_stream[chip_id];
   if (stream) {
     // TODO: lock or caller here because gRPC does not allow overlapping writes.
     packet::PacketResponse response;
     // Copies the borrowed packet for output
     auto str_packet = std::string(packet.begin(), packet.end());
-    if (kind == ChipKind::BLUETOOTH) {
+    if (packet_type != packet::HCIPacket_PacketType_HCI_PACKET_UNSPECIFIED) {
       response.mutable_hci_packet()->set_packet_type(packet_type);
       response.mutable_hci_packet()->set_packet(str_packet);
     } else {
       response.set_packet(str_packet);
     }
     if (!stream->Write(response)) {
-      BtsLogWarn("grpc_server: write failed for facade_id: %d", facade_id);
+      BtsLogWarn("grpc_server: write failed for chip_id: %d", chip_id);
     }
   } else {
-    BtsLogWarn("grpc_server: no stream for facade_id: %d", facade_id);
+    BtsLogWarn("grpc_server: no stream for chip_id: %d", chip_id);
   }
 }
 
 // for cxx
-void HandleResponseCxx(uint32_t kind, uint32_t facade_id,
-                       const rust::Vec<rust::u8> &packet,
+void HandleResponseCxx(uint32_t chip_id, const rust::Vec<rust::u8> &packet,
                        /* optional */ uint8_t packet_type) {
   std::vector<uint8_t> vec(packet.begin(), packet.end());
-  HandleResponse(ChipKind(kind), facade_id, vec,
-                 packet::HCIPacket_PacketType(packet_type));
+  HandleResponse(chip_id, vec, packet::HCIPacket_PacketType(packet_type));
 }
 
 }  // namespace backend
diff --git a/src/hci/bluetooth_facade.cc b/src/hci/bluetooth_facade.cc
index 495cc78..b97eb42 100644
--- a/src/hci/bluetooth_facade.cc
+++ b/src/hci/bluetooth_facade.cc
@@ -331,7 +331,7 @@
 
 void Patch(uint32_t id, const model::Chip::Bluetooth &request) {
   if (id_to_chip_info_.find(id) == id_to_chip_info_.end()) {
-    BtsLogWarn("Patch an unknown facade_id: %d", id);
+    BtsLogWarn("Patch an unknown rootcanal_id: %d", id);
     return;
   }
   auto model = id_to_chip_info_[id]->model;
@@ -352,7 +352,7 @@
 }
 
 void Remove(uint32_t id) {
-  BtsLogInfo("Removing HCI chip facade_id: %d.", id);
+  BtsLogInfo("Removing HCI chip rootcanal_id: %d.", id);
   id_to_chip_info_.erase(id);
   // Call the transport close callback. This invokes HciDevice::Close and
   // TestModel close callback.
@@ -364,9 +364,10 @@
 
 // Rename AddChip(model::Chip, device, transport)
 
-uint32_t Add(uint32_t simulation_device, const std::string &address_string,
+uint32_t Add(uint32_t simulation_device, uint32_t chip_id,
+             const std::string &address_string,
              const rust::Slice<::std::uint8_t const> controller_proto_bytes) {
-  auto transport = std::make_shared<HciPacketTransport>(gAsyncManager);
+  auto transport = std::make_shared<HciPacketTransport>(chip_id, gAsyncManager);
 
   std::shared_ptr<rootcanal::configuration::Controller> controller_proto =
       controller_proto_;
@@ -397,8 +398,8 @@
 
   // Use the `AsyncManager` to ensure that the `AddHciConnection` method is
   // invoked atomically, preventing data races.
-  std::promise<uint32_t> facade_id_promise;
-  auto facade_id_future = facade_id_promise.get_future();
+  std::promise<uint32_t> rootcanal_id_promise;
+  auto rootcanal_id_future = rootcanal_id_promise.get_future();
 
   std::optional<Address> address_option;
   if (address_string != "") {
@@ -406,14 +407,14 @@
   }
   gAsyncManager->ExecAsync(
       gSocketUserId, std::chrono::milliseconds(0),
-      [hci_device, &facade_id_promise, address_option]() {
-        facade_id_promise.set_value(
+      [hci_device, &rootcanal_id_promise, address_option]() {
+        rootcanal_id_promise.set_value(
             gTestModel->AddHciConnection(hci_device, address_option));
       });
-  auto facade_id = facade_id_future.get();
+  auto rootcanal_id = rootcanal_id_future.get();
 
-  HciPacketTransport::Add(facade_id, transport);
-  BtsLogInfo("Creating HCI facade_id: %d for device_id: %d", facade_id,
+  HciPacketTransport::Add(rootcanal_id, transport);
+  BtsLogInfo("Creating HCI rootcanal_id: %d for device_id: %d", rootcanal_id,
              simulation_device);
 
   auto model = std::make_shared<model::Chip::Bluetooth>();
@@ -421,14 +422,14 @@
   model->mutable_low_energy()->set_state(model::State::ON);
 
   id_to_chip_info_.emplace(
-      facade_id,
+      rootcanal_id,
       std::make_shared<ChipInfo>(simulation_device, model, controller_proto,
                                  std::move(controller_properties)));
-  return facade_id;
+  return rootcanal_id;
 }
 
-void RemoveRustDevice(uint32_t facade_id) {
-  gTestModel->RemoveDevice(facade_id);
+void RemoveRustDevice(uint32_t rootcanal_id) {
+  gTestModel->RemoveDevice(rootcanal_id);
 }
 
 rust::Box<AddRustDeviceResult> AddRustDevice(
@@ -441,24 +442,24 @@
   // TODO: Use the `AsyncManager` to ensure that the `AddDevice` and
   // `AddDeviceToPhy` methods are invoked atomically, preventing data races.
   // For unknown reason, use `AsyncManager` hangs.
-  auto facade_id = gTestModel->AddDevice(rust_device);
-  gTestModel->AddDeviceToPhy(facade_id, phy_low_energy_index_);
+  auto rootcanal_id = gTestModel->AddDevice(rust_device);
+  gTestModel->AddDeviceToPhy(rootcanal_id, phy_low_energy_index_);
 
   auto model = std::make_shared<model::Chip::Bluetooth>();
   // Only enable ble for beacon.
   model->mutable_low_energy()->set_state(model::State::ON);
   id_to_chip_info_.emplace(
-      facade_id, std::make_shared<ChipInfo>(simulation_device, model));
+      rootcanal_id, std::make_shared<ChipInfo>(simulation_device, model));
   return CreateAddRustDeviceResult(
-      facade_id, std::make_unique<RustBluetoothChip>(rust_device));
+      rootcanal_id, std::make_unique<RustBluetoothChip>(rust_device));
 }
 
 void SetRustDeviceAddress(
-    uint32_t facade_id,
+    uint32_t rootcanal_id,
     std::array<uint8_t, rootcanal::Address::kLength> address) {
   uint8_t addr[rootcanal::Address::kLength];
   std::memcpy(addr, address.data(), rootcanal::Address::kLength);
-  gTestModel->SetDeviceAddress(facade_id, rootcanal::Address(addr));
+  gTestModel->SetDeviceAddress(rootcanal_id, rootcanal::Address(addr));
 }
 
 void IncrTx(uint32_t id, rootcanal::Phy::Type phy_type) {
diff --git a/src/hci/bluetooth_facade.h b/src/hci/bluetooth_facade.h
index 8a05755..b8998a2 100644
--- a/src/hci/bluetooth_facade.h
+++ b/src/hci/bluetooth_facade.h
@@ -39,7 +39,8 @@
 void Remove(uint32_t);
 void Patch(uint32_t, const model::Chip::Bluetooth &);
 model::Chip::Bluetooth Get(uint32_t);
-uint32_t Add(uint32_t simulation_device, const std::string &address_string,
+uint32_t Add(uint32_t simulation_device, uint32_t chip_id,
+             const std::string &address_string,
              const rust::Slice<::std::uint8_t const> controller_proto_bytes);
 
 rust::Box<AddRustDeviceResult> AddRustDevice(
@@ -47,9 +48,9 @@
     rust::Box<DynRustBluetoothChipCallbacks> callbacks, const std::string &type,
     const std::string &address);
 void SetRustDeviceAddress(
-    uint32_t facade_id,
+    uint32_t rootcanal_id,
     std::array<uint8_t, rootcanal::Address::kLength> address);
-void RemoveRustDevice(uint32_t facade_id);
+void RemoveRustDevice(uint32_t rootcanal_id);
 
 void Start(const rust::Slice<::std::uint8_t const> proto_bytes,
            uint16_t instance_num, bool disable_address_reuse);
diff --git a/src/hci/hci_packet_hub.h b/src/hci/hci_packet_hub.h
index f696990..3e175d2 100644
--- a/src/hci/hci_packet_hub.h
+++ b/src/hci/hci_packet_hub.h
@@ -31,11 +31,11 @@
 /* Handle packet requests for the Bluetooth Facade which may come over
    different transports including gRPC. */
 
-void handle_bt_request(uint32_t facade_id,
+void handle_bt_request(uint32_t rootcanal_id,
                        packet::HCIPacket_PacketType packet_type,
                        const std::shared_ptr<std::vector<uint8_t>> &packet);
 
-void HandleBtRequestCxx(uint32_t facade_id, uint8_t packet_type,
+void HandleBtRequestCxx(uint32_t rootcanal_id, uint8_t packet_type,
                         const rust::Vec<uint8_t> &packet);
 
 }  // namespace hci
diff --git a/src/hci/hci_packet_transport.cc b/src/hci/hci_packet_transport.cc
index 7f25ab1..81de642 100644
--- a/src/hci/hci_packet_transport.cc
+++ b/src/hci/hci_packet_transport.cc
@@ -30,7 +30,7 @@
 namespace hci {
 
 std::unordered_map<uint32_t, std::shared_ptr<HciPacketTransport>>
-    device_to_transport_;
+    rootcanal_id_to_transport_;
 
 /**
  * @class HciPacketTransport
@@ -39,17 +39,22 @@
  *
  */
 HciPacketTransport::HciPacketTransport(
-    std::shared_ptr<rootcanal::AsyncManager> async_manager)
-    : mDeviceId(std::nullopt), mAsyncManager(std::move(async_manager)) {}
+    uint32_t chip_id, std::shared_ptr<rootcanal::AsyncManager> async_manager)
+    : rootcanalId(std::nullopt),
+      netsimChipId(chip_id),
+      mAsyncManager(std::move(async_manager)) {}
 
 /**
  * @brief Connect the phy device to the transport
  *
- * @param - device_id identifier of the owning device
+ * @param - rootcanal_id identifier of the owning device
+ *
+ * @param - chip_id identifier generated from netsimd
  */
-void HciPacketTransport::Connect(rootcanal::PhyDevice::Identifier device_id) {
-  assert(!mDeviceId.has_value());
-  mDeviceId.emplace(device_id);
+void HciPacketTransport::Connect(
+    rootcanal::PhyDevice::Identifier rootcanal_id) {
+  assert(!rootcanalId.has_value());
+  rootcanalId.emplace(rootcanal_id);
 }
 
 // Called by HCITransport (rootcanal)
@@ -59,13 +64,12 @@
   // rootcanal::PacketType to HCIPacket_PacketType is safe.
   packet::HCIPacket_PacketType hci_packet_type =
       static_cast<packet::HCIPacket_PacketType>(packet_type);
-  if (!mDeviceId.has_value()) {
+  if (!rootcanalId.has_value()) {
     BtsLogWarn("hci_packet_transport: response with no device.");
     return;
   }
   // Send response to transport dispatcher.
-  netsim::echip::HandleResponse(common::ChipKind::BLUETOOTH, mDeviceId.value(),
-                                data, hci_packet_type);
+  netsim::echip::HandleResponse(netsimChipId, data, hci_packet_type);
 }
 
 // Called by HCITransport (rootcanal)
@@ -94,29 +98,30 @@
 }
 
 void HciPacketTransport::Add(
-    rootcanal::PhyDevice::Identifier device_id,
+    rootcanal::PhyDevice::Identifier rootcanal_id,
     const std::shared_ptr<HciPacketTransport> &transport) {
-  transport->Connect(device_id);
-  device_to_transport_[device_id] = transport;
+  transport->Connect(rootcanal_id);
+  rootcanal_id_to_transport_[rootcanal_id] = transport;
 }
 
-void HciPacketTransport::Remove(rootcanal::PhyDevice::Identifier device_id) {
+void HciPacketTransport::Remove(rootcanal::PhyDevice::Identifier rootcanal_id) {
   BtsLogInfo("hci_packet_transport remove from netsim");
-  if (device_to_transport_.find(device_id) != device_to_transport_.end() &&
-      device_to_transport_[device_id]) {
+  if (rootcanal_id_to_transport_.find(rootcanal_id) !=
+          rootcanal_id_to_transport_.end() &&
+      rootcanal_id_to_transport_[rootcanal_id]) {
     // Calls HciDevice::Close, will disconnect AclHandles with
     // CONNECTION_TIMEOUT, and call TestModel::CloseCallback.
-    device_to_transport_[device_id]->mCloseCallback();
+    rootcanal_id_to_transport_[rootcanal_id]->mCloseCallback();
   }
 }
 
 // Called by HciDevice::Close
 void HciPacketTransport::Close() {
-  if (mDeviceId.has_value()) {
-    device_to_transport_.erase(mDeviceId.value());
+  if (rootcanalId.has_value()) {
+    rootcanal_id_to_transport_.erase(rootcanalId.value());
   }
   BtsLogInfo("hci_packet_transport close from rootcanal");
-  mDeviceId = std::nullopt;
+  rootcanalId = std::nullopt;
 }
 
 // handle_request is the main entry for incoming packets called by
@@ -124,29 +129,30 @@
 //
 // Transfer the request to the HciTransport to deliver to Rootcanal via the
 // acl/sco/iso/command callback methods under synchronization.
-void handle_bt_request(uint32_t facade_id,
+void handle_bt_request(uint32_t rootcanal_id,
                        packet::HCIPacket_PacketType packet_type,
                        const std::shared_ptr<std::vector<uint8_t>> &packet) {
-  if (device_to_transport_.find(facade_id) != device_to_transport_.end() &&
-      device_to_transport_[facade_id]) {
-    auto transport = device_to_transport_[facade_id];
+  if (rootcanal_id_to_transport_.find(rootcanal_id) !=
+          rootcanal_id_to_transport_.end() &&
+      rootcanal_id_to_transport_[rootcanal_id]) {
+    auto transport = rootcanal_id_to_transport_[rootcanal_id];
     transport->Request(packet_type, packet);
   } else {
-    std::cout << "device_to_transport_ ids ";
-    for (auto [k, _] : device_to_transport_) std::cout << k << " ";
+    std::cout << "rootcanal_id_to_transport_ ids ";
+    for (auto [k, _] : rootcanal_id_to_transport_) std::cout << k << " ";
     std::cout << std::endl;
     BtsLogWarn(
         "hci_packet_transport: handle_request with no transport for device "
-        "with facade_id: %d",
-        facade_id);
+        "with rootcanal_id: %d",
+        rootcanal_id);
   }
 }
 
-void HandleBtRequestCxx(uint32_t facade_id, uint8_t packet_type,
+void HandleBtRequestCxx(uint32_t rootcanal_id, uint8_t packet_type,
                         const rust::Vec<uint8_t> &packet) {
   std::vector<uint8_t> buffer(packet.begin(), packet.end());
   auto packet_ptr = std::make_shared<std::vector<uint8_t>>(buffer);
-  handle_bt_request(facade_id,
+  handle_bt_request(rootcanal_id,
                     static_cast<packet::HCIPacket_PacketType>(packet_type),
                     packet_ptr);
 }
diff --git a/src/hci/hci_packet_transport.h b/src/hci/hci_packet_transport.h
index 080a35e..decc10b 100644
--- a/src/hci/hci_packet_transport.h
+++ b/src/hci/hci_packet_transport.h
@@ -36,7 +36,7 @@
  */
 class HciPacketTransport : public rootcanal::HciTransport {
  public:
-  HciPacketTransport(std::shared_ptr<rootcanal::AsyncManager>);
+  HciPacketTransport(uint32_t, std::shared_ptr<rootcanal::AsyncManager>);
   ~HciPacketTransport() = default;
 
   static void Add(rootcanal::PhyDevice::Identifier id,
@@ -49,7 +49,7 @@
    *
    * Moves HCI packets between packet_hub and rootcanal HciTransport
    */
-  void Connect(rootcanal::PhyDevice::Identifier device_id);
+  void Connect(rootcanal::PhyDevice::Identifier rootcanal_id);
 
   void Send(rootcanal::PacketType packet_type,
             const std::vector<uint8_t> &packet) override;
@@ -68,7 +68,8 @@
   rootcanal::PacketCallback mPacketCallback;
   rootcanal::CloseCallback mCloseCallback;
   // Device ID is the same as Chip Id externally.
-  std::optional<rootcanal::PhyDevice::Identifier> mDeviceId;
+  std::optional<rootcanal::PhyDevice::Identifier> rootcanalId;
+  uint32_t netsimChipId;
   std::shared_ptr<rootcanal::AsyncManager> mAsyncManager;
 };
 
diff --git a/src/wifi/wifi_facade.cc b/src/wifi/wifi_facade.cc
index d66fc39..1a9eaae 100644
--- a/src/wifi/wifi_facade.cc
+++ b/src/wifi/wifi_facade.cc
@@ -28,17 +28,13 @@
 
 namespace netsim::wifi {
 namespace {
-// To detect bugs of misuse of chip_id more efficiently.
-const int kGlobalChipStartIndex = 2000;
 
 class ChipInfo {
  public:
-  uint32_t simulation_device;
   std::shared_ptr<model::Chip::Radio> model;
 
-  ChipInfo(uint32_t simulation_device,
-           std::shared_ptr<model::Chip::Radio> model)
-      : simulation_device(simulation_device), model(std::move(model)) {}
+  ChipInfo(std::shared_ptr<model::Chip::Radio> model)
+      : model(std::move(model)) {}
 };
 
 std::unordered_map<uint32_t, std::shared_ptr<ChipInfo>> id_to_chip_info_;
@@ -56,7 +52,7 @@
     auto &model = it->second->model;
     return model->state();
   }
-  BtsLogWarn("Failed to get WiFi state with unknown facade %d", id);
+  BtsLogWarn("Failed to get WiFi state with unknown chip_id %d", id);
   return std::nullopt;
 }
 
@@ -96,7 +92,7 @@
   BtsLog("wifi::facade::Patch(%d)", id);
   auto it = id_to_chip_info_.find(id);
   if (it == id_to_chip_info_.end()) {
-    BtsLogWarn("Patch an unknown facade_id: %d", id);
+    BtsLogWarn("Patch an unknown chip_id: %d", id);
     return;
   }
   auto &model = it->second->model;
@@ -131,28 +127,24 @@
   return proto_rust_bytes;
 }
 
-uint32_t Add(uint32_t simulation_device) {
-  BtsLog("wifi::facade::Add(%d)", simulation_device);
-  static uint32_t global_chip_id = kGlobalChipStartIndex;
+void Add(uint32_t chip_id) {
+  BtsLog("wifi::facade::Add(%d)", chip_id);
 
   auto model = std::make_shared<model::Chip::Radio>();
   model->set_state(model::State::ON);
-  id_to_chip_info_.emplace(
-      global_chip_id, std::make_shared<ChipInfo>(simulation_device, model));
-
-  return global_chip_id++;
+  id_to_chip_info_.emplace(chip_id, std::make_shared<ChipInfo>(model));
 }
 
 size_t HandleWifiCallback(const uint8_t *buf, size_t size) {
   //  Broadcast the response to all WiFi chips.
   std::vector<uint8_t> packet(buf, buf + size);
-  for (auto [facade_id, _] : id_to_chip_info_) {
-    if (auto state = GetState(facade_id);
+  for (auto [chip_id, chip_info] : id_to_chip_info_) {
+    if (auto state = chip_info->model->state();
         !state || state == model::State::OFF) {
       continue;
     }
-    netsim::wifi::IncrRx(facade_id);
-    echip::HandleResponse(common::ChipKind::WIFI, facade_id, packet,
+    netsim::wifi::IncrRx(chip_id);
+    echip::HandleResponse(chip_id, packet,
                           packet::HCIPacket::HCI_PACKET_UNSPECIFIED);
   }
   return size;
@@ -209,13 +201,13 @@
 
 }  // namespace facade
 
-void HandleWifiRequest(uint32_t facade_id,
+void HandleWifiRequest(uint32_t chip_id,
                        const std::shared_ptr<std::vector<uint8_t>> &packet) {
 #ifdef NETSIM_ANDROID_EMULATOR
-  if (auto state = GetState(facade_id); !state || state == model::State::OFF) {
+  if (auto state = GetState(chip_id); !state || state == model::State::OFF) {
     return;
   }
-  netsim::wifi::IncrTx(facade_id);
+  netsim::wifi::IncrTx(chip_id);
   // Send the packet to the WiFi service.
   struct iovec iov[1];
   iov[0].iov_base = packet->data();
@@ -224,11 +216,10 @@
 #endif
 }
 
-void HandleWifiRequestCxx(uint32_t facade_id,
-                          const rust::Vec<uint8_t> &packet) {
+void HandleWifiRequestCxx(uint32_t chip_id, const rust::Vec<uint8_t> &packet) {
   std::vector<uint8_t> buffer(packet.begin(), packet.end());
   auto packet_ptr = std::make_shared<std::vector<uint8_t>>(buffer);
-  HandleWifiRequest(facade_id, packet_ptr);
+  HandleWifiRequest(chip_id, packet_ptr);
 }
 
 }  // namespace netsim::wifi
diff --git a/src/wifi/wifi_facade.h b/src/wifi/wifi_facade.h
index 9be93aa..c634bbb 100644
--- a/src/wifi/wifi_facade.h
+++ b/src/wifi/wifi_facade.h
@@ -33,7 +33,7 @@
 void Remove(uint32_t);
 void Patch(uint32_t, const model::Chip::Radio &);
 model::Chip::Radio Get(uint32_t);
-uint32_t Add(uint32_t simulation_device);
+void Add(uint32_t chip_id);
 
 void Start(const rust::Slice<::std::uint8_t const> proto_bytes);
 void Stop();
diff --git a/src/wifi/wifi_facade_test.cc b/src/wifi/wifi_facade_test.cc
index 95b93a1..4372452 100644
--- a/src/wifi/wifi_facade_test.cc
+++ b/src/wifi/wifi_facade_test.cc
@@ -20,51 +20,52 @@
 
 namespace netsim::wifi::facade {
 
-class WiFiFacadeTest : public ::testing::Test {
-  void TearDown() { netsim::wifi::facade::Remove(SIMULATION_DEVICE); }
-
- protected:
-  const int SIMULATION_DEVICE = 123;
-};
+class WiFiFacadeTest : public ::testing::Test {};
 
 TEST_F(WiFiFacadeTest, AddAndGetTest) {
-  auto facade_id = Add(SIMULATION_DEVICE);
+  Add(123);
 
-  auto radio = Get(facade_id);
+  auto radio = Get(123);
   EXPECT_EQ(model::State::ON, radio.state());
   EXPECT_EQ(0, radio.tx_count());
   EXPECT_EQ(0, radio.rx_count());
+
+  Remove(123);
 }
 
 TEST_F(WiFiFacadeTest, RemoveTest) {
-  auto facade_id = Add(SIMULATION_DEVICE);
+  Add(234);
 
-  Remove(facade_id);
+  Remove(234);
 
-  auto radio = Get(facade_id);
+  auto radio = Get(234);
   EXPECT_EQ(model::State::UNKNOWN, radio.state());
 }
 
 TEST_F(WiFiFacadeTest, PatchTest) {
-  auto facade_id = Add(SIMULATION_DEVICE);
+  Add(345);
 
   model::Chip::Radio request;
   request.set_state(model::State::OFF);
-  Patch(facade_id, request);
+  Patch(345, request);
 
-  auto radio = Get(facade_id);
+  auto radio = Get(345);
   EXPECT_EQ(model::State::OFF, radio.state());
+
+  Remove(345);
 }
 
 TEST_F(WiFiFacadeTest, ResetTest) {
-  auto facade_id = Add(SIMULATION_DEVICE);
+  Add(456);
 
-  Reset(facade_id);
+  Reset(456);
 
-  auto radio = Get(facade_id);
+  auto radio = Get(456);
   EXPECT_EQ(model::State::ON, radio.state());
   EXPECT_EQ(0, radio.tx_count());
   EXPECT_EQ(0, radio.rx_count());
+
+  Remove(456);
 }
 
 }  // namespace netsim::wifi::facade
\ No newline at end of file
diff --git a/src/wifi/wifi_packet_hub.h b/src/wifi/wifi_packet_hub.h
index 95b865f..fb47de9 100644
--- a/src/wifi/wifi_packet_hub.h
+++ b/src/wifi/wifi_packet_hub.h
@@ -27,9 +27,9 @@
 /* Handle packet requests for the WiFi Facade which may come over
    different transports including gRPC. */
 
-void HandleWifiRequest(uint32_t facade_id,
+void HandleWifiRequest(uint32_t chip_id,
                        const std::shared_ptr<std::vector<uint8_t>> &packet);
 
-void HandleWifiRequestCxx(uint32_t facade_id, const rust::Vec<uint8_t> &packet);
+void HandleWifiRequestCxx(uint32_t chip_id, const rust::Vec<uint8_t> &packet);
 
 }  // namespace netsim::wifi