aboutsummaryrefslogtreecommitdiff
path: root/ble/LinuxBluetooth.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ble/LinuxBluetooth.cpp')
-rw-r--r--ble/LinuxBluetooth.cpp112
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;
-// }
}
}