Skip to content

Commit

Permalink
SimpleDBus Proxy objects are now linked to their interfaces (#345)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdewald authored Sep 30, 2024
1 parent be7a6c6 commit 2bd1a5d
Show file tree
Hide file tree
Showing 46 changed files with 190 additions and 140 deletions.
9 changes: 9 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ The format is based on `Keep a Changelog`_, and this project adheres to `Semanti
[0.8.0] - XXXX-XX-XX
--------------------

This version brings a few important changes to the project, so please read the following carefully. The two main
changes are the introduction of the Android backend and an important refactor of SimpleBluez and SimpleDBus.

From an API perspective, SimpleBLE users won't notice any changes, but SimpleBluez users must now handle the
SimpleBluez::Bluez object as a std::shared_ptr, due to the upcoming work supporting Peripheral mode on Linux.
Some of these changes might have downstream effects that are hard to predict, so make sure to test after updating
and please report any issues you find.

**Added**

- (Android) Alpha preview of Android support.
Expand All @@ -17,6 +25,7 @@ The format is based on `Keep a Changelog`_, and this project adheres to `Semanti

- Implemented standalone ByteArray class derived from `kvn::bytearray`. *(Thanks tlifschitz!)*
- **API CHANGE**: Notify and Indicate callback in C bindings now receive the peripheral handle as the first argument.
- **API CHANGE**: SimpleBluez::Bluez must now be handled as a std::shared_ptr.

**Fixed**

Expand Down
7 changes: 3 additions & 4 deletions examples/simplebluez/ble_nus/ble_nus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
#include <iostream>
#include <thread>

SimpleBluez::Bluez bluez;
std::shared_ptr<SimpleBluez::Bluez> bluez = SimpleBluez::Bluez::create();

std::atomic_bool async_thread_active = true;
void async_thread_function() {
while (async_thread_active) {
bluez.run_async();
bluez->run_async();
std::this_thread::sleep_for(std::chrono::microseconds(10));
}
}
Expand All @@ -37,10 +37,9 @@ std::vector<std::shared_ptr<SimpleBluez::Device>> peripherals;
int main(int argc, char* argv[]) {
int selection = -1;

bluez.init();
std::thread* async_thread = new std::thread(async_thread_function);

auto adapters = bluez.get_adapters();
auto adapters = bluez->get_adapters();
std::cout << "Available adapters:" << std::endl;
for (int i = 0; i < adapters.size(); i++) {
std::cout << "[" << i << "] " << adapters[i]->identifier() << " [" << adapters[i]->address() << "]"
Expand Down
7 changes: 3 additions & 4 deletions examples/simplebluez/connect/connect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
#include <iostream>
#include <thread>

SimpleBluez::Bluez bluez;
std::shared_ptr<SimpleBluez::Bluez> bluez = SimpleBluez::Bluez::create();

std::atomic_bool async_thread_active = true;
void async_thread_function() {
while (async_thread_active) {
bluez.run_async();
bluez->run_async();
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
Expand All @@ -29,10 +29,9 @@ std::vector<std::shared_ptr<SimpleBluez::Device>> peripherals;
int main(int argc, char* argv[]) {
int selection = -1;

bluez.init();
std::thread* async_thread = new std::thread(async_thread_function);

auto adapters = bluez.get_adapters();
auto adapters = bluez->get_adapters();
std::cout << "Available adapters:" << std::endl;
for (int i = 0; i < adapters.size(); i++) {
std::cout << "[" << i << "] " << adapters[i]->identifier() << " [" << adapters[i]->address() << "]"
Expand Down
7 changes: 3 additions & 4 deletions examples/simplebluez/list_adapters/list_adapters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
#include <iostream>
#include <thread>

SimpleBluez::Bluez bluez;
std::shared_ptr<SimpleBluez::Bluez> bluez = SimpleBluez::Bluez::create();

std::atomic_bool async_thread_active = true;
void async_thread_function() {
while (async_thread_active) {
bluez.run_async();
bluez->run_async();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
Expand All @@ -23,10 +23,9 @@ void millisecond_delay(int ms) {
}

int main(int argc, char* argv[]) {
bluez.init();
std::thread* async_thread = new std::thread(async_thread_function);

auto adapters = bluez.get_adapters();
auto adapters = bluez->get_adapters();
std::cout << "The following adapters were found:" << std::endl;
for (int i = 0; i < adapters.size(); i++) {
std::cout << "[" << i << "] " << adapters[i]->identifier() << " [" << adapters[i]->address() << "]"
Expand Down
7 changes: 3 additions & 4 deletions examples/simplebluez/list_paired/list_paired.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
#include <iostream>
#include <thread>

SimpleBluez::Bluez bluez;
std::shared_ptr<SimpleBluez::Bluez> bluez = SimpleBluez::Bluez::create();

std::atomic_bool async_thread_active = true;
void async_thread_function() {
while (async_thread_active) {
bluez.run_async();
bluez->run_async();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
Expand All @@ -23,10 +23,9 @@ void millisecond_delay(int ms) {
}

int main(int argc, char* argv[]) {
bluez.init();
std::thread* async_thread = new std::thread(async_thread_function);

auto adapters = bluez.get_adapters();
auto adapters = bluez->get_adapters();
std::cout << "The following adapters were found:" << std::endl;
for (int i = 0; i < adapters.size(); i++) {
std::cout << "[" << i << "] " << adapters[i]->identifier() << " [" << adapters[i]->address() << "]"
Expand Down
7 changes: 3 additions & 4 deletions examples/simplebluez/notify/notify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
#include <iostream>
#include <thread>

SimpleBluez::Bluez bluez;
std::shared_ptr<SimpleBluez::Bluez> bluez = SimpleBluez::Bluez::create();

std::atomic_bool async_thread_active = true;
void async_thread_function() {
while (async_thread_active) {
bluez.run_async();
bluez->run_async();
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
Expand All @@ -37,10 +37,9 @@ std::vector<std::shared_ptr<SimpleBluez::Device>> peripherals;
int main(int argc, char* argv[]) {
int selection = -1;

bluez.init();
std::thread* async_thread = new std::thread(async_thread_function);

auto adapters = bluez.get_adapters();
auto adapters = bluez->get_adapters();
std::cout << "Available adapters:" << std::endl;
for (int i = 0; i < adapters.size(); i++) {
std::cout << "[" << i << "] " << adapters[i]->identifier() << " [" << adapters[i]->address() << "]"
Expand Down
11 changes: 5 additions & 6 deletions examples/simplebluez/pair/pair.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
#include <iostream>
#include <thread>

SimpleBluez::Bluez bluez;
std::shared_ptr<SimpleBluez::Bluez> bluez = SimpleBluez::Bluez::create();

std::atomic_bool async_thread_active = true;
void async_thread_function() {
while (async_thread_active) {
bluez.run_async();
bluez->run_async();
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
Expand All @@ -29,10 +29,9 @@ std::vector<std::shared_ptr<SimpleBluez::Device>> peripherals;
int main(int argc, char* argv[]) {
int selection = -1;

bluez.init();
std::thread* async_thread = new std::thread(async_thread_function);

auto agent = bluez.get_agent();
auto agent = bluez->get_agent();
agent->set_capabilities(SimpleBluez::Agent::Capabilities::KeyboardDisplay);

// Configure all callback handlers for the agent, as part of this example.
Expand Down Expand Up @@ -70,9 +69,9 @@ int main(int argc, char* argv[]) {
return true;
});

bluez.register_agent();
bluez->register_agent();

auto adapters = bluez.get_adapters();
auto adapters = bluez->get_adapters();
std::cout << "Available adapters:" << std::endl;
for (int i = 0; i < adapters.size(); i++) {
std::cout << "[" << i << "] " << adapters[i]->identifier() << " [" << adapters[i]->address() << "]"
Expand Down
7 changes: 3 additions & 4 deletions examples/simplebluez/read/read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
#include <iostream>
#include <thread>

SimpleBluez::Bluez bluez;
std::shared_ptr<SimpleBluez::Bluez> bluez = SimpleBluez::Bluez::create();

std::atomic_bool async_thread_active = true;
void async_thread_function() {
while (async_thread_active) {
bluez.run_async();
bluez->run_async();
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
Expand All @@ -37,10 +37,9 @@ std::vector<std::shared_ptr<SimpleBluez::Device>> peripherals;
int main(int argc, char* argv[]) {
int selection = -1;

bluez.init();
std::thread* async_thread = new std::thread(async_thread_function);

auto adapters = bluez.get_adapters();
auto adapters = bluez->get_adapters();
std::cout << "Available adapters:" << std::endl;
for (int i = 0; i < adapters.size(); i++) {
std::cout << "[" << i << "] " << adapters[i]->identifier() << " [" << adapters[i]->address() << "]"
Expand Down
7 changes: 3 additions & 4 deletions examples/simplebluez/scan/scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
#include <iostream>
#include <thread>

SimpleBluez::Bluez bluez;
std::shared_ptr<SimpleBluez::Bluez> bluez = SimpleBluez::Bluez::create();

std::atomic_bool async_thread_active = true;
void async_thread_function() {
while (async_thread_active) {
bluez.run_async();
bluez->run_async();
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
Expand All @@ -26,10 +26,9 @@ void millisecond_delay(int ms) {
int main(int argc, char* argv[]) {
int selection = -1;

bluez.init();
std::thread* async_thread = new std::thread(async_thread_function);

auto adapters = bluez.get_adapters();
auto adapters = bluez->get_adapters();
std::cout << "The following adapters were found:" << std::endl;
for (int i = 0; i < adapters.size(); i++) {
std::cout << "[" << i << "] " << adapters[i]->identifier() << " [" << adapters[i]->address() << "]"
Expand Down
4 changes: 2 additions & 2 deletions simpleble/src/backends/linux/AdapterBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ using namespace SimpleBLE;

std::vector<std::shared_ptr<AdapterBase>> AdapterBase::get_adapters() {
std::vector<std::shared_ptr<AdapterBase>> adapter_list;
auto internal_adapters = Bluez::get()->bluez.get_adapters();
auto internal_adapters = Bluez::get()->bluez->get_adapters();
for (auto& adapter : internal_adapters) {
adapter_list.push_back(std::make_shared<AdapterBase>(adapter));
}
Expand All @@ -18,7 +18,7 @@ std::vector<std::shared_ptr<AdapterBase>> AdapterBase::get_adapters() {
bool AdapterBase::bluetooth_enabled() {
bool enabled = false;

auto internal_adapters = Bluez::get()->bluez.get_adapters();
auto internal_adapters = Bluez::get()->bluez->get_adapters();
for (auto& adapter : internal_adapters) {
if (adapter->powered()) {
enabled = true;
Expand Down
10 changes: 5 additions & 5 deletions simpleble/src/backends/linux/Bluez.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
using namespace SimpleBLE;

Bluez* Bluez::get() {
static std::mutex get_mutex; // Static mutex to ensure thread safety when accessing the logger
static std::mutex get_mutex; // Static mutex to ensure thread safety when accessing the instance
std::scoped_lock lock(get_mutex); // Unlock the mutex on function return
static Bluez instance; // Static instance of the logger to ensure proper lifecycle management
static Bluez instance; // Static instance to ensure proper lifecycle management
return &instance;
}

Bluez::Bluez() {
bluez.init();
bluez = SimpleBluez::Bluez::create();
async_thread_active = true;
async_thread = new std::thread(&Bluez::async_thread_function, this);
}
Expand All @@ -29,10 +29,10 @@ Bluez::~Bluez() {
}

void Bluez::async_thread_function() {
SAFE_RUN({ bluez.register_agent(); });
SAFE_RUN({ bluez->register_agent(); });

while (async_thread_active) {
SAFE_RUN({ bluez.run_async(); });
SAFE_RUN({ bluez->run_async(); });
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
3 changes: 2 additions & 1 deletion simpleble/src/backends/linux/Bluez.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
#include <simplebluez/Bluez.h>
#include <atomic>
#include <thread>
#include <memory>

namespace SimpleBLE {

class Bluez {
public:
static Bluez* get();

SimpleBluez::Bluez bluez;
std::shared_ptr<SimpleBluez::Bluez> bluez;

private:
Bluez();
Expand Down
2 changes: 2 additions & 0 deletions simplebluez/include/simplebluez/Agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Agent : public SimpleDBus::Proxy {
Agent(std::shared_ptr<SimpleDBus::Connection> conn, const std::string& bus_name, const std::string& path);
virtual ~Agent() = default;

void init();

// ----- PROPERTIES -----
std::string capabilities() const;
void set_capabilities(Capabilities capabilities);
Expand Down
21 changes: 18 additions & 3 deletions simplebluez/include/simplebluez/Bluez.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,34 @@ namespace SimpleBluez {

class Bluez : public SimpleDBus::Proxy {
public:
Bluez();

// Note: This class MUST be consumed as a shared_ptr, as internally objects
// are linked together and proper usage of `shared_from_this()` is relied upon.
static std::shared_ptr<Bluez> create() {
static std::shared_ptr<Bluez> instance = std::shared_ptr<Bluez>(new Bluez());
instance->init();
return instance;
}
virtual ~Bluez();

void init();
// Delete copy and move operations
Bluez(const Bluez&) = delete;
Bluez& operator=(const Bluez&) = delete;
Bluez(Bluez&&) = delete;
Bluez& operator=(Bluez&&) = delete;

void run_async();

std::vector<std::shared_ptr<Adapter>> get_adapters();
std::shared_ptr<Agent> get_agent();
void register_agent();

private:
std::shared_ptr<SimpleDBus::Proxy> path_create(const std::string& path) override;

Bluez();
void init();

std::shared_ptr<SimpleDBus::Proxy> path_create(const std::string& path) override;
std::shared_ptr<SimpleDBus::ObjectManager> object_manager();

std::shared_ptr<Agent> _agent;
Expand Down
2 changes: 1 addition & 1 deletion simplebluez/include/simplebluez/interfaces/Adapter1.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Adapter1 : public SimpleDBus::Interface {
};

// ----- CONSTRUCTORS -----
Adapter1(std::shared_ptr<SimpleDBus::Connection> conn, std::string path);
Adapter1(std::shared_ptr<SimpleDBus::Connection> conn, std::shared_ptr<SimpleDBus::Proxy> proxy);
virtual ~Adapter1() = default;

// ----- METHODS -----
Expand Down
2 changes: 1 addition & 1 deletion simplebluez/include/simplebluez/interfaces/Agent1.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace SimpleBluez {

class Agent1 : public SimpleDBus::Interface {
public:
Agent1(std::shared_ptr<SimpleDBus::Connection> conn, std::string path);
Agent1(std::shared_ptr<SimpleDBus::Connection> conn, std::shared_ptr<SimpleDBus::Proxy> proxy);
virtual ~Agent1() = default;

// ----- METHODS -----
Expand Down
2 changes: 1 addition & 1 deletion simplebluez/include/simplebluez/interfaces/AgentManager1.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace SimpleBluez {

class AgentManager1 : public SimpleDBus::Interface {
public:
AgentManager1(std::shared_ptr<SimpleDBus::Connection> conn, std::string path);
AgentManager1(std::shared_ptr<SimpleDBus::Connection> conn, std::shared_ptr<SimpleDBus::Proxy> proxy);
virtual ~AgentManager1() = default;

// ----- METHODS -----
Expand Down
2 changes: 1 addition & 1 deletion simplebluez/include/simplebluez/interfaces/Battery1.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace SimpleBluez {

class Battery1 : public SimpleDBus::Interface {
public:
Battery1(std::shared_ptr<SimpleDBus::Connection> conn, std::string path);
Battery1(std::shared_ptr<SimpleDBus::Connection> conn, std::shared_ptr<SimpleDBus::Proxy> proxy);
virtual ~Battery1();

// ----- METHODS -----
Expand Down
Loading

0 comments on commit 2bd1a5d

Please sign in to comment.