blob: 4e343b9da483d677906811b93a415277e4928eba [file] [log] [blame]
use crate::ble_composer::BlePayload;
use crate::callback::CallbackSubscription;
use crate::callback::SubscribableCallback;
use crate::result;
use crate::shared_memory::SharedMemory;
use crate::syscalls;
const DRIVER_NUMBER: usize = 0x30000;
pub const MAX_PAYLOAD_SIZE: usize = 9;
pub const BUFFER_SIZE_ADVERTISE: usize = 39;
pub const BUFFER_SIZE_SCAN: usize = 39;
mod ble_commands {
pub const START_ADVERTISING: usize = 0;
pub const ALLOW_ADVERTISMENT_BUFFER: usize = 0;
pub const BLE_PASSIVE_SCAN_SUB: usize = 0;
pub const ALLOW_SCAN_BUFFER: usize = 1;
pub const PASSIVE_SCAN: usize = 5;
}
mod gap_flags {
pub const BLE_DISCOVERABLE: usize = 0x02;
}
pub mod gap_data {
pub const COMPLETE_LIST_16BIT_SERVICE_IDS: usize = 0x03;
pub const COMPLETE_LOCAL_NAME: usize = 0x09;
pub const SET_FLAGS: usize = 1;
pub const SERVICE_DATA: usize = 0x16;
}
pub struct BleAdvertisingDriver;
impl BleAdvertisingDriver {
pub fn create_advertising_buffer() -> [u8; BUFFER_SIZE_ADVERTISE] {
[0; BUFFER_SIZE_ADVERTISE]
}
pub fn initialize<'a>(
interval: usize,
service_payload: &BlePayload,
advertising_buffer: &'a mut [u8; BUFFER_SIZE_ADVERTISE],
) -> Result<SharedMemory<'a>, isize> {
let mut shared_memory = syscalls::allow(
DRIVER_NUMBER,
ble_commands::ALLOW_ADVERTISMENT_BUFFER,
advertising_buffer,
)?;
shared_memory.write_bytes(&service_payload.bytes);
Self::start_advertising(gap_flags::BLE_DISCOVERABLE, interval)?;
Ok(shared_memory)
}
fn start_advertising(pdu_type: usize, interval: usize) -> Result<(), isize> {
let result = unsafe {
syscalls::command(
DRIVER_NUMBER,
ble_commands::START_ADVERTISING,
pdu_type,
interval,
)
};
convert_result(result)
}
}
pub struct BleCallback<CB> {
callback: CB,
}
impl<CB> BleCallback<CB> {
pub fn new(callback: CB) -> Self {
BleCallback { callback }
}
}
impl<CB: FnMut(usize, usize)> SubscribableCallback for BleCallback<CB> {
fn call_rust(&mut self, arg0: usize, arg1: usize, _: usize) {
(self.callback)(arg0, arg1);
}
}
pub struct BleDriver;
impl BleDriver {
pub fn create_scan_buffer() -> [u8; BUFFER_SIZE_SCAN] {
[0; BUFFER_SIZE_SCAN]
}
pub fn share_memory(scan_buffer: &mut [u8; BUFFER_SIZE_SCAN]) -> Result<SharedMemory, isize> {
syscalls::allow(DRIVER_NUMBER, ble_commands::ALLOW_SCAN_BUFFER, scan_buffer)
}
pub fn start<CB>(callback: &mut BleCallback<CB>) -> Result<CallbackSubscription, isize>
where
BleCallback<CB>: SubscribableCallback,
{
let subscription =
syscalls::subscribe(DRIVER_NUMBER, ble_commands::BLE_PASSIVE_SCAN_SUB, callback)?;
let result = unsafe { syscalls::command(DRIVER_NUMBER, ble_commands::PASSIVE_SCAN, 1, 0) };
convert_result(result)?;
Ok(subscription)
}
}
fn convert_result(code: isize) -> Result<(), isize> {
match code {
result::SUCCESS => Ok(()),
code => Err(code),
}
}