[bt] [sl4f] Parse serde JSON GATT DB descriptors
This CL focuses on parsing the third part of
the input GATT databass, GATT Descriptors.
BT-677
Test: act.py -c <config> -tc FuchsiaCmdLineTest
Change-Id: I92e3fe29125256419210f5fbc2b97200263b0a3e
diff --git a/garnet/bin/sl4f/src/bluetooth/gatt_server_facade.rs b/garnet/bin/sl4f/src/bluetooth/gatt_server_facade.rs
index 3793542..fd72b66 100644
--- a/garnet/bin/sl4f/src/bluetooth/gatt_server_facade.rs
+++ b/garnet/bin/sl4f/src/bluetooth/gatt_server_facade.rs
@@ -221,18 +221,65 @@
}
}
- pub fn generate_descriptors(&self, descriptor_list_json: &Value) -> Vec<Descriptor> {
- // TODO: Parse characteristic_json_list to create Characteristics.
- fx_log_info!(
- tag: &dtag!(),
- "Generating descriptors from json input {:?}",
- descriptor_list_json
- );
- let descriptors: Vec<Descriptor> = Vec::new();
+ pub fn generate_descriptors(
+ &self, descriptor_list_json: &Value,
+ ) -> Result<Vec<Descriptor>, Error> {
+ let mut descriptors: Vec<Descriptor> = Vec::new();
+ // Fuchsia will automatically setup these descriptors and manage them.
+ // Skip setting them up if found in the input descriptor list.
+ let banned_descriptor_uuids = [
+ "00002900-0000-1000-8000-00805f9b34fb".to_string(), // CCC Descriptor
+ "00002902-0000-1000-8000-00805f9b34fb".to_string(), // Client Configuration Descriptor
+ "00002903-0000-1000-8000-00805f9b34fb".to_string(), // Server Configuration Descriptor
+ ];
+
if descriptor_list_json.is_null() {
- ()
+ return Ok(descriptors);
}
- descriptors
+
+ let descriptor_list = match descriptor_list_json.as_array() {
+ Some(d) => d,
+ None => bail!("Attribute 'descriptors' is not a parseable list."),
+ };
+
+ for descriptor in descriptor_list.into_iter() {
+ let descriptor_uuid = match descriptor["uuid"].as_str() {
+ Some(uuid) => uuid.to_string(),
+ None => bail!("Descriptor uuid was unable to cast to str."),
+ };
+ let descriptor_value = self.parse_attribute_value_to_byte_array(&descriptor["value"]);
+
+ // No properties for descriptors.
+ let properties = 0u32;
+
+ if banned_descriptor_uuids.contains(&descriptor_uuid) {
+ continue;
+ }
+
+ let raw_descriptor_permissions = match descriptor["permissions"].as_u64() {
+ Some(permissions) => permissions as u32,
+ None => bail!("Descriptor permissions was unable to cast to u64."),
+ };
+
+ let desc_permission_attributes = self.permissions_and_properties_from_raw_num(
+ raw_descriptor_permissions,
+ properties,
+ );
+
+ let descriptor_id = self.inner.write().generic_id_counter.next();
+ self.inner
+ .write()
+ .attribute_value_mapping
+ .insert(descriptor_id, descriptor_value);
+ let descriptor_obj = Descriptor {
+ id: descriptor_id,
+ type_: descriptor_uuid.clone(),
+ permissions: Some(Box::new(desc_permission_attributes)),
+ };
+
+ descriptors.push(descriptor_obj);
+ }
+ Ok(descriptors)
}
pub fn generate_characteristics(
@@ -245,7 +292,7 @@
let characteristic_list = match characteristic_list_json.as_array() {
Some(c) => c,
- None => bail!("Attribute 'characteristic' is not a parseable list."),
+ None => bail!("Attribute 'characteristics' is not a parseable list."),
};
for characteristic in characteristic_list.into_iter() {
@@ -267,7 +314,7 @@
let characteristic_value =
self.parse_attribute_value_to_byte_array(&characteristic["value"]);
let descriptor_list = &characteristic["descriptors"];
- let descriptors = self.generate_descriptors(descriptor_list);
+ let descriptors = self.generate_descriptors(descriptor_list)?;
let characteristic_permissions = self.permissions_and_properties_from_raw_num(
raw_characteristic_permissions,