#include "AdapterLinux.h"
#include "BackendBase.h"
#include "BackendUtils.h"
#include "CommonUtils.h"
#include <simplebluez/Bluez.h>
#include <simpleble/Config.h>
#include <simplebluez/Config.h>
#include <atomic>
#include <memory>
#include <mutex>
#include <thread>
namespace SimpleBLE {
class BackendBluez : public BackendSingleton<BackendBluez> {
public:
BackendBluez(buildToken);
virtual ~BackendBluez();
SimpleBluez::Bluez bluez;
virtual SharedPtrVector<AdapterBase> adapters() override;
virtual bool bluetooth_enabled() override;
std::string identifier() const noexcept override;
virtual bool is_active() override;
private:
std::thread* async_thread;
std::atomic_bool async_thread_active;
void async_thread_function();
};
std::shared_ptr<BackendBase> BACKEND_LINUX() { return BackendBluez::get(); }
BackendBluez::BackendBluez(buildToken) {
static std::mutex get_mutex; std::scoped_lock lock(get_mutex);
SimpleBluez::Config::use_system_bus = Config::SimpleBluez::use_system_bus;
bluez.init();
async_thread_active = true;
async_thread = new std::thread(&BackendBluez::async_thread_function, this);
}
BackendBluez::~BackendBluez() {
async_thread_active = false;
while (!async_thread->joinable()) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
async_thread->join();
delete async_thread;
}
SharedPtrVector<AdapterBase> BackendBluez::adapters() {
SharedPtrVector<AdapterBase> adapter_list;
auto internal_adapters = bluez.get_adapters();
for (auto& adapter : internal_adapters) {
adapter_list.push_back(std::make_shared<AdapterLinux>(adapter));
}
return adapter_list;
}
bool BackendBluez::bluetooth_enabled() {
bool enabled = false;
auto internal_adapters = bluez.get_adapters();
for (auto& adapter : internal_adapters) {
if (adapter->powered()) {
enabled = true;
break;
}
}
return enabled;
}
bool BackendBluez::is_active() {
return !Config::SimpleBluez::use_legacy_bluez_backend;
}
std::string BackendBluez::identifier() const noexcept { return "SimpleBluez"; }
void BackendBluez::async_thread_function() {
SAFE_RUN({
std::shared_ptr<SimpleBluez::Agent> agent = bluez.root_custom()->agent_add("default");
bluez.register_agent(agent);
});
while (async_thread_active) {
SAFE_RUN({ bluez.run_async(); });
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
}