Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux BLE module #539

Draft
wants to merge 38 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
81f8176
BLE end of workday commit
MathJud May 30, 2022
d5b4976
feat: [Flutter] add BLE permission requests on libqaul worker initial…
brenodt Jul 18, 2022
4b61ace
feat: listen for RightsRequest to trigger permission request on Android
brenodt Jul 20, 2022
b0ea7dc
fix: [Flutter] compilation errors
brenodt Sep 20, 2022
2cb2cf0
chore: [Flutter] update gradle version
brenodt Sep 28, 2022
1251005
Add Libqaul & Blemodule(android) interface module.
mingchee1026 Nov 20, 2022
843c29d
Fixed code for building
MathJud Nov 21, 2022
9e75dc5
Upgraded Java-Version to 11 for Gradle
MathJud Nov 21, 2022
8d70a03
Fix compilation issue for flutter app
mingchee1026 Nov 22, 2022
6391975
Fix ble service issue on blemodule
mingchee1026 Nov 25, 2022
0ddac80
added protobuf dependency to flutter android gradle
MathJud Nov 23, 2022
9088b3f
BLE: added comments
MathJud Dec 12, 2022
82d3ee4
qaul ID bytes to string logging function
MathJud Jan 18, 2023
eaa923c
debug file reformatted
MathJud Jan 18, 2023
16b7240
added debug logs
MathJud Jan 18, 2023
78441e2
Flutter: added missing Android BLE permission
MathJud Jan 24, 2023
125eb5e
Android BLE comments: TODO catch permission result
MathJud Jan 24, 2023
8894a92
Fix Permission Issue
vishalbluepixel Feb 2, 2023
5ddccac
run android without building rust libqaul
MathJud Jan 30, 2023
8fb57e6
Moved Kotlin BLEModule and Libqaul to Flutter Android project
vishalbluepixel Feb 3, 2023
65dd8ca
I have read the CLA Document and I hereby sign the CLA
vishalbluepixel Feb 2, 2023
7744afd
reinstating build script
MathJud Feb 7, 2023
581db10
fix: compilation issue with Flutter, accessing invalid package "badges"
brenodt Feb 7, 2023
02f0fb6
fixed linux android build
MathJud Feb 7, 2023
795a837
removed android folder
MathJud Feb 7, 2023
b51d1d4
BLE: added log entries
MathJud Feb 13, 2023
3d78c13
Feature/314 ble linux (#1)
6d7a Mar 9, 2023
e45fa41
fix(ble): import generated protobuf from libqaul
6d7a Mar 9, 2023
df77e55
style: remove unused UUID
6d7a Mar 9, 2023
7a320bc
chore(ble): revert changes to generated protorust
6d7a Mar 9, 2023
f46f66e
added ble_module to libqaul for linux
MathJud Mar 13, 2023
13af785
created a library out of the ble_module
MathJud Mar 19, 2023
c523d15
Removed unused SYS channels
MathJud Mar 19, 2023
2db4574
refactor(linux-ble): run main loop on local task
6d7a Mar 24, 2023
8564030
feat(linux-ble): send up results from main loop
6d7a Mar 24, 2023
2e533c9
refactor(linux-ble): remove main.rs and pass callback to init
6d7a Apr 14, 2023
8a7404b
refactor(ble_module): run in tokio runtime
6d7a Apr 14, 2023
2c01e4c
ci(ble_module): apt install bluer dependencies
6d7a Apr 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
created a library out of the ble_module
  • Loading branch information
MathJud committed Mar 19, 2023
commit 13af7857279a0607c6bc826c5776061136f847bc
32 changes: 17 additions & 15 deletions rust/ble_module/src/ble/ble_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ impl IdleBleService {
.ble_handles
.push(QaulBleHandle::AdvertisementHandle(handle)),
Err(err) => {
error!("{:#?}", err);
log::error!("{:#?}", err);
return QaulBleService::Idle(self);
}
};

debug!(
log::debug!(
"Advertising qaul main BLE service at UUID {}",
main_service_uuid()
);
Expand All @@ -121,7 +121,7 @@ impl IdleBleService {
fun: Box::new(move |req| {
let value = qaul_id.clone();
async move {
debug!("Read request {:?} with value {:x?}", &req, &value);
log::debug!("Read request {:?} with value {:x?}", &req, &value);
Ok(value.to_vec())
}
.boxed()
Expand Down Expand Up @@ -164,7 +164,7 @@ impl IdleBleService {
match self.adapter.serve_gatt_application(app).await {
Ok(handle) => self.ble_handles.push(QaulBleHandle::AppHandle(handle)),
Err(err) => {
error!("{:#?}", err);
log::error!("{:#?}", err);
return QaulBleService::Idle(self);
}
};
Expand All @@ -187,7 +187,7 @@ impl IdleBleService {
_ => None,
}),
Err(err) => {
error!("{:#?}", err);
log::error!("{:#?}", err);
return QaulBleService::Idle(self);
}
};
Expand Down Expand Up @@ -215,11 +215,13 @@ impl IdleBleService {
while let Some(evt) = merged_ble_streams.next().await {
match evt {
BleMainLoopEvent::Stop => {
info!("Received stop signal, stopping advertising, scanning, and listening.");
log::info!(
"Received stop signal, stopping advertising, scanning, and listening."
);
break;
}
BleMainLoopEvent::MessageReceived(e) => {
info!(
log::info!(
"Received {} bytes of data from {}",
e.0.len(),
mac_to_string(&e.1)
Expand Down Expand Up @@ -247,7 +249,7 @@ impl IdleBleService {
}
}
Err(err) => {
error!("{:#?}", err);
log::error!("{:#?}", err);
}
}
}
Expand All @@ -272,7 +274,7 @@ impl IdleBleService {

let stringified_addr = mac_to_string(&device.address());
let uuids = device.uuids().await?.unwrap_or_default();
trace!(
log::trace!(
"Discovered device {} with service UUIDs {:?}",
&stringified_addr,
&uuids
Expand All @@ -281,11 +283,11 @@ impl IdleBleService {
if !uuids.contains(&main_service_uuid()) {
return Ok(msg_receivers);
}
debug!("Discovered qaul bluetooth device {}", &stringified_addr);
log::debug!("Discovered qaul bluetooth device {}", &stringified_addr);

if !device.is_connected().await? {
device.connect().await?;
info!("Connected to device {}", &stringified_addr);
log::info!("Connected to device {}", &stringified_addr);
}

for service in device.services().await? {
Expand All @@ -297,7 +299,7 @@ impl IdleBleService {
let flags = char.flags().await?;
if flags.notify || flags.indicate {
msg_receivers.push(char.notify_io().await?);
info!(
log::info!(
"Setting up notification for characteristic {} of device {}",
char.uuid().await?,
&stringified_addr
Expand Down Expand Up @@ -331,7 +333,7 @@ impl IdleBleService {
reader.device_address(),
)))
.await
.map_err(|err| error!("{:#?}", err));
.map_err(|err| log::error!("{:#?}", err));
}
});
}
Expand All @@ -351,7 +353,7 @@ impl StartedBleService {

if !device.is_connected().await? {
device.connect().await?;
info!("Connected to device {}", &stringified_addr);
log::info!("Connected to device {}", &stringified_addr);
}

for service in device.services().await? {
Expand All @@ -369,7 +371,7 @@ impl StartedBleService {

pub async fn stop(self) -> QaulBleService {
if let Err(err) = self.stop_handle.send(true).await {
error!("Failed to stop bluetooth service: {:#?}", &err);
log::error!("Failed to stop bluetooth service: {:#?}", &err);
send_stop_unsuccessful(err.to_string());
return QaulBleService::Started(self);
}
Expand Down
41 changes: 41 additions & 0 deletions rust/ble_module/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2023 Open Community Project Association https://ocpa.ch
// This software is published under the AGPLv3 license.

//! # qaul BLE Module for Linux
//!
//! qaul BLE module for Linux

use crate::ble::ble_service::IdleBleService;
use futures::executor::block_on;
use rpc::msg_loop::listen_for_sys_msgs;
use std::thread;

mod ble;
pub mod rpc;

/// initialize and start the ble_module in an own thread
pub fn init() {
// Spawn new thread
thread::spawn(move || {
block_on(async move {
// start BLE module main loop
main_loop().await;
})
});
}

/// Start the setup and main loop of this library
async fn main_loop() {
let rpc_receiver = rpc::init();
let ble_service = IdleBleService::new().await.unwrap_or_else(|err| {
log::error!("{:#?}", err);
std::process::exit(1);
});

listen_for_sys_msgs(rpc_receiver, ble_service)
.await
.unwrap_or_else(|err| {
log::error!("{:#?}", err);
std::process::exit(1);
});
}
27 changes: 13 additions & 14 deletions rust/ble_module/src/rpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ pub mod msg_loop;
pub mod utils;

use async_trait::async_trait;
use bytes::Bytes;
use prost::Message;
use state::Storage;

Expand All @@ -22,7 +21,7 @@ use proto_sys::Ble;
/// receiver of the mpsc channel: ui ---> ble_module
static EXTERN_RECEIVE: Storage<crossbeam_channel::Receiver<Vec<u8>>> = Storage::new();
/// sender of the mpsc channel: ui ---> ble_module
static EXTERN_SEND: Storage<async_std::channel::Sender<Bytes>> = Storage::new();
static EXTERN_SEND: Storage<async_std::channel::Sender<Vec<u8>>> = Storage::new();
/// sender handle of the mpsc channel: ble_module ---> ui
static BLE_MODULE_SEND: Storage<crossbeam_channel::Sender<Vec<u8>>> = Storage::new();

Expand All @@ -32,7 +31,7 @@ pub trait SysRpcReceiver {
}

pub struct BleRpc {
receiver: async_std::channel::Receiver<Bytes>,
receiver: async_std::channel::Receiver<Vec<u8>>,
}

#[async_trait]
Expand All @@ -49,7 +48,7 @@ impl SysRpcReceiver for BleRpc {

/// Initialize RPC module
/// Create the sending and receiving channels and persist them across threads.
/// Return the receiver for the channel ui ---> ble_module
/// Return the receiver for the channel libqaul ---> ble_module
pub fn init() -> BleRpc {
// create channels
let (ble_send, ui_rec) = crossbeam_channel::bounded::<Vec<u8>>(32);
Expand All @@ -63,16 +62,16 @@ pub fn init() -> BleRpc {
BleRpc { receiver: ble_rec }
}

/// send rpc message ui ---> ble_module
/// send sys message libqaul ---> ble_module
#[allow(dead_code)]
pub fn send_to_ble_module(binary_message: Bytes) {
pub fn send_to_ble_module(binary_message: Vec<u8>) {
if let Err(err) = EXTERN_SEND.get().try_send(binary_message) {
error!("{:?}", err);
log::error!("{:?}", err);
}
}

/// check whether there are new messages in
/// the receiving rpc channel ble_module ---> ui
/// the receiving sys channel ble_module ---> libqaul
#[allow(dead_code)]
pub fn receive_from_ble_module() -> Result<Vec<u8>, crossbeam_channel::TryRecvError> {
EXTERN_RECEIVE.get().try_recv()
Expand All @@ -84,22 +83,22 @@ pub fn queue_length_ble_to_ui() -> usize {
BLE_MODULE_SEND.get().len()
}

/// send rpc message ble_module ---> ui
/// send sys message ble_module ---> libqaul
pub fn send_to_ui(binary_message: Vec<u8>) {
if let Err(err) = BLE_MODULE_SEND.get().try_send(binary_message) {
error!("{:?}", err);
log::error!("{:?}", err);
}
}

/// Process received binary protobuf encoded RPC message
/// Process received binary protobuf encoded SYS message
///
/// This function will decode the message from the binary
/// protobuf format to a rust struct and return it
pub fn process_received_message(data: Bytes) -> Option<Ble> {
match Ble::decode(data.clone()) {
pub fn process_received_message(data: Vec<u8>) -> Option<Ble> {
match Ble::decode(&data[..]) {
Ok(ble) => Some(ble),
Err(err) => {
error!("{:#?}", err);
log::error!("{:#?}", err);
None
}
}
Expand Down
18 changes: 11 additions & 7 deletions rust/ble_module/src/rpc/msg_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ pub async fn listen_for_sys_msgs(
let evt = rpc_receiver.recv().await;
match evt {
None => {
info!("Qaul 'sys' message channel closed. Shutting down gracefully.");
log::info!("Qaul 'sys' message channel closed. Shutting down gracefully.");
break;
}
Some(msg) => {
debug!("Received 'sys' message: {:#?}", msg);
log::debug!("Received 'sys' message: {:#?}", msg);
if msg.message.is_none() {
continue;
}
Expand All @@ -38,11 +38,13 @@ pub async fn listen_for_sys_msgs(
QaulBleService::Idle(svc) => {
let qaul_id = Bytes::from(req.qaul_id);
ble_service = svc.advertise_scan_listen(qaul_id, None).await;
debug!("Set up advertisement and scan filter, entering BLE main loop.");
log::debug!(
"Set up advertisement and scan filter, entering BLE main loop."
);
send_start_successful();
}
QaulBleService::Started(_) => {
warn!(
log::warn!(
"Received Start Request, but bluetooth service is already running!"
);
send_result_already_running()
Expand All @@ -53,7 +55,9 @@ pub async fn listen_for_sys_msgs(
ble_service = svc.stop().await;
}
QaulBleService::Idle(_) => {
warn!("Received Stop Request, but bluetooth service is not running!");
log::warn!(
"Received Stop Request, but bluetooth service is not running!"
);
send_stop_successful(); // Is this really a success case?
}
},
Expand All @@ -63,14 +67,14 @@ pub async fn listen_for_sys_msgs(
Err(err) => send_direct_send_error(req.receiver_id, err.to_string()),
},
QaulBleService::Idle(_) => {
warn!("Received Direct Send Request, but bluetooth service is not running!");
log::warn!("Received Direct Send Request, but bluetooth service is not running!");
send_result_not_running()
}
},
InfoRequest(_) => {
spawn(async {
get_device_info().await.unwrap_or_else(|err| {
error!("Error getting device info: {:#?}", &err)
log::error!("Error getting device info: {:#?}", &err)
})
});
}
Expand Down