1use anyhow::{format_err, Error};
6use fidl::prelude::*;
7use fidl_fuchsia_bluetooth_gatt2::{
8 self as gatt, AttributePermissions, Characteristic, CharacteristicPropertyBits, Descriptor,
9 Handle, LocalServiceControlHandle, LocalServiceMarker, LocalServiceReadValueResponder,
10 LocalServiceRequest, LocalServiceRequestStream, LocalServiceWriteValueResponder,
11 SecurityRequirements, Server_Marker, Server_Proxy, ServiceHandle, ServiceInfo, ServiceKind,
12 ValueChangedParameters,
13};
14use fuchsia_bluetooth::types::{PeerId, Uuid};
15use fuchsia_sync::RwLock;
16use futures::stream::TryStreamExt;
17use log::{error, info, warn};
18use serde_json::value::Value;
19use std::collections::HashMap;
20use std::str::FromStr;
21use {fuchsia_async as fasync, fuchsia_component as app};
22
23use crate::bluetooth::constants::{
24 CHARACTERISTIC_EXTENDED_PROPERTIES_UUID, GATT_MAX_ATTRIBUTE_VALUE_LENGTH,
25 PERMISSION_READ_ENCRYPTED, PERMISSION_READ_ENCRYPTED_MITM, PERMISSION_WRITE_ENCRYPTED,
26 PERMISSION_WRITE_ENCRYPTED_MITM, PERMISSION_WRITE_SIGNED, PERMISSION_WRITE_SIGNED_MITM,
27 PROPERTY_INDICATE, PROPERTY_NOTIFY, PROPERTY_READ, PROPERTY_WRITE,
28};
29
30#[derive(Debug)]
31struct Counter {
32 count: u64,
33}
34
35impl Counter {
36 pub fn new() -> Counter {
37 Counter { count: 0 }
38 }
39
40 fn next(&mut self) -> u64 {
41 let id: u64 = self.count;
42 self.count += 1;
43 id
44 }
45}
46
47#[derive(Debug)]
48struct InnerGattServerFacade {
49 attribute_value_mapping: HashMap<u64, (Vec<u8>, bool)>,
55
56 generic_id_counter: Counter,
58
59 server_proxy: Option<Server_Proxy>,
61
62 service_tasks: Vec<fasync::Task<()>>,
64}
65
66#[derive(Debug)]
71pub struct GattServerFacade {
72 inner: RwLock<InnerGattServerFacade>,
73}
74
75impl GattServerFacade {
76 pub fn new() -> GattServerFacade {
77 GattServerFacade {
78 inner: RwLock::new(InnerGattServerFacade {
79 attribute_value_mapping: HashMap::new(),
80 generic_id_counter: Counter::new(),
81 server_proxy: None,
82 service_tasks: vec![],
83 }),
84 }
85 }
86
87 fn create_server_proxy(&self) -> Result<Server_Proxy, Error> {
88 let tag = "GattServerFacade::create_server_proxy:";
89 match self.inner.read().server_proxy.clone() {
90 Some(service) => {
91 info!(
92 tag = &[tag, &line!().to_string()].join("").as_str();
93 "Current service proxy: {:?}", service
94 );
95 Ok(service)
96 }
97 None => {
98 info!(
99 tag = &[tag, &line!().to_string()].join("").as_str();
100 "Setting new server proxy"
101 );
102 let service = app::client::connect_to_protocol::<Server_Marker>();
103 if let Err(err) = service {
104 error!(
105 tag = &[tag, &line!().to_string()].join("").as_str(),
106 err:?;
107 "Failed to create server proxy"
108 );
109 return Err(format_err!("Failed to create server proxy: {:?}", err));
110 }
111 service
112 }
113 }
114 }
115
116 fn parse_attribute_value_to_byte_array(&self, value_to_parse: &Value) -> Vec<u8> {
119 match value_to_parse {
120 Value::String(obj) => String::from(obj.as_str()).into_bytes(),
121 Value::Number(obj) => match obj.as_u64() {
122 Some(num) => vec![num as u8],
123 None => vec![],
124 },
125 Value::Array(obj) => {
126 obj.into_iter().filter_map(|v| v.as_u64()).map(|v| v as u8).collect()
127 }
128 _ => vec![],
129 }
130 }
131
132 fn on_characteristic_configuration(
133 peer_id: PeerId,
134 handle: Handle,
135 notify: bool,
136 indicate: bool,
137 control_handle: &LocalServiceControlHandle,
138 ) {
139 let tag = "GattServerFacade::on_characteristic_configuration:";
140 info!(
141 tag = &[tag, &line!().to_string()].join("").as_str(),
142 notify:%,
143 indicate:%,
144 id:% = peer_id;
145 "OnCharacteristicConfiguration"
146 );
147
148 if indicate {
149 let value = ValueChangedParameters {
150 handle: Some(handle),
151 value: Some(vec![0x02, 0x00]),
152 peer_ids: Some(vec![peer_id.into()]),
153 ..Default::default()
154 };
155 let (confirmation, _) = fidl::EventPair::create();
157 let _ = control_handle.send_on_indicate_value(&value, confirmation);
158 } else if notify {
159 let value = ValueChangedParameters {
160 handle: Some(handle),
161 value: Some(vec![0x01, 0x00]),
162 peer_ids: Some(vec![peer_id.into()]),
163 ..Default::default()
164 };
165 let _ = control_handle.send_on_notify_value(&value);
166 }
167 }
168
169 fn on_read_value(
170 peer_id: PeerId,
171 handle: Handle,
172 offset: i32,
173 responder: LocalServiceReadValueResponder,
174 value_in_mapping: Option<&(Vec<u8>, bool)>,
175 ) {
176 let tag = "GattServerFacade::on_read_value:";
177 info!(
178 tag = &[tag, &line!().to_string()].join("").as_str(),
179 at_id:? = handle.value,
180 offset:? = offset,
181 id:% = peer_id;
182 "OnReadValue request",
183 );
184 match value_in_mapping {
185 Some(v) => {
186 let (value, _enforce_initial_attribute_length) = v;
187 if value.len() < offset as usize {
188 let _result = responder.send(Err(gatt::Error::InvalidOffset));
189 } else {
190 let _result = responder.send(Ok(&value[offset as usize..]));
191 }
192 }
193 None => {
194 let _result = responder.send(Err(gatt::Error::ReadNotPermitted));
196 }
197 };
198 }
199
200 fn write_and_extend(value: &mut Vec<u8>, value_to_write: Vec<u8>, offset: usize) {
201 let split_idx = (value.len() - offset).min(value_to_write.len());
202 let (overlapping, extending) = value_to_write.split_at(split_idx);
203 let end_of_overlap = offset + overlapping.len();
204 value.splice(offset..end_of_overlap, overlapping.iter().cloned());
205 value.extend_from_slice(extending);
206 }
207
208 fn on_write_value(
209 peer_id: PeerId,
210 handle: Handle,
211 offset: u32,
212 value_to_write: Vec<u8>,
213 responder: LocalServiceWriteValueResponder,
214 value_in_mapping: Option<&mut (Vec<u8>, bool)>,
215 ) {
216 let tag = "GattServerFacade::on_write_value:";
217 info!(
218 tag = &[tag, &line!().to_string()].join("").as_str(),
219 at_id = handle.value,
220 offset = offset,
221 value:? = value_to_write,
222 id:% = peer_id;
223 "OnWriteValue request",
224 );
225
226 match value_in_mapping {
227 Some(v) => {
228 let (value, enforce_initial_attribute_length) = v;
229 let max_attribute_size: usize = match enforce_initial_attribute_length {
230 true => value.len(),
231 false => GATT_MAX_ATTRIBUTE_VALUE_LENGTH,
232 };
233 if max_attribute_size < (value_to_write.len() + offset as usize) {
234 let _result = responder.send(Err(gatt::Error::InvalidAttributeValueLength));
235 } else if value.len() < offset as usize {
236 let _result = responder.send(Err(gatt::Error::InvalidOffset));
237 } else {
238 GattServerFacade::write_and_extend(value, value_to_write, offset as usize);
239 let _result = responder.send(Ok(()));
240 }
241 }
242 None => {
243 let _result = responder.send(Err(gatt::Error::WriteNotPermitted));
245 }
246 }
247 }
248
249 async fn monitor_service_request_stream(
250 stream: LocalServiceRequestStream,
251 control_handle: LocalServiceControlHandle,
252 mut attribute_value_mapping: HashMap<u64, (Vec<u8>, bool)>,
253 ) -> Result<(), Error> {
254 stream
255 .map_ok(move |request| match request {
256 LocalServiceRequest::CharacteristicConfiguration {
257 peer_id,
258 handle,
259 notify,
260 indicate,
261 responder,
262 } => {
263 GattServerFacade::on_characteristic_configuration(
264 peer_id.into(),
265 handle,
266 notify,
267 indicate,
268 &control_handle,
269 );
270 let _ = responder.send();
271 }
272 LocalServiceRequest::ReadValue { peer_id, handle, offset, responder } => {
273 GattServerFacade::on_read_value(
274 peer_id.into(),
275 handle,
276 offset,
277 responder,
278 attribute_value_mapping.get(&handle.value),
279 );
280 }
281 LocalServiceRequest::WriteValue { payload, responder } => {
282 GattServerFacade::on_write_value(
283 payload.peer_id.unwrap().into(),
284 payload.handle.unwrap(),
285 payload.offset.unwrap(),
286 payload.value.unwrap(),
287 responder,
288 attribute_value_mapping.get_mut(&payload.handle.unwrap().value),
289 );
290 }
291 LocalServiceRequest::PeerUpdate { payload: _, responder } => {
292 responder.drop_without_shutdown();
293 }
294 LocalServiceRequest::ValueChangedCredit { .. } => {}
295 })
296 .try_collect::<()>()
297 .await
298 .map_err(|e| e.into())
299 }
300
301 fn permissions_and_properties_from_raw_num(
323 &self,
324 permissions: u32,
325 properties: u32,
326 ) -> AttributePermissions {
327 let mut read_encryption_required = false;
328 let mut read_authentication_required = false;
329 let mut read_authorization_required = false;
330
331 let mut write_encryption_required = false;
332 let mut write_authentication_required = false;
333 let mut write_authorization_required = false;
334
335 let mut update_encryption_required = false;
336 let mut update_authentication_required = false;
337 let mut update_authorization_required = false;
338
339 if permissions & PERMISSION_READ_ENCRYPTED != 0 {
340 read_encryption_required = true;
341 read_authentication_required = true;
342 read_authorization_required = true;
343 }
344
345 if permissions & PERMISSION_READ_ENCRYPTED_MITM != 0 {
346 read_encryption_required = true;
347 update_encryption_required = true;
348 }
349
350 if permissions & PERMISSION_WRITE_ENCRYPTED != 0 {
351 write_encryption_required = true;
352 update_encryption_required = true;
353 }
354
355 if permissions & PERMISSION_WRITE_ENCRYPTED_MITM != 0 {
356 write_encryption_required = true;
357 update_encryption_required = true;
358 update_authentication_required = true;
359 update_authorization_required = true;
360 }
361
362 if permissions & PERMISSION_WRITE_SIGNED != 0 {
363 write_authorization_required = true;
364 }
365
366 if permissions & PERMISSION_WRITE_SIGNED_MITM != 0 {
367 write_encryption_required = true;
368 write_authentication_required = true;
369 write_authorization_required = true;
370 update_encryption_required = true;
371 update_authentication_required = true;
372 update_authorization_required = true;
373 }
374
375 let update_sec_requirement = if properties & (PROPERTY_NOTIFY | PROPERTY_INDICATE) != 0 {
378 Some(SecurityRequirements {
379 encryption_required: Some(update_encryption_required),
380 authentication_required: Some(update_authentication_required),
381 authorization_required: Some(update_authorization_required),
382 ..Default::default()
383 })
384 } else {
385 None
386 };
387
388 let read_sec_requirement = if properties & PROPERTY_READ != 0 {
389 Some(SecurityRequirements {
390 encryption_required: Some(read_encryption_required),
391 authentication_required: Some(read_authentication_required),
392 authorization_required: Some(read_authorization_required),
393 ..Default::default()
394 })
395 } else {
396 None
397 };
398
399 let write_sec_requirement = if properties & PROPERTY_WRITE != 0 {
400 Some(SecurityRequirements {
401 encryption_required: Some(write_encryption_required),
402 authentication_required: Some(write_authentication_required),
403 authorization_required: Some(write_authorization_required),
404 ..Default::default()
405 })
406 } else {
407 None
408 };
409
410 AttributePermissions {
411 read: read_sec_requirement,
412 write: write_sec_requirement,
413 update: update_sec_requirement,
414 ..Default::default()
415 }
416 }
417
418 fn process_descriptors(
424 &self,
425 descriptor_list_json: &Value,
426 ) -> Result<(Vec<Descriptor>, CharacteristicPropertyBits), Error> {
427 let mut descriptors: Vec<Descriptor> = Vec::new();
428 let banned_descriptor_uuids = [
431 Uuid::from_str("00002900-0000-1000-8000-00805f9b34fb").unwrap(), Uuid::from_str("00002902-0000-1000-8000-00805f9b34fb").unwrap(), Uuid::from_str("00002903-0000-1000-8000-00805f9b34fb").unwrap(), ];
435
436 if descriptor_list_json.is_null() {
437 return Ok((descriptors, CharacteristicPropertyBits::empty()));
438 }
439
440 let descriptor_list = descriptor_list_json
441 .as_array()
442 .ok_or_else(|| format_err!("Attribute 'descriptors' is not a parseable list."))?;
443
444 let mut ext_property_bits = CharacteristicPropertyBits::empty();
445
446 for descriptor in descriptor_list.into_iter() {
447 let descriptor_uuid: Uuid = match descriptor["uuid"].as_str() {
448 Some(uuid_str) => Uuid::from_str(uuid_str)
449 .map_err(|_| format_err!("Descriptor uuid is invalid"))?,
450 None => return Err(format_err!("Descriptor uuid was unable to cast to str.")),
451 };
452 let descriptor_value = self.parse_attribute_value_to_byte_array(&descriptor["value"]);
453
454 if descriptor_uuid == Uuid::new16(CHARACTERISTIC_EXTENDED_PROPERTIES_UUID) {
456 if descriptor_value.is_empty() {
457 warn!("Extended properties descriptor has empty value. Ignoring.");
458 continue;
459 }
460 let ext_bits_raw: u16 = (descriptor_value[0] as u16) << u8::BITS;
462 ext_property_bits = CharacteristicPropertyBits::from_bits_truncate(ext_bits_raw);
463 continue;
464 }
465
466 let raw_enforce_enforce_initial_attribute_length =
467 descriptor["enforce_initial_attribute_length"].as_bool().unwrap_or(false);
468
469 let properties = 0u32;
471
472 if banned_descriptor_uuids.contains(&descriptor_uuid) {
473 continue;
474 }
475
476 let raw_descriptor_permissions = match descriptor["permissions"].as_u64() {
477 Some(permissions) => permissions as u32,
478 None => {
479 return Err(format_err!("Descriptor permissions was unable to cast to u64."))
480 }
481 };
482
483 let desc_permission_attributes = self
484 .permissions_and_properties_from_raw_num(raw_descriptor_permissions, properties);
485
486 let descriptor_id = self.inner.write().generic_id_counter.next();
487 self.inner.write().attribute_value_mapping.insert(
488 descriptor_id,
489 (descriptor_value, raw_enforce_enforce_initial_attribute_length),
490 );
491 let fidl_descriptor = Descriptor {
492 handle: Some(Handle { value: descriptor_id }),
493 type_: Some(descriptor_uuid.into()),
494 permissions: Some(desc_permission_attributes),
495 ..Default::default()
496 };
497
498 descriptors.push(fidl_descriptor);
499 }
500 Ok((descriptors, ext_property_bits))
501 }
502
503 fn generate_characteristics(
504 &self,
505 characteristic_list_json: &Value,
506 ) -> Result<Vec<Characteristic>, Error> {
507 let mut characteristics: Vec<Characteristic> = Vec::new();
508 if characteristic_list_json.is_null() {
509 return Ok(characteristics);
510 }
511
512 let characteristic_list = match characteristic_list_json.as_array() {
513 Some(c) => c,
514 None => {
515 return Err(format_err!("Attribute 'characteristics' is not a parseable list."))
516 }
517 };
518
519 for characteristic in characteristic_list.into_iter() {
520 let characteristic_uuid = match characteristic["uuid"].as_str() {
521 Some(uuid_str) => Uuid::from_str(uuid_str)
522 .map_err(|_| format_err!("Invalid characteristic uuid: {}", uuid_str))?,
523 None => return Err(format_err!("Characteristic uuid was unable to cast to str.")),
524 };
525
526 let characteristic_properties = match characteristic["properties"].as_u64() {
527 Some(properties) => properties as u32,
528 None => {
529 return Err(format_err!("Characteristic properties was unable to cast to u64."))
530 }
531 };
532
533 let raw_characteristic_permissions = match characteristic["permissions"].as_u64() {
534 Some(permissions) => permissions as u32,
535 None => {
536 return Err(format_err!(
537 "Characteristic permissions was unable to cast to u64."
538 ))
539 }
540 };
541
542 let characteristic_value =
543 self.parse_attribute_value_to_byte_array(&characteristic["value"]);
544
545 let raw_enforce_enforce_initial_attribute_length =
546 characteristic["enforce_initial_attribute_length"].as_bool().unwrap_or(false);
547
548 let descriptor_list = &characteristic["descriptors"];
549 let (fidl_descriptors, ext_properties_bits) =
550 self.process_descriptors(descriptor_list)?;
551
552 let characteristic_permissions = self.permissions_and_properties_from_raw_num(
553 raw_characteristic_permissions,
554 characteristic_properties,
555 );
556
557 let characteristic_properties =
562 CharacteristicPropertyBits::from_bits_truncate(characteristic_properties as u16)
563 | ext_properties_bits;
564
565 let characteristic_id = self.inner.write().generic_id_counter.next();
566 self.inner.write().attribute_value_mapping.insert(
567 characteristic_id,
568 (characteristic_value, raw_enforce_enforce_initial_attribute_length),
569 );
570 let fidl_characteristic = Characteristic {
571 handle: Some(Handle { value: characteristic_id }),
572 type_: Some(characteristic_uuid.into()),
573 properties: Some(characteristic_properties),
574 permissions: Some(characteristic_permissions),
575 descriptors: Some(fidl_descriptors),
576 ..Default::default()
577 };
578
579 characteristics.push(fidl_characteristic);
580 }
581 Ok(characteristics)
582 }
583
584 fn generate_service(&self, service_json: &Value) -> Result<ServiceInfo, Error> {
585 let service_id = self.inner.write().generic_id_counter.next();
587 let service_kind = match service_json["type"]
588 .as_i64()
589 .ok_or_else(|| format_err!("Invalid service type"))?
590 {
591 0 => ServiceKind::Primary,
592 1 => ServiceKind::Secondary,
593 _ => return Err(format_err!("Invalid Service type")),
594 };
595
596 let service_uuid_str = service_json["uuid"]
598 .as_str()
599 .ok_or_else(|| format_err!("Service uuid was unable to cast to str"))?;
600 let service_uuid =
601 Uuid::from_str(service_uuid_str).map_err(|_| format_err!("Invalid service uuid"))?;
602
603 let characteristics = self.generate_characteristics(&service_json["characteristics"])?;
605
606 Ok(ServiceInfo {
607 handle: Some(ServiceHandle { value: service_id }),
608 kind: Some(service_kind),
609 type_: Some(service_uuid.into()),
610 characteristics: Some(characteristics),
611 ..Default::default()
612 })
613 }
614
615 async fn publish_service(
616 &self,
617 service_info: ServiceInfo,
618 service_uuid: String,
619 ) -> Result<(), Error> {
620 let tag = "GattServerFacade::publish_service:";
621 let (service_client, service_server) =
622 fidl::endpoints::create_endpoints::<LocalServiceMarker>();
623 let (service_request_stream, service_control_handle) =
624 service_server.into_stream_and_control_handle();
625
626 let server_proxy = self
627 .inner
628 .read()
629 .server_proxy
630 .as_ref()
631 .ok_or_else(|| format_err!("No Server Proxy created."))?
632 .clone();
633 match server_proxy.publish_service(&service_info, service_client).await? {
634 Ok(()) => info!(
635 tag = &[tag, &line!().to_string()].join("").as_str(),
636 uuid:? = service_uuid;
637 "Successfully published GATT service",
638 ),
639 Err(e) => return Err(format_err!("PublishService error: {:?}", e)),
640 }
641
642 let monitor_delegate_fut = GattServerFacade::monitor_service_request_stream(
643 service_request_stream,
644 service_control_handle,
645 self.inner.read().attribute_value_mapping.clone(),
646 );
647 let fut = async {
648 let result = monitor_delegate_fut.await;
649 if let Err(err) = result {
650 error!(
651 tag = "publish_service",
652 err:?;
653 "Failed to create or monitor the gatt service delegate"
654 );
655 }
656 };
657 self.inner.write().service_tasks.push(fasync::Task::spawn(fut));
658 Ok(())
659 }
660
661 pub async fn publish_server(&self, args: Value) -> Result<(), Error> {
730 let tag = "GattServerFacade::publish_server:";
731 info!(tag = &[tag, &line!().to_string()].join("").as_str(); "Publishing service");
732 let server_proxy = self.create_server_proxy()?;
733 self.inner.write().server_proxy = Some(server_proxy);
734 let services = args
735 .get("database")
736 .ok_or_else(|| format_err!("Could not find the 'database' key in the json database."))?
737 .get("services")
738 .ok_or_else(|| {
739 format_err!("Could not find the 'services' key in the json database.")
740 })?;
741
742 let service_list = match services.as_array() {
743 Some(s) => s,
744 None => return Err(format_err!("Attribute 'service' is not a parseable list.")),
745 };
746
747 for service in service_list.into_iter() {
748 self.inner.write().attribute_value_mapping.clear();
749 let service_info = self.generate_service(service)?;
750 let service_uuid = &service["uuid"];
751 self.publish_service(service_info, service_uuid.to_string()).await?;
752 }
753 Ok(())
754 }
755
756 pub async fn close_server(&self) {
757 self.inner.write().server_proxy = None;
758 let _ = self.inner.write().service_tasks.drain(..).collect::<Vec<fasync::Task<()>>>();
759 }
760
761 pub fn cleanup(&self) {
763 let tag = "GattServerFacade::cleanup:";
764 info!(tag = &[tag, &line!().to_string()].join("").as_str(); "Cleanup GATT server objects");
765 self.inner.write().server_proxy = None;
766 let _ = self.inner.write().service_tasks.drain(..).collect::<Vec<fasync::Task<()>>>();
767 }
768
769 pub fn print(&self) {
772 let tag = "GattServerFacade::print:";
773 info!(tag = &[tag, &line!().to_string()].join("").as_str(); "Unimplemented print function");
774 }
775}