aboutsummaryrefslogtreecommitdiff
path: root/ble/LinuxBluetooth.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ble/LinuxBluetooth.cpp')
-rw-r--r--ble/LinuxBluetooth.cpp96
1 files changed, 63 insertions, 33 deletions
diff --git a/ble/LinuxBluetooth.cpp b/ble/LinuxBluetooth.cpp
index b687807..a5d092b 100644
--- a/ble/LinuxBluetooth.cpp
+++ b/ble/LinuxBluetooth.cpp
@@ -21,6 +21,8 @@ namespace linux {
using namespace uuids;
+class LinuxBluetoothGatt;
+
class LinuxBluetoothDevice;
class LinuxBluetoothAdapter;
@@ -50,13 +52,24 @@ private:
map<Mac, LinuxBluetoothDevice *> devices;
};
-class LinuxBluetoothDevice : public DefaultBluetoothDevice {
+class LinuxBluetoothDevice : public DefaultBluetoothDevice<LinuxBluetoothAdapter> {
public:
- LinuxBluetoothDevice(LinuxBluetoothAdapter &adapter, Mac mac);
+ LinuxBluetoothDevice(LinuxBluetoothAdapter &adapter, Mac &mac);
+ ~LinuxBluetoothDevice();
+
+ BluetoothGatt &connectGatt() override;
+
+private:
+ LinuxBluetoothGatt* gatt;
+ int l2cap;
+};
- Mac const &mac() override;
+class LinuxBluetoothGatt : public DefaultBluetoothGatt {
+public:
+ LinuxBluetoothGatt(LinuxBluetoothDevice &device, int l2cap);
+ ~LinuxBluetoothGatt();
- LinuxBluetoothAdapter &adapter() override;
+// LinuxBluetoothDevice &getDevice() override;
void connect() override;
@@ -71,10 +84,7 @@ private:
ByteBuffer writeAndRead(ByteBuffer &out, shared_ptr<uint8_t> buffer, size_t size);
- uuid_t readUuid(const ByteBuffer &bytes) const;
-
- LinuxBluetoothAdapter &_adapter;
- Mac _mac;
+ LinuxBluetoothDevice &device;
int l2cap;
};
@@ -96,26 +106,45 @@ Mac parseMac(bdaddr_t &a) {
// Device
// -----------------------------------------------------------------------
-LinuxBluetoothDevice::LinuxBluetoothDevice(LinuxBluetoothAdapter &adapter, Mac mac) :
- DefaultBluetoothDevice(), _adapter(adapter), _mac(mac) {
+LinuxBluetoothDevice::LinuxBluetoothDevice(LinuxBluetoothAdapter &adapter, Mac &mac) :
+ DefaultBluetoothDevice(adapter, mac), gatt(nullptr) {
}
-Mac const &LinuxBluetoothDevice::mac() {
- return _mac;
+LinuxBluetoothDevice::~LinuxBluetoothDevice() {
+ if (gatt) {
+ delete gatt;
+ }
+};
+
+BluetoothGatt &LinuxBluetoothDevice::connectGatt() {
+ if (!gatt) {
+ gatt = new LinuxBluetoothGatt(*this, l2cap);
+ }
+
+ gatt->connect();
+
+ return *gatt;
+}
+
+// -----------------------------------------------------------------------
+// Gatt
+// -----------------------------------------------------------------------
+
+LinuxBluetoothGatt::LinuxBluetoothGatt(LinuxBluetoothDevice &device, int l2cap) :
+ device(device), l2cap(l2cap) {
}
-LinuxBluetoothAdapter &LinuxBluetoothDevice::adapter() {
- return _adapter;
+LinuxBluetoothGatt::~LinuxBluetoothGatt() {
}
-void LinuxBluetoothDevice::connect() {
+void LinuxBluetoothGatt::connect() {
struct sockaddr_l2 addr;
- D << "connect: mac=" << _mac.str();
+ D << "connect: mac=" << device.getMac().str();
l2cap = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
if (l2cap < 0) {
- throw BluetoothException(this, "LinuxBluetoothDevice::connect(): socket(): " + errnoAsString());
+ throw BluetoothException(&device, "LinuxBluetoothDevice::connect(): socket(): " + errnoAsString());
}
memset(&addr, 0, sizeof(addr));
@@ -126,7 +155,7 @@ void LinuxBluetoothDevice::connect() {
if (bind(l2cap, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
close(l2cap);
- throw BluetoothException(this, "LinuxBluetoothDevice::connect(): bind(): " + errnoAsString());
+ throw BluetoothException(&device, "LinuxBluetoothDevice::connect(): bind(): " + errnoAsString());
}
struct bt_security btsec;
@@ -134,14 +163,15 @@ void LinuxBluetoothDevice::connect() {
btsec.level = BT_SECURITY_LOW;
if (setsockopt(l2cap, SOL_BLUETOOTH, BT_SECURITY, &btsec, sizeof(btsec)) != 0) {
close(l2cap);
- throw BluetoothException(this, "LinuxBluetoothDevice::connect(): setsockopt(): " + errnoAsString());
+ throw BluetoothException(&device, "LinuxBluetoothDevice::connect(): setsockopt(): " + errnoAsString());
}
memset(&addr, 0, sizeof(addr));
addr.l2_family = AF_BLUETOOTH;
addr.l2_cid = htobs(ATT_CID);
addr.l2_bdaddr_type = BDADDR_LE_RANDOM;
- _mac.copy(addr.l2_bdaddr.b[5],
+ device.getMac().copy(
+ addr.l2_bdaddr.b[5],
addr.l2_bdaddr.b[4],
addr.l2_bdaddr.b[3],
addr.l2_bdaddr.b[2],
@@ -150,16 +180,16 @@ void LinuxBluetoothDevice::connect() {
if (::connect(l2cap, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
close(l2cap);
- throw BluetoothException(this, "LinuxBluetoothDevice::connect(): connect(): " + errnoAsString());
+ throw BluetoothException(&device, "LinuxBluetoothDevice::connect(): connect(): " + errnoAsString());
}
}
-void LinuxBluetoothDevice::disconnect() {
- DF << "mac = " << _mac.str();
+void LinuxBluetoothGatt::disconnect() {
+ DF << "mac = " << device.getMac().str();
close(l2cap);
}
-uuid_t LinuxBluetoothDevice::readUuid(const ByteBuffer &bytes) const {
+uuid_t readUuid(BluetoothDevice *device, const ByteBuffer &bytes) {
size_t bytesLeft = bytes.getBytesLeft();
uuid_t u;
@@ -189,13 +219,13 @@ uuid_t LinuxBluetoothDevice::readUuid(const ByteBuffer &bytes) const {
bs[0] = bytes.get8(15);
memcpy(&u, bs, 16);
} else {
- throw BluetoothException(this, "Unexpected bytes left: " + to_string(bytesLeft));
+ throw BluetoothException(device, "Unexpected bytes left: " + to_string(bytesLeft));
}
return u;
}
-void LinuxBluetoothDevice::discoverServices() {
+void LinuxBluetoothGatt::discoverServices() {
uint16_t startHandle = 0x0001;
removeServices();
@@ -217,9 +247,9 @@ void LinuxBluetoothDevice::discoverServices() {
// ", endGroupHandle: 0x" << hex << setw(4) << setfill('0') << endGroupHandle <<
// ", value: " << data.value.toString();
- uuid_t u = readUuid(data.value);
+ uuid_t u = readUuid(&device, data.value);
- addService(new DefaultBluetoothGattService(*this, u, data.handle, endGroupHandle));
+ addService(new DefaultBluetoothGattService(device, u, data.handle, endGroupHandle));
}
auto last = values.back();
@@ -263,7 +293,7 @@ void LinuxBluetoothDevice::discoverServices() {
uint8_t properties = c.value.read8();
uint16_t valueHandle = c.value.read16le();
- uuid_t uuid = readUuid(c.value);
+ uuid_t uuid = readUuid(&device, c.value);
// D << "characteristic: handle: " << setw(2) << setfill('0') << hex << (int) c.handle <<
// ", properties: " << setw(2) << setfill('0') << hex << (int) properties <<
@@ -279,7 +309,7 @@ void LinuxBluetoothDevice::discoverServices() {
} while (startHandle != 0xffff);
}
-ByteBuffer LinuxBluetoothDevice::writeAndRead(ByteBuffer &out, shared_ptr<uint8_t> buffer, size_t size) {
+ByteBuffer LinuxBluetoothGatt::writeAndRead(ByteBuffer &out, shared_ptr<uint8_t> buffer, size_t size) {
D << "pdu size=" << out.getCursor();
ssize_t written = write(l2cap, buffer.get(), out.getCursor());
@@ -288,7 +318,7 @@ ByteBuffer LinuxBluetoothDevice::writeAndRead(ByteBuffer &out, shared_ptr<uint8_
ssize_t r = read(l2cap, buffer.get(), size);
if (r == -1) {
- throw BluetoothException(this, "read(): " + errnoAsString());
+ throw BluetoothException(&device, "read(): " + errnoAsString());
}
auto in = ByteBuffer(buffer, (size_t) r);
@@ -298,7 +328,7 @@ ByteBuffer LinuxBluetoothDevice::writeAndRead(ByteBuffer &out, shared_ptr<uint8_
return in;
}
-vector<AttributeData> LinuxBluetoothDevice::discoverServices(uint16_t startHandle) {
+vector<AttributeData> LinuxBluetoothGatt::discoverServices(uint16_t startHandle) {
DF;
shared_ptr<uint8_t> buffer(new uint8_t[MAX_MTU]);
@@ -315,7 +345,7 @@ vector<AttributeData> LinuxBluetoothDevice::discoverServices(uint16_t startHandl
return values;
}
-vector<AttributeData> LinuxBluetoothDevice::discoverCharacteristics(uint16_t startHandle, uint16_t endHandle) {
+vector<AttributeData> LinuxBluetoothGatt::discoverCharacteristics(uint16_t startHandle, uint16_t endHandle) {
DF;
shared_ptr<uint8_t> buffer(new uint8_t[MAX_MTU]);