From e6683a4ed2e0c09545a724488b87b5ceead5bfb7 Mon Sep 17 00:00:00 2001 From: sukhman Date: Mon, 1 Jul 2024 21:18:20 +0530 Subject: [PATCH] Fix: linux ble send message flow Signed-off-by: sukhman --- .../main/java/net/qaul/ble/core/BleActor.kt | 36 +-- .../java/net/qaul/ble/core/BleWrapperClass.kt | 7 +- .../java/net/qaul/ble/service/BleService.kt | 34 +-- rust/ble_module/Cargo.toml | 2 + rust/ble_module/src/ble/ble_service.rs | 207 ++++++++++++++---- rust/ble_module/src/ble/utils.rs | 21 +- 6 files changed, 233 insertions(+), 74 deletions(-) diff --git a/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/core/BleActor.kt b/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/core/BleActor.kt index 05a8dfb1e..1fd3867e5 100644 --- a/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/core/BleActor.kt +++ b/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/core/BleActor.kt @@ -80,7 +80,7 @@ class BleActor(private val mContext: Context, var listener: BleConnectionListene private fun connectDevice(): Boolean { AppLog.i(TAG, "connectDevice : $bluetoothDevice") if (bluetoothDevice == null) { - AppLog.e("zzz", "connectDevice : $bluetoothDevice") + AppLog.e(TAG, "connectDevice : $bluetoothDevice") listener!!.onConnectionFailed(bleScanDevice = bleDevice!!) } failTimer = Timer() @@ -145,7 +145,7 @@ class BleActor(private val mContext: Context, var listener: BleConnectionListene ) { super.onCharacteristicRead(gatt, characteristic, status) AppLog.e( - "zzz", + TAG, "onCharacteristicRead : " + characteristic.uuid.toString() + " , isFromMessage-> $isFromMessage" ) @@ -173,12 +173,12 @@ class BleActor(private val mContext: Context, var listener: BleConnectionListene gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int ) { super.onCharacteristicWrite(gatt, characteristic, status) -// AppLog.e( -// "zzz ", -// "onCharacteristicWrite --------------> $listener $messageId $ : , data : " + BLEUtils.byteToHex( -// characteristic.value -// ) -// ) + // AppLog.e( + // TAG, + // "onCharacteristicWrite -------------->, data : " + BLEUtils.byteToHex( + // characteristic.value + // ) + // ) if (listener != null) { if (messageId.isEmpty() || messageId.isBlank()) { listener!!.onCharacteristicWrite(gatt = gatt, characteristic = characteristic) @@ -220,6 +220,7 @@ class BleActor(private val mContext: Context, var listener: BleConnectionListene gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int ) { super.onDescriptorWrite(gatt, descriptor, status) + AppLog.e(TAG, "onDescriptorWrite asked") if (descriptorWriteQueue != null && descriptorWriteQueue.size > 0) { descriptorWriteQueue.remove() if (descriptorWriteQueue.size > 0) writeGattDescriptor(descriptorWriteQueue.element()) else { @@ -261,7 +262,7 @@ class BleActor(private val mContext: Context, var listener: BleConnectionListene } fun send(data: String): Int { -// AppLog.e("zzz", "send data-----------------> isWriting $isWriting data $data") + AppLog.e(TAG, "send data-----------------> isWriting $isWriting data $data") var data = data while (data.length > 40) { sendQueue.add(data.substring(0, 40)) @@ -277,8 +278,9 @@ class BleActor(private val mContext: Context, var listener: BleConnectionListene AppLog.e("TAG", "_send(): EMPTY QUEUE") return false } -// AppLog.e(TAG, "_send(): $attempt Sending: " + sendQueue.peek()) + AppLog.e(TAG, "_send(): $attempt Sending: " + sendQueue.peek()) val tx = BLEUtils.hexToByteArray(sendQueue.poll()) + // AppLog.e(TAG, "_send(): $attempt Sending: ") // val tx = sendQueue.poll()?.toByteArray(Charset.forName("UTF-8")) isWriting = true // Set the write in progress flag writeServiceData(BleService.SERVICE_UUID, BleService.MSG_CHAR, tx, attempt) @@ -346,6 +348,7 @@ class BleActor(private val mContext: Context, var listener: BleConnectionListene * This method is used to write descriptor of gatt */ private fun writeGattDescriptor(d: BluetoothGattDescriptor) { + AppLog.e(TAG, "writeGattDescriptor request ") if (isCharacteristicNotifiable(d.characteristic)) { d.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE } else { @@ -376,7 +379,7 @@ class BleActor(private val mContext: Context, var listener: BleConnectionListene override fun run() { if (listener != null) { listener!!.onConnectionFailed(bleDevice!!) - AppLog.e("zzz", "ConnectionFailedTask : $bluetoothDevice") + AppLog.e(TAG, "ConnectionFailedTask : $bluetoothDevice") disConnectedDevice() listener!!.onDisconnected(bleDevice!!) Handler(Looper.getMainLooper()).postDelayed({ @@ -430,18 +433,17 @@ class BleActor(private val mContext: Context, var listener: BleConnectionListene ): Boolean { if (attempt < 3) { if (data != null) { -// AppLog.e( -// TAG, -// "writeServiceData -----------> : serUUID : $serUUID, charUUID:$charUUID, data :" + BLEUtils.byteToHex( -// data -// ) -// ) + // AppLog.e( + // TAG, + // "writeServiceData -----------> : data : ${data}" + // ) if (mBluetoothGatt != null) { val service = mBluetoothGatt!!.getService(UUID.fromString(serUUID)) if (service != null) { val characteristic = service.getCharacteristic(UUID.fromString(charUUID)) if (characteristic != null) { characteristic.value = data + AppLog.e(TAG, "===================Characterstic value = $data") return mBluetoothGatt!!.writeCharacteristic(characteristic) } } else { diff --git a/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/core/BleWrapperClass.kt b/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/core/BleWrapperClass.kt index aba7826c9..7a000f47f 100644 --- a/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/core/BleWrapperClass.kt +++ b/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/core/BleWrapperClass.kt @@ -130,7 +130,7 @@ open class BleWrapperClass(context: Activity) { } BleOuterClass.Ble.MessageCase.DIRECT_SEND -> { - AppLog.e("zzz", " DIRECT_SEND ") + AppLog.e(TAG, " DIRECT_SEND ") val bleDirectSend = bleReq.directSend if (BleService().isRunning()) { @@ -265,16 +265,17 @@ open class BleWrapperClass(context: Activity) { } override fun onMessageReceived(bleDevice: BLEScanDevice, message: ByteArray) { - AppLog.e("zzz", "---->onMessageReceived---> ${BLEUtils.byteToHex(message)}") + // AppLog.e(TAG, "---->onMessageReceived---> ${BLEUtils.byteToHex(message)}") val bleRes = BleOuterClass.Ble.newBuilder() val directReceived = BleOuterClass.BleDirectReceived.newBuilder() val msgData = String(message).removeSuffix("$$").removePrefix("$$") + AppLog.e(TAG, "---->onMessageReceived---> " + msgData) val msgObject = Gson().fromJson(msgData, Message::class.java) directReceived.from = ByteString.copyFrom(bleDevice.qaulId) directReceived.data = ByteString.copyFrom(msgObject.message) // ByteString.copyFrom(msgObject.message, Charset.defaultCharset()) bleRes.directReceived = directReceived.build() - AppLog.e("zzz", "---->onMessageReceived msgObject $msgObject") + // AppLog.e(TAG, "---->onMessageReceived msgObject $msgObject") sendResponse(bleRes) } }) diff --git a/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/service/BleService.kt b/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/service/BleService.kt index efef6a6a0..75bc52494 100644 --- a/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/service/BleService.kt +++ b/qaul_ui/android/blemodule/src/main/java/net/qaul/ble/service/BleService.kt @@ -422,9 +422,9 @@ class BleService : LifecycleService() { super.onCharacteristicWriteRequest( device, requestId, characteristic, preparedWrite, responseNeeded, offset, value ) - AppLog.e("zzz", "Write Request Received: " + String(value) + " :: " + requestId) + // AppLog.e(TAG, "Write Request Received: " + String(value) + " :: " + requestId) val s = BLEUtils.byteToHex(value) -// AppLog.e(TAG, "Data in hex:: $s") + AppLog.e(TAG, "Data in hex:: $s") var bleDevice = ignoreList.find { it.macAddress == device.address } if (bleDevice == null) { bleDevice = receiveList.find { it.macAddress == device.address } @@ -437,6 +437,8 @@ class BleService : LifecycleService() { var oldValue = msgMap[device.address] if (s.endsWith("2424") || (oldValue!!.endsWith("24") && s == "24")) { //SendResponse of oldValue + + AppLog.e(TAG, "onCharacteristicWriteRequest: contain 2424") oldValue += s val msgData = String(BLEUtils.hexToByteArray(oldValue)!!).removeSuffix("$$") .removePrefix("$$") @@ -458,6 +460,7 @@ class BleService : LifecycleService() { Log.e(TAG, "onCharacteristicWriteRequest: contain $$") } } else { + AppLog.e(TAG, "onCharacteristicWriteRequest: not contain 2424") oldValue += s msgMap[device.address] = oldValue } @@ -466,6 +469,7 @@ class BleService : LifecycleService() { //Send Response of s val msgData = String(BLEUtils.hexToByteArray(s)!!).removeSuffix("$$") .removePrefix("$$") + AppLog.e(TAG, "Got whole message at once $msgData") val msgObject = Gson().fromJson(msgData, Message::class.java) if (bleDevice == null) { bleDevice = BLEScanDevice.getDevice() @@ -776,12 +780,12 @@ class BleService : LifecycleService() { ) { val queue = hashMap[gatt?.device?.address] if (queue?.isNotEmpty() == true) { - Log.e("zzz", "onMessageSent:SIZE -> queue.isNotEmpty() ") + AppLog.e(TAG, "onMessageSent:SIZE -> queue.isNotEmpty() ") queue.poll() hashMap[gatt?.device?.address!!] = queue } - Log.e("zzz", "onMessageSent:SIZE -> ${queue?.size} ") + AppLog.e(TAG, "onMessageSent:SIZE -> ${queue?.size} ") bleCallback?.onMessageSent(id = id, success = true, data = value) sendMessageFromQueu(gatt?.device?.address!!) @@ -797,12 +801,12 @@ class BleService : LifecycleService() { override fun addToBlackList(bleScanDevice: BLEScanDevice) { blackList.add(bleScanDevice) - AppLog.e(TAG, " addToBlackList : $blackList") + // AppLog.e(TAG, " addToBlackList : $blackList") } override fun addToIgnoreList(bleScanDevice: BLEScanDevice) { ignoreList.add(bleScanDevice) - AppLog.e(TAG, " addToIgnoreList : $ignoreList") + // AppLog.e(TAG, " addToIgnoreList : $ignoreList") } } @@ -837,9 +841,9 @@ class BleService : LifecycleService() { } AppLog.e( - "zzz", "sendMessage ${BLEUtils.byteToHex(message)}" + TAG, "sendMessage ${BLEUtils.byteToHex(message)}" ) - var mainQueue: Queue>? = null + // var mainQueue: Queue>? = null bleDevice?.let { if (hashMap.containsKey(it.macAddress)) { var queue = hashMap[it.macAddress!!] @@ -849,14 +853,16 @@ class BleService : LifecycleService() { queue = LinkedList() } hashMap[it.macAddress!!] = queue!! - mainQueue = queue + // mainQueue = queue + // AppLog.d(TAG, " Manual send ======= Queue size was already 1 ") } else { + // AppLog.d(TAG, " Manual send ===== Queue size was empty ") val queue: Queue> = LinkedList() queue.add(Triple(id, from, message)) hashMap[it.macAddress!!] = queue - mainQueue = queue + // mainQueue = queue } - AppLog.e(TAG, "device--> ${it.macAddress} ${mainQueue?.size}") + // AppLog.e(TAG, "device--> ${it.macAddress} ${mainQueue?.size}") sendMessageFromQueu(it.macAddress!!, true) } @@ -871,7 +877,7 @@ class BleService : LifecycleService() { if (!queue.isNullOrEmpty()) { AppLog.e( TAG, - "sendMessageFromQueu ${queue.size}" + "sendMessageFromQueu ${queue.size} ${isFromSendMessage}" ) if (!isFromSendMessage || queue.size == 1) { var bleDevice = ignoreList.find { it.macAddress.contentEquals(macAddress) } @@ -899,14 +905,14 @@ class BleService : LifecycleService() { delimiter[1] = 36 bleActor.tempData = delimiter + btArray + delimiter AppLog.e( - "zzz", + TAG, "data------------>sendMessage ${BLEUtils.byteToHex(bleActor.tempData)}" ) // },500) } else { AppLog.e( - "zzz", "data------------>onMessageSent Failed" + TAG, "data------------>onMessageSent Failed" ) bleCallback?.onMessageSent( id = mesTrip.first, success = false, data = ByteArray(0) diff --git a/rust/ble_module/Cargo.toml b/rust/ble_module/Cargo.toml index 873213f96..fc1ef18f8 100644 --- a/rust/ble_module/Cargo.toml +++ b/rust/ble_module/Cargo.toml @@ -17,6 +17,8 @@ futures-concurrency = "7.6.1" lazy_static = "1.4" log = "0.4" prost = "0.12.6" +serde = "1.0.203" +serde_json = "1.0.118" simplelog = "0.12.2" state = "0.6.0" tokio = { version = "1", features = ["full"] } diff --git a/rust/ble_module/src/ble/ble_service.rs b/rust/ble_module/src/ble/ble_service.rs index e8f347e09..02c138a97 100644 --- a/rust/ble_module/src/ble/ble_service.rs +++ b/rust/ble_module/src/ble/ble_service.rs @@ -1,3 +1,11 @@ +use crate::ble::ble_uuids::msg_char; +use crate::ble::ble_uuids::msg_service_uuid; +use crate::ble::ble_uuids::read_char; +use crate::ble::{ble_uuids::main_service_uuid, utils::hex_to_bytes}; +use crate::{ + ble::utils, + rpc::{proto_sys::*, utils::*}, +}; use async_std::{channel::Sender, prelude::*, task::JoinHandle}; use bluer::{ adv::{Advertisement, AdvertisementHandle}, @@ -7,16 +15,28 @@ use bluer::{ use bytes::Bytes; use futures::FutureExt; use futures_concurrency::stream::Merge; -use std::{cell::RefCell, collections::HashMap, collections::HashSet, error::Error}; - -use crate::ble::ble_uuids::msg_char; -use crate::ble::ble_uuids::msg_service_uuid; -use crate::ble::ble_uuids::read_char; -use crate::ble::{ble_uuids::main_service_uuid, utils::hex_to_bytes}; -use crate::{ - ble::utils, - rpc::{proto_sys::*, utils::*}, +use lazy_static::lazy_static; +use serde::{Deserialize, Serialize}; +use serde_json; +use std::string; +use std::{ + cell::RefCell, collections::HashMap, collections::HashSet, collections::VecDeque, error::Error, + sync::Mutex, }; + +lazy_static! { + static ref HASH_MAP: Mutex, Vec)>>> = + Mutex::new(HashMap::new()); +} + +#[derive(Serialize, Deserialize)] +struct Message { + #[serde(rename = "qaul_id")] + qaulId: Option>, + + #[serde(rename = "message")] + message: Option>, +} pub enum QaulBleService { Idle(IdleBleService), Started(StartedBleService), @@ -276,7 +296,12 @@ impl IdleBleService { Ok(msg_id) => { log::info!("Message ID: {:?}", msg_id); match self - .send_direct_message(msg_id.to_string(), receiver_id, sender_id, data) + .send_direct_message( + msg_id.to_string(), + receiver_id, + sender_id, + data, + ) .await { Ok(_) => { @@ -311,9 +336,11 @@ impl IdleBleService { } BleMainLoopEvent::MsgCharEvent(e) => match e { CharacteristicControlEvent::Write(write) => { + let mac_address = write.device_address(); if let Ok(reader) = write.accept() { let message_tx = message_tx.clone(); - let _ = self.spawn_msg_listener(reader, message_tx); + let _ = + self.spawn_msg_listener(reader, message_tx, mac_address); } } CharacteristicControlEvent::Notify(_) => (), @@ -441,6 +468,7 @@ impl IdleBleService { &self, reader: CharacteristicReader, message_tx: Sender, + mac_address: Address, ) { async_std::task::spawn(async move { while let Some(msg) = reader.recv().await.ok() { @@ -448,21 +476,60 @@ impl IdleBleService { break; } let mut hex_msg = utils::bytes_to_hex(&msg); - log::debug!( - "Received message: {:?} reader.device {:?} ", - hex_msg, - reader.device_address() - ); - if hex_msg.starts_with("$$") { - hex_msg = hex_msg["$$".len()..].to_string(); - } - if hex_msg.ends_with("$$") { - hex_msg = hex_msg[..hex_msg.len() - 2].to_string(); + log::debug!("Received message: {:?} ", hex_msg); + let stringified_addr = utils::mac_to_string(&mac_address); + // let device = utils::find_device_by_mac(mac_address).unwrap(); + // let mut msg_map = MSG_MAP.lock().unwrap(); + match utils::find_msg_map_by_mac(stringified_addr.clone()) { + Some(old_value) => { + let mut old_value = old_value.clone(); + if hex_msg.ends_with("2424") + || (old_value.ends_with("24") && hex_msg == "24") + { + old_value = old_value + &hex_msg; + let trim_old_value = &old_value[2..old_value.len() - 2]; + if !trim_old_value.contains("$$") { + hex_msg = trim_old_value.to_string(); + utils::remove_msg_map_by_mac(stringified_addr); + // msg_map.remove(&stringified_addr); + } + } else { + old_value += &hex_msg; + utils::add_msg_map(stringified_addr, old_value.clone()); + // msg_map.insert(stringified_addr.clone(), old_value.clone()); + } + } + None => { + if hex_msg.starts_with("2424") && hex_msg.ends_with("2424") { + // Nothing to do here for now + } else if hex_msg.starts_with("2424") { + utils::add_msg_map(stringified_addr, hex_msg.clone()); + // msg_map.insert(stringified_addr.clone(), hex_msg.clone()); + } else { + // Error handling + } + } } + // let old_value_hex = utils::hex_to_bytes(&hex_msg.clone()); + // let mut msg_data = utils::bytes_to_str(&old_value_hex).unwrap(); + let mut data = if let Some(stripped) = hex_msg.strip_prefix("$$") { + stripped.to_string() + } else { + hex_msg.to_string() + }; + + data = if let Some(stripped) = data.strip_suffix("$$") { + stripped.to_string() + } else { + data.to_string() + }; + let msg_object: Message = serde_json::from_str(&data).unwrap(); + let message = msg_object.message.clone().unwrap(); let _ = message_tx .send(BleMainLoopEvent::MessageReceived(( - hex_to_bytes(&hex_msg), - reader.device_address(), + // hex_to_bytes(&message), + message, + mac_address, ))) .await .map_err(|err| log::error!("{:#?}", err)); @@ -476,35 +543,97 @@ impl IdleBleService { receiver_id: Vec, sender_id: Vec, data: Vec, - ) -> Result<(), Box> { + ) -> Result> { println!( "=============Sending direct message again to {:?}", receiver_id ); let addr_loopup = self.address_lookup.borrow(); - let recipient = addr_loopup + let mac_address = addr_loopup .get(&receiver_id) .ok_or("Could not find a device address for the given qaul ID!")?; - let stringified_addr = utils::mac_to_string(&recipient); - let device = self.adapter.device(recipient.to_owned())?; - - if !device.is_connected().await? { - device.connect().await?; - log::info!("Connected to device {}", &stringified_addr); - } + let stringified_addr = utils::mac_to_string(mac_address); + // let device = self.adapter.device(recipient.to_owned())?; + + // let device = utils::find_ignore_device_by_mac(*recipient); + match utils::find_ignore_device_by_mac(*mac_address) { + Some(ble_device) => { + let device = ble_device.device.clone(); + + // let mainQueue : HashMap, Vec)>> = HashMap::new(); + let mut hash_map = HASH_MAP.lock().unwrap(); + match hash_map.get(&stringified_addr) { + Some(queue) => { + let mut queue = queue.clone(); + if queue.len() < 2 { + queue.push_back((message_id, sender_id, data.clone())); + } else { + queue.clear(); + } + hash_map.insert(stringified_addr.clone(), queue); + } + None => { + let mut queue: VecDeque<(String, Vec, Vec)> = VecDeque::new(); + queue.push_back((message_id, sender_id, data.clone())); + hash_map.insert(stringified_addr.clone(), queue); + } + } - for service in device.services().await? { - if service.uuid().await? == msg_service_uuid() { - for chara in service.characteristics().await? { - if chara.uuid().await? == msg_char() { - chara.write(&data).await?; + let extracted_queue = hash_map.get(&stringified_addr).clone(); + let mut message_id: String = "".to_string(); + let mut send_queue: VecDeque = VecDeque::new(); + if let Some(queue) = extracted_queue { + let mut queue = queue.clone(); + if !queue.is_empty() { + let data = queue.pop_front().unwrap(); + message_id = data.0; + let msg = Message { + qaulId: Some(data.1), + message: Some(data.2), + }; + let json_str = serde_json::to_string(&msg).unwrap(); + let bt_array = json_str.as_bytes(); + let delimiter = vec![0x24, 0x24]; + let temp = [delimiter.clone(), bt_array.to_vec(), delimiter].concat(); + let mut final_data = utils::bytes_to_hex(&temp); + + while final_data.len() > 40 { + send_queue.push_back(final_data[..40].to_string()); + final_data = final_data[40..].to_string(); + } + if !final_data.is_empty() { + send_queue.push_back(final_data); + } + } + } + if !device.is_connected().await? { + device.connect().await?; + log::info!("Connected to device {}", &stringified_addr); + } + while send_queue.len() > 0 { + let data = send_queue.pop_front().unwrap(); + let data = utils::hex_to_bytes(&data); + for service in device.services().await? { + if service.uuid().await? == msg_service_uuid() { + for chara in service.characteristics().await? { + if chara.uuid().await? == msg_char() { + chara.write(&data).await?; + } + } + } } } + if message_id != "" { + Ok(message_id) + } else { + Err("Message ID not found".into()) + } + } + None => { + return Err("Device not found".into()); } } - - Ok(()) } } diff --git a/rust/ble_module/src/ble/utils.rs b/rust/ble_module/src/ble/utils.rs index 18b6923ca..6e4a5d83b 100644 --- a/rust/ble_module/src/ble/utils.rs +++ b/rust/ble_module/src/ble/utils.rs @@ -3,7 +3,8 @@ use crate::rpc::utils::*; use lazy_static::lazy_static; use std::time::{SystemTime, UNIX_EPOCH}; use std::sync::Mutex; - +use std:: {string, collections::HashMap}; +// use std::string; #[derive(Debug, Clone)] pub struct BleScanDevice { pub qaul_id: Vec, @@ -21,6 +22,9 @@ lazy_static! { lazy_static! { static ref DEVICE_LIST: Mutex> = Mutex::new(Vec::new()); } +lazy_static! { + static ref MSG_MAP: Mutex> = Mutex::new(HashMap::new()); +} pub fn mac_to_string(addr: &Address) -> String { addr.map(|octet| format!("{:02x?}", octet)).join(":") @@ -60,6 +64,21 @@ pub fn remove_device_by_mac(mac_address: Address) { devices.retain(|device| device.mac_address != mac_address); } +pub fn add_msg_map(stringified_addr: String, hex_msg: String) { + let mut msg_map = MSG_MAP.lock().unwrap(); + msg_map.insert(stringified_addr.clone(), hex_msg.clone()); +} + +pub fn find_msg_map_by_mac(stringified_addr: String) -> Option { + let msg_map = MSG_MAP.lock().unwrap(); + msg_map.get(&stringified_addr).cloned() +} + +pub fn remove_msg_map_by_mac(stringified_addr: String) { + let mut msg_map = MSG_MAP.lock().unwrap(); + msg_map.remove(&stringified_addr); +} + pub fn add_ignore_device(device: BleScanDevice) { let mut ignore_devices = IGNORE_LIST.lock().unwrap(); ignore_devices.push(device);