diff options
Diffstat (limited to 'ble/LinuxBluetooth.cpp')
-rw-r--r-- | ble/LinuxBluetooth.cpp | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/ble/LinuxBluetooth.cpp b/ble/LinuxBluetooth.cpp index 99762cb..9e7193f 100644 --- a/ble/LinuxBluetooth.cpp +++ b/ble/LinuxBluetooth.cpp @@ -84,7 +84,7 @@ public: LinuxBluetoothDevice &operator=(const LinuxBluetoothDevice &) = delete; - shared_ptr<BluetoothGatt> connectGatt() override; + shared_ptr<BluetoothGatt> connectGatt(BluetoothCallback* callback) override; private: LinuxBluetoothGatt *gatt; @@ -92,7 +92,7 @@ private: class LinuxBluetoothGatt final : public DefaultBluetoothGatt<LinuxBluetoothDevice, LinuxBluetoothGattService> { public: - explicit LinuxBluetoothGatt(LinuxBluetoothDevice &device); + explicit LinuxBluetoothGatt(LinuxBluetoothDevice &device, BluetoothCallback *callback); ~LinuxBluetoothGatt() override; @@ -104,9 +104,11 @@ public: void discoverServices() override; - void writeValue(const BluetoothGattCharacteristicPtr &c, const ByteBuffer &bytes) override; + void process(std::chrono::system_clock::duration max_duration) override; - void write(const BluetoothGattDescriptorPtr &c) override; + void writeValue(const BluetoothGattCharacteristicPtr &characteristic, const ByteBuffer &bytes) override; + + void write(const BluetoothGattDescriptorPtr &descriptor) override; ByteBuffer readValue(const BluetoothGattCharacteristicPtr &c, ByteBuffer &response) override; @@ -132,6 +134,9 @@ private: template<typename clock = std::chrono::system_clock> AttVariant exchangeAndWaitFor(ByteBuffer &buffer, std::chrono::time_point<clock> time); + template<typename clock = std::chrono::system_clock> + AttVariant waitFor(ByteBuffer &buffer, std::chrono::time_point<clock> time); + template<typename T, typename clock = std::chrono::system_clock> T exchangeAndWaitFor(ByteBuffer &buffer, std::chrono::time_point<clock> time, bool fail_on_error); @@ -174,11 +179,11 @@ LinuxBluetoothDevice::~LinuxBluetoothDevice() { delete gatt; }; -shared_ptr<BluetoothGatt> LinuxBluetoothDevice::connectGatt() { +shared_ptr<BluetoothGatt> LinuxBluetoothDevice::connectGatt(BluetoothCallback* callback) { // Make sure that we close the old connection and create a new one when the user asks for it. delete gatt; - gatt = new LinuxBluetoothGatt(*this); + gatt = new LinuxBluetoothGatt(*this, callback); return shared_ptr<LinuxBluetoothGatt>(shared_from_this(), gatt); } @@ -187,8 +192,8 @@ shared_ptr<BluetoothGatt> LinuxBluetoothDevice::connectGatt() { // Gatt // ----------------------------------------------------------------------- -LinuxBluetoothGatt::LinuxBluetoothGatt(LinuxBluetoothDevice &device) : - DefaultBluetoothGatt(device), l2cap() { +LinuxBluetoothGatt::LinuxBluetoothGatt(LinuxBluetoothDevice &device, BluetoothCallback *callback) : + DefaultBluetoothGatt(device, callback), l2cap() { connect(); } @@ -436,7 +441,7 @@ void LinuxBluetoothGatt::writeAndRead(const ByteBuffer &buffer, ByteBuffer &resp // LOG_DEBUG("written=" << written); - ssize_t r = read(l2cap, response.underlying(), response.getSize()); + ssize_t r = ::read(l2cap, response.underlying(), response.getSize()); if (r == -1) { throw BluetoothException(&device, "read(): " + errnoAsString()); @@ -465,7 +470,7 @@ AttVariant LinuxBluetoothGatt::processAvailableMessages(ByteBuffer &buffer) { // ", bytes available: " << to_string(bytes_available)); while (!ret && bytes_available) { - ssize_t r = read(l2cap, buffer.underlying(), buffer.getBytesLeft()); + ssize_t r = ::read(l2cap, buffer.underlying(), buffer.getBytesLeft()); if (r == -1) { throw BluetoothException(&device, "read(): " + errnoAsString()); } @@ -484,6 +489,9 @@ AttVariant LinuxBluetoothGatt::processAvailableMessages(ByteBuffer &buffer) { AttPdu::makeExchangeMtuRes(buffer, mtu); writeL2cap(buffer); + } else if (holds_alternative<HandleValueNotification>(v)) { + auto value = get<HandleValueNotification>(v); + LOG_DEBUG("got notification: " + to_string(value.data.getSize()) + ", pos=" + to_string(value.data.getSize())); } else { return v; } @@ -544,6 +552,11 @@ AttVariant LinuxBluetoothGatt::exchangeAndWaitFor(ByteBuffer &buffer, std::chron LOG_DEBUG("Writing message " << to_string(static_cast<AttPduType>(buffer.get8(0)))); this->writeL2cap(buffer); + return waitFor(buffer, time); +} + +template<typename clock> +AttVariant LinuxBluetoothGatt::waitFor(ByteBuffer &buffer, std::chrono::time_point<clock> time) { fd_set rfds; struct timeval tv{}; @@ -638,6 +651,15 @@ void LinuxBluetoothGatt::discoverDescriptors(shared_ptr<DefaultBluetoothGattChar } } +void LinuxBluetoothGatt::process(std::chrono::system_clock::duration max_duration) { + uint8_t b[mtu]; + ByteBuffer buffer{b, mtu}; + + processAvailableMessages(buffer); + + auto variant = waitFor(buffer, std::chrono::system_clock::now() + max_duration); +} + // ----------------------------------------------------------------------- // Adapter // ----------------------------------------------------------------------- @@ -791,9 +813,9 @@ void LinuxBluetoothAdapter::runScan(std::function<void(const shared_ptr<Bluetoot stopScan(); } -} -} -} +} // namespace linux +} // namespace bluetooth +} // namespace trygvis // ----------------------------------------------------------------------- // Implementation of platform-specific method. |