blob: 071528af92a8a2d7b16b2c4c947b83f109ed6e35 [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 anyhow::{format_err, Error};
use fidl_fuchsia_bluetooth_avdtp::PeerControllerProxy;
use fidl_fuchsia_bluetooth_avrcp::{AvcPanelCommand, PlayStatus, PlaybackStatus};
use fidl_fuchsia_bluetooth_gatt::{
AttributePermissions, Characteristic, Descriptor, ReadByTypeResult, SecurityRequirements,
ServiceInfo,
};
use fidl_fuchsia_bluetooth_sys::Peer;
//use num_traits::FromPrimitive;
use num_derive::FromPrimitive;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
/// Handling different sessions.
/// Key is a generic id that is generated by the tool that is associated with a remote peer.
/// Value is the controller associated with the remote peer.
pub type PeerFactoryMap = HashMap<String, PeerControllerProxy>;
/// BleScan result type
/// TODO(fxbug.dev/875): Add support for RemoteDevices when clone() is implemented
#[derive(Serialize, Clone, Debug)]
pub struct BleScanResponse {
pub id: String,
pub name: String,
pub connectable: bool,
}
impl BleScanResponse {
pub fn new(id: String, name: String, connectable: bool) -> BleScanResponse {
BleScanResponse { id, name, connectable }
}
}
/// BleAdvertise result type (only uuid)
/// TODO(fxbug.dev/875): Add support for AdvertisingData when clone() is implemented
#[derive(Serialize, Clone, Debug)]
pub struct BleAdvertiseResponse {
pub name: Option<String>,
}
impl BleAdvertiseResponse {
pub fn new(name: Option<String>) -> BleAdvertiseResponse {
BleAdvertiseResponse { name }
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SecurityRequirementsContainer {
pub encryption_required: bool,
pub authentication_required: bool,
pub authorization_required: bool,
}
impl SecurityRequirementsContainer {
pub fn new(info: Option<Box<SecurityRequirements>>) -> SecurityRequirementsContainer {
match info {
Some(s) => {
let sec = *s;
SecurityRequirementsContainer {
encryption_required: sec.encryption_required,
authentication_required: sec.authentication_required,
authorization_required: sec.authorization_required,
}
}
None => SecurityRequirementsContainer {
encryption_required: false,
authentication_required: false,
authorization_required: false,
},
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct AttributePermissionsContainer {
pub read: SecurityRequirementsContainer,
pub write: SecurityRequirementsContainer,
pub update: SecurityRequirementsContainer,
}
impl AttributePermissionsContainer {
pub fn new(
info: Option<Box<AttributePermissions>>,
) -> Result<AttributePermissionsContainer, Error> {
match info {
Some(p) => {
let perm = *p;
Ok(AttributePermissionsContainer {
read: SecurityRequirementsContainer::new(perm.read),
write: SecurityRequirementsContainer::new(perm.write),
update: SecurityRequirementsContainer::new(perm.update),
})
}
None => return Err(format_err!("Unable to get information of AttributePermissions.")),
}
}
}
// Discover Characteristic response to hold characteristic info
// as Characteristics are not serializable.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct GattcDiscoverDescriptorResponse {
pub id: u64,
pub permissions: Option<AttributePermissionsContainer>,
pub uuid_type: String,
}
impl GattcDiscoverDescriptorResponse {
pub fn new(info: Vec<Descriptor>) -> Vec<GattcDiscoverDescriptorResponse> {
let mut res = Vec::new();
for v in info {
let copy = GattcDiscoverDescriptorResponse {
id: v.id,
permissions: match AttributePermissionsContainer::new(v.permissions) {
Ok(n) => Some(n),
Err(_) => None,
},
uuid_type: v.type_,
};
res.push(copy)
}
res
}
}
// Discover Characteristic response to hold characteristic info
// as Characteristics are not serializable.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct GattcDiscoverCharacteristicResponse {
pub id: u64,
pub properties: u32,
pub permissions: Option<AttributePermissionsContainer>,
pub uuid_type: String,
pub descriptors: Vec<GattcDiscoverDescriptorResponse>,
}
impl GattcDiscoverCharacteristicResponse {
pub fn new(info: Vec<Characteristic>) -> Vec<GattcDiscoverCharacteristicResponse> {
let mut res = Vec::new();
for v in info {
let copy = GattcDiscoverCharacteristicResponse {
id: v.id,
properties: v.properties,
permissions: match AttributePermissionsContainer::new(v.permissions) {
Ok(n) => Some(n),
Err(_) => None,
},
uuid_type: v.type_,
descriptors: {
match v.descriptors {
Some(d) => GattcDiscoverDescriptorResponse::new(d),
None => Vec::new(),
}
},
};
res.push(copy)
}
res
}
}
/// BleConnectPeripheral response (aka ServiceInfo)
/// TODO(fxbug.dev/875): Add support for ServiceInfo when clone(), serialize(), derived
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct BleConnectPeripheralResponse {
pub id: u64,
pub primary: bool,
pub uuid_type: String,
}
impl BleConnectPeripheralResponse {
pub fn new(info: Vec<ServiceInfo>) -> Vec<BleConnectPeripheralResponse> {
let mut res = Vec::new();
for v in info {
let copy =
BleConnectPeripheralResponse { id: v.id, primary: v.primary, uuid_type: v.type_ };
res.push(copy)
}
res
}
}
#[derive(Clone, Debug, Serialize)]
pub struct SerializablePeer {
pub address: Option<[u8; 6]>,
pub appearance: Option<u32>,
pub device_class: Option<u32>,
pub id: Option<u64>,
pub name: Option<String>,
pub connected: Option<bool>,
pub bonded: Option<bool>,
pub rssi: Option<i8>,
pub services: Option<Vec<[u8; 16]>>,
pub technology: Option<u32>,
pub tx_power: Option<i8>,
}
impl From<&Peer> for SerializablePeer {
fn from(peer: &Peer) -> Self {
let services = match &peer.services {
Some(s) => {
let mut service_list = Vec::new();
for item in s {
service_list.push(item.value);
}
Some(service_list)
}
None => None,
};
SerializablePeer {
address: peer.address.map(|a| a.bytes),
appearance: peer.appearance.map(|a| a.into_primitive() as u32),
device_class: peer.device_class.map(|d| d.value),
id: peer.id.map(|i| i.value),
name: peer.name.clone(),
connected: peer.connected,
bonded: peer.bonded,
rssi: peer.rssi,
services: services,
technology: peer.technology.map(|t| t as u32),
tx_power: peer.tx_power,
}
}
}
#[derive(Clone, Debug, Serialize)]
pub struct SerializableReadByTypeResult {
pub id: Option<u64>,
pub value: Option<Vec<u8>>,
}
impl SerializableReadByTypeResult {
pub fn new(result: &ReadByTypeResult) -> Self {
SerializableReadByTypeResult { id: result.id.clone(), value: result.value.clone() }
}
}
#[derive(Clone, Debug, Serialize, Eq, Copy)]
pub struct CustomPlayStatus {
pub song_length: Option<u32>,
pub song_position: Option<u32>,
pub playback_status: Option<u8>,
}
impl CustomPlayStatus {
pub fn new(status: &PlayStatus) -> Self {
let playback_status = match status.playback_status {
Some(p) => Some(p as u8),
None => None,
};
CustomPlayStatus {
song_length: status.song_length,
song_position: status.song_position,
playback_status: playback_status,
}
}
}
impl From<CustomPlayStatus> for PlayStatus {
fn from(status: CustomPlayStatus) -> Self {
let playback_status = match status.playback_status {
Some(0) => Some(PlaybackStatus::Stopped),
Some(1) => Some(PlaybackStatus::Playing),
Some(2) => Some(PlaybackStatus::Paused),
Some(3) => Some(PlaybackStatus::FwdSeek),
Some(4) => Some(PlaybackStatus::RevSeek),
Some(255) => Some(PlaybackStatus::Error),
None => None,
_ => panic!("Unknown playback status!"),
};
PlayStatus {
song_length: status.song_length,
song_position: status.song_position,
playback_status: playback_status,
..PlayStatus::EMPTY
}
}
}
impl From<PlayStatus> for CustomPlayStatus {
fn from(status: PlayStatus) -> Self {
CustomPlayStatus {
song_length: status.song_length,
song_position: status.song_position,
playback_status: match status.playback_status {
Some(p) => Some(p as u8),
None => None,
},
}
}
}
impl PartialEq for CustomPlayStatus {
fn eq(&self, other: &CustomPlayStatus) -> bool {
self.song_length == other.song_length
&& self.song_position == other.song_position
&& self.playback_status == other.playback_status
}
}
#[derive(Copy, Clone, Debug, FromPrimitive, Serialize, Deserialize)]
#[repr(u8)]
pub enum CustomAvcPanelCommand {
Select = 0,
Up = 1,
Down = 2,
Left = 3,
Right = 4,
RootMenu = 9,
ContentsMenu = 11,
FavoriteMenu = 12,
Exit = 13,
OnDemandMenu = 14,
AppsMenu = 15,
Key0 = 32,
Key1 = 33,
Key2 = 34,
Key3 = 35,
Key4 = 36,
Key5 = 37,
Key6 = 38,
Key7 = 39,
Key8 = 40,
Key9 = 41,
Dot = 42,
Enter = 43,
ChannelUp = 48,
ChannelDown = 49,
ChannelPrevious = 50,
InputSelect = 52,
Info = 53,
Help = 54,
PageUp = 55,
PageDown = 56,
Lock = 58,
Power = 64,
VolumeUp = 65,
VolumeDown = 66,
Mute = 67,
Play = 68,
Stop = 69,
Pause = 70,
Record = 71,
Rewind = 72,
FastForward = 73,
Eject = 74,
Forward = 75,
Backward = 76,
List = 77,
F1 = 113,
F2 = 114,
F3 = 115,
F4 = 116,
F5 = 117,
F6 = 118,
F7 = 119,
F8 = 120,
F9 = 121,
Red = 122,
Green = 123,
Blue = 124,
Yellow = 125,
}
impl From<CustomAvcPanelCommand> for AvcPanelCommand {
fn from(command: CustomAvcPanelCommand) -> Self {
match command {
CustomAvcPanelCommand::Select => AvcPanelCommand::Select,
CustomAvcPanelCommand::Up => AvcPanelCommand::Up,
CustomAvcPanelCommand::Down => AvcPanelCommand::Down,
CustomAvcPanelCommand::Left => AvcPanelCommand::Left,
CustomAvcPanelCommand::Right => AvcPanelCommand::Right,
CustomAvcPanelCommand::RootMenu => AvcPanelCommand::RootMenu,
CustomAvcPanelCommand::ContentsMenu => AvcPanelCommand::ContentsMenu,
CustomAvcPanelCommand::FavoriteMenu => AvcPanelCommand::FavoriteMenu,
CustomAvcPanelCommand::Exit => AvcPanelCommand::Exit,
CustomAvcPanelCommand::OnDemandMenu => AvcPanelCommand::OnDemandMenu,
CustomAvcPanelCommand::AppsMenu => AvcPanelCommand::AppsMenu,
CustomAvcPanelCommand::Key0 => AvcPanelCommand::Key0,
CustomAvcPanelCommand::Key1 => AvcPanelCommand::Key1,
CustomAvcPanelCommand::Key2 => AvcPanelCommand::Key2,
CustomAvcPanelCommand::Key3 => AvcPanelCommand::Key3,
CustomAvcPanelCommand::Key4 => AvcPanelCommand::Key4,
CustomAvcPanelCommand::Key5 => AvcPanelCommand::Key5,
CustomAvcPanelCommand::Key6 => AvcPanelCommand::Key6,
CustomAvcPanelCommand::Key7 => AvcPanelCommand::Key7,
CustomAvcPanelCommand::Key8 => AvcPanelCommand::Key8,
CustomAvcPanelCommand::Key9 => AvcPanelCommand::Key9,
CustomAvcPanelCommand::Dot => AvcPanelCommand::Dot,
CustomAvcPanelCommand::Enter => AvcPanelCommand::Enter,
CustomAvcPanelCommand::ChannelUp => AvcPanelCommand::ChannelUp,
CustomAvcPanelCommand::ChannelDown => AvcPanelCommand::ChannelDown,
CustomAvcPanelCommand::ChannelPrevious => AvcPanelCommand::ChannelPrevious,
CustomAvcPanelCommand::InputSelect => AvcPanelCommand::InputSelect,
CustomAvcPanelCommand::Info => AvcPanelCommand::Info,
CustomAvcPanelCommand::Help => AvcPanelCommand::Help,
CustomAvcPanelCommand::PageUp => AvcPanelCommand::PageUp,
CustomAvcPanelCommand::PageDown => AvcPanelCommand::PageDown,
CustomAvcPanelCommand::Lock => AvcPanelCommand::Lock,
CustomAvcPanelCommand::Power => AvcPanelCommand::Power,
CustomAvcPanelCommand::VolumeUp => AvcPanelCommand::VolumeUp,
CustomAvcPanelCommand::VolumeDown => AvcPanelCommand::VolumeDown,
CustomAvcPanelCommand::Mute => AvcPanelCommand::Mute,
CustomAvcPanelCommand::Play => AvcPanelCommand::Play,
CustomAvcPanelCommand::Stop => AvcPanelCommand::Stop,
CustomAvcPanelCommand::Pause => AvcPanelCommand::Pause,
CustomAvcPanelCommand::Record => AvcPanelCommand::Record,
CustomAvcPanelCommand::Rewind => AvcPanelCommand::Rewind,
CustomAvcPanelCommand::FastForward => AvcPanelCommand::FastForward,
CustomAvcPanelCommand::Eject => AvcPanelCommand::Eject,
CustomAvcPanelCommand::Forward => AvcPanelCommand::Forward,
CustomAvcPanelCommand::Backward => AvcPanelCommand::Backward,
CustomAvcPanelCommand::List => AvcPanelCommand::List,
CustomAvcPanelCommand::F1 => AvcPanelCommand::F1,
CustomAvcPanelCommand::F2 => AvcPanelCommand::F2,
CustomAvcPanelCommand::F3 => AvcPanelCommand::F3,
CustomAvcPanelCommand::F4 => AvcPanelCommand::F4,
CustomAvcPanelCommand::F5 => AvcPanelCommand::F5,
CustomAvcPanelCommand::F6 => AvcPanelCommand::F6,
CustomAvcPanelCommand::F7 => AvcPanelCommand::F7,
CustomAvcPanelCommand::F8 => AvcPanelCommand::F8,
CustomAvcPanelCommand::F9 => AvcPanelCommand::F9,
CustomAvcPanelCommand::Red => AvcPanelCommand::Red,
CustomAvcPanelCommand::Green => AvcPanelCommand::Green,
CustomAvcPanelCommand::Blue => AvcPanelCommand::Blue,
CustomAvcPanelCommand::Yellow => AvcPanelCommand::Yellow,
}
}
}
impl From<String> for CustomAvcPanelCommand {
fn from(command: String) -> Self {
match command.as_str() {
"Select" => CustomAvcPanelCommand::Select,
"Up" => CustomAvcPanelCommand::Up,
"Down" => CustomAvcPanelCommand::Down,
"Left" => CustomAvcPanelCommand::Left,
"Right" => CustomAvcPanelCommand::Right,
"RootMenu" => CustomAvcPanelCommand::RootMenu,
"ContentsMenu" => CustomAvcPanelCommand::ContentsMenu,
"FavoriteMenu" => CustomAvcPanelCommand::FavoriteMenu,
"Exit" => CustomAvcPanelCommand::Exit,
"OnDemandMenu" => CustomAvcPanelCommand::OnDemandMenu,
"AppsMenu" => CustomAvcPanelCommand::AppsMenu,
"Key0" => CustomAvcPanelCommand::Key0,
"Key1" => CustomAvcPanelCommand::Key1,
"Key2" => CustomAvcPanelCommand::Key2,
"Key3" => CustomAvcPanelCommand::Key3,
"Key4" => CustomAvcPanelCommand::Key4,
"Key5" => CustomAvcPanelCommand::Key5,
"Key6" => CustomAvcPanelCommand::Key6,
"Key7" => CustomAvcPanelCommand::Key7,
"Key8" => CustomAvcPanelCommand::Key8,
"Key9" => CustomAvcPanelCommand::Key9,
"Dot" => CustomAvcPanelCommand::Dot,
"Enter" => CustomAvcPanelCommand::Enter,
"ChannelUp" => CustomAvcPanelCommand::ChannelUp,
"ChannelDown" => CustomAvcPanelCommand::ChannelDown,
"ChannelPrevious" => CustomAvcPanelCommand::ChannelPrevious,
"InputSelect" => CustomAvcPanelCommand::InputSelect,
"Info" => CustomAvcPanelCommand::Info,
"Help" => CustomAvcPanelCommand::Help,
"PageUp" => CustomAvcPanelCommand::PageUp,
"PageDown" => CustomAvcPanelCommand::PageDown,
"Lock" => CustomAvcPanelCommand::Lock,
"Power" => CustomAvcPanelCommand::Power,
"VolumeUp" => CustomAvcPanelCommand::VolumeUp,
"VolumeDown" => CustomAvcPanelCommand::VolumeDown,
"Mute" => CustomAvcPanelCommand::Mute,
"Play" => CustomAvcPanelCommand::Play,
"Stop" => CustomAvcPanelCommand::Stop,
"Pause" => CustomAvcPanelCommand::Pause,
"Record" => CustomAvcPanelCommand::Record,
"Rewind" => CustomAvcPanelCommand::Rewind,
"FastForward" => CustomAvcPanelCommand::FastForward,
"Eject" => CustomAvcPanelCommand::Eject,
"Forward" => CustomAvcPanelCommand::Forward,
"Backward" => CustomAvcPanelCommand::Backward,
"List" => CustomAvcPanelCommand::List,
"F1" => CustomAvcPanelCommand::F1,
"F2" => CustomAvcPanelCommand::F2,
"F3" => CustomAvcPanelCommand::F3,
"F4" => CustomAvcPanelCommand::F4,
"F5" => CustomAvcPanelCommand::F5,
"F6" => CustomAvcPanelCommand::F6,
"F7" => CustomAvcPanelCommand::F7,
"F8" => CustomAvcPanelCommand::F8,
"F9" => CustomAvcPanelCommand::F9,
"Red" => CustomAvcPanelCommand::Red,
"Green" => CustomAvcPanelCommand::Green,
"Blue" => CustomAvcPanelCommand::Blue,
"Yellow" => CustomAvcPanelCommand::Yellow,
_invalid => panic!("Invalid CustomAvcPanelCommand command:{:?}", _invalid),
}
}
}
#[derive(Deserialize)]
pub struct AbsoluteVolumeCommand {
pub absolute_volume: u8,
}