aboutsummaryrefslogtreecommitdiff
path: root/ble
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2018-11-23 09:40:48 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2018-11-23 09:40:48 +0100
commit2034b1bb10720a2f0e6cc97427346f2320c115bc (patch)
treec382c6e404d48078aac71e2fd3f7f34587b99e7b /ble
parent0e2228fae626ec617a6a1f042ceb6dbdbd774558 (diff)
downloadble-toys-2034b1bb10720a2f0e6cc97427346f2320c115bc.tar.gz
ble-toys-2034b1bb10720a2f0e6cc97427346f2320c115bc.tar.bz2
ble-toys-2034b1bb10720a2f0e6cc97427346f2320c115bc.tar.xz
ble-toys-2034b1bb10720a2f0e6cc97427346f2320c115bc.zip
o Starting to handle notifications and indications
Cleaning up: o Using more of the shared_ptr typedefs. o Adding code styles used by CLion.
Diffstat (limited to 'ble')
-rw-r--r--ble/BluetoothImpl.h40
-rw-r--r--ble/LinuxBluetooth.cpp48
-rw-r--r--ble/att.cpp15
3 files changed, 66 insertions, 37 deletions
diff --git a/ble/BluetoothImpl.h b/ble/BluetoothImpl.h
index 5b53cd4..c41712c 100644
--- a/ble/BluetoothImpl.h
+++ b/ble/BluetoothImpl.h
@@ -110,7 +110,7 @@ public:
return valueHandle;
}
- shared_ptr<BluetoothGattDescriptor> getDescriptor(Uuid uuid) const override {
+ BluetoothGattDescriptorPtr getDescriptor(Uuid uuid) const override {
for (auto &d: descriptors) {
if (d->getUuid() == uuid) {
return d;
@@ -120,7 +120,7 @@ public:
return {};
}
- void addDescriptor(shared_ptr<BluetoothGattDescriptor> &&d) {
+ void addDescriptor(BluetoothGattDescriptorPtr &&d) {
descriptors.push_back(std::move(d));
}
@@ -166,17 +166,17 @@ public:
return endGroupHandle;
}
- vector<shared_ptr<BluetoothGattCharacteristic>> getCharacteristics() const override {
- vector<shared_ptr<BluetoothGattCharacteristic>> cs(characteristics.size());
+ vector<BluetoothGattCharacteristicPtr> getCharacteristics() const override {
+ vector<BluetoothGattCharacteristicPtr> cs(characteristics.size());
std::copy(begin(characteristics), end(characteristics), begin(cs));
return cs;
}
- virtual void addCharacteristic(shared_ptr<BluetoothGattCharacteristic> &&characteristic) {
+ virtual void addCharacteristic(BluetoothGattCharacteristicPtr &&characteristic) {
characteristics.emplace_back(characteristic);
}
- o<shared_ptr<BluetoothGattCharacteristic>> findCharacteristic(Uuid uuid) override {
+ o<BluetoothGattCharacteristicPtr> findCharacteristic(Uuid uuid) override {
for (auto &c: characteristics) {
if (c->getUuid() == uuid) {
return {c};
@@ -191,7 +191,7 @@ protected:
const Uuid uuid;
const uint16_t handle;
const uint16_t endGroupHandle;
- vector<shared_ptr<BluetoothGattCharacteristic>> characteristics;
+ vector<BluetoothGattCharacteristicPtr> characteristics;
};
template<class _D, class _S>
@@ -201,12 +201,8 @@ public:
return device;
}
-// virtual Collection <BluetoothGattService> getServices() const {
-// return CollectionImpl<BluetoothGattService, vector<_S>>(services);
-// }
-
- vector<shared_ptr<BluetoothGattService>> getServices() const override {
- vector<shared_ptr<BluetoothGattService>> ss(services.size());
+ vector <BluetoothGattServicePtr> getServices() const override {
+ vector<BluetoothGattServicePtr> ss(services.size());
std::copy(begin(services), end(services), begin(ss));
return ss;
}
@@ -214,32 +210,30 @@ public:
o <BluetoothGattServicePtr> findService(Uuid uuid) override {
for (auto &s: services) {
if (s->getUuid() == uuid) {
- return o<shared_ptr<BluetoothGattService>>(s);
+ return o<BluetoothGattServicePtr>(s);
}
}
- return o<shared_ptr<BluetoothGattService>>();
+ return {};
}
- void addService(shared_ptr<_S> service) {
+ void addService(std::shared_ptr<_S> service) {
services.emplace_back(service);
}
protected:
- explicit DefaultBluetoothGatt(_D &device) : LogSetup("BluetoothGatt"), device(device) {
- }
+ explicit DefaultBluetoothGatt(_D &device, BluetoothCallback *callback) :
+ LogSetup("BluetoothGatt"), device(device), callback(callback) {}
~DefaultBluetoothGatt() override = default;
void removeServices() {
-// for (auto s: services) {
-// delete s;
-// }
services.clear();
}
_D &device;
- vector<shared_ptr<_S>> services;
+ vector <std::shared_ptr<_S>> services;
+ BluetoothCallback *callback;
};
template<class A>
@@ -293,7 +287,7 @@ protected:
Mac &mac;
};
-shared_ptr <BluetoothAdapter> getAdapterImpl(string name);
+BluetoothAdapterPtr getAdapterImpl(string name);
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
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.
diff --git a/ble/att.cpp b/ble/att.cpp
index 301918d..4d3529a 100644
--- a/ble/att.cpp
+++ b/ble/att.cpp
@@ -153,7 +153,8 @@ vector<AttributeData> AttPdu::parseAttributeData(ByteBuffer &bytes) {
}
AttVariant AttPdu::parse(ByteBuffer &bytes) {
- switch (static_cast<AttPduType>(bytes.read8())) {
+ auto type = static_cast<AttPduType>(bytes.read8());
+ switch (type) {
case AttPduType::ERROR:
return ErrorRes::parse(bytes);
case AttPduType::EXCHANGE_MTU_REQ:
@@ -166,6 +167,10 @@ AttVariant AttPdu::parse(ByteBuffer &bytes) {
return ReadByGroupTypeRes{parseAttributeData(bytes)};
case AttPduType::READ_BY_TYPE_RES:
return ReadByTypeRes{parseAttributeData(bytes)};
+ case AttPduType::HANDLE_VALUE_NOTIFICATION:
+ return parseHandleValueNotification(bytes);
+ case AttPduType::HANDLE_VALUE_INDICATION:
+ return parseHandleValueIndication(bytes);
default:
return {};
}
@@ -196,6 +201,14 @@ FindInformationRes AttPdu::parseFindInformationRes(ByteBuffer &bytes) {
return {format, information};
}
+HandleValueNotification AttPdu::parseHandleValueNotification(ByteBuffer &bytes) {
+ return {bytes.read16le(), bytes.viewCursorToEnd()};
+}
+
+HandleValueIndication AttPdu::parseHandleValueIndication(ByteBuffer &bytes) {
+ return {bytes.read16le(), bytes.viewCursorToEnd()};
+}
+
void AttPdu::parseRead(ByteBuffer &bytes) {
auto t = static_cast<AttPduType>(bytes.read8());