1use anyhow::{Error, format_err};
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) => obj.iter().filter_map(|v| v.as_u64()).map(|v| v as u8).collect(),
126 _ => vec![],
127 }
128 }
129
130 fn on_characteristic_configuration(
131 peer_id: PeerId,
132 handle: Handle,
133 notify: bool,
134 indicate: bool,
135 control_handle: &LocalServiceControlHandle,
136 ) {
137 let tag = "GattServerFacade::on_characteristic_configuration:";
138 info!(
139 tag = &[tag, &line!().to_string()].join("").as_str(),
140 notify:%,
141 indicate:%,
142 id:% = peer_id;
143 "OnCharacteristicConfiguration"
144 );
145
146 if indicate {
147 let value = ValueChangedParameters {
148 handle: Some(handle),
149 value: Some(vec![0x02, 0x00]),
150 peer_ids: Some(vec![peer_id.into()]),
151 ..Default::default()
152 };
153 let (confirmation, _) = fidl::EventPair::create();
155 let _ = control_handle.send_on_indicate_value(&value, confirmation);
156 } else if notify {
157 let value = ValueChangedParameters {
158 handle: Some(handle),
159 value: Some(vec![0x01, 0x00]),
160 peer_ids: Some(vec![peer_id.into()]),
161 ..Default::default()
162 };
163 let _ = control_handle.send_on_notify_value(&value);
164 }
165 }
166
167 fn on_read_value(
168 peer_id: PeerId,
169 handle: Handle,
170 offset: i32,
171 responder: LocalServiceReadValueResponder,
172 value_in_mapping: Option<&(Vec<u8>, bool)>,
173 ) {
174 let tag = "GattServerFacade::on_read_value:";
175 info!(
176 tag = &[tag, &line!().to_string()].join("").as_str(),
177 at_id:? = handle.value,
178 offset:? = offset,
179 id:% = peer_id;
180 "OnReadValue request",
181 );
182 match value_in_mapping {
183 Some(v) => {
184 let (value, _enforce_initial_attribute_length) = v;
185 if value.len() < offset as usize {
186 let _result = responder.send(Err(gatt::Error::InvalidOffset));
187 } else {
188 let _result = responder.send(Ok(&value[offset as usize..]));
189 }
190 }
191 None => {
192 let _result = responder.send(Err(gatt::Error::ReadNotPermitted));
194 }
195 };
196 }
197
198 fn write_and_extend(value: &mut Vec<u8>, value_to_write: Vec<u8>, offset: usize) {
199 let split_idx = (value.len() - offset).min(value_to_write.len());
200 let (overlapping, extending) = value_to_write.split_at(split_idx);
201 let end_of_overlap = offset + overlapping.len();
202 value.splice(offset..end_of_overlap, overlapping.iter().cloned());
203 value.extend_from_slice(extending);
204 }
205
206 fn on_write_value(
207 peer_id: PeerId,
208 handle: Handle,
209 offset: u32,
210 value_to_write: Vec<u8>,
211 responder: LocalServiceWriteValueResponder,
212 value_in_mapping: Option<&mut (Vec<u8>, bool)>,
213 ) {
214 let tag = "GattServerFacade::on_write_value:";
215 info!(
216 tag = &[tag, &line!().to_string()].join("").as_str(),
217 at_id = handle.value,
218 offset = offset,
219 value:? = value_to_write,
220 id:% = peer_id;
221 "OnWriteValue request",
222 );
223
224 match value_in_mapping {
225 Some(v) => {
226 let (value, enforce_initial_attribute_length) = v;
227 let max_attribute_size: usize = match enforce_initial_attribute_length {
228 true => value.len(),
229 false => GATT_MAX_ATTRIBUTE_VALUE_LENGTH,
230 };
231 if max_attribute_size < (value_to_write.len() + offset as usize) {
232 let _result = responder.send(Err(gatt::Error::InvalidAttributeValueLength));
233 } else if value.len() < offset as usize {
234 let _result = responder.send(Err(gatt::Error::InvalidOffset));
235 } else {
236 GattServerFacade::write_and_extend(value, value_to_write, offset as usize);
237 let _result = responder.send(Ok(()));
238 }
239 }
240 None => {
241 let _result = responder.send(Err(gatt::Error::WriteNotPermitted));
243 }
244 }
245 }
246
247 async fn monitor_service_request_stream(
248 stream: LocalServiceRequestStream,
249 control_handle: LocalServiceControlHandle,
250 mut attribute_value_mapping: HashMap<u64, (Vec<u8>, bool)>,
251 ) -> Result<(), Error> {
252 stream
253 .map_ok(move |request| match request {
254 LocalServiceRequest::CharacteristicConfiguration {
255 peer_id,
256 handle,
257 notify,
258 indicate,
259 responder,
260 } => {
261 GattServerFacade::on_characteristic_configuration(
262 peer_id.into(),
263 handle,
264 notify,
265 indicate,
266 &control_handle,
267 );
268 let _ = responder.send();
269 }
270 LocalServiceRequest::ReadValue { peer_id, handle, offset, responder } => {
271 GattServerFacade::on_read_value(
272 peer_id.into(),
273 handle,
274 offset,
275 responder,
276 attribute_value_mapping.get(&handle.value),
277 );
278 }
279 LocalServiceRequest::WriteValue { payload, responder } => {
280 GattServerFacade::on_write_value(
281 payload.peer_id.unwrap().into(),
282 payload.handle.unwrap(),
283 payload.offset.unwrap(),
284 payload.value.unwrap(),
285 responder,
286 attribute_value_mapping.get_mut(&payload.handle.unwrap().value),
287 );
288 }
289 LocalServiceRequest::PeerUpdate { payload: _, responder } => {
290 responder.drop_without_shutdown();
291 }
292 LocalServiceRequest::ValueChangedCredit { .. } => {}
293 })
294 .try_collect::<()>()
295 .await
296 .map_err(|e| e.into())
297 }
298
299 fn permissions_and_properties_from_raw_num(
321 &self,
322 permissions: u32,
323 properties: u32,
324 ) -> AttributePermissions {
325 let mut read_encryption_required = false;
326 let mut read_authentication_required = false;
327 let mut read_authorization_required = false;
328
329 let mut write_encryption_required = false;
330 let mut write_authentication_required = false;
331 let mut write_authorization_required = false;
332
333 let mut update_encryption_required = false;
334 let mut update_authentication_required = false;
335 let mut update_authorization_required = false;
336
337 if permissions & PERMISSION_READ_ENCRYPTED != 0 {
338 read_encryption_required = true;
339 read_authentication_required = true;
340 read_authorization_required = true;
341 }
342
343 if permissions & PERMISSION_READ_ENCRYPTED_MITM != 0 {
344 read_encryption_required = true;
345 update_encryption_required = true;
346 }
347
348 if permissions & PERMISSION_WRITE_ENCRYPTED != 0 {
349 write_encryption_required = true;
350 update_encryption_required = true;
351 }
352
353 if permissions & PERMISSION_WRITE_ENCRYPTED_MITM != 0 {
354 write_encryption_required = true;
355 update_encryption_required = true;
356 update_authentication_required = true;
357 update_authorization_required = true;
358 }
359
360 if permissions & PERMISSION_WRITE_SIGNED != 0 {
361 write_authorization_required = true;
362 }
363
364 if permissions & PERMISSION_WRITE_SIGNED_MITM != 0 {
365 write_encryption_required = true;
366 write_authentication_required = true;
367 write_authorization_required = true;
368 update_encryption_required = true;
369 update_authentication_required = true;
370 update_authorization_required = true;
371 }
372
373 let update_sec_requirement = if properties & (PROPERTY_NOTIFY | PROPERTY_INDICATE) != 0 {
376 Some(SecurityRequirements {
377 encryption_required: Some(update_encryption_required),
378 authentication_required: Some(update_authentication_required),
379 authorization_required: Some(update_authorization_required),
380 ..Default::default()
381 })
382 } else {
383 None
384 };
385
386 let read_sec_requirement = if properties & PROPERTY_READ != 0 {
387 Some(SecurityRequirements {
388 encryption_required: Some(read_encryption_required),
389 authentication_required: Some(read_authentication_required),
390 authorization_required: Some(read_authorization_required),
391 ..Default::default()
392 })
393 } else {
394 None
395 };
396
397 let write_sec_requirement = if properties & PROPERTY_WRITE != 0 {
398 Some(SecurityRequirements {
399 encryption_required: Some(write_encryption_required),
400 authentication_required: Some(write_authentication_required),
401 authorization_required: Some(write_authorization_required),
402 ..Default::default()
403 })
404 } else {
405 None
406 };
407
408 AttributePermissions {
409 read: read_sec_requirement,
410 write: write_sec_requirement,
411 update: update_sec_requirement,
412 ..Default::default()
413 }
414 }
415
416 fn process_descriptors(
422 &self,
423 descriptor_list_json: &Value,
424 ) -> Result<(Vec<Descriptor>, CharacteristicPropertyBits), Error> {
425 let mut descriptors: Vec<Descriptor> = Vec::new();
426 let banned_descriptor_uuids = [
429 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(), ];
433
434 if descriptor_list_json.is_null() {
435 return Ok((descriptors, CharacteristicPropertyBits::empty()));
436 }
437
438 let descriptor_list = descriptor_list_json
439 .as_array()
440 .ok_or_else(|| format_err!("Attribute 'descriptors' is not a parseable list."))?;
441
442 let mut ext_property_bits = CharacteristicPropertyBits::empty();
443
444 for descriptor in descriptor_list.iter() {
445 let descriptor_uuid: Uuid = match descriptor["uuid"].as_str() {
446 Some(uuid_str) => Uuid::from_str(uuid_str)
447 .map_err(|_| format_err!("Descriptor uuid is invalid"))?,
448 None => return Err(format_err!("Descriptor uuid was unable to cast to str.")),
449 };
450 let descriptor_value = self.parse_attribute_value_to_byte_array(&descriptor["value"]);
451
452 if descriptor_uuid == Uuid::new16(CHARACTERISTIC_EXTENDED_PROPERTIES_UUID) {
454 if descriptor_value.is_empty() {
455 warn!("Extended properties descriptor has empty value. Ignoring.");
456 continue;
457 }
458 let ext_bits_raw: u16 = (descriptor_value[0] as u16) << u8::BITS;
460 ext_property_bits = CharacteristicPropertyBits::from_bits_truncate(ext_bits_raw);
461 continue;
462 }
463
464 let raw_enforce_enforce_initial_attribute_length =
465 descriptor["enforce_initial_attribute_length"].as_bool().unwrap_or(false);
466
467 let properties = 0u32;
469
470 if banned_descriptor_uuids.contains(&descriptor_uuid) {
471 continue;
472 }
473
474 let raw_descriptor_permissions = match descriptor["permissions"].as_u64() {
475 Some(permissions) => permissions as u32,
476 None => {
477 return Err(format_err!("Descriptor permissions was unable to cast to u64."));
478 }
479 };
480
481 let desc_permission_attributes = self
482 .permissions_and_properties_from_raw_num(raw_descriptor_permissions, properties);
483
484 let descriptor_id = self.inner.write().generic_id_counter.next();
485 self.inner.write().attribute_value_mapping.insert(
486 descriptor_id,
487 (descriptor_value, raw_enforce_enforce_initial_attribute_length),
488 );
489 let fidl_descriptor = Descriptor {
490 handle: Some(Handle { value: descriptor_id }),
491 type_: Some(descriptor_uuid.into()),
492 permissions: Some(desc_permission_attributes),
493 ..Default::default()
494 };
495
496 descriptors.push(fidl_descriptor);
497 }
498 Ok((descriptors, ext_property_bits))
499 }
500
501 fn generate_characteristics(
502 &self,
503 characteristic_list_json: &Value,
504 ) -> Result<Vec<Characteristic>, Error> {
505 let mut characteristics: Vec<Characteristic> = Vec::new();
506 if characteristic_list_json.is_null() {
507 return Ok(characteristics);
508 }
509
510 let characteristic_list = match characteristic_list_json.as_array() {
511 Some(c) => c,
512 None => {
513 return Err(format_err!("Attribute 'characteristics' is not a parseable list."));
514 }
515 };
516
517 for characteristic in characteristic_list.iter() {
518 let characteristic_uuid = match characteristic["uuid"].as_str() {
519 Some(uuid_str) => Uuid::from_str(uuid_str)
520 .map_err(|_| format_err!("Invalid characteristic uuid: {}", uuid_str))?,
521 None => return Err(format_err!("Characteristic uuid was unable to cast to str.")),
522 };
523
524 let characteristic_properties = match characteristic["properties"].as_u64() {
525 Some(properties) => properties as u32,
526 None => {
527 return Err(format_err!(
528 "Characteristic properties was unable to cast to u64."
529 ));
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.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}