diff options
Diffstat (limited to 'ble/LinuxBluetooth.cpp')
-rw-r--r-- | ble/LinuxBluetooth.cpp | 96 |
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]); |