Add handle for allowed buffers.
diff --git a/src/simple_ble.rs b/src/simple_ble.rs
index 573d585..c7e1026 100644
--- a/src/simple_ble.rs
+++ b/src/simple_ble.rs
@@ -2,6 +2,11 @@
use alloc::Vec;
use callback::CallbackSubscription;
use callback::SubscribableCallback;
+use result;
+use result::TockResult;
+use result::TockValue;
+use shared_memory::ShareableMemory;
+use shared_memory::SharedMemory;
use syscalls;
const DRIVER_NUMBER: usize = 0x30000;
@@ -32,45 +37,32 @@
pub const SERVICE_DATA: usize = 0x16;
}
-#[allow(dead_code)]
-pub struct BleDeviceUninitialized<'a> {
- interval: u16,
- name: String,
- uuid: Vec<u16>,
- flags: Vec<u8>,
- buffer: [u8; BUFFER_SIZE],
- service_payload: &'a mut Vec<u8>,
+pub struct AdvertisingBuffer {
+ shared_memory: [u8; BUFFER_SIZE],
}
-#[allow(dead_code)]
-pub struct BleDeviceInitialized<'a> {
- interval: &'a mut u16,
- name: &'a mut String,
- uuid: &'a mut Vec<u16>,
- flags: &'a mut Vec<u8>,
- buffer: &'a mut [u8; 39],
- service_payload: &'a mut Vec<u8>,
+impl<'a> ShareableMemory for AdvertisingBuffer {
+ fn driver_number(&self) -> usize {
+ DRIVER_NUMBER
+ }
+ fn allow_number(&self) -> usize {
+ ble_commands::ALLOW_ADVERTISMENT_BUFFER
+ }
+ fn to_bytes(&mut self) -> &mut [u8] {
+ &mut self.shared_memory
+ }
}
-#[allow(dead_code)]
-pub struct BleDeviceAdvertising<'a> {
- interval: &'a mut u16,
- name: &'a mut String,
- uuid: &'a mut Vec<u16>,
- flags: &'a mut Vec<u8>,
- buffer: &'a mut [u8; 39],
- service_payload: &'a mut Vec<u8>,
-}
+pub struct BleAdvertisingDriver;
-#[allow(dead_code)]
-impl<'a> BleDeviceUninitialized<'a> {
- pub fn new(
+impl BleAdvertisingDriver {
+ pub fn initialize(
interval: u16,
name: String,
uuid: Vec<u16>,
stay_visible: bool,
- service_payload: &'a mut Vec<u8>,
- ) -> BleDeviceUninitialized {
+ service_payload: Vec<u8>,
+ ) -> TockResult<SharedMemory<AdvertisingBuffer>, isize> {
let flags: [u8; 1] = [
gap_flags::ONLY_LE | (if stay_visible {
gap_flags::BLE_DISCOVERABLE
@@ -78,127 +70,77 @@
gap_flags::BLE_NOT_DISCOVERABLE
}),
];
-
- BleDeviceUninitialized {
- interval: interval,
- name: name,
- uuid: uuid,
- flags: flags.to_vec(),
- buffer: [0; 39],
- service_payload: service_payload,
- }
- }
- pub fn initialize(&'a mut self) -> Result<BleDeviceInitialized<'a>, &'static str> {
- Ok(self)
- .and_then(|ble| ble.set_advertising_buffer())
- .and_then(|ble| ble.request_address())
- .and_then(|ble| ble.set_advertising_interval())
- .and_then(|ble| ble.set_advertising_flags())
- .and_then(|ble| ble.set_advertising_name())
- .and_then(|ble| ble.set_advertsing_uuid())
- .and_then(|ble| ble.set_service_payload())
- .and_then(|ble| {
- Ok(BleDeviceInitialized {
- interval: &mut ble.interval,
- name: &mut ble.name,
- uuid: &mut ble.uuid,
- flags: &mut ble.flags,
- buffer: &mut ble.buffer,
- service_payload: &mut ble.service_payload,
- })
- })
+ let buffer = AdvertisingBuffer {
+ shared_memory: [0; BUFFER_SIZE],
+ };
+ let (_, shared_memory) = syscalls::allow_new(buffer);
+ Self::set_advertising_interval(interval)?;
+ Self::request_adv_address()?;
+ Self::set_local_name(name)?;
+ Self::set_uuid(uuid)?;
+ Self::set_flags(flags)?;
+ Self::set_service_payload(service_payload)?;
+ Self::start_advertising()?;
+ Ok(shared_memory)
}
- fn set_advertising_interval(&mut self) -> Result<&mut Self, &'static str> {
- match unsafe {
+ // TODO: Write generic error converter
+
+ fn set_advertising_interval(interval: u16) -> TockResult<(), isize> {
+ let result = unsafe {
syscalls::command(
DRIVER_NUMBER,
ble_commands::SET_ADVERTISING_INTERVAL,
- self.interval as usize,
+ interval as usize,
0,
)
- } {
- 0 => Ok(self),
- _ => Err(""),
- }
+ };
+ convert_result(result)
}
- fn request_address(&mut self) -> Result<&mut Self, &'static str> {
- match unsafe { syscalls::command(DRIVER_NUMBER, ble_commands::REQ_ADV_ADDRESS, 0, 0) } {
- 0 => Ok(self),
- _ => Err(""),
- }
+ fn request_adv_address() -> TockResult<(), isize> {
+ let result =
+ unsafe { syscalls::command(DRIVER_NUMBER, ble_commands::REQ_ADV_ADDRESS, 0, 0) };
+ convert_result(result)
}
- fn set_advertising_name(&mut self) -> Result<&mut Self, &'static str> {
- match unsafe {
+ fn set_local_name(name: String) -> TockResult<(), isize> {
+ let result = unsafe {
syscalls::allow(
DRIVER_NUMBER,
gap_data::COMPLETE_LOCAL_NAME,
- self.name.as_bytes(),
+ name.as_bytes(),
)
- } {
- 0 => Ok(self),
- _ => Err(""),
- }
+ };
+ convert_result(result)
}
- fn set_advertsing_uuid(&mut self) -> Result<&mut Self, &'static str> {
- match unsafe {
+ fn set_uuid(uuid: Vec<u16>) -> TockResult<(), isize> {
+ let result = unsafe {
syscalls::allow16(
DRIVER_NUMBER,
gap_data::COMPLETE_LIST_16BIT_SERVICE_IDS,
- &self.uuid,
+ &uuid.to_vec(),
)
- } {
- 0 => Ok(self),
- _ => Err(""),
- }
+ };
+ convert_result(result)
}
- fn set_advertising_flags(&mut self) -> Result<&mut Self, &'static str> {
- match unsafe { syscalls::allow(DRIVER_NUMBER, gap_data::SET_FLAGS, &self.flags) } {
- 0 => Ok(self),
- _ => Err(""),
- }
+ fn set_flags(flags: [u8; 1]) -> TockResult<(), isize> {
+ let result = unsafe { syscalls::allow(DRIVER_NUMBER, gap_data::SET_FLAGS, &flags) };
+ convert_result(result)
}
- fn set_advertising_buffer(&mut self) -> Result<&mut Self, &'static str> {
- match unsafe {
- syscalls::allow(
- DRIVER_NUMBER,
- ble_commands::ALLOW_ADVERTISMENT_BUFFER,
- &self.buffer,
- )
- } {
- 0 => Ok(self),
- _ => Err(""),
- }
+ fn set_service_payload(service_payload: Vec<u8>) -> TockResult<(), isize> {
+ let result =
+ unsafe { syscalls::allow(DRIVER_NUMBER, gap_data::SERVICE_DATA, &service_payload) };
+ convert_result(result)
}
- fn set_service_payload(&mut self) -> Result<&mut Self, &'static str> {
- match unsafe {
- syscalls::allow(DRIVER_NUMBER, gap_data::SERVICE_DATA, self.service_payload)
- } {
- 0 => Ok(self),
- _ => Err(""),
- }
- }
-}
-
-impl<'a> BleDeviceInitialized<'a> {
- pub fn start_advertising(&mut self) -> Result<BleDeviceAdvertising, &'static str> {
- match unsafe { syscalls::command(DRIVER_NUMBER, ble_commands::START_ADVERTISING, 0, 0) } {
- 0 => Ok(BleDeviceAdvertising {
- interval: &mut self.interval,
- name: &mut self.name,
- uuid: &mut self.uuid,
- flags: &mut self.flags,
- buffer: &mut self.buffer,
- service_payload: &mut self.service_payload,
- }),
- _ => Err(""),
- }
+ fn start_advertising() -> TockResult<(), isize> {
+ let result =
+ unsafe { syscalls::command(DRIVER_NUMBER, ble_commands::START_ADVERTISING, 0, 0) };
+ convert_result(result)
}
}
@@ -220,18 +162,50 @@
}
}
+pub struct ScanBuffer {
+ shared_memory: [u8; BUFFER_SIZE_SCAN],
+}
+
+impl<'a> ShareableMemory for ScanBuffer {
+ fn driver_number(&self) -> usize {
+ DRIVER_NUMBER
+ }
+ fn allow_number(&self) -> usize {
+ ble_commands::ALLOW_SCAN_BUFFER
+ }
+ fn to_bytes(&mut self) -> &mut [u8] {
+ &mut self.shared_memory
+ }
+}
+
pub struct BleDriver;
impl BleDriver {
+ pub fn share_memory() -> TockResult<SharedMemory<ScanBuffer>, isize> {
+ let (result, shared_memory) = syscalls::allow_new(ScanBuffer {
+ shared_memory: [0; BUFFER_SIZE_SCAN],
+ });
+ convert_result(result)?;
+ Ok(shared_memory)
+ }
+
pub fn start<CB: FnMut(usize, usize)>(
- buffer: &[u8; BUFFER_SIZE_SCAN],
callback: CB,
- ) -> Result<CallbackSubscription<BleCallback<CB>>, ()> {
- let (_, subscription) = syscalls::subscribe_new(BleCallback { callback });
- unsafe {
- syscalls::allow(DRIVER_NUMBER, ble_commands::ALLOW_SCAN_BUFFER, buffer);
- syscalls::command(DRIVER_NUMBER, ble_commands::PASSIVE_SCAN, 1, 0);
- }
+ ) -> TockResult<CallbackSubscription<BleCallback<CB>>, isize> {
+ let (result, subscription) = syscalls::subscribe_new(BleCallback { callback });
+ convert_result(result)?;
+
+ let result = unsafe { syscalls::command(DRIVER_NUMBER, ble_commands::PASSIVE_SCAN, 1, 0) };
+ convert_result(result)?;
Ok(subscription)
}
}
+
+fn convert_result(code: isize) -> TockResult<(), isize> {
+ match code {
+ result::SUCCESS => Ok(()),
+ result::ESIZE => Err(TockValue::Expected(result::ESIZE)),
+ result::EINVAL => Err(TockValue::Expected(result::EINVAL)),
+ _ => Err(TockValue::Unexpected(code)),
+ }
+}