mod handle;
mod pdus;
mod server;
mod uuid;
use self::{handle::*, pdus::*};
use crate::{l2cap::Sender, Error};
pub use self::handle::{Handle, HandleRange};
pub use self::server::{AttributeServer, AttributeServerTx};
pub use self::uuid::AttUuid;
pub struct Attribute<T>
where
T: ?Sized,
{
pub att_type: AttUuid,
pub handle: Handle,
pub value: T,
}
impl<T: AsRef<[u8]>> Attribute<T> {
pub fn new(att_type: AttUuid, handle: Handle, value: T) -> Self {
assert_ne!(handle, Handle::NULL);
Attribute {
att_type,
handle,
value,
}
}
pub fn value(&self) -> &[u8] {
self.value.as_ref()
}
pub fn set_value(&mut self, value: T) {
self.value = value;
}
}
pub enum AttributeAccessPermissions {
Readable,
Writeable,
ReadableAndWriteable,
}
impl AttributeAccessPermissions {
fn is_readable(&self) -> bool {
match self {
AttributeAccessPermissions::Readable
| AttributeAccessPermissions::ReadableAndWriteable => true,
AttributeAccessPermissions::Writeable => false,
}
}
fn is_writeable(&self) -> bool {
match self {
AttributeAccessPermissions::Writeable
| AttributeAccessPermissions::ReadableAndWriteable => true,
AttributeAccessPermissions::Readable => false,
}
}
}
impl Default for AttributeAccessPermissions {
fn default() -> Self {
AttributeAccessPermissions::Readable
}
}
pub trait AttributeProvider {
fn for_attrs_in_range(
&mut self,
range: HandleRange,
f: impl FnMut(&Self, &Attribute<dyn AsRef<[u8]>>) -> Result<(), Error>,
) -> Result<(), Error>;
fn is_grouping_attr(&self, uuid: AttUuid) -> bool;
fn group_end(&self, handle: Handle) -> Option<&Attribute<dyn AsRef<[u8]>>>;
fn attr_access_permissions(&self, _handle: Handle) -> AttributeAccessPermissions {
AttributeAccessPermissions::Readable
}
fn write_attr(&mut self, _handle: Handle, _data: &[u8]) -> Result<(), Error> {
unimplemented!("by default, no attributes should have write access permissions, and this should never be called");
}
fn read_attr_dynamic(&mut self, _handle: Handle, _buffer: &mut [u8]) -> Option<usize> {
None
}
fn prepare_write_attr(
&mut self,
_handle: Handle,
_offset: u16,
_data: &[u8],
) -> Result<(), Error> {
unimplemented!("you need to implement prepare_write_attr to make queued writes work")
}
fn execute_write_attr(&mut self, _flags: u8) -> Result<(), Error> {
unimplemented!("you need to implement execute_write_attr to make queued writes work")
}
fn find_information(
&mut self,
_range: HandleRange,
_responder: &mut Sender<'_>,
) -> Result<(), Error> {
unimplemented!("you need to implement find_information to make things like Client Characteristic Configuration work")
}
}
pub struct NoAttributes;
impl AttributeProvider for NoAttributes {
fn for_attrs_in_range(
&mut self,
_range: HandleRange,
_f: impl FnMut(&Self, &Attribute<dyn AsRef<[u8]>>) -> Result<(), Error>,
) -> Result<(), Error> {
Ok(())
}
fn is_grouping_attr(&self, _uuid: AttUuid) -> bool {
false
}
fn group_end(&self, _handle: Handle) -> Option<&Attribute<dyn AsRef<[u8]>>> {
None
}
}