diff options
Diffstat (limited to 'ble/LinuxBluetooth.cpp')
-rw-r--r-- | ble/LinuxBluetooth.cpp | 112 |
1 files changed, 58 insertions, 54 deletions
diff --git a/ble/LinuxBluetooth.cpp b/ble/LinuxBluetooth.cpp index f662d45..b774644 100644 --- a/ble/LinuxBluetooth.cpp +++ b/ble/LinuxBluetooth.cpp @@ -28,15 +28,19 @@ class LinuxBluetoothAdapter; class LinuxBluetoothManager; -class LinuxBluetoothAdapter : public DefaultBluetoothAdapter { +class LinuxBluetoothAdapter final : public DefaultBluetoothAdapter { public: LinuxBluetoothAdapter(int hciDeviceId, Mac &mac); ~LinuxBluetoothAdapter(); - void runScan(std::function<void(BluetoothDevice &device)>) override; + LinuxBluetoothAdapter(const LinuxBluetoothAdapter &) = delete; - BluetoothDevice &getDevice(Mac &mac) override; + LinuxBluetoothAdapter& operator=(const LinuxBluetoothAdapter&) = delete; + + void runScan(std::function<void(const shared_ptr<BluetoothDevice> &device)>) override; + + shared_ptr <BluetoothDevice> getDevice(Mac &mac) override; private: void startScan() override; @@ -48,25 +52,29 @@ private: struct hci_filter hciFilter; bool scanning; - map<Mac, LinuxBluetoothDevice *> devices; + map<Mac, shared_ptr<LinuxBluetoothDevice>> devices; }; -class LinuxBluetoothDevice : public DefaultBluetoothDevice<LinuxBluetoothAdapter> { +class LinuxBluetoothDevice final : public DefaultBluetoothDevice<LinuxBluetoothAdapter>, + public std::enable_shared_from_this<LinuxBluetoothDevice> { public: LinuxBluetoothDevice(LinuxBluetoothAdapter &adapter, Mac &mac); - ~LinuxBluetoothDevice(); + virtual ~LinuxBluetoothDevice(); + + LinuxBluetoothDevice(const LinuxBluetoothDevice &) = delete; + + LinuxBluetoothDevice& operator=(const LinuxBluetoothDevice&) = delete; shared_ptr<BluetoothGatt> connectGatt() override; private: - weak_ptr<LinuxBluetoothGatt> gatt; - int l2cap; + LinuxBluetoothGatt *gatt; }; -class LinuxBluetoothGatt : public DefaultBluetoothGatt<LinuxBluetoothDevice> { +class LinuxBluetoothGatt final : public DefaultBluetoothGatt<LinuxBluetoothDevice> { public: - LinuxBluetoothGatt(LinuxBluetoothDevice &device, int l2cap); + LinuxBluetoothGatt(LinuxBluetoothDevice &device); ~LinuxBluetoothGatt(); @@ -94,8 +102,6 @@ private: ByteBuffer writeAndRead(ByteBuffer &out, shared_ptr<uint8_t> buffer, size_t size); int l2cap; - - bool connected; }; // Utilities @@ -121,28 +127,29 @@ LinuxBluetoothDevice::LinuxBluetoothDevice(LinuxBluetoothAdapter &adapter, Mac & } LinuxBluetoothDevice::~LinuxBluetoothDevice() { -// if (gatt) { -// delete gatt; -// } + LOG_DEBUG("Closing device " << mac.str()); + if (gatt) { + delete gatt; + } }; shared_ptr<BluetoothGatt> LinuxBluetoothDevice::connectGatt() { - if (auto p = gatt.lock()) { - return p; + // Make sure that we close the old connection and create a new one when the user asks for it. + if (gatt) { + delete gatt; } - auto ref = make_shared<LinuxBluetoothGatt>(*this, l2cap); - gatt = ref; + gatt = new LinuxBluetoothGatt(*this); - return ref; + return shared_ptr<LinuxBluetoothGatt>(shared_from_this(), gatt); } // ----------------------------------------------------------------------- // Gatt // ----------------------------------------------------------------------- -LinuxBluetoothGatt::LinuxBluetoothGatt(LinuxBluetoothDevice &device, int l2cap) : - DefaultBluetoothGatt(device), l2cap(l2cap) { +LinuxBluetoothGatt::LinuxBluetoothGatt(LinuxBluetoothDevice &device) : + DefaultBluetoothGatt(device) { connect(); } @@ -151,7 +158,7 @@ LinuxBluetoothGatt::~LinuxBluetoothGatt() { } bool LinuxBluetoothGatt::isConnected() const { - return connected; + return l2cap >= 0; } void LinuxBluetoothGatt::connect() { @@ -202,10 +209,10 @@ void LinuxBluetoothGatt::connect() { } void LinuxBluetoothGatt::disconnect() { - if (!connected) { + if (l2cap < 0) { return; } - LOG_DEBUG("mac = " << device.getMac().str()); + LOG_DEBUG("Disconnecting from mac = " << device.getMac().str()); close(l2cap); } @@ -439,15 +446,14 @@ LinuxBluetoothAdapter::LinuxBluetoothAdapter(int hciDeviceId, Mac &mac) : Defaul } LinuxBluetoothAdapter::~LinuxBluetoothAdapter() { - LOG_DEBUG("Stopping scan on device #" << hciDeviceId); + LOG_DEBUG("Closing adapter #" << hciDeviceId); stopScan(); close(hciSocket); - for (auto &pair : devices) { - delete pair.second; - } + // Hopefully all devices are disposed at this point. + devices.clear(); } void LinuxBluetoothAdapter::startScan() { @@ -504,19 +510,19 @@ void LinuxBluetoothAdapter::stopScan() { } } -BluetoothDevice &LinuxBluetoothAdapter::getDevice(Mac &mac) { - map<Mac, LinuxBluetoothDevice *>::iterator it = devices.find(mac); +shared_ptr<BluetoothDevice> LinuxBluetoothAdapter::getDevice(Mac &mac) { + auto it = devices.find(mac); if (it == devices.end()) { - LinuxBluetoothDevice *device = new LinuxBluetoothDevice(*this, mac); + auto device = make_shared<LinuxBluetoothDevice>(*this, mac); devices[mac] = device; - return *device; + return device; } - return *it->second; + return it->second; } -void LinuxBluetoothAdapter::runScan(std::function<void(BluetoothDevice &device)> callback) { +void LinuxBluetoothAdapter::runScan(std::function<void(const shared_ptr<BluetoothDevice> &device)> callback) { fd_set rfds; FD_ZERO(&rfds); @@ -559,7 +565,7 @@ void LinuxBluetoothAdapter::runScan(std::function<void(BluetoothDevice &device)> Mac mac = parseMac(advertisingInfo->bdaddr); - BluetoothDevice &device = getDevice(mac); + auto device = getDevice(mac); callback(device); } @@ -580,30 +586,28 @@ namespace trygvis { namespace bluetooth { using namespace trygvis::bluetooth::linux; -map<int, shared_ptr<LinuxBluetoothAdapter>> adapters; - -shared_ptr<BluetoothAdapter> getAdapterImpl(int hciDevice) { - map<int, shared_ptr<LinuxBluetoothAdapter>>::iterator it = adapters.find(hciDevice); - - if (it == adapters.end()) { - struct hci_dev_info di; - if (hci_devinfo(hciDevice, &di) < 0) { - throw BluetoothException("Could not query device info: " + errnoAsString()); - } - auto mac = parseMac(di.bdaddr); +shared_ptr<BluetoothAdapter> getAdapterImpl(string name) { + int hciDevice; + try { + hciDevice = std::stoi(name); + } catch (const std::invalid_argument &) { + throw BluetoothException("Bad device name: " + name); + } catch (const std::out_of_range &) { + throw BluetoothException("Bad device name: " + name); + } - auto adapter = adapters[hciDevice] = make_shared<LinuxBluetoothAdapter>(hciDevice, mac); - return adapter; + struct hci_dev_info di; + if (hci_devinfo(hciDevice, &di) < 0) { + throw BluetoothException("Could not query device info: " + errnoAsString()); } + auto mac = parseMac(di.bdaddr); - return std::static_pointer_cast<BluetoothAdapter, LinuxBluetoothAdapter>(it->second); + auto adapter = make_shared<LinuxBluetoothAdapter>(hciDevice, mac); + + return std::static_pointer_cast<BluetoothAdapter, LinuxBluetoothAdapter>(adapter); } void shutdownImpl() { - adapters.clear(); -// for (auto &pair: adapters) { -// delete pair.second; -// } } } |