sl4f_lib/bluetooth/
commands.rs

1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::server::Facade;
6use anyhow::{format_err, Error};
7use async_trait::async_trait;
8use bt_rfcomm::ServerChannel;
9use fidl_fuchsia_bluetooth::PeerId;
10use fidl_fuchsia_bluetooth_a2dp::Role;
11use fidl_fuchsia_bluetooth_hfp::{CallDirection, CallState, NetworkInformation, SignalStrength};
12use fidl_fuchsia_bluetooth_le::Filter;
13use fidl_fuchsia_bluetooth_sys::{LeSecurityMode, Settings};
14use serde_json::{from_value, to_value, Value};
15use test_call_manager::TestCallManager as HfpFacade;
16use test_rfcomm_client::RfcommManager as RfcommFacade;
17
18// Bluetooth-related functionality
19use crate::bluetooth::a2dp_facade::A2dpFacade;
20use crate::bluetooth::avdtp_facade::AvdtpFacade;
21use crate::bluetooth::avrcp_facade::AvrcpFacade;
22use crate::bluetooth::ble_advertise_facade::BleAdvertiseFacade;
23use crate::bluetooth::bt_sys_facade::BluetoothSysFacade;
24use crate::bluetooth::gatt_client_facade::GattClientFacade;
25use crate::bluetooth::gatt_server_facade::GattServerFacade;
26use crate::bluetooth::profile_server_facade::ProfileServerFacade;
27use crate::bluetooth::types::{
28    AbsoluteVolumeCommand, BleAdvertiseResponse, BleConnectPeripheralResponse, CustomBatteryStatus,
29    CustomNotificationsFilter, CustomPlayerApplicationSettings,
30    CustomPlayerApplicationSettingsAttributeIds, FacadeArg, GattcDiscoverCharacteristicResponse,
31};
32
33use crate::common_utils::common::{
34    parse_identifier, parse_identifier_as_u64, parse_max_bytes, parse_offset, parse_psm,
35    parse_service_identifier, parse_u64_identifier, parse_write_value,
36};
37
38use crate::common_utils::common::macros::parse_arg;
39
40#[async_trait(?Send)]
41impl Facade for BleAdvertiseFacade {
42    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
43        // TODO(armansito): Once the facade supports multi-advertising it should generate and
44        // return a unique ID for each instance. For now we return this dummy ID for the
45        // singleton advertisement.
46        let id = to_value(BleAdvertiseResponse::new(Some("singleton-instance".to_string())))?;
47        match method.as_ref() {
48            "BleAdvertise" => {
49                self.start_adv(args).await?;
50            }
51            "BleStopAdvertise" => {
52                self.stop_adv();
53            }
54            _ => return Err(format_err!("Invalid BleAdvertise FIDL method: {:?}", method)),
55        };
56        Ok(id)
57    }
58
59    fn cleanup(&self) {
60        Self::cleanup(self)
61    }
62
63    fn print(&self) {
64        Self::print(self)
65    }
66}
67
68#[async_trait(?Send)]
69impl Facade for BluetoothSysFacade {
70    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
71        match method.as_ref() {
72            "BluetoothAcceptPairing" => {
73                let input = parse_arg!(args, as_str, "input")?;
74                let output = parse_arg!(args, as_str, "output")?;
75                let result = self.accept_pairing(input, output).await?;
76                Ok(to_value(result)?)
77            }
78            "BluetoothInitSys" => {
79                let result = self.init_access_proxy().await?;
80                Ok(to_value(result)?)
81            }
82            "BluetoothGetKnownRemoteDevices" => {
83                let result = self.get_known_remote_devices().await?;
84                Ok(to_value(result)?)
85            }
86            "BluetoothSetDiscoverable" => {
87                let discoverable = parse_arg!(args, as_bool, "discoverable")?;
88                let result = self.set_discoverable(discoverable).await?;
89                Ok(to_value(result)?)
90            }
91            "BluetoothSetName" => {
92                let name = parse_arg!(args, as_str, "name")?;
93                let result = self.set_name(name.to_string()).await?;
94                Ok(to_value(result)?)
95            }
96            "BluetoothForgetDevice" => {
97                let identifier = parse_identifier_as_u64(&args)?;
98                let result = self.forget(identifier).await?;
99                Ok(to_value(result)?)
100            }
101            "BluetoothConnectDevice" => {
102                let identifier = parse_identifier_as_u64(&args)?;
103                let result = self.connect(identifier).await?;
104                Ok(to_value(result)?)
105            }
106            "BluetoothDisconnectDevice" => {
107                let identifier = parse_identifier_as_u64(&args)?;
108                let result = self.disconnect(identifier).await?;
109                Ok(to_value(result)?)
110            }
111            "BluetoothRequestDiscovery" => {
112                let discovery = parse_arg!(args, as_bool, "discovery")?;
113                let result = self.start_discovery(discovery).await?;
114                Ok(to_value(result)?)
115            }
116            "BluetoothInputPairingPin" => {
117                let pin = parse_arg!(args, as_str, "pin")?;
118                let result = self.input_pairing_pin(pin.to_string()).await?;
119                Ok(to_value(result)?)
120            }
121            "BluetoothGetPairingPin" => {
122                let result = self.get_pairing_pin().await?;
123                Ok(to_value(result)?)
124            }
125            "BluetoothGetActiveAdapterAddress" => {
126                let result = self.get_active_adapter_address().await?;
127                Ok(to_value(result)?)
128            }
129            "BluetoothPairDevice" => {
130                let identifier = parse_identifier_as_u64(&args)?;
131                let pairing_security_level =
132                    match parse_arg!(args, as_u64, "pairing_security_level") {
133                        Ok(v) => Some(v),
134                        Err(_e) => None,
135                    };
136                let non_bondable = match parse_arg!(args, as_bool, "non_bondable") {
137                    Ok(v) => Some(v),
138                    Err(_e) => None,
139                };
140                let transport = parse_arg!(args, as_u64, "transport")?;
141
142                let result =
143                    self.pair(identifier, pairing_security_level, non_bondable, transport).await?;
144                Ok(to_value(result)?)
145            }
146            "BluetoothUpdateSystemSettings" => {
147                let le_privacy = parse_arg!(args, as_bool, "le_privacy").ok();
148                let le_background_scan = parse_arg!(args, as_bool, "le_background_scan").ok();
149                let bredr_connectable_mode =
150                    parse_arg!(args, as_bool, "bredr_connectable_mode").ok();
151                let le_security_mode = if let Ok(s) = parse_arg!(args, as_str, "le_security_mode") {
152                    match s.to_uppercase().as_ref() {
153                        "MODE_1" => Some(LeSecurityMode::Mode1),
154                        "SECURE_CONNECTIONS_ONLY" => Some(LeSecurityMode::SecureConnectionsOnly),
155                        _ => bail!(
156                            "Invalid le_security_mode {} passed to BluetoothUpdateSystemSettings",
157                            s
158                        ),
159                    }
160                } else {
161                    None
162                };
163                let result = self
164                    .update_settings(Settings {
165                        le_privacy,
166                        le_background_scan,
167                        bredr_connectable_mode,
168                        le_security_mode,
169                        ..Default::default()
170                    })
171                    .await?;
172                Ok(to_value(result)?)
173            }
174            _ => bail!("Invalid Bluetooth control FIDL method: {:?}", method),
175        }
176    }
177
178    fn cleanup(&self) {
179        Self::cleanup(self)
180    }
181
182    fn print(&self) {
183        Self::print(self)
184    }
185}
186
187#[async_trait(?Send)]
188impl Facade for GattClientFacade {
189    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
190        match method.as_ref() {
191            "BleStartScan" => {
192                let scan_filter = FacadeArg::new(args);
193                start_scan_async(&self, Some(scan_filter.try_into()?)).await
194            }
195            "BleStopScan" => stop_scan_async(self).await,
196            "BleGetDiscoveredDevices" => le_get_discovered_devices_async(self).await,
197            "BleConnectPeripheral" => {
198                let id = parse_identifier(args)?;
199                connect_peripheral_async(self, id).await
200            }
201            "BleDisconnectPeripheral" => {
202                let id = parse_identifier(args)?;
203                disconnect_peripheral_async(self, id).await
204            }
205            "GattcConnectToService" => {
206                let periph_id = parse_identifier(args.clone())?;
207                let service_id = parse_service_identifier(args)?;
208                gattc_connect_to_service_async(self, periph_id, service_id).await
209            }
210            "GattcDiscoverCharacteristics" => gattc_discover_characteristics_async(self).await,
211            "GattcWriteCharacteristicById" => {
212                let id = parse_u64_identifier(args.clone())?;
213                let value = parse_write_value(args)?;
214                gattc_write_char_by_id_async(self, id, value).await
215            }
216            "GattcWriteLongCharacteristicById" => {
217                let id = parse_u64_identifier(args.clone())?;
218                let offset_as_u64 = parse_offset(args.clone())?;
219                let offset = offset_as_u64 as u16;
220                let value = parse_write_value(args.clone())?;
221                let reliable_mode = parse_arg!(args, as_bool, "reliable_mode")?;
222                gattc_write_long_char_by_id_async(self, id, offset, value, reliable_mode).await
223            }
224            "GattcWriteCharacteristicByIdWithoutResponse" => {
225                let id = parse_u64_identifier(args.clone())?;
226                let value = parse_write_value(args)?;
227                gattc_write_char_by_id_without_response_async(self, id, value).await
228            }
229            "GattcEnableNotifyCharacteristic" => {
230                let id = parse_u64_identifier(args.clone())?;
231                gattc_toggle_notify_characteristic_async(self, id, true).await
232            }
233            "GattcDisableNotifyCharacteristic" => {
234                let id = parse_u64_identifier(args.clone())?;
235                gattc_toggle_notify_characteristic_async(self, id, false).await
236            }
237            "GattcReadCharacteristicById" => {
238                let id = parse_u64_identifier(args.clone())?;
239                gattc_read_char_by_id_async(self, id).await
240            }
241            "GattcReadCharacteristicByType" => {
242                let uuid = parse_arg!(args, as_str, "uuid")?;
243                let result = self.gattc_read_char_by_type(uuid.to_string()).await?;
244                Ok(to_value(result)?)
245            }
246            "GattcReadLongCharacteristicById" => {
247                let id = parse_u64_identifier(args.clone())?;
248                let offset_as_u64 = parse_offset(args.clone())?;
249                let offset = offset_as_u64 as u16;
250                let max_bytes_as_u64 = parse_max_bytes(args)?;
251                let max_bytes = max_bytes_as_u64 as u16;
252                gattc_read_long_char_by_id_async(self, id, offset, max_bytes).await
253            }
254            "GattcReadLongDescriptorById" => {
255                let id = parse_u64_identifier(args.clone())?;
256                let offset_as_u64 = parse_offset(args.clone())?;
257                let offset = offset_as_u64 as u16;
258                let max_bytes_as_u64 = parse_max_bytes(args)?;
259                let max_bytes = max_bytes_as_u64 as u16;
260                gattc_read_long_desc_by_id_async(self, id, offset, max_bytes).await
261            }
262            "GattcWriteDescriptorById" => {
263                let id = parse_u64_identifier(args.clone())?;
264                let value = parse_write_value(args)?;
265                gattc_write_desc_by_id_async(self, id, value).await
266            }
267            "GattcWriteLongDescriptorById" => {
268                let id = parse_u64_identifier(args.clone())?;
269                let offset_as_u64 = parse_offset(args.clone())?;
270                let offset = offset_as_u64 as u16;
271                let value = parse_write_value(args)?;
272                gattc_write_long_desc_by_id_async(self, id, offset, value).await
273            }
274            "GattcReadDescriptorById" => {
275                let id = parse_u64_identifier(args.clone())?;
276                gattc_read_desc_by_id_async(self, id.clone()).await
277            }
278            "GattcListServices" => {
279                let id = parse_identifier(args)?;
280                list_services_async(self, id).await
281            }
282            _ => return Err(format_err!("Invalid Gatt Client FIDL method: {:?}", method)),
283        }
284    }
285
286    fn cleanup(&self) {
287        Self::cleanup(self)
288    }
289
290    fn print(&self) {
291        Self::print(self)
292    }
293}
294
295#[async_trait(?Send)]
296impl Facade for GattServerFacade {
297    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
298        match method.as_ref() {
299            "GattServerPublishServer" => {
300                let result = self.publish_server(args).await?;
301                Ok(to_value(result)?)
302            }
303            "GattServerCloseServer" => {
304                let result = self.close_server().await;
305                Ok(to_value(result)?)
306            }
307            _ => return Err(format_err!("Invalid Gatt Server FIDL method: {:?}", method)),
308        }
309    }
310
311    fn cleanup(&self) {
312        Self::cleanup(self)
313    }
314
315    fn print(&self) {
316        Self::print(self)
317    }
318}
319
320#[async_trait(?Send)]
321impl Facade for ProfileServerFacade {
322    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
323        match method.as_ref() {
324            "ProfileServerInit" => {
325                let result = self.init_profile_server_proxy().await?;
326                Ok(to_value(result)?)
327            }
328            "ProfileServerAddSearch" => {
329                let result = self.add_search(args).await?;
330                Ok(to_value(result)?)
331            }
332            "ProfileServerAddService" => {
333                let result = self.add_service(args).await?;
334                Ok(to_value(result)?)
335            }
336            "ProfileServerCleanup" => {
337                let result = self.cleanup().await?;
338                Ok(to_value(result)?)
339            }
340            "ProfileServerConnectL2cap" => {
341                let id = parse_identifier(args.clone())?;
342                let psm = parse_psm(args.clone())?;
343                let mode = parse_arg!(args, as_str, "mode")?;
344                let result = self.connect(id, psm as u16, mode).await?;
345                Ok(to_value(result)?)
346            }
347            "ProfileServerRemoveService" => {
348                let service_id = parse_u64_identifier(args)? as usize;
349                let result = self.remove_service(service_id).await?;
350                Ok(to_value(result)?)
351            }
352            _ => return Err(format_err!("Invalid Profile Server FIDL method: {:?}", method)),
353        }
354    }
355}
356
357#[async_trait(?Send)]
358impl Facade for AvdtpFacade {
359    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
360        match method.as_ref() {
361            "AvdtpInit" => {
362                let result = self.init_avdtp_service_proxy().await?;
363                Ok(to_value(result)?)
364            }
365            "AvdtpGetConnectedPeers" => {
366                let result = self.get_connected_peers().await?;
367                Ok(to_value(result)?)
368            }
369            "AvdtpSetConfiguration" => {
370                let peer_id = parse_u64_identifier(args)?;
371                let result = self.set_configuration(peer_id).await?;
372                Ok(to_value(result)?)
373            }
374            "AvdtpGetConfiguration" => {
375                let peer_id = parse_u64_identifier(args)?;
376                let result = self.get_configuration(peer_id).await?;
377                Ok(to_value(result)?)
378            }
379            "AvdtpGetCapabilities" => {
380                let peer_id = parse_u64_identifier(args)?;
381                let result = self.get_capabilities(peer_id).await?;
382                Ok(to_value(result)?)
383            }
384            "AvdtpGetAllCapabilities" => {
385                let peer_id = parse_u64_identifier(args)?;
386                let result = self.get_all_capabilities(peer_id).await?;
387                Ok(to_value(result)?)
388            }
389            "AvdtpReconfigureStream" => {
390                let peer_id = parse_u64_identifier(args)?;
391                let result = self.reconfigure_stream(peer_id).await?;
392                Ok(to_value(result)?)
393            }
394            "AvdtpSuspendStream" => {
395                let peer_id = parse_u64_identifier(args)?;
396                let result = self.suspend_stream(peer_id).await?;
397                Ok(to_value(result)?)
398            }
399            "AvdtpSuspendAndReconfigure" => {
400                let peer_id = parse_u64_identifier(args)?;
401                let result = self.suspend_and_reconfigure(peer_id).await?;
402                Ok(to_value(result)?)
403            }
404            "AvdtpReleaseStream" => {
405                let peer_id = parse_u64_identifier(args)?;
406                let result = self.release_stream(peer_id).await?;
407                Ok(to_value(result)?)
408            }
409            "AvdtpEstablishStream" => {
410                let peer_id = parse_u64_identifier(args)?;
411                let result = self.establish_stream(peer_id).await?;
412                Ok(to_value(result)?)
413            }
414            "AvdtpStartStream" => {
415                let peer_id = parse_u64_identifier(args)?;
416                let result = self.start_stream(peer_id).await?;
417                Ok(to_value(result)?)
418            }
419            "AvdtpAbortStream" => {
420                let peer_id = parse_u64_identifier(args)?;
421                let result = self.abort_stream(peer_id).await?;
422                Ok(to_value(result)?)
423            }
424            "AvdtpRemoveService" => {
425                let result = self.remove_service().await;
426                Ok(to_value(result)?)
427            }
428            _ => bail!("Invalid AVDTP FIDL method: {:?}", method),
429        }
430    }
431}
432
433#[async_trait(?Send)]
434impl Facade for A2dpFacade {
435    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
436        match method.as_ref() {
437            "A2dpSetRole" => {
438                let a2dp_role = if let Ok(s) = parse_arg!(args, as_str, "a2dp_role") {
439                    match s.to_uppercase().as_ref() {
440                        "SOURCE" => Role::Source,
441                        "SINK" => Role::Sink,
442                        _ => bail!("Invalid A2DP role {} passed to A2dpSetRole", s),
443                    }
444                } else {
445                    bail!("Could not parse A2DP role passed to A2dpSetRole")
446                };
447
448                self.init_audio_mode_proxy().await?;
449                let result = self.set_role(a2dp_role).await?;
450                Ok(to_value(result)?)
451            }
452
453            _ => {
454                bail!("Invalid A2DP FIDL method: {:?}", method)
455            }
456        }
457    }
458}
459
460#[async_trait(?Send)]
461impl Facade for AvrcpFacade {
462    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
463        match method.as_ref() {
464            "AvrcpInit" => {
465                let target_id = parse_arg!(args, as_str, "target_id")?;
466                let target_id = target_id.parse::<u64>()?;
467                let result = self.init_avrcp(target_id).await?;
468                Ok(to_value(result)?)
469            }
470            "AvrcpGetMediaAttributes" => {
471                let result = self.get_media_attributes().await?;
472                Ok(to_value(result)?)
473            }
474            "AvrcpGetPlayStatus" => {
475                let result = self.get_play_status().await?;
476                Ok(to_value(result)?)
477            }
478            "AvrcpGetPlayerApplicationSettings" => {
479                let attribute_ids: CustomPlayerApplicationSettingsAttributeIds =
480                    match from_value(args.clone()) {
481                        Ok(attribute_ids) => attribute_ids,
482                        _ => bail!(
483                            "Invalid json argument to AvrcpGetPlayerApplicationSettings! - {}",
484                            args
485                        ),
486                    };
487                let result = self.get_player_application_settings(attribute_ids.clone()).await?;
488                Ok(to_value(result)?)
489            }
490            "AvrcpInformBatteryStatus" => {
491                let battery_status: CustomBatteryStatus = match from_value(args.clone()) {
492                    Ok(battery_status) => battery_status,
493                    _ => bail!("Invalid json argument to AvrcpInformBatteryStatus! - {}", args),
494                };
495                let result = self.inform_battery_status(battery_status.clone()).await?;
496                Ok(to_value(result)?)
497            }
498            "AvrcpNotifyNotificationHandled" => {
499                let result = self.notify_notification_handled().await?;
500                Ok(to_value(result)?)
501            }
502            "AvrcpSetAddressedPlayer" => {
503                let player_id: u16 = match from_value(args.clone()) {
504                    Ok(settings) => settings,
505                    _ => bail!("Invalid json argument to AvrcpSetAddressedPlayer! - {}", args),
506                };
507                let result = self.set_addressed_player(player_id.clone()).await?;
508                Ok(to_value(result)?)
509            }
510            "AvrcpSetPlayerApplicationSettings" => {
511                let settings: CustomPlayerApplicationSettings = match from_value(args.clone()) {
512                    Ok(settings) => settings,
513                    _ => bail!(
514                        "Invalid json argument to AvrcpSetPlayerApplicationSettings! - {}",
515                        args
516                    ),
517                };
518                let result = self.set_player_application_settings(settings.clone()).await?;
519                Ok(to_value(result)?)
520            }
521            "AvrcpSendCommand" => {
522                let command_str = parse_arg!(args, as_str, "command")?;
523                let result = self.send_command(command_str.to_string().into()).await?;
524                Ok(to_value(result)?)
525            }
526            "AvrcpSetAbsoluteVolume" => {
527                let absolute_volume_command: AbsoluteVolumeCommand = match from_value(args.clone())
528                {
529                    Ok(absolute_volume) => absolute_volume,
530                    _ => bail!("Invalid json argument to AvrcpSetAbsoluteVolume! - {}", args),
531                };
532                let result =
533                    self.set_absolute_volume(absolute_volume_command.absolute_volume).await?;
534                Ok(to_value(result)?)
535            }
536            "AvrcpSetNotificationFilter" => {
537                let custom_notifications: CustomNotificationsFilter = match from_value(args.clone())
538                {
539                    Ok(custom_notifications) => custom_notifications,
540                    _ => bail!("Invalid json argument to AvrcpSetNotificationFilter! - {}", args),
541                };
542                let result = self
543                    .set_notification_filter(
544                        custom_notifications.notifications,
545                        match custom_notifications.position_change_interval {
546                            Some(position_change_interval) => position_change_interval,
547                            _ => 0,
548                        },
549                    )
550                    .await?;
551                Ok(to_value(result)?)
552            }
553            _ => bail!("Invalid AVRCP FIDL method: {:?}", method),
554        }
555    }
556
557    fn cleanup(&self) {}
558
559    fn print(&self) {}
560}
561
562async fn start_scan_async(
563    facade: &GattClientFacade,
564    filter: Option<Filter>,
565) -> Result<Value, Error> {
566    let start_scan_result = facade.start_scan(filter).await?;
567    Ok(to_value(start_scan_result)?)
568}
569
570async fn stop_scan_async(facade: &GattClientFacade) -> Result<Value, Error> {
571    facade.stop_scan().await?;
572    // Get the list of devices discovered by the scan.
573    let devices = facade.get_scan_responses();
574    match to_value(devices) {
575        Ok(dev) => Ok(dev),
576        Err(e) => Err(e.into()),
577    }
578}
579
580async fn le_get_discovered_devices_async(facade: &GattClientFacade) -> Result<Value, Error> {
581    // Get the list of devices discovered by the scan.
582    match to_value(facade.get_scan_responses()) {
583        Ok(dev) => Ok(dev),
584        Err(e) => Err(e.into()),
585    }
586}
587
588async fn connect_peripheral_async(facade: &GattClientFacade, id: String) -> Result<Value, Error> {
589    let connect_periph_result = facade.connect_peripheral(id).await?;
590    Ok(to_value(connect_periph_result)?)
591}
592
593async fn disconnect_peripheral_async(
594    facade: &GattClientFacade,
595    id: String,
596) -> Result<Value, Error> {
597    let value = facade.disconnect_peripheral(id).await?;
598    Ok(to_value(value)?)
599}
600
601// Uses the same return type as connect_peripheral_async -- Returns subset of
602// fidl::ServiceInfo
603async fn list_services_async(facade: &GattClientFacade, id: String) -> Result<Value, Error> {
604    let list_services_result = facade.list_services(id).await?;
605    Ok(to_value(BleConnectPeripheralResponse::new(list_services_result))?)
606}
607
608async fn gattc_connect_to_service_async(
609    facade: &GattClientFacade,
610    periph_id: String,
611    service_id: u64,
612) -> Result<Value, Error> {
613    let connect_to_service_result = facade.gattc_connect_to_service(periph_id, service_id).await?;
614    Ok(to_value(connect_to_service_result)?)
615}
616
617async fn gattc_discover_characteristics_async(facade: &GattClientFacade) -> Result<Value, Error> {
618    let discover_characteristics_results = facade.gattc_discover_characteristics().await?;
619    Ok(to_value(GattcDiscoverCharacteristicResponse::new(discover_characteristics_results))?)
620}
621
622async fn gattc_write_char_by_id_async(
623    facade: &GattClientFacade,
624    id: u64,
625    write_value: Vec<u8>,
626) -> Result<Value, Error> {
627    let write_char_status = facade.gattc_write_char_by_id(id, write_value).await?;
628    Ok(to_value(write_char_status)?)
629}
630
631async fn gattc_write_long_char_by_id_async(
632    facade: &GattClientFacade,
633    id: u64,
634    offset: u16,
635    write_value: Vec<u8>,
636    reliable_mode: bool,
637) -> Result<Value, Error> {
638    let write_char_status =
639        facade.gattc_write_long_char_by_id(id, offset, write_value, reliable_mode).await?;
640    Ok(to_value(write_char_status)?)
641}
642
643async fn gattc_write_char_by_id_without_response_async(
644    facade: &GattClientFacade,
645    id: u64,
646    write_value: Vec<u8>,
647) -> Result<Value, Error> {
648    let write_char_status = facade.gattc_write_char_by_id_without_response(id, write_value).await?;
649    Ok(to_value(write_char_status)?)
650}
651
652async fn gattc_read_char_by_id_async(facade: &GattClientFacade, id: u64) -> Result<Value, Error> {
653    let read_char_status = facade.gattc_read_char_by_id(id).await?;
654    Ok(to_value(read_char_status)?)
655}
656
657async fn gattc_read_long_char_by_id_async(
658    facade: &GattClientFacade,
659    id: u64,
660    offset: u16,
661    max_bytes: u16,
662) -> Result<Value, Error> {
663    let read_long_char_status = facade.gattc_read_long_char_by_id(id, offset, max_bytes).await?;
664    Ok(to_value(read_long_char_status)?)
665}
666
667async fn gattc_read_long_desc_by_id_async(
668    facade: &GattClientFacade,
669    id: u64,
670    offset: u16,
671    max_bytes: u16,
672) -> Result<Value, Error> {
673    let read_long_desc_status = facade.gattc_read_long_desc_by_id(id, offset, max_bytes).await?;
674    Ok(to_value(read_long_desc_status)?)
675}
676
677async fn gattc_read_desc_by_id_async(facade: &GattClientFacade, id: u64) -> Result<Value, Error> {
678    let read_desc_status = facade.gattc_read_desc_by_id(id).await?;
679    Ok(to_value(read_desc_status)?)
680}
681
682async fn gattc_write_desc_by_id_async(
683    facade: &GattClientFacade,
684    id: u64,
685    write_value: Vec<u8>,
686) -> Result<Value, Error> {
687    let write_desc_status = facade.gattc_write_desc_by_id(id, write_value).await?;
688    Ok(to_value(write_desc_status)?)
689}
690
691async fn gattc_write_long_desc_by_id_async(
692    facade: &GattClientFacade,
693    id: u64,
694    offset: u16,
695    write_value: Vec<u8>,
696) -> Result<Value, Error> {
697    let write_desc_status = facade.gattc_write_long_desc_by_id(id, offset, write_value).await?;
698    Ok(to_value(write_desc_status)?)
699}
700
701async fn gattc_toggle_notify_characteristic_async(
702    facade: &GattClientFacade,
703    id: u64,
704    value: bool,
705) -> Result<Value, Error> {
706    let toggle_notify_result = facade.gattc_toggle_notify_characteristic(id, value).await?;
707    Ok(to_value(toggle_notify_result)?)
708}
709
710#[async_trait(?Send)]
711impl Facade for HfpFacade {
712    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
713        match method.as_ref() {
714            "HfpInit" => {
715                let result = self.init_hfp_service().await?;
716                Ok(to_value(result)?)
717            }
718            "HfpRemoveService" => {
719                self.cleanup().await;
720                Ok(to_value(())?)
721            }
722            "ListPeers" => {
723                let result = self.list_peers().await?;
724                Ok(to_value(result)?)
725            }
726            "SetActivePeer" => {
727                let id = parse_arg!(args, as_u64, "peer_id")?;
728                let result = self.set_active_peer(id).await?;
729                Ok(to_value(result)?)
730            }
731            "ListCalls" => {
732                let result = self.list_calls().await?;
733                Ok(to_value(result)?)
734            }
735            "NewCall" => {
736                let remote = parse_arg!(args, as_str, "remote")?;
737                let state = parse_arg!(args, as_str, "state")?.to_lowercase();
738                let state = match &*state {
739                    "ringing" => CallState::IncomingRinging,
740                    "waiting" => CallState::IncomingWaiting,
741                    "dialing" => CallState::OutgoingDialing,
742                    "alerting" => CallState::OutgoingAlerting,
743                    "active" => CallState::OngoingActive,
744                    "held" => CallState::OngoingHeld,
745                    _ => bail!("Invalid state argument: {}", state),
746                };
747                let direction = parse_arg!(args, as_str, "direction")?;
748                let direction = match &*direction {
749                    "incoming" => CallDirection::MobileTerminated,
750                    "outgoing" => CallDirection::MobileOriginated,
751                    _ => bail!("Invalid direction argument: {}", direction),
752                };
753                let result = self.new_call(&remote, state, direction).await?;
754                Ok(to_value(result)?)
755            }
756            "IncomingCall" => {
757                let remote = parse_arg!(args, as_str, "remote")?;
758                let result = self.incoming_ringing_call(&remote).await?;
759                Ok(to_value(result)?)
760            }
761            "IncomingWaitingCall" => {
762                let remote = parse_arg!(args, as_str, "remote")?;
763                let result = self.incoming_waiting_call(&remote).await?;
764                Ok(to_value(result)?)
765            }
766            "OutgoingCall" => {
767                let remote = parse_arg!(args, as_str, "remote")?;
768                let result = self.outgoing_call(&remote).await?;
769                Ok(to_value(result)?)
770            }
771            "SetCallActive" => {
772                let call_id = parse_arg!(args, as_u64, "call_id")?;
773                let result = self.set_call_active(call_id).await?;
774                Ok(to_value(result)?)
775            }
776            "SetCallHeld" => {
777                let call_id = parse_arg!(args, as_u64, "call_id")?;
778                let result = self.set_call_held(call_id).await?;
779                Ok(to_value(result)?)
780            }
781            "SetCallTerminated" => {
782                let call_id = parse_arg!(args, as_u64, "call_id")?;
783                let result = self.set_call_terminated(call_id).await?;
784                Ok(to_value(result)?)
785            }
786            "SetCallTransferredToAg" => {
787                let call_id = parse_arg!(args, as_u64, "call_id")?;
788                let result = self.set_call_transferred_to_ag(call_id).await?;
789                Ok(to_value(result)?)
790            }
791            "SetSpeakerGain" => {
792                let value = parse_arg!(args, as_u64, "value")?;
793                let result = self.set_speaker_gain(value).await?;
794                Ok(to_value(result)?)
795            }
796            "SetMicrophoneGain" => {
797                let value = parse_arg!(args, as_u64, "value")?;
798                let result = self.set_microphone_gain(value).await?;
799                Ok(to_value(result)?)
800            }
801            "SetServiceAvailable" => {
802                let service_available = Some(parse_arg!(args, as_bool, "value")?);
803                let result = self
804                    .update_network_information(NetworkInformation {
805                        service_available,
806                        ..Default::default()
807                    })
808                    .await?;
809                Ok(to_value(result)?)
810            }
811            "SetRoaming" => {
812                let roaming = Some(parse_arg!(args, as_bool, "value")?);
813                let result = self
814                    .update_network_information(NetworkInformation {
815                        roaming,
816                        ..Default::default()
817                    })
818                    .await?;
819                Ok(to_value(result)?)
820            }
821            "SetSignalStrength" => {
822                let signal_strength = parse_arg!(args, as_u64, "value")?;
823                let signal_strength = Some(match signal_strength {
824                    0 => SignalStrength::None,
825                    1 => SignalStrength::VeryLow,
826                    2 => SignalStrength::Low,
827                    3 => SignalStrength::Medium,
828                    4 => SignalStrength::High,
829                    5 => SignalStrength::VeryHigh,
830                    _ => panic!(""),
831                });
832                let result = self
833                    .update_network_information(NetworkInformation {
834                        signal_strength,
835                        ..Default::default()
836                    })
837                    .await?;
838                Ok(to_value(result)?)
839            }
840            "SetSubscriberNumber" => {
841                let number = parse_arg!(args, as_str, "value")?;
842                self.set_subscriber_number(number).await;
843                Ok(to_value(())?)
844            }
845            "SetOperator" => {
846                let value = parse_arg!(args, as_str, "value")?;
847                self.set_operator(value).await;
848                Ok(to_value(())?)
849            }
850            "SetNrecSupport" => {
851                let support = parse_arg!(args, as_bool, "value")?;
852                self.set_nrec_support(support).await;
853                Ok(to_value(())?)
854            }
855            "SetBatteryLevel" => {
856                let level = parse_arg!(args, as_u64, "value")?;
857                self.set_battery_level(level).await?;
858                Ok(to_value(())?)
859            }
860            "SetLastDialed" => {
861                let number = parse_arg!(args, as_str, "number")?.to_string();
862                self.set_last_dialed(Some(number)).await;
863                Ok(to_value(())?)
864            }
865            "ClearLastDialed" => {
866                self.set_last_dialed(None).await;
867                Ok(to_value(())?)
868            }
869            "SetMemoryLocation" => {
870                let location = parse_arg!(args, as_str, "location")?.to_string();
871                let number = parse_arg!(args, as_str, "number")?.to_string();
872                self.set_memory_location(location, Some(number)).await;
873                Ok(to_value(())?)
874            }
875            "ClearMemoryLocation" => {
876                let location = parse_arg!(args, as_str, "location")?.to_string();
877                self.set_memory_location(location, None).await;
878                Ok(to_value(())?)
879            }
880            "SetDialResult" => {
881                let number = parse_arg!(args, as_str, "number")?.to_string();
882                let status = parse_arg!(args, as_i64, "status")?.try_into()?;
883                let status = zx::Status::from_raw(status);
884                self.set_dial_result(number, status).await;
885                Ok(to_value(())?)
886            }
887            "GetState" => {
888                let result = self.get_state().await;
889                Ok(to_value(result)?)
890            }
891            "SetConnectionBehavior" => {
892                let autoconnect = parse_arg!(args, as_bool, "autoconnect")?;
893                self.set_connection_behavior(autoconnect).await?;
894                Ok(to_value(())?)
895            }
896            _ => bail!("Invalid Hfp FIDL method: {:?}", method),
897        }
898    }
899}
900
901#[async_trait(?Send)]
902impl Facade for RfcommFacade {
903    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
904        match method.as_ref() {
905            "RfcommInit" => {
906                let result = self.advertise()?;
907                Ok(to_value(result)?)
908            }
909            "RfcommRemoveService" => {
910                let result = self.clear_services();
911                Ok(to_value(result)?)
912            }
913            "DisconnectSession" => {
914                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
915                let result = self.close_session(id.into())?;
916                Ok(to_value(result)?)
917            }
918            "ConnectRfcommChannel" => {
919                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
920                let channel_number = parse_arg!(args, as_u64, "server_channel_number")?;
921                let channel_number = ServerChannel::try_from(u8::try_from(channel_number)?)?;
922                let result = self.outgoing_rfcomm_channel(id.into(), channel_number).await?;
923                Ok(to_value(result)?)
924            }
925            "DisconnectRfcommChannel" => {
926                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
927                let channel_number = parse_arg!(args, as_u64, "server_channel_number")?;
928                let channel_number = ServerChannel::try_from(u8::try_from(channel_number)?)?;
929                let result = self.close_rfcomm_channel(id.into(), channel_number)?;
930                Ok(to_value(result)?)
931            }
932            "SendRemoteLineStatus" => {
933                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
934                let channel_number = parse_arg!(args, as_u64, "server_channel_number")?;
935                let channel_number = ServerChannel::try_from(u8::try_from(channel_number)?)?;
936                let result = self.send_rls(id.into(), channel_number)?;
937                Ok(to_value(result)?)
938            }
939            "RfcommWrite" => {
940                let id = PeerId { value: parse_arg!(args, as_u64, "peer_id")? };
941                let channel_number = parse_arg!(args, as_u64, "server_channel_number")?;
942                let channel_number = ServerChannel::try_from(u8::try_from(channel_number)?)?;
943                let data = parse_arg!(args, as_str, "data")?.to_string();
944                let result = self.send_user_data(id.into(), channel_number, data.into_bytes())?;
945                Ok(to_value(result)?)
946            }
947            _ => bail!("Invalid RFCOMM method: {:?}", method),
948        }
949    }
950}