From b6f080193d71334e8afea95ae26afbc03c27fac3 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Fri, 20 Feb 2015 20:45:43 +0100 Subject: o Decoding GATT characteristics. --- LinuxBluetooth.cpp | 128 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 54 deletions(-) (limited to 'LinuxBluetooth.cpp') diff --git a/LinuxBluetooth.cpp b/LinuxBluetooth.cpp index 22d657e..4b7f0e0 100644 --- a/LinuxBluetooth.cpp +++ b/LinuxBluetooth.cpp @@ -68,9 +68,13 @@ public: private: vector discoverServices(uint16_t startHandle); + vector discoverCharacteristics(uint16_t startHandle, uint16_t endHandle); + ByteBuffer writeAndRead(ByteBuffer &out, shared_ptr buffer, size_t size); + uuid_t readUuid(const ByteBuffer &bytes) const; + LinuxBluetoothAdapter &_adapter; Mac _mac; int l2cap; @@ -153,45 +157,51 @@ void LinuxBluetoothDevice::connect() { } void LinuxBluetoothDevice::disconnect() { - DF << "mac=" << _mac.str(); + DF << "mac = " << _mac.str(); close(l2cap); } -uuid_t readUuid(ByteBuffer &bytes) { - size_t s = data.value.getBytesLeft(); +uuid_t LinuxBluetoothDevice::readUuid(const ByteBuffer &bytes) const { + size_t bytesLeft = bytes.getBytesLeft(); - if (s == 2) { + uuid_t u; + + if (bytesLeft == 2) { uint8_t bs[16] = BLUETOOTH_UUID_INITIALIZER; - bs[2] = data.value.get8(1); - bs[3] = data.value.get8(0); + bs[2] = bytes.get8(1); + bs[3] = bytes.get8(0); memcpy(&u, bs, 16); - } else if (s == 16) { + } else if (bytesLeft == 16) { uint8_t bs[16]; - bs[15] = data.value.get8(0); - bs[14] = data.value.get8(1); - bs[13] = data.value.get8(2); - bs[12] = data.value.get8(3); - bs[11] = data.value.get8(4); - bs[10] = data.value.get8(5); - bs[9] = data.value.get8(6); - bs[8] = data.value.get8(7); - bs[7] = data.value.get8(8); - bs[6] = data.value.get8(9); - bs[5] = data.value.get8(10); - bs[4] = data.value.get8(11); - bs[3] = data.value.get8(12); - bs[2] = data.value.get8(13); - bs[1] = data.value.get8(14); - bs[0] = data.value.get8(15); + bs[15] = bytes.get8(0); + bs[14] = bytes.get8(1); + bs[13] = bytes.get8(2); + bs[12] = bytes.get8(3); + bs[11] = bytes.get8(4); + bs[10] = bytes.get8(5); + bs[9] = bytes.get8(6); + bs[8] = bytes.get8(7); + bs[7] = bytes.get8(8); + bs[6] = bytes.get8(9); + bs[5] = bytes.get8(10); + bs[4] = bytes.get8(11); + bs[3] = bytes.get8(12); + bs[2] = bytes.get8(13); + bs[1] = bytes.get8(14); + bs[0] = bytes.get8(15); memcpy(&u, bs, 16); } else { - throw BluetoothException(this, "Unexpected size: " + to_string(data.value.getSize())); + throw BluetoothException(this, "Unexpected bytes left: " + to_string(bytesLeft)); } + + return u; } void LinuxBluetoothDevice::discoverServices() { uint16_t startHandle = 0x0001; + removeServices(); + do { vector values = discoverServices(startHandle); @@ -200,29 +210,41 @@ void LinuxBluetoothDevice::discoverServices() { break; } + uint16_t endGroupHandle; + for (auto &data: values) { - D << "handle: 0x" << hex << setw(4) << setfill('0') << data.handle << - ", endGroupHandle: 0x" << hex << setw(4) << setfill('0') << data.endGroupHandle << - ", value: " << data.value.toString(); + endGroupHandle = data.value.read16le(); + +// D << "handle: 0x" << hex << setw(4) << setfill('0') << data.handle << +// ", endGroupHandle: 0x" << hex << setw(4) << setfill('0') << endGroupHandle << +// ", value: " << data.value.toString(); uuid_t u = readUuid(data.value); - services.push_back(new DefaultBluetoothGattService(*this, u, data.handle, data.endGroupHandle)); + addService(new DefaultBluetoothGattService(*this, u, data.handle, endGroupHandle)); } auto last = values.back(); - startHandle = last.endGroupHandle; + startHandle = endGroupHandle; } while (startHandle != 0xffff); - for (auto &s : services) { - D << "service: " << to_string(s->getUuid()) << ", handle: " << s->getHandle() << ", end group handle: " << s->getEndGroupHandle(); - } +// for (auto &s : services) { +// D << "service: " << to_string(s->getUuid()) << ", handle: " << s->getHandle() << ", end group handle: " << s->getEndGroupHandle(); +// D << "s= " << (uint64_t) s; +// } auto it = services.begin(), - end = services.end(); + end = services.end(); + + if (it == end) { + return; + } startHandle = 0x0001; + vector chars; + + auto s = *it; do { vector values = discoverCharacteristics(startHandle, 0xffff); @@ -231,32 +253,32 @@ void LinuxBluetoothDevice::discoverServices() { break; } - for (auto c : values) { - uint8_t properties = c.data.read8(); - uint16_t valueHandle = c.data.read16le(); + uint16_t lastHandle = 0xffff; - if (values.data.getBytesLeft() == 2) { - uint16_t uuid = values.data.read16le(); - } else { + for (auto &c : values) { + while (c.handle > s->getEndGroupHandle() && it != end) { + s = *it++; +// D << "service: " << s->getHandle(); } - } - - auto last = values.back(); - startHandle = last.endGroupHandle; - } while (startHandle != 0xffff); + lastHandle = c.handle; - /* - if (it != end) { - auto &service = *it; + uint8_t properties = c.value.read8(); + uint16_t valueHandle = c.value.read16le(); + uuid_t uuid = readUuid(c.value); - for (auto &s : services) { - vector values = discoverCharacteristics(s->getHandle(), 0xffff); +// D << "characteristic: handle: " << setw(2) << setfill('0') << hex << (int) c.handle << +// ", properties: " << setw(2) << setfill('0') << hex << (int) properties << +// ", valueHandle: 0x" << setw(4) << setfill('0') << hex << (int) valueHandle << +// ", uuid: " << uuid; -// service = accumulate(services.begin(), services.end(), [](a&, b&){}); + s->addCharacteristic(new DefaultBluetoothGattCharacteristic(*s, c.handle, uuid, properties, valueHandle)); } - } - */ + + auto last = values.back(); + + startHandle = lastHandle + (uint8_t) 2; + } while (startHandle != 0xffff); } ByteBuffer LinuxBluetoothDevice::writeAndRead(ByteBuffer &out, shared_ptr buffer, size_t size) { @@ -343,8 +365,6 @@ LinuxBluetoothAdapter::~LinuxBluetoothAdapter() { close(hciSocket); - D << "Depeting " << devices.size() << " devices"; - for (auto &pair : devices) { delete pair.second; } -- cgit v1.2.3