#include "core/internal/medium_manager.h" #include "platform/synchronized.h" namespace location { namespace nearby { namespace connections { template MediumManager::MediumManager() : mediums_(new Mediums()), bluetooth_classic_lock_(Platform::createLock()), ble_lock_(Platform::createLock()), wifi_lan_lock_(Platform::createLock()) {} template MediumManager::~MediumManager() { // TODO(reznor): log.atDebug().log("Initiating shutdown of MediumManager."); Synchronized s1(bluetooth_classic_lock_.get()); Synchronized s2(ble_lock_.get()); Synchronized s3(wifi_lan_lock_.get()); mediums_.destroy(); // TODO(reznor): log.atDebug().log("MediumManager has shut down."); } // ~~~~~~~~~~~~~~~~~~~~~~~~ BLUETOOTH ~~~~~~~~~~~~~~~~~~~~~~~~ template bool MediumManager::isBluetoothAvailable() { Synchronized s(bluetooth_classic_lock_.get()); return mediums_->bluetoothClassic()->isAvailable(); } template bool MediumManager::turnOnBluetoothDiscoverability( const string& device_name) { Synchronized s(bluetooth_classic_lock_.get()); return mediums_->bluetoothRadio()->enable() && mediums_->bluetoothClassic()->turnOnDiscoverability(device_name); } template void MediumManager::turnOffBluetoothDiscoverability() { Synchronized s(bluetooth_classic_lock_.get()); mediums_->bluetoothClassic()->turnOffDiscoverability(); } template class DiscoveredDeviceCallback : public BluetoothClassic::DiscoveredDeviceCallback { public: typedef typename MediumManager::FoundBluetoothDeviceProcessor FoundBluetoothDeviceProcessor; explicit DiscoveredDeviceCallback( Ptr found_bluetooth_device_processor) : found_bluetooth_device_processor_(found_bluetooth_device_processor) {} void onDeviceDiscovered(Ptr device) override { found_bluetooth_device_processor_->onFoundBluetoothDevice(device); } void onDeviceNameChanged(Ptr device) override { found_bluetooth_device_processor_->onFoundBluetoothDevice(device); } void onDeviceLost(Ptr device) override { found_bluetooth_device_processor_->onLostBluetoothDevice(device); } private: ScopedPtr > found_bluetooth_device_processor_; }; template bool MediumManager::startScanningForBluetoothDevices( Ptr found_bluetooth_device_processor) { Synchronized s(bluetooth_classic_lock_.get()); return mediums_->bluetoothRadio()->enable() && mediums_->bluetoothClassic()->startDiscovery( MakePtr(new DiscoveredDeviceCallback( found_bluetooth_device_processor))); } template void MediumManager::stopScanningForBluetoothDevices() { Synchronized s(bluetooth_classic_lock_.get()); mediums_->bluetoothClassic()->stopDiscovery(); } template bool MediumManager::isListeningForIncomingBluetoothConnections( const string& service_name) { Synchronized s(bluetooth_classic_lock_.get()); return mediums_->bluetoothClassic()->isAcceptingConnections(service_name); } template class BluetoothAcceptedConnectionCallback : public BluetoothClassic::AcceptedConnectionCallback { public: typedef typename MediumManager::IncomingBluetoothConnectionProcessor IncomingBluetoothConnectionProcessor; explicit BluetoothAcceptedConnectionCallback( Ptr incoming_bluetooth_connection_processor) : incoming_bluetooth_connection_processor_( incoming_bluetooth_connection_processor) {} void onConnectionAccepted(Ptr socket) override { incoming_bluetooth_connection_processor_->onIncomingBluetoothConnection( socket); } private: ScopedPtr > incoming_bluetooth_connection_processor_; }; template bool MediumManager::startListeningForIncomingBluetoothConnections( const string& service_name, Ptr incoming_bluetooth_connection_processor) { Synchronized s(bluetooth_classic_lock_.get()); return mediums_->bluetoothRadio()->enable() && mediums_->bluetoothClassic()->startAcceptingConnections( service_name, MakePtr(new BluetoothAcceptedConnectionCallback( incoming_bluetooth_connection_processor))); } template void MediumManager::stopListeningForIncomingBluetoothConnections( const string& service_name) { Synchronized s(bluetooth_classic_lock_.get()); mediums_->bluetoothClassic()->stopAcceptingConnections(service_name); } template Ptr MediumManager::connectToBluetoothDevice( Ptr bluetooth_device, const string& service_name) { Synchronized s(bluetooth_classic_lock_.get()); if (!mediums_->bluetoothRadio()->enable()) { return Ptr(); } return mediums_->bluetoothClassic()->connect(bluetooth_device, service_name); } // ~~~~~~~~~~~~~~~~~~~~~~~~ BLE ~~~~~~~~~~~~~~~~~~~~~~~~ template bool MediumManager::isBleAvailable() { Synchronized s(ble_lock_.get()); #if BLE_V2_IMPLEMENTED return mediums_->bleV2()->isAvailable(); #else return mediums_->ble()->isAvailable(); #endif } // TODO(ahlee): Add nearbyNotificationsBeaconData for phase 2 of implementation. // TODO(ahlee): Add fast_advertisement_service_uuid and power_level to // AdvertisingOptions and pass it through. template bool MediumManager::startBleAdvertising( const string& service_id, ConstPtr advertisement_data) { Synchronized s(ble_lock_.get()); return mediums_->bluetoothRadio()->enable() && #if BLE_V2_IMPLEMENTED mediums_->bleV2()->startAdvertising( service_id, advertisement_data, BLEMediumV2::PowerMode::HIGH, /* fast_advertisement_service_uuid= */ ""); #else mediums_->ble()->startAdvertising(service_id, advertisement_data); #endif } template void MediumManager::stopBleAdvertising(const string& service_id) { Synchronized s(ble_lock_.get()); #if BLE_V2_IMPLEMENTED mediums_->bleV2()->stopAdvertising(); #else mediums_->ble()->stopAdvertising(); #endif } #if BLE_V2_IMPLEMENTED template class BLEAcceptedConnectionCallback : public mediums::BLEV2::AcceptedConnectionCallback { public: BLEAcceptedConnectionCallback() {} }; #else template class BLEAcceptedConnectionCallback : public BLE::AcceptedConnectionCallback { public: typedef typename MediumManager::IncomingBleConnectionProcessor IncomingBleConnectionProcessor; explicit BLEAcceptedConnectionCallback( Ptr incoming_ble_connection_processor) : incoming_ble_connection_processor_(incoming_ble_connection_processor) {} void onConnectionAccepted(Ptr socket, const string& service_id) override { incoming_ble_connection_processor_->onIncomingBleConnection(socket, service_id); } private: ScopedPtr > incoming_ble_connection_processor_; }; #endif template bool MediumManager::isListeningForIncomingBleConnections( const string& service_id) { Synchronized s(ble_lock_.get()); #if BLE_V2_IMPLEMENTED return mediums_->bleV2()->isAcceptingConnections(); #else return mediums_->ble()->isAcceptingConnections(); #endif } template bool MediumManager::startListeningForIncomingBleConnections( const string& service_id, Ptr incoming_ble_connection_processor) { Synchronized s(ble_lock_.get()); return mediums_->bluetoothRadio()->enable() && #if BLE_V2_IMPLEMENTED mediums_->bleV2()->startAcceptingConnections( service_id, MakePtr(new BLEAcceptedConnectionCallback())); #else mediums_->ble()->startAcceptingConnections( service_id, MakePtr(new BLEAcceptedConnectionCallback( incoming_ble_connection_processor))); #endif } template void MediumManager::stopListeningForIncomingBleConnections( const string& service_id) { Synchronized s(ble_lock_.get()); #if BLE_V2_IMPLEMENTED mediums_->bleV2()->stopAcceptingConnections(); #else mediums_->ble()->stopAcceptingConnections(); #endif } template class DiscoveredPeripheralCallback : public DISCOVERED_PERIPHERAL_CALLBACK { public: typedef typename MediumManager::FoundBlePeripheralProcessor FoundBlePeripheralProcessor; explicit DiscoveredPeripheralCallback( Ptr found_ble_peripheral_processor) : found_ble_peripheral_processor_(found_ble_peripheral_processor) {} void onPeripheralDiscovered(Ptr ble_peripheral, const string& service_id, #if BLE_V2_IMPLEMENTED ConstPtr advertisement_data, // TODO(ahlee): Add is_fast_advertisement to // FoundBlePeripheralProcessor. bool is_fast_advertisement) override { #else ConstPtr advertisement_data) { #endif found_ble_peripheral_processor_->onFoundBlePeripheral( ble_peripheral, service_id, advertisement_data); } void onPeripheralLost(Ptr ble_peripheral, const string& service_id) override { found_ble_peripheral_processor_->onLostBlePeripheral(ble_peripheral, service_id); } private: ScopedPtr > found_ble_peripheral_processor_; }; // TODO(ahlee): Add fast_advertisement_service_uuid and power_level to // DiscoveryOptions and pass it through. template bool MediumManager::startBleScanning( const string& service_id, Ptr found_ble_peripheral_processor) { Synchronized s(ble_lock_.get()); return mediums_->bluetoothRadio()->enable() && #if BLE_V2_IMPLEMENTED mediums_->bleV2()->startScanning( service_id, MakePtr(new DiscoveredPeripheralCallback( found_ble_peripheral_processor)), BLEMediumV2::PowerMode::HIGH, /* fast_advertisement_service_uuid= */ ""); #else mediums_->ble()->startScanning( service_id, MakePtr(new DiscoveredPeripheralCallback( found_ble_peripheral_processor))); #endif } template void MediumManager::stopBleScanning(const string& service_id) { Synchronized s(ble_lock_.get()); #if BLE_V2_IMPLEMENTED mediums_->bleV2()->stopScanning(); #else mediums_->ble()->stopScanning(); #endif } template Ptr MediumManager::connectToBlePeripheral( Ptr ble_peripheral, const string& service_id) { Synchronized s(ble_lock_.get()); if (!mediums_->bluetoothRadio()->enable()) { return Ptr(); } #if BLE_V2_IMPLEMENTED // TODO(ahlee): Replace when connecting logic is implemented. return Ptr(); #else return mediums_->ble()->connect(ble_peripheral, service_id); #endif } // ~~~~~~~~~~~~~~~~~~~~~~~~ WIFILAN ~~~~~~~~~~~~~~~~~~~~~~~~ template bool MediumManager::IsWifiLanAvailable() { Synchronized s(wifi_lan_lock_.get()); return mediums_->wifi_lan()->IsAvailable(); } template bool MediumManager::StartWifiLanAdvertising( absl::string_view service_id, absl::string_view service_info_name) { Synchronized s(wifi_lan_lock_.get()); return mediums_->wifi_lan()->StartAdvertising(service_id, service_info_name); } template void MediumManager::StopWifiLanAdvertising( absl::string_view service_id) { Synchronized s(wifi_lan_lock_.get()); mediums_->wifi_lan()->StopAdvertising(service_id); } template class DiscoveredServiceCallback : public mediums::DiscoveredServiceCallback { public: typedef typename MediumManager::FoundWifiLanServiceProcessor FoundWifiLanServiceProcessor; explicit DiscoveredServiceCallback( Ptr found_wifi_lan_service_processor) : found_wifi_lan_service_processor_(found_wifi_lan_service_processor) {} void OnServiceDiscovered(Ptr wifi_lan_service) override { found_wifi_lan_service_processor_->OnFoundWifiLanService(wifi_lan_service); } void OnServiceLost(Ptr wifi_lan_service) override { found_wifi_lan_service_processor_->OnLostWifiLanService(wifi_lan_service); } private: ScopedPtr > found_wifi_lan_service_processor_; }; template bool MediumManager::StartWifiLanDiscovery( absl::string_view service_id, Ptr found_wifi_lan_service_processor) { Synchronized s(wifi_lan_lock_.get()); return mediums_->wifi_lan()->StartDiscovery( service_id, MakePtr(new DiscoveredServiceCallback( found_wifi_lan_service_processor))); } template void MediumManager::StopWifiLanDiscovery( absl::string_view service_id) { Synchronized s(wifi_lan_lock_.get()); mediums_->wifi_lan()->StopDiscovery(service_id); } template class WifiLanAcceptedConnectionCallback : public mediums::WifiLan::AcceptedConnectionCallback { public: typedef typename MediumManager::IncomingWifiLanConnectionProcessor IncomingWifiLanConnectionProcessor; explicit WifiLanAcceptedConnectionCallback( Ptr incoming_wifi_lan_connection_processor) : incoming_wifi_lan_connection_processor_( incoming_wifi_lan_connection_processor) {} void OnConnectionAccepted(Ptr socket, absl::string_view service_id) override { incoming_wifi_lan_connection_processor_->OnIncomingWifiLanConnection( socket); } private: ScopedPtr > incoming_wifi_lan_connection_processor_; }; template bool MediumManager::IsListeningForIncomingWifiLanConnections( absl::string_view service_id) { Synchronized s(wifi_lan_lock_.get()); return mediums_->wifi_lan()->IsAcceptingConnections(service_id); } template bool MediumManager::StartListeningForIncomingWifiLanConnections( absl::string_view service_id, Ptr incoming_wifi_lan_connection_processor) { Synchronized s(wifi_lan_lock_.get()); return mediums_->wifi_lan()->StartAcceptingConnections( service_id, MakePtr(new WifiLanAcceptedConnectionCallback( incoming_wifi_lan_connection_processor))); } template void MediumManager::StopListeningForIncomingWifiLanConnections( absl::string_view service_id) { Synchronized s(wifi_lan_lock_.get()); mediums_->wifi_lan()->StopAcceptingConnections(service_id); } template Ptr MediumManager::ConnectToWifiLanService( Ptr wifi_lan_service, absl::string_view service_id) { Synchronized s(wifi_lan_lock_.get()); return mediums_->wifi_lan()->Connect(wifi_lan_service, service_id); } } // namespace connections } // namespace nearby } // namespace location