blob: 6db4114fc0f05f418ee15fd5bcb78b8fad9c7f52 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
fidl_fuchsia_bluetooth_gatt::{
self as fidl_gatt,
Characteristic as FidlCharacteristic, ServiceInfo,
},
fuchsia_bluetooth::assigned_numbers::{
find_characteristic_number,
find_descriptor_number,
find_service_uuid,
},
std::fmt,
};
// TODO(armansito): Make these objects stateful so that GATT operations can be performed through
// them. Later, move these into a public bluetooth crate as a developer API.
/// Service
pub struct Service {
pub info: ServiceInfo,
// The characteristics of this service. None, if not yet discovered.
characteristics: Option<Vec<Characteristic>>,
}
impl Service {
pub fn new(info: ServiceInfo) -> Service {
Service {
info: info,
characteristics: None,
}
}
pub fn set_characteristics(&mut self, chrcs: Vec<FidlCharacteristic>) {
self.characteristics = Some(chrcs.into_iter().map(|info| Characteristic(info)).collect());
}
}
impl fmt::Display for Service {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let type_pretty = find_service_uuid(&self.info.type_)
.map(|an| an.name)
.unwrap_or(&self.info.type_);
write!(
f,
"[service: id: {}, primary: {}, type: {}]",
self.info.id, self.info.primary, type_pretty
)?;
if let Some(ref chrcs) = self.characteristics {
let mut i: i32 = 0;
for ref chrc in chrcs {
write!(f, "\n {}: {}", i, chrc)?;
i += 1;
}
}
Ok(())
}
}
struct Characteristic(FidlCharacteristic);
impl fmt::Display for Characteristic {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let type_pretty = find_characteristic_number(&self.0.type_)
.map(|an| an.name)
.unwrap_or(&self.0.type_);
write!(
f,
"[chara.: id: {}, type: {}, prop.: {}]",
self.0.id,
type_pretty,
props_to_string(self.0.properties)
)?;
if let Some(ref descrs) = self.0.descriptors {
let mut i: i32 = 0;
for ref descr in descrs {
let type_pretty = find_descriptor_number(&descr.type_)
.map(|an| an.name)
.unwrap_or(&descr.type_);
write!(
f,
"\n {}: [descr.: id: {}, type: {}]",
i, descr.id, type_pretty
)?;
i += 1;
}
}
Ok(())
}
}
fn props_to_string(props: u32) -> String {
let mut prop_strs = vec![];
if props & fidl_gatt::PROPERTY_BROADCAST != 0 {
prop_strs.push("broadcast");
}
if props & fidl_gatt::PROPERTY_READ != 0 {
prop_strs.push("read");
}
if props & fidl_gatt::PROPERTY_WRITE_WITHOUT_RESPONSE != 0 {
prop_strs.push("write (without response)");
}
if props & fidl_gatt::PROPERTY_WRITE != 0 {
prop_strs.push("write");
}
if props & fidl_gatt::PROPERTY_NOTIFY != 0 {
prop_strs.push("notify");
}
if props & fidl_gatt::PROPERTY_INDICATE != 0 {
prop_strs.push("indicate");
}
if props & fidl_gatt::PROPERTY_AUTHENTICATED_SIGNED_WRITES != 0 {
prop_strs.push("write (signed)");
}
if props & fidl_gatt::PROPERTY_RELIABLE_WRITE != 0 {
prop_strs.push("write (reliable)");
}
if props & fidl_gatt::PROPERTY_WRITABLE_AUXILIARIES != 0 {
prop_strs.push("writable aux.");
}
prop_strs.join(", ")
}