Refactor IPC-message sending

This commit is contained in:
fokinv 2016-04-25 13:54:06 +02:00 committed by Attila Dusnoki
parent ecf4c942da
commit c8672ed0af
7 changed files with 326 additions and 493 deletions

View file

@ -9,7 +9,10 @@ use device::bluetooth::BluetoothGATTDescriptor;
use device::bluetooth::BluetoothGATTService;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use net_traits::bluetooth_scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence, RequestDeviceoptions};
use net_traits::bluetooth_thread::{BluetoothMethodMsg, BluetoothObjectMsg};
use net_traits::bluetooth_thread::{BluetoothCharacteristicMsg, BluetoothCharacteristicsMsg};
use net_traits::bluetooth_thread::{BluetoothDescriptorMsg, BluetoothDescriptorsMsg};
use net_traits::bluetooth_thread::{BluetoothDeviceMsg, BluetoothMethodMsg};
use net_traits::bluetooth_thread::{BluetoothResult, BluetoothServiceMsg, BluetoothServicesMsg};
use std::borrow::ToOwned;
use std::collections::HashMap;
use std::string::String;
@ -37,12 +40,6 @@ bitflags! {
}
}
macro_rules! send_error(
($sender:expr, $error:expr) => (
return $sender.send(BluetoothObjectMsg::Error { error: String::from($error) }).unwrap();
);
);
macro_rules! return_if_cached(
($cache:expr, $key:expr) => (
if $cache.contains_key($key) {
@ -351,14 +348,16 @@ impl BluetoothManager {
// Methods
fn request_device(&mut self, options: RequestDeviceoptions, sender: IpcSender<BluetoothObjectMsg>) {
fn request_device(&mut self,
options: RequestDeviceoptions,
sender: IpcSender<BluetoothResult<BluetoothDeviceMsg>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let devices = self.get_and_cache_devices(&mut adapter);
if devices.is_empty() {
send_error!(sender, DEVICE_ERROR);
return drop(sender.send(Err(String::from(DEVICE_ERROR))));
}
let matched_devices: Vec<BluetoothDevice> = devices.into_iter()
@ -366,34 +365,28 @@ impl BluetoothManager {
.collect();
for device in matched_devices {
if let Ok(address) = device.get_address() {
let message = BluetoothObjectMsg::BluetoothDevice {
id: address,
name: device.get_name().ok(),
device_class: device.get_class().ok(),
vendor_id_source: device.get_vendor_id_source().ok(),
vendor_id: device.get_vendor_id().ok(),
product_id: device.get_product_id().ok(),
product_version: device.get_device_id().ok(),
appearance: device.get_appearance().ok(),
tx_power: match device.get_tx_power() {
Ok(p) => Some(p as i8),
Err(_) => None,
},
rssi: match device.get_rssi() {
Ok(p) => Some(p as i8),
Err(_) => None,
},
};
return sender.send(message).unwrap();
let message = Ok(BluetoothDeviceMsg {
id: address,
name: device.get_name().ok(),
device_class: device.get_class().ok(),
vendor_id_source: device.get_vendor_id_source().ok(),
vendor_id: device.get_vendor_id().ok(),
product_id: device.get_product_id().ok(),
product_version: device.get_device_id().ok(),
appearance: device.get_appearance().ok(),
tx_power: device.get_tx_power().ok().map(|p| p as i8),
rssi: device.get_rssi().ok().map(|p| p as i8),
});
return drop(sender.send(message));
}
}
send_error!(sender, DEVICE_MATCH_ERROR);
return drop(sender.send(Err(String::from(DEVICE_MATCH_ERROR))));
}
fn gatt_server_connect(&mut self, device_id: String, sender: IpcSender<BluetoothObjectMsg>) {
fn gatt_server_connect(&mut self, device_id: String, sender: IpcSender<BluetoothResult<bool>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let connected = match self.get_device(&mut adapter, &device_id) {
@ -404,19 +397,16 @@ impl BluetoothManager {
d.connect().is_ok()
}
},
None => send_error!(sender, DEVICE_ERROR),
None => return drop(sender.send(Err(String::from(DEVICE_ERROR)))),
};
let message = BluetoothObjectMsg::BluetoothServer {
connected: connected
};
sender.send(message).unwrap();
let _ = sender.send(Ok(connected));
}
fn gatt_server_disconnect(&mut self, device_id: String, sender: IpcSender<BluetoothObjectMsg>) {
fn gatt_server_disconnect(&mut self, device_id: String, sender: IpcSender<BluetoothResult<bool>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let connected = match self.get_device(&mut adapter, &device_id) {
@ -427,201 +417,205 @@ impl BluetoothManager {
false
}
},
None => send_error!(sender, DEVICE_ERROR),
None => return drop(sender.send(Err(String::from(DEVICE_ERROR)))),
};
let message = BluetoothObjectMsg::BluetoothServer {
connected: connected
};
sender.send(message).unwrap();
let _ = sender.send(Ok(connected));
}
fn get_primary_service(&mut self, device_id: String, uuid: String, sender: IpcSender<BluetoothObjectMsg>) {
fn get_primary_service(&mut self,
device_id: String,
uuid: String,
sender: IpcSender<BluetoothResult<BluetoothServiceMsg>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let services = self.get_gatt_services_by_uuid(&mut adapter, &device_id, &uuid);
if services.is_empty() {
send_error!(sender, PRIMARY_SERVICE_ERROR);
return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR))));
}
for service in services {
if service.is_primary().unwrap_or(false) {
if let Ok(uuid) = service.get_uuid() {
let message = BluetoothObjectMsg::BluetoothService {
uuid: uuid,
is_primary: true,
instance_id: service.get_object_path(),
};
return sender.send(message).unwrap();
return drop(sender.send(Ok(BluetoothServiceMsg {
uuid: uuid,
is_primary: true,
instance_id: service.get_object_path(),
})));
}
}
}
send_error!(sender, PRIMARY_SERVICE_ERROR);
return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR))));
}
fn get_primary_services(&mut self,
device_id: String,
uuid: Option<String>,
sender: IpcSender<BluetoothObjectMsg>) {
sender: IpcSender<BluetoothResult<BluetoothServicesMsg>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let services = match uuid {
Some(id) => self.get_gatt_services_by_uuid(&mut adapter, &device_id, &id),
None => self.get_and_cache_gatt_services(&mut adapter, &device_id),
};
if services.is_empty() {
send_error!(sender, PRIMARY_SERVICE_ERROR);
return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR))));
}
let mut services_vec = vec!();
for service in services {
if service.is_primary().unwrap_or(false) {
if let Ok(uuid) = service.get_uuid() {
services_vec.push(BluetoothObjectMsg::BluetoothService {
uuid: uuid,
is_primary: true,
instance_id: service.get_object_path(),
});
services_vec.push(BluetoothServiceMsg {
uuid: uuid,
is_primary: true,
instance_id: service.get_object_path(),
});
}
}
}
if services_vec.is_empty() {
send_error!(sender, PRIMARY_SERVICE_ERROR);
return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR))));
}
let message = BluetoothObjectMsg::BluetoothServices { services_vec: services_vec };
sender.send(message).unwrap();
let _ = sender.send(Ok(services_vec));
}
fn get_characteristic(&mut self, service_id: String, uuid: String, sender: IpcSender<BluetoothObjectMsg>) {
fn get_characteristic(&mut self,
service_id: String,
uuid: String,
sender: IpcSender<BluetoothResult<BluetoothCharacteristicMsg>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let characteristics = self.get_gatt_characteristics_by_uuid(&mut adapter, &service_id, &uuid);
if characteristics.is_empty() {
send_error!(sender, CHARACTERISTIC_ERROR);
return drop(sender.send(Err(String::from(CHARACTERISTIC_ERROR))));
}
for characteristic in characteristics {
if let Ok(uuid) = characteristic.get_uuid() {
let properties = self.get_characteristic_properties(&characteristic);
let message = BluetoothObjectMsg::BluetoothCharacteristic {
uuid: uuid,
instance_id: characteristic.get_object_path(),
broadcast: properties.contains(BROADCAST),
read: properties.contains(READ),
write_without_response: properties.contains(WRITE_WITHOUT_RESPONSE),
write: properties.contains(WRITE),
notify: properties.contains(NOTIFY),
indicate: properties.contains(INDICATE),
authenticated_signed_writes: properties.contains(AUTHENTICATED_SIGNED_WRITES),
reliable_write: properties.contains(RELIABLE_WRITE),
writable_auxiliaries: properties.contains(WRITABLE_AUXILIARIES),
};
return sender.send(message).unwrap();
let message = Ok(BluetoothCharacteristicMsg {
uuid: uuid,
instance_id: characteristic.get_object_path(),
broadcast: properties.contains(BROADCAST),
read: properties.contains(READ),
write_without_response: properties.contains(WRITE_WITHOUT_RESPONSE),
write: properties.contains(WRITE),
notify: properties.contains(NOTIFY),
indicate: properties.contains(INDICATE),
authenticated_signed_writes: properties.contains(AUTHENTICATED_SIGNED_WRITES),
reliable_write: properties.contains(RELIABLE_WRITE),
writable_auxiliaries: properties.contains(WRITABLE_AUXILIARIES),
});
return drop(sender.send(message));
}
}
send_error!(sender, CHARACTERISTIC_ERROR);
return drop(sender.send(Err(String::from(CHARACTERISTIC_ERROR))));
}
fn get_characteristics(&mut self,
service_id: String,
uuid: Option<String>,
sender: IpcSender<BluetoothObjectMsg>) {
sender: IpcSender<BluetoothResult<BluetoothCharacteristicsMsg>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let characteristics = match uuid {
Some(id) => self.get_gatt_characteristics_by_uuid(&mut adapter, &service_id, &id),
None => self.get_and_cache_gatt_characteristics(&mut adapter, &service_id),
};
if characteristics.is_empty() {
send_error!(sender, CHARACTERISTIC_ERROR);
return drop(sender.send(Err(String::from(CHARACTERISTIC_ERROR))));
}
let mut characteristics_vec = vec!();
for characteristic in characteristics {
if let Ok(uuid) = characteristic.get_uuid() {
let properties = self.get_characteristic_properties(&characteristic);
characteristics_vec.push(BluetoothObjectMsg::BluetoothCharacteristic {
uuid: uuid,
instance_id: characteristic.get_object_path(),
broadcast: properties.contains(BROADCAST),
read: properties.contains(READ),
write_without_response: properties.contains(WRITE_WITHOUT_RESPONSE),
write: properties.contains(WRITE),
notify: properties.contains(NOTIFY),
indicate: properties.contains(INDICATE),
authenticated_signed_writes: properties.contains(AUTHENTICATED_SIGNED_WRITES),
reliable_write: properties.contains(RELIABLE_WRITE),
writable_auxiliaries: properties.contains(WRITABLE_AUXILIARIES),
});
characteristics_vec.push(
BluetoothCharacteristicMsg {
uuid: uuid,
instance_id: characteristic.get_object_path(),
broadcast: properties.contains(BROADCAST),
read: properties.contains(READ),
write_without_response: properties.contains(WRITE_WITHOUT_RESPONSE),
write: properties.contains(WRITE),
notify: properties.contains(NOTIFY),
indicate: properties.contains(INDICATE),
authenticated_signed_writes: properties.contains(AUTHENTICATED_SIGNED_WRITES),
reliable_write: properties.contains(RELIABLE_WRITE),
writable_auxiliaries: properties.contains(WRITABLE_AUXILIARIES),
});
}
}
if characteristics_vec.is_empty() {
send_error!(sender, CHARACTERISTIC_ERROR);
return drop(sender.send(Err(String::from(CHARACTERISTIC_ERROR))));
}
let message = BluetoothObjectMsg::BluetoothCharacteristics { characteristics_vec: characteristics_vec };
sender.send(message).unwrap();
let _ = sender.send(Ok(characteristics_vec));
}
fn get_descriptor(&mut self, characteristic_id: String, uuid: String, sender: IpcSender<BluetoothObjectMsg>) {
fn get_descriptor(&mut self,
characteristic_id: String,
uuid: String,
sender: IpcSender<BluetoothResult<BluetoothDescriptorMsg>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let descriptors = self.get_gatt_descriptors_by_uuid(&mut adapter, &characteristic_id, &uuid);
if descriptors.is_empty() {
send_error!(sender, DESCRIPTOR_ERROR);
return drop(sender.send(Err(String::from(DESCRIPTOR_ERROR))));
}
for descriptor in descriptors {
if let Ok(uuid) = descriptor.get_uuid() {
let message = BluetoothObjectMsg::BluetoothDescriptor {
uuid: uuid,
instance_id: descriptor.get_object_path(),
};
return sender.send(message).unwrap();
return drop(sender.send(Ok(BluetoothDescriptorMsg {
uuid: uuid,
instance_id: descriptor.get_object_path(),
})));
}
}
send_error!(sender, DESCRIPTOR_ERROR);
return drop(sender.send(Err(String::from(DESCRIPTOR_ERROR))));
}
fn get_descriptors(&mut self,
characteristic_id: String,
uuid: Option<String>,
sender: IpcSender<BluetoothObjectMsg>) {
sender: IpcSender<BluetoothResult<BluetoothDescriptorsMsg>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let descriptors = match uuid {
Some(id) => self.get_gatt_descriptors_by_uuid(&mut adapter, &characteristic_id, &id),
None => self.get_and_cache_gatt_descriptors(&mut adapter, &characteristic_id),
};
if descriptors.is_empty() {
send_error!(sender, DESCRIPTOR_ERROR);
return drop(sender.send(Err(String::from(DESCRIPTOR_ERROR))));
}
let mut descriptors_vec = vec!();
for descriptor in descriptors {
if let Ok(uuid) = descriptor.get_uuid() {
descriptors_vec.push(BluetoothObjectMsg::BluetoothDescriptor {
uuid: uuid,
instance_id: descriptor.get_object_path(),
});
descriptors_vec.push(BluetoothDescriptorMsg {
uuid: uuid,
instance_id: descriptor.get_object_path(),
});
}
}
if descriptors_vec.is_empty() {
send_error!(sender, DESCRIPTOR_ERROR);
return drop(sender.send(Err(String::from(DESCRIPTOR_ERROR))));
}
let message = BluetoothObjectMsg::BluetoothDescriptors { descriptors_vec: descriptors_vec };
sender.send(message).unwrap();
let _ = sender.send(Ok(descriptors_vec));
}
fn read_value(&mut self, id: String, sender: IpcSender<BluetoothObjectMsg>) {
fn read_value(&mut self, id: String, sender: IpcSender<BluetoothResult<Vec<u8>>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let mut value = self.get_gatt_characteristic(&mut adapter, &id)
.map(|c| c.read_value().unwrap_or(vec![]));
@ -629,19 +623,13 @@ impl BluetoothManager {
value = self.get_gatt_descriptor(&mut adapter, &id)
.map(|d| d.read_value().unwrap_or(vec![]));
}
let message = match value {
Some(v) => BluetoothObjectMsg::BluetoothReadValue { value: v },
None => send_error!(sender, VALUE_ERROR),
};
sender.send(message).unwrap();
let _ = sender.send(value.ok_or(String::from(VALUE_ERROR)));
}
fn write_value(&mut self, id: String, value: Vec<u8>, sender: IpcSender<BluetoothObjectMsg>) {
fn write_value(&mut self, id: String, value: Vec<u8>, sender: IpcSender<BluetoothResult<bool>>) {
let mut adapter = match self.get_or_create_adapter() {
Some(a) => a,
None => send_error!(sender, ADAPTER_ERROR),
None => return drop(sender.send(Err(String::from(ADAPTER_ERROR)))),
};
let mut result = self.get_gatt_characteristic(&mut adapter, &id)
.map(|c| c.write_value(value.clone()));
@ -649,15 +637,13 @@ impl BluetoothManager {
result = self.get_gatt_descriptor(&mut adapter, &id)
.map(|d| d.write_value(value.clone()));
}
let message = match result {
Some(v) => match v {
Ok(_) => BluetoothObjectMsg::BluetoothWriteValue,
Err(e) => send_error!(sender, e.to_string()),
Ok(_) => Ok(true),
Err(e) => return drop(sender.send(Err(e.to_string()))),
},
None => send_error!(sender, VALUE_ERROR),
None => return drop(sender.send(Err(String::from(VALUE_ERROR)))),
};
sender.send(message).unwrap();
let _ = sender.send(message);
}
}