M module-bluetooth/Bluetooth/BluetoothWorker.cpp => module-bluetooth/Bluetooth/BluetoothWorker.cpp +96 -79
@@ 1,18 1,13 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+#include <service-bluetooth/ServiceBluetooth.hpp>
#include "BluetoothWorker.hpp"
#include "BtCommand.hpp"
#include "log/log.hpp"
#include "interface/profiles/A2DP/A2DP.hpp"
#include "interface/profiles/HSP/HSP.hpp"
#include "BtKeysStorage.hpp"
-extern "C"
-{
-#include "module-bluetooth/lib/btstack/src/btstack_util.h"
-}
-#include <btstack_run_loop_freertos.h>
-#include <service-bluetooth/ServiceBluetooth.hpp>
#if DEBUG_BLUETOOTH_HCI_COMS == 1
#define logHciComs(...) LOG_DEBUG(__VA_ARGS__)
@@ 29,36 24,34 @@ extern "C"
using namespace bsp;
-const char *c_str(Bt::Error::Code code)
+[[nodiscard]] auto to_string(bluetooth::Error::Code code) -> std::string
{
- switch (code) {
- case Bt::Error::Code::Success:
- return "Success";
- case Bt::Error::Code::NotReady:
- return "NotReady";
- case Bt::Error::Code::SystemError:
- return "SystemError";
- case Bt::Error::Code::LibraryError:
- return "LibraryError";
- }
- return "";
+ return utils::enumToString(code);
}
namespace queues
{
constexpr inline auto io = "qBtIO";
constexpr inline auto cmd = "qBtCmds";
+ constexpr inline auto btstack = "qBtStack";
+
+ constexpr inline auto queueLength = 10;
+ constexpr inline auto triggerQueueLength = 3;
} // namespace queues
BluetoothWorker::BluetoothWorker(sys::Service *service)
- : Worker(service), service(service), currentProfile(std::make_shared<Bt::HSP>()),
- settings(static_cast<ServiceBluetooth *>(service)->settingsHolder)
+ : Worker(service), service(service), currentProfile(std::make_shared<bluetooth::HSP>()),
+ settings(static_cast<ServiceBluetooth *>(service)->settingsHolder),
+ runLoop(std::make_unique<bluetooth::RunLoop>()), driver(std::make_unique<bluetooth::Driver>())
{
init({
- {queues::io, sizeof(Bt::Message), 10},
- {queues::cmd, sizeof(Bt::Command), 10},
+ {queues::io, sizeof(bluetooth::Message), queues::queueLength},
+ {queues::cmd, sizeof(bluetooth::Command), queues::queueLength},
+ {queues::btstack, sizeof(bool), queues::triggerQueueLength},
});
static_cast<ServiceBluetooth *>(service)->workerQueue = Worker::getQueueHandleByName(queues::cmd);
+ runLoop->setTriggerQueue(Worker::getQueueHandleByName(queues::btstack));
+ driver->init(runLoop->getRunLoopInstance());
}
BluetoothWorker::~BluetoothWorker()
@@ 69,7 62,7 @@ BluetoothWorker::~BluetoothWorker()
LOG_INFO("Worker removed");
}
-bool BluetoothWorker::run()
+auto BluetoothWorker::run() -> bool
{
LOG_INFO("-> BluetoothWorker run request");
if (is_running) {
@@ 79,48 72,49 @@ bool BluetoothWorker::run()
is_running = true;
auto el = queues[queueIO_handle];
BlueKitchen::getInstance()->qHandle = el->GetQueueHandle();
- Bt::KeyStorage::settings = settings;
- Bt::initialize_stack();
- Bt::register_hw_error_callback();
- Bt::GAP::register_scan();
+ bluetooth::KeyStorage::settings = settings;
+
+ driver->registerHardwareErrorCallback(nullptr);
+ bluetooth::GAP::register_scan();
std::string name = "PurePhone";
- auto settingsName = std::get<std::string>(settings->getValue(Bluetooth::Settings::DeviceName));
+ auto settingsName = std::get<std::string>(settings->getValue(bluetooth::Settings::DeviceName));
if (settingsName.empty()) {
LOG_ERROR("settings name empty!");
- settings->setValue(Bluetooth::Settings::DeviceName, name);
+ settings->setValue(bluetooth::Settings::DeviceName, name);
settingsName = name;
}
- Bt::set_name(settingsName);
- Bt::GAP::set_visibility(
- std::visit(Bluetooth::BoolVisitor(), settings->getValue(Bluetooth::Settings::Visibility)));
- settings->setValue(Bluetooth::Settings::State, static_cast<int>(BluetoothStatus::State::On));
+ bluetooth::set_name(settingsName);
+ bluetooth::GAP::set_visibility(
+ std::visit(bluetooth::BoolVisitor(), settings->getValue(bluetooth::Settings::Visibility)));
+
+ settings->setValue(bluetooth::Settings::State, static_cast<int>(BluetoothStatus::State::On));
+
settings->onLinkKeyAdded = [this](std::string addr) {
- for (auto &device : Bt::GAP::devices) {
+ for (auto &device : bluetooth::GAP::devices) {
if (bd_addr_to_str(device.address) == addr) {
// found paired device
pairedDevices.emplace_back(device);
- settings->setValue(Bluetooth::Settings::BondedDevices, SettingsSerializer::toString(pairedDevices));
+ settings->setValue(bluetooth::Settings::BondedDevices, SettingsSerializer::toString(pairedDevices));
}
}
};
- Bt::run_stack(&this->bt_worker_task);
- return true;
+ return driver->run() == bluetooth::Error::Success;
}
else {
return false;
}
}
-bool BluetoothWorker::scan()
+auto BluetoothWorker::scan() -> bool
{
std::vector<Device> empty;
- Bt::GAP::setOwnerService(service);
- auto ret = Bt::GAP::scan();
- if (ret.err != Bt::Error::Success) {
- LOG_ERROR("Cant start scan!: %s %" PRIu32 "", c_str(ret.err), ret.lib_code);
+ bluetooth::GAP::setOwnerService(service);
+ auto ret = bluetooth::GAP::scan();
+ if (ret.err != bluetooth::Error::Success) {
+ LOG_ERROR("Cant start scan!: %s %" PRIu32 "", to_string(ret.err).c_str(), ret.lib_code);
return false;
}
else {
@@ 132,59 126,77 @@ bool BluetoothWorker::scan()
void BluetoothWorker::stopScan()
{
- Bt::GAP::stop_scan();
+ bluetooth::GAP::stop_scan();
}
void BluetoothWorker::setVisibility(bool visibility)
{
- Bt::GAP::set_visibility(visibility);
- settings->setValue(Bluetooth::Settings::Visibility, visibility);
+ bluetooth::GAP::set_visibility(visibility);
+ settings->setValue(bluetooth::Settings::Visibility, visibility);
}
-bool BluetoothWorker::start_pan()
+auto BluetoothWorker::start_pan() -> bool
{
- Bt::PAN::bnep_setup();
- auto err = Bt::PAN::bnep_start();
- if (err.err != Bt::Error::Success) {
- LOG_ERROR("PAN setup error: %s %" PRIu32, c_str(err.err), err.lib_code);
+ bluetooth::PAN::bnep_setup();
+ auto err = bluetooth::PAN::bnep_start();
+ if (err.err != bluetooth::Error::Success) {
+ LOG_ERROR("PAN setup error: %s %" PRIu32, to_string(err.err).c_str(), err.lib_code);
}
return false;
}
-bool BluetoothWorker::handleCommand(QueueHandle_t queue)
+auto BluetoothWorker::handleCommand(QueueHandle_t queue) -> bool
{
- Bt::Command command;
+ bluetooth::Command command;
if (xQueueReceive(queue, &command, 0) != pdTRUE) {
LOG_ERROR("Queue receive failure!");
return false;
}
switch (command) {
- case Bt::PowerOn:
+ case bluetooth::PowerOn:
break;
- case Bt::StartScan:
+ case bluetooth::StartScan:
scan();
break;
- case Bt::StopScan:
+ case bluetooth::StopScan:
stopScan();
break;
- case Bt::VisibilityOn:
+ case bluetooth::VisibilityOn:
setVisibility(true);
break;
- case Bt::VisibilityOff:
+ case bluetooth::VisibilityOff:
setVisibility(false);
break;
- case Bt::ConnectAudio:
+ case bluetooth::ConnectAudio:
establishAudioConnection();
break;
- case Bt::DisconnectAudio:
+ case bluetooth::DisconnectAudio:
disconnectAudioConnection();
break;
- case Bt::PowerOff:
+ case bluetooth::PowerOff:
break;
}
return true;
}
-bool BluetoothWorker::handleMessage(uint32_t queueID)
+
+auto BluetoothWorker::handleBtStackTrigger(QueueHandle_t queue) -> bool
+{
+ bool notification;
+ if (xQueueReceive(queue, ¬ification, 0) != pdTRUE) {
+ LOG_ERROR("Queue receive failure!");
+ return false;
+ }
+ if (notification) {
+ runLoop->process();
+
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+auto BluetoothWorker::handleMessage(uint32_t queueID) -> bool
{
QueueHandle_t queue = queues[queueID]->GetQueueHandle();
if (queueID == queueService) {
@@ 196,33 208,36 @@ bool BluetoothWorker::handleMessage(uint32_t queueID)
handleCommand(queue);
return true;
}
+ if (queueID == queueRunloopTrigger) {
+ handleBtStackTrigger(queue);
+ return true;
+ }
if (queueID != queueIO_handle) {
LOG_ERROR("Wrong queue! %" PRIu32, queueID);
return false;
}
- Bt::Message notification = Bt::Message::EvtErrorRec;
+ auto notification = bluetooth::Message::EvtErrorRec;
if (xQueueReceive(queue, ¬ification, 0) != pdTRUE) {
LOG_ERROR("Queue receive failure!");
return false;
}
auto bt = BlueKitchen::getInstance();
switch (notification) {
- case Bt::Message::EvtSending:
+ case bluetooth::Message::EvtSending:
logHciComs("[evt] sending");
break;
- case Bt::Message::EvtSent:
+ case bluetooth::Message::EvtSent:
logHciComs("[evt] sent");
if (bt->write_done_cb) {
- btstack_run_loop_freertos_execute_code_on_main_thread(reinterpret_cast<void (*)(void *)>(bt->write_done_cb),
- nullptr);
+ bt->write_done_cb();
}
break;
- case Bt::Message::EvtReceiving:
+ case bluetooth::Message::EvtReceiving:
logHciComs("[evt] receiving");
break;
- case Bt::Message::EvtReceived: {
+ case bluetooth::Message::EvtReceived: {
logHciBytes("[evt] BT DMA received <-- [%ld]>%s<",
bt->read_len,
[&]() -> std::string {
@@ 237,15 252,17 @@ bool BluetoothWorker::handleMessage(uint32_t queueID)
bt->read_len = 0;
if (bt->read_ready_cb) {
- btstack_run_loop_freertos_execute_code_on_main_thread(reinterpret_cast<void (*)(void *)>(bt->read_ready_cb),
- nullptr);
+ bt->read_ready_cb();
}
} break;
- case Bt::Message::EvtSendingError:
- case Bt::Message::EvtReceivingError:
- case Bt::Message::EvtUartError:
- case Bt::Message::EvtRecUnwanted:
- LOG_ERROR("Uart error [%d]: %s", notification, Bt::MessageCstr(notification));
+ case bluetooth::Message::EvtSendingError:
+ [[fallthrough]];
+ case bluetooth::Message::EvtReceivingError:
+ [[fallthrough]];
+ case bluetooth::Message::EvtUartError:
+ [[fallthrough]];
+ case bluetooth::Message::EvtRecUnwanted:
+ LOG_ERROR("Uart error [%d]: %s", notification, bluetooth::MessageCstr(notification));
break;
default:
LOG_ERROR("ERROR");
@@ 254,22 271,22 @@ bool BluetoothWorker::handleMessage(uint32_t queueID)
return true;
}
-bool BluetoothWorker::establishAudioConnection()
+auto BluetoothWorker::establishAudioConnection() -> bool
{
currentProfile->setOwnerService(service);
- if (currentProfile->init() != Bt::Error::Success) {
+ if (currentProfile->init() != bluetooth::Error::Success) {
return false;
}
currentProfile->connect();
return true;
}
-bool BluetoothWorker::disconnectAudioConnection()
+auto BluetoothWorker::disconnectAudioConnection() -> bool
{
currentProfile->disconnect();
return true;
}
void BluetoothWorker::setDeviceAddress(bd_addr_t addr)
{
- Bt::GAP::do_pairing(addr);
+ bluetooth::GAP::do_pairing(addr);
currentProfile->setDeviceAddress(addr);
}
M module-bluetooth/Bluetooth/BluetoothWorker.hpp => module-bluetooth/Bluetooth/BluetoothWorker.hpp +16 -22
@@ 12,13 12,14 @@
#include <task.h>
#include <vector>
#include "service-bluetooth/SettingsHolder.hpp"
-
+#include "glucode/BluetoothRunLoop.hpp"
+#include "interface/BluetoothDriver.hpp"
struct HCI;
/// debug option for HCI (uart) commands debugging
// #define DO_DEBUG_HCI_COMS
-namespace Bt
+namespace bluetooth
{
enum Message : std::uint8_t
{
@@ 83,9 84,8 @@ class BluetoothWorker : private sys::Worker
queueService = 0,
queueControl = 1,
queueIO_handle, /// bsp support queue
- // queue_profiles, /// queue for communication between profile workers,
- // /// main bt_worker_task should dispatch these in events
queueCommands,
+ queueRunloopTrigger // btstack run_loop queue
};
TaskHandle_t bt_worker_task = nullptr;
@@ 101,32 101,26 @@ class BluetoothWorker : private sys::Worker
};
BluetoothWorker(sys::Service *service);
- virtual ~BluetoothWorker();
-
- virtual bool handleMessage(uint32_t queueID);
+ ~BluetoothWorker() override;
- bool handleCommand(QueueHandle_t queue);
+ auto handleMessage(uint32_t queueID) -> bool override;
+ auto handleCommand(QueueHandle_t queue) -> bool;
+ auto handleBtStackTrigger(QueueHandle_t queue) -> bool;
bool run();
-
- bool scan();
-
+ auto scan() -> bool;
void setVisibility(bool visibility);
-
- bool start_pan();
-
- bool establishAudioConnection();
-
- bool disconnectAudioConnection();
-
- Error aud_init();
+ auto start_pan() -> bool;
+ auto establishAudioConnection() -> bool;
+ auto disconnectAudioConnection() -> bool;
/// bluetooth stack id in use
unsigned long active_features;
void stopScan();
void setDeviceAddress(bd_addr_t addr);
- void initAudioBT();
- std::shared_ptr<Bt::Profile> currentProfile;
- std::shared_ptr<Bluetooth::SettingsHolder> settings;
+ std::shared_ptr<bluetooth::Profile> currentProfile;
+ std::shared_ptr<bluetooth::SettingsHolder> settings;
std::vector<Devicei> pairedDevices;
+ std::unique_ptr<bluetooth::RunLoop> runLoop;
+ std::unique_ptr<bluetooth::Driver> driver;
};
M module-bluetooth/Bluetooth/BtCommand.hpp => module-bluetooth/Bluetooth/BtCommand.hpp +3 -4
@@ 8,13 8,12 @@
#include "BluetoothWorker.hpp"
#include "Error.hpp"
#include <functional>
+#include <btstack_run_loop.h>
-namespace Bt
+namespace bluetooth
{
- auto initialize_stack() -> Error;
- auto register_hw_error_callback(std::function<void(uint8_t)> new_callback = nullptr) -> Error;
+
auto set_name(std::string &name) -> Error;
- auto run_stack(TaskHandle_t *handle) -> Error;
namespace GAP
{
extern std::vector<Devicei> devices;
M module-bluetooth/Bluetooth/BtKeysStorage.cpp => module-bluetooth/Bluetooth/BtKeysStorage.cpp +8 -8
@@ 4,13 4,13 @@
#include <algorithm>
#include "BtKeysStorage.hpp"
-json11::Json Bt::KeyStorage::keysJson = json11::Json();
-btstack_link_key_db_t Bt::KeyStorage::keyStorage;
-json11::Json::array Bt::KeyStorage::keys;
-std::string Bt::KeyStorage::keysEntry;
-std::shared_ptr<Bluetooth::SettingsHolder> Bt::KeyStorage::settings = nullptr;
+json11::Json bluetooth::KeyStorage::keysJson = json11::Json();
+btstack_link_key_db_t bluetooth::KeyStorage::keyStorage;
+json11::Json::array bluetooth::KeyStorage::keys;
+std::string bluetooth::KeyStorage::keysEntry;
+std::shared_ptr<bluetooth::SettingsHolder> bluetooth::KeyStorage::settings = nullptr;
-namespace Bt
+namespace bluetooth
{
namespace strings
{
@@ 39,7 39,7 @@ namespace Bt
{
LOG_INFO("opening storage from API");
if (settings) {
- keysEntry = std::visit(Bluetooth::StringVisitor(), settings->getValue(Bluetooth::Settings::BtKeys));
+ keysEntry = std::visit(bluetooth::StringVisitor(), settings->getValue(bluetooth::Settings::BtKeys));
}
else {
LOG_ERROR("failed opening settings for BT!");
@@ 140,7 140,7 @@ namespace Bt
json11::Json finalJson = json11::Json::object{{strings::keys, keys}};
keysEntry = finalJson.dump();
if (settings) {
- settings->setValue(Bluetooth::Settings::BtKeys, keysEntry);
+ settings->setValue(bluetooth::Settings::BtKeys, keysEntry);
}
else {
LOG_ERROR("failed to open settings to write!");
M module-bluetooth/Bluetooth/BtKeysStorage.hpp => module-bluetooth/Bluetooth/BtKeysStorage.hpp +2 -2
@@ 9,14 9,14 @@
#include <json/json11.hpp>
#include <service-bluetooth/SettingsHolder.hpp>
-namespace Bt
+namespace bluetooth
{
class KeyStorage
{
public:
static auto getKeyStorage() -> btstack_link_key_db_t *;
- static std::shared_ptr<Bluetooth::SettingsHolder> settings;
+ static std::shared_ptr<bluetooth::SettingsHolder> settings;
private:
static void openStorage();
M module-bluetooth/Bluetooth/Error.hpp => module-bluetooth/Bluetooth/Error.hpp +3 -3
@@ 7,7 7,7 @@
#include <variant>
#include <optional>
-namespace Bt
+namespace bluetooth
{
struct Error
@@ 20,9 20,9 @@ namespace Bt
LibraryError,
} err = Success;
uint32_t lib_code = 0;
- Error(enum Code err = Success, int lib_code = Success) : err(err), lib_code(0)
+ Error(enum Code err = Success, int lib_code = Success) : err(err)
{}
};
} // namespace Bt
-const char *c_str(Bt::Error::Code code);
+const char *c_str(bluetooth::Error::Code code);
A module-bluetooth/Bluetooth/glucode/BluetoothRunLoop.cpp => module-bluetooth/Bluetooth/glucode/BluetoothRunLoop.cpp +198 -0
@@ 0,0 1,198 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include "BluetoothRunLoop.hpp"
+#include "btstack_util.h"
+#include <cassert>
+namespace bluetooth
+{
+
+ btstack_linked_list_t RunLoop::timers;
+ btstack_linked_list_t RunLoop::data_sources;
+ bool RunLoop::run_loop_exit_requested;
+
+ QueueHandle_t RunLoop::btstack_run_loop_queue;
+ TaskHandle_t RunLoop::btstack_run_loop_task;
+ QueueHandle_t RunLoop::triggerQueue;
+ TimerHandle_t RunLoop::testTimer;
+
+ auto RunLoop::removeTimer(btstack_timer_source_t *ts) -> bool
+ {
+ return btstack_linked_list_remove(&timers, reinterpret_cast<btstack_linked_item_t *>(ts));
+ }
+ void RunLoop::setTriggerQueue(QueueHandle_t queue)
+ {
+ assert(queue != nullptr);
+ triggerQueue = queue;
+ }
+ void RunLoop::init()
+ {
+ timers = nullptr;
+ btstack_run_loop_queue = xQueueCreate(RUN_LOOP_QUEUE_LENGTH, RUN_LOOP_QUEUE_ITEM_SIZE);
+
+ // task to handle to optimize 'run on main thread'
+ btstack_run_loop_task = xTaskGetCurrentTaskHandle();
+
+ LOG_INFO("run loop init, task %p, queue item size %u",
+ btstack_run_loop_task,
+ static_cast<int>(sizeof(function_call_t)));
+ }
+ void RunLoop::enableDataSourceCallbacks(btstack_data_source_t *ds, uint16_t callback_types)
+ {
+ ds->flags |= callback_types;
+ }
+
+ void RunLoop::disableDataSourceCallbacks(btstack_data_source_t *ds, uint16_t callback_types)
+ {
+ ds->flags &= ~callback_types;
+ }
+
+ void RunLoop::addDataSource(btstack_data_source_t *ds)
+ {
+ btstack_linked_list_add(&data_sources, (btstack_linked_item_t *)ds);
+ }
+
+ auto RunLoop::removeDataSource(btstack_data_source_t *ds) -> bool
+ {
+ return btstack_linked_list_remove(&data_sources, (btstack_linked_item_t *)ds);
+ }
+ void RunLoop::triggerExit()
+ {
+ run_loop_exit_requested = true;
+ }
+ auto RunLoop::getTimeMs() -> TickType_t
+ {
+ return xTaskGetTickCount();
+ }
+ void RunLoop::trigger()
+ {
+
+ bool trigger = true;
+ if (triggerQueue != nullptr) {
+ xQueueSend(triggerQueue, &trigger, 0);
+ }
+ else {
+ LOG_FATAL("Trigger queue does not exist!");
+ }
+ }
+ void RunLoop::executeCodeOnMainThread(void (*fn)(void *arg), void *arg)
+ {
+
+ // directly call function if already on btstack task
+ if (xTaskGetCurrentTaskHandle() == btstack_run_loop_task) {
+ (*fn)(arg);
+ return;
+ }
+
+ function_call_t message;
+ message.fn = fn;
+ message.arg = arg;
+ BaseType_t res = xQueueSendToBack(btstack_run_loop_queue, &message, 0); // portMAX_DELAY);
+ if (res != pdTRUE) {
+ LOG_ERROR("Failed to post fn %p", fn);
+ }
+ trigger();
+ }
+
+ void RunLoop::addTimer(btstack_timer_source_t *ts)
+ {
+ btstack_linked_item_t *it = nullptr;
+ for (it = reinterpret_cast<btstack_linked_item_t *>(&timers); it->next != nullptr; it = it->next) {
+ // don't add timer that's already in there
+ auto *next = reinterpret_cast<btstack_timer_source_t *>(it->next);
+ if (next == ts) {
+ LOG_ERROR("btstack_run_loop_timer_add error: timer to add already in list!");
+ return;
+ }
+ // exit if new timeout before list timeout
+ int32_t delta = btstack_time_delta(ts->timeout, next->timeout);
+ if (delta < 0) {
+ break;
+ }
+ }
+ ts->item.next = it->next;
+ it->next = reinterpret_cast<btstack_linked_item_t *>(ts);
+ trigger();
+ }
+ void RunLoop::setTimer(btstack_timer_source_t *ts, uint32_t timeout_in_ms)
+ {
+ ts->timeout = getTimeMs() + timeout_in_ms + 1;
+ trigger();
+ }
+ void RunLoop::triggerCallback(TimerHandle_t xTimer)
+ {
+ trigger();
+ }
+ void RunLoop::start()
+ {
+ testTimer = xTimerCreate("TestTimer", pdMS_TO_TICKS(1000), pdTRUE, nullptr, triggerCallback);
+ xTimerStart(testTimer, 0);
+ }
+ auto RunLoop::process() -> bool
+ {
+
+ btstack_data_source_t *ds;
+ btstack_data_source_t *next;
+ for (ds = reinterpret_cast<btstack_data_source_t *>(data_sources); ds != nullptr; ds = next) {
+ next = reinterpret_cast<btstack_data_source_t *>(
+ ds->item.next); // cache pointer to next data_source to allow data source to remove itself
+ if ((ds->flags & DATA_SOURCE_CALLBACK_POLL) != 0) {
+ ds->process(ds, DATA_SOURCE_CALLBACK_POLL);
+ }
+ }
+ // process registered function calls on run loop thread
+ while (true) {
+ function_call_t message = {nullptr, nullptr};
+ BaseType_t res = xQueueReceive(btstack_run_loop_queue, &message, 0);
+ if (res == pdFALSE) {
+ break;
+ }
+ if (message.fn != nullptr) {
+ message.fn(message.arg);
+ }
+ }
+
+ // process timers and get next timeout
+ uint32_t timeout_ms = 1000;
+ while (timers != nullptr) {
+ auto *ts = reinterpret_cast<btstack_timer_source_t *>(timers);
+ uint32_t now = getTimeMs();
+ int32_t delta_ms = btstack_time_delta(ts->timeout, now);
+ if (delta_ms > 0) {
+ timeout_ms = delta_ms;
+ break;
+ }
+ // remove timer before processing it to allow handler to re-register with run loop
+ removeTimer(ts);
+ ts->process(ts);
+ }
+
+ // exit triggered by btstack_run_loop_freertos_trigger_exit (from data source, timer, run on main thread)
+ if (run_loop_exit_requested) {
+ return true;
+ }
+
+ xTimerChangePeriod(testTimer, pdMS_TO_TICKS(timeout_ms), 0);
+ return false;
+ }
+
+ auto RunLoop::getRunLoopInstance() -> btstack_run_loop *
+ {
+
+ runLoop = btstack_run_loop{
+ &init,
+ &addDataSource,
+ &removeDataSource,
+ &enableDataSourceCallbacks,
+ &disableDataSourceCallbacks,
+ &setTimer,
+ &addTimer,
+ &removeTimer,
+ &start,
+ nullptr,
+ &getTimeMs,
+ };
+ return &runLoop;
+ }
+
+} // namespace bluetooth
A module-bluetooth/Bluetooth/glucode/BluetoothRunLoop.hpp => module-bluetooth/Bluetooth/glucode/BluetoothRunLoop.hpp +54 -0
@@ 0,0 1,54 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+#include <log/log.hpp>
+#include "queue.hpp"
+#include <btstack_run_loop.h>
+#include <timer.hpp>
+
+namespace bluetooth
+{
+
+ using function_call_t = struct function_call
+ {
+ void (*fn)(void *arg);
+ void *arg;
+ };
+
+ constexpr inline auto RUN_LOOP_QUEUE_LENGTH = 20;
+ constexpr inline auto RUN_LOOP_QUEUE_ITEM_SIZE = sizeof(function_call_t);
+
+ class RunLoop
+ {
+ private:
+ static auto removeTimer(btstack_timer_source_t *ts) -> bool;
+ static void init();
+ static void enableDataSourceCallbacks(btstack_data_source_t *ds, uint16_t callback_types);
+ static void disableDataSourceCallbacks(btstack_data_source_t *ds, uint16_t callback_types);
+ static void addDataSource(btstack_data_source_t *ds);
+ static auto removeDataSource(btstack_data_source_t *ds) -> bool;
+ static void triggerExit();
+ static auto getTimeMs() -> TickType_t;
+ static void trigger();
+ static void executeCodeOnMainThread(void (*fn)(void *arg), void *arg);
+ static void addTimer(btstack_timer_source_t *ts);
+ static void setTimer(btstack_timer_source_t *ts, uint32_t timeout_in_ms);
+ static void start();
+ static void triggerCallback(TimerHandle_t xTimer);
+ static QueueHandle_t btstack_run_loop_queue;
+ static TaskHandle_t btstack_run_loop_task;
+ static QueueHandle_t triggerQueue;
+ static TimerHandle_t testTimer;
+ static btstack_linked_list_t timers;
+ static btstack_linked_list_t data_sources;
+ static bool run_loop_exit_requested;
+ btstack_run_loop runLoop;
+
+ public:
+ auto process() -> bool;
+ void setTriggerQueue(QueueHandle_t queue);
+ auto getRunLoopInstance() -> btstack_run_loop *;
+ };
+
+} // namespace bluetooth
R module-bluetooth/Bluetooth/BtstackWorker.cpp => module-bluetooth/Bluetooth/interface/BluetoothDriver.cpp +128 -171
@@ 1,27 1,27 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include <cstdlib>
-#include <log/log.hpp>
+#include "BluetoothDriver.hpp"
extern "C"
{
#include <btstack_event.h>
-
+#include <btstack_util.h>
#include <bluetooth_company_id.h>
#include <btstack_memory.h>
#include <btstack_run_loop.h>
-#include <btstack_stdin.h>
#include <hci.h>
#include <hci_dump.h>
#include <btstack_chipset_cc256x.h>
#include <btstack_link_key_db_memory.h>
-};
+}
+
+#include <service-bluetooth/ServiceBluetooth.hpp>
+#include <BtKeysStorage.hpp>
#ifdef TARGET_RT1051
#include <Bluetooth/glucode/btstack_uart_block_rt1051.h>
-#include <btstack_run_loop_freertos.h>
#else
extern "C"
{
@@ 30,178 30,139 @@ extern "C"
}
#endif
-#include "BtKeysStorage.hpp"
-#include <Error.hpp>
-#include <functional>
-
-// #define TLV_DB_PATH_PREFIX "/tmp/btstack_"
-// #define TLV_DB_PATH_POSTFIX ".tlv"
-// static char tlv_db_path[100];
-// static const btstack_tlv_t * tlv_impl;
-// static btstack_tlv_posix_t tlv_context;
-
-static void local_version_information_handler(uint8_t *packet);
-
-static hci_transport_config_uart_t config = {
- .type = HCI_TRANSPORT_CONFIG_UART,
- .baudrate_init = 115200,
- .baudrate_main = 0, // main baudrate
- .flowcontrol = 1, // flow control
- .device_name = nullptr,
-};
-
-static btstack_packet_callback_registration_t hci_event_callback_registration;
-
-static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
-{
- bd_addr_t addr;
- if (packet_type != HCI_EVENT_PACKET) {
- return;
- }
- switch (hci_event_packet_get_type(packet)) {
- case BTSTACK_EVENT_STATE:
- if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) {
- break;
- }
- gap_local_bd_addr(addr);
- LOG_INFO("BTstack up and running at %s", bd_addr_to_str(addr));
- // setup TLV
- // strcpy(tlv_db_path, TLV_DB_PATH_PREFIX);
- // strcat(tlv_db_path, bd_addr_to_str(addr));
- // strcat(tlv_db_path, TLV_DB_PATH_POSTFIX);
- // tlv_impl = btstack_tlv_posix_init_instance(&tlv_context, tlv_db_path);
- // btstack_tlv_set_instance(tlv_impl, &tlv_context);
- break;
- case HCI_EVENT_COMMAND_COMPLETE:
- if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)) {
- if (hci_event_command_complete_get_return_parameters(packet)[0] != 0u)
- break;
- // terminate, name 248 chars
- packet[6 + 248] = 0;
- LOG_INFO("Local name: %s", &packet[6]);
- }
- if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)) {
- local_version_information_handler(packet);
- }
- break;
- default:
- break;
- }
-}
-
-static void sigint_handler(int param)
-{
- UNUSED(param);
-
- LOG_INFO("CTRL-C - SIGINT received, shutting down..");
-
- // reset anyway
- btstack_stdin_reset();
-
- // power down
- hci_power_control(HCI_POWER_OFF);
- hci_close();
- exit(0);
-}
-
-static int led_state = 0;
-void hal_led_toggle()
-{
- led_state = 1 - led_state;
- LOG_INFO("LED State %u", led_state);
-}
-static void use_fast_uart()
-{
-#if defined(HAVE_POSIX_B240000_MAPPED_TO_3000000) || defined(HAVE_POSIX_B600_MAPPED_TO_3000000)
- LOG_INFO("Using 3000000 baud.");
- config.baudrate_main = 3000000;
-#elif defined(HAVE_POSIX_B1200_MAPPED_TO_2000000) || defined(HAVE_POSIX_B300_MAPPED_TO_2000000)
- LOG_INFO("Using 2000000 baud.");
- config.baudrate_main = 2000000;
-#else
- LOG_INFO("Using 921600 baud");
- config.baudrate_main = 921600;
-#endif
-}
-
-static void local_version_information_handler(uint8_t *packet)
+namespace bluetooth
{
- LOG_INFO("Local version information:");
- uint16_t hci_version = packet[6];
- uint16_t hci_revision = little_endian_read_16(packet, 7);
- uint16_t lmp_version = packet[9];
- uint16_t manufacturer = little_endian_read_16(packet, 10);
- uint16_t lmp_subversion = little_endian_read_16(packet, 12);
- LOG_INFO("- HCI Version 0x%04x", hci_version);
- LOG_INFO("- HCI Revision 0x%04x", hci_revision);
- LOG_INFO("- LMP Version 0x%04x", lmp_version);
- LOG_INFO("- LMP Subversion 0x%04x", lmp_subversion);
- LOG_INFO("- Manufacturer 0x%04x", manufacturer);
- switch (manufacturer) {
- case BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC:
- LOG_INFO("Texas Instruments - CC256x compatible chipset.");
- if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion()) {
- LOG_INFO("Error: LMP Subversion does not match initscript! ");
- LOG_INFO("Your initscripts is for %s chipset",
- btstack_chipset_cc256x_lmp_subversion() < lmp_subversion ? "an older" : "a newer");
- LOG_INFO("Please update Makefile to include the appropriate bluetooth_init_cc256???.c file");
- exit(10);
- }
- use_fast_uart();
- hci_set_chipset(btstack_chipset_cc256x_instance());
-#ifdef ENABLE_EHCILL
- LOG_INFO("eHCILL enabled.");
-#else
- LOG_INFO("eHCILL disable.");
-#endif
+ hci_transport_config_uart_t Driver::config;
- break;
- case BLUETOOTH_COMPANY_ID_NORDIC_SEMICONDUCTOR_ASA:
- LOG_INFO("Nordic Semiconductor nRF5 chipset.");
- break;
- default:
- LOG_INFO("Unknown manufacturer / manufacturer not supported yet.\n");
- break;
+#ifdef TARGET_RT1051
+ [[maybe_unused]] auto Driver::runLoopInitTarget(const btstack_run_loop *runLoop) -> const btstack_uart_block_t *
+ {
+ btstack_run_loop_init(runLoop);
+ const btstack_uart_block_t *uartDriver = btstack_uart_block_rt1051_instance();
+ return uartDriver;
}
-}
-
-extern "C"
-{
-#include <FreeRTOS.h>
-#include <task.h>
-};
+#else
-namespace Bt
-{
- void run_btstack(void *)
+ [[maybe_unused]] auto Driver::runLoopInitLinux(const btstack_run_loop *runLoop) -> const btstack_uart_block_t *
{
- LOG_INFO("- run BtStack loop\n");
- btstack_run_loop_execute();
+ btstack_run_loop_init(btstack_run_loop_posix_get_instance());
+ config.device_name = "/dev/telit";
+ LOG_INFO("H4 device: %s", config.device_name);
+ const btstack_uart_block_t *uartDriver = btstack_uart_block_posix_instance();
+ return uartDriver;
}
+#endif
- auto initialize_stack() -> Error
+ auto Driver::init(const btstack_run_loop *runLoop) -> Error::Code
{
btstack_memory_init();
+ config = {
+ .type = HCI_TRANSPORT_CONFIG_UART,
+ .baudrate_init = 115200,
+ .baudrate_main = 0,
+ .flowcontrol = 1,
+ .device_name = nullptr,
+ };
#ifdef TARGET_RT1051
- btstack_run_loop_init(btstack_run_loop_freertos_get_instance());
- const btstack_uart_block_t *uart_driver = btstack_uart_block_rt1051_instance();
+ auto uartDriver = runLoopInitTarget(runLoop);
#else
- btstack_run_loop_init(btstack_run_loop_posix_get_instance());
- config.device_name = "/dev/telit";
- LOG_INFO("H4 device: %s", config.device_name);
- const btstack_uart_block_t *uart_driver = btstack_uart_block_posix_instance();
+ auto uartDriver = runLoopInitLinux(runLoop);
#endif
- const hci_transport_t *transport = hci_transport_h4_instance(uart_driver);
+ const hci_transport_t *transport = hci_transport_h4_instance(uartDriver);
hci_init(transport, (void *)&config);
- hci_set_link_key_db(KeyStorage::getKeyStorage());
+ hci_set_link_key_db(bluetooth::KeyStorage::getKeyStorage());
hci_event_callback_registration.callback = &hci_packet_handler;
hci_add_event_handler(&hci_event_callback_registration);
LOG_DEBUG("BT worker run success");
- return Error();
+ return Error::Success;
}
- auto register_hw_error_callback(std::function<void(uint8_t)> new_callback) -> Error
+ void Driver::hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
+ {
+ bd_addr_t addr;
+ if (packet_type != HCI_EVENT_PACKET) {
+ return;
+ }
+ switch (hci_event_packet_get_type(packet)) {
+ case BTSTACK_EVENT_STATE:
+ if (btstack_event_state_get_state(packet) != HCI_STATE_WORKING) {
+ break;
+ }
+ gap_local_bd_addr(addr);
+ LOG_INFO("BTstack up and running at %s", bd_addr_to_str(addr));
+ break;
+ case HCI_EVENT_COMMAND_COMPLETE:
+ if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_name)) {
+ if (hci_event_command_complete_get_return_parameters(packet)[0] != 0u) {
+ break;
+ }
+ // terminate, name 248 chars
+ packet[6 + 248] = 0;
+ LOG_INFO("Local name: %s", &packet[6]);
+ }
+ if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)) {
+ local_version_information_handler(packet);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ void Driver::local_version_information_handler(uint8_t *packet)
+ {
+ LOG_INFO("Local version information:");
+ uint16_t hci_version = packet[6];
+ uint16_t hci_revision = little_endian_read_16(packet, 7);
+ uint16_t lmp_version = packet[9];
+ uint16_t manufacturer = little_endian_read_16(packet, 10);
+ uint16_t lmp_subversion = little_endian_read_16(packet, 12);
+ LOG_INFO("- HCI Version 0x%04x", hci_version);
+ LOG_INFO("- HCI Revision 0x%04x", hci_revision);
+ LOG_INFO("- LMP Version 0x%04x", lmp_version);
+ LOG_INFO("- LMP Subversion 0x%04x", lmp_subversion);
+ LOG_INFO("- Manufacturer 0x%04x", manufacturer);
+ switch (manufacturer) {
+ case BLUETOOTH_COMPANY_ID_TEXAS_INSTRUMENTS_INC:
+ LOG_INFO("Texas Instruments - CC256x compatible chipset.");
+ if (lmp_subversion != btstack_chipset_cc256x_lmp_subversion()) {
+ LOG_INFO("Error: LMP Subversion does not match initscript! ");
+ LOG_INFO("Your initscripts is for %s chipset",
+ btstack_chipset_cc256x_lmp_subversion() < lmp_subversion ? "an older" : "a newer");
+ LOG_INFO("Please update Makefile to include the appropriate bluetooth_init_cc256???.c file");
+ exit(10);
+ }
+ LOG_INFO("Using 921600 baud");
+ config.baudrate_main = 921600;
+ hci_set_chipset(btstack_chipset_cc256x_instance());
+#ifdef ENABLE_EHCILL
+ LOG_INFO("eHCILL enabled.");
+#else
+ LOG_INFO("eHCILL disable.");
+#endif
+
+ break;
+ case BLUETOOTH_COMPANY_ID_NORDIC_SEMICONDUCTOR_ASA:
+ LOG_INFO("Nordic Semiconductor nRF5 chipset.");
+ break;
+ default:
+ LOG_INFO("Unknown manufacturer / manufacturer not supported yet.\n");
+ break;
+ }
+ }
+ auto Driver::run() -> Error::Code
+ {
+ auto ret = hci_power_control(HCI_POWER_ON);
+ if (ret != 0) {
+ LOG_ERROR("HCI power on failed, can't start Bluetooth!");
+ return Error::LibraryError;
+ }
+ LOG_INFO("HCI turned on - run BtStack loop\n");
+ btstack_run_loop_execute();
+ return Error::Success;
+ }
+
+ void Driver::registerHardwareErrorCallback(std::function<void(uint8_t)> new_callback)
{
static std::function<void(uint8_t)> callback = nullptr;
callback = new_callback;
@@ 211,18 172,14 @@ namespace Bt
callback(val);
}
});
- return Error();
}
-
- auto run_stack(TaskHandle_t *handle) -> Error
+ auto Driver::stop() -> Error::Code
{
- BaseType_t taskerr = 0;
- LOG_INFO("Past last moment for Bt registration prior to RUN state");
- hci_power_control(HCI_POWER_ON);
- if ((taskerr = xTaskCreate(run_btstack, "BtStack", 1024, NULL, tskIDLE_PRIORITY, handle)) != pdPASS) {
- LOG_ERROR("BT Service failure! %lu", taskerr);
- return Error(Error::SystemError, taskerr);
+ auto ret = hci_power_control(HCI_POWER_OFF);
+ if (ret != 0) {
+ LOG_ERROR("Can't turn off Bluetooth Stack!");
}
- return Error();
+ hci_close();
+ return ret != 0 ? Error::LibraryError : Error::Success;
}
-} // namespace Bt
+} // namespace bluetooth
A module-bluetooth/Bluetooth/interface/BluetoothDriver.hpp => module-bluetooth/Bluetooth/interface/BluetoothDriver.hpp +29 -0
@@ 0,0 1,29 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <btstack.h>
+#include <functional>
+#include "Error.hpp"
+
+namespace bluetooth
+{
+
+ class Driver
+ {
+ private:
+ static hci_transport_config_uart_t config;
+ btstack_packet_callback_registration_t hci_event_callback_registration;
+ static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
+ static void local_version_information_handler(uint8_t *packet);
+ [[maybe_unused]] auto runLoopInitTarget(const btstack_run_loop *runLoop) -> const btstack_uart_block_t *;
+ [[maybe_unused]] auto runLoopInitLinux(const btstack_run_loop *runLoop) -> const btstack_uart_block_t *;
+
+ public:
+ auto init(const btstack_run_loop *runLoop) -> Error::Code;
+ auto run() -> Error::Code;
+ auto stop() -> Error::Code;
+ void registerHardwareErrorCallback(std::function<void(uint8_t)> new_callback);
+ };
+} // namespace bluetooth
M module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.cpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.cpp +3 -3
@@ 23,7 23,7 @@ extern "C"
#include <btstack_defines.h>
}
-namespace Bt
+namespace bluetooth
{
A2DP::A2DP() : pimpl(std::make_unique<A2DPImpl>(A2DPImpl()))
{}
@@ 120,7 120,7 @@ namespace Bt
AVDTP::sbcCodecConfiguration.size());
if (local_stream_endpoint == nullptr) {
LOG_INFO("A2DP Source: not enough memory to create local stream endpoint\n");
- return Bt::Error::SystemError;
+ return bluetooth::Error::SystemError;
}
AVRCP::mediaTracker.local_seid = avdtp_local_seid(local_stream_endpoint);
avdtp_source_register_delay_reporting_category(AVRCP::mediaTracker.local_seid);
@@ 165,7 165,7 @@ namespace Bt
LOG_INFO("Init done!");
- return Bt::Error::Success;
+ return bluetooth::Error::Success;
}
void A2DP::A2DPImpl::sendMediaPacket()
M module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.hpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DP.hpp +1 -1
@@ 9,7 9,7 @@
#include "queue.h"
#include <memory>
#include <service-bluetooth/ServiceBluetoothCommon.hpp>
-namespace Bt
+namespace bluetooth
{
class A2DP : public Profile
{
M module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DPImpl.hpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/A2DPImpl.hpp +1 -1
@@ 15,7 15,7 @@ extern "C"
#include <btstack_defines.h>
}
-namespace Bt
+namespace bluetooth
{
static constexpr int SBC_STORAGE_SIZE = 1030;
struct MediaContext
M module-bluetooth/Bluetooth/interface/profiles/A2DP/AVDTP.cpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/AVDTP.cpp +1 -1
@@ 3,7 3,7 @@
#include "AVDTP.hpp"
-namespace Bt
+namespace bluetooth
{
AVDTP::SbcConfiguration AVDTP::sbcConfig;
btstack_sbc_encoder_state_t AVDTP::sbcEncoderState;
M module-bluetooth/Bluetooth/interface/profiles/A2DP/AVDTP.hpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/AVDTP.hpp +1 -1
@@ 10,7 10,7 @@ extern "C"
#include <btstack_defines.h>
#include <classic/avdtp.h>
}
-namespace Bt
+namespace bluetooth
{
class AVDTP
M module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.cpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.cpp +1 -1
@@ 3,7 3,7 @@
#include "AVRCP.hpp"
-namespace Bt
+namespace bluetooth
{
AVRCP::PlaybackStatusInfo AVRCP::playInfo;
M module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.hpp => module-bluetooth/Bluetooth/interface/profiles/A2DP/AVRCP.hpp +1 -1
@@ 15,7 15,7 @@ extern "C"
#include <btstack_defines.h>
}
-namespace Bt
+namespace bluetooth
{
class AVRCP
{
M module-bluetooth/Bluetooth/interface/profiles/GAP.cpp => module-bluetooth/Bluetooth/interface/profiles/GAP.cpp +25 -28
@@ 19,7 19,7 @@ extern "C"
btstack_packet_callback_registration_t cb_handler;
-std::vector<Devicei> Bt::GAP::devices;
+std::vector<Devicei> bluetooth::GAP::devices;
static auto start_scan() -> int;
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
@@ 42,7 42,7 @@ enum STATE
};
enum STATE state = INIT;
-namespace Bt::GAP
+namespace bluetooth::GAP
{
static sys::Service *ownerService = nullptr;
@@ 99,7 99,7 @@ namespace Bt::GAP
return false;
}
-} // namespace Bt::GAP
+} // namespace bluetooth::GAP
#define INQUIRY_INTERVAL 5
static auto start_scan() -> int
@@ 110,9 110,8 @@ static auto start_scan() -> int
static auto has_more_remote_name_requests() -> int
{
- int i;
- for (i = 0; i < Bt::GAP::devices.size(); i++) {
- if (Bt::GAP::devices[i].state == REMOTE_NAME_REQUEST) {
+ for (int i = 0; i < bluetooth::GAP::devices.size(); i++) {
+ if (bluetooth::GAP::devices[i].state == REMOTE_NAME_REQUEST) {
return 1;
}
}
@@ 121,15 120,13 @@ static auto has_more_remote_name_requests() -> int
static void do_next_remote_name_request()
{
- int i;
- for (i = 0; i < Bt::GAP::devices.size(); i++) {
+
+ for (auto &device : bluetooth::GAP::devices) {
// remote name request
- if (Bt::GAP::devices[i].state == REMOTE_NAME_REQUEST) {
- Bt::GAP::devices[i].state = REMOTE_NAME_INQUIRED;
- LOG_INFO("Get remote name of %s...", bd_addr_to_str(Bt::GAP::devices[i].address));
- gap_remote_name_request(Bt::GAP::devices[i].address,
- Bt::GAP::devices[i].pageScanRepetitionMode,
- Bt::GAP::devices[i].clockOffset | 0x8000);
+ if (device.state == REMOTE_NAME_REQUEST) {
+ device.state = REMOTE_NAME_INQUIRED;
+ LOG_INFO("Get remote name of %s...", bd_addr_to_str(device.address));
+ gap_remote_name_request(device.address, device.pageScanRepetitionMode, device.clockOffset | 0x8000);
return;
}
}
@@ 189,7 186,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
case GAP_EVENT_INQUIRY_RESULT: {
gap_event_inquiry_result_get_bd_addr(packet, addr);
- index = getDeviceIndexForAddress(Bt::GAP::devices, addr);
+ index = getDeviceIndexForAddress(bluetooth::GAP::devices, addr);
if (index >= 0) {
break; // already in our list
}
@@ 218,36 215,36 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
else {
dev.state = REMOTE_NAME_REQUEST;
}
- Bt::GAP::devices.push_back(dev);
- auto msg = std::make_shared<BluetoothScanResultMessage>(Bt::GAP::devices);
- sys::Bus::SendUnicast(msg, "ApplicationSettings", Bt::GAP::ownerService);
- sys::Bus::SendUnicast(msg, "ApplicationSettingsNew", Bt::GAP::ownerService);
+ bluetooth::GAP::devices.push_back(dev);
+ auto msg = std::make_shared<BluetoothScanResultMessage>(bluetooth::GAP::devices);
+ sys::Bus::SendUnicast(msg, "ApplicationSettings", bluetooth::GAP::ownerService);
+ sys::Bus::SendUnicast(msg, "ApplicationSettingsNew", bluetooth::GAP::ownerService);
} break;
case GAP_EVENT_INQUIRY_COMPLETE:
- for (i = 0; i < Bt::GAP::devices.size(); i++) {
+ for (i = 0; i < bluetooth::GAP::devices.size(); i++) {
// retry remote name request
- if (Bt::GAP::devices[i].state == REMOTE_NAME_INQUIRED)
- Bt::GAP::devices[i].state = REMOTE_NAME_REQUEST;
+ if (bluetooth::GAP::devices[i].state == REMOTE_NAME_INQUIRED)
+ bluetooth::GAP::devices[i].state = REMOTE_NAME_REQUEST;
}
continue_remote_names();
break;
case HCI_EVENT_REMOTE_NAME_REQUEST_COMPLETE: {
reverse_bd_addr(&packet[3], addr);
- index = getDeviceIndexForAddress(Bt::GAP::devices, addr);
+ index = getDeviceIndexForAddress(bluetooth::GAP::devices, addr);
if (index >= 0) {
if (packet[2] == 0) {
LOG_INFO("Name: '%s'", &packet[9]);
- Bt::GAP::devices[index].state = REMOTE_NAME_FETCHED;
- Bt::GAP::devices[index].name = reinterpret_cast<char *>(&packet[9]);
+ bluetooth::GAP::devices[index].state = REMOTE_NAME_FETCHED;
+ bluetooth::GAP::devices[index].name = reinterpret_cast<char *>(&packet[9]);
}
else {
LOG_INFO("Failed to get name: page timeout");
}
}
- if (index + 1 == Bt::GAP::devices.size()) {
+ if (index + 1 == bluetooth::GAP::devices.size()) {
LOG_INFO("Scanned all");
state = DONE;
gap_inquiry_stop();
@@ 258,8 255,8 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
case GAP_EVENT_DEDICATED_BONDING_COMPLETED: {
auto result = packet[2];
auto msg = std::make_shared<BluetoothPairResultMessage>(result == 0u);
- sys::Bus::SendUnicast(msg, "ApplicationSettings", Bt::GAP::ownerService);
- sys::Bus::SendUnicast(msg, "ApplicationSettingsNew", Bt::GAP::ownerService);
+ sys::Bus::SendUnicast(msg, "ApplicationSettings", bluetooth::GAP::ownerService);
+ sys::Bus::SendUnicast(msg, "ApplicationSettingsNew", bluetooth::GAP::ownerService);
} break;
default:
break;
M module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp => module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.cpp +2 -2
@@ 17,7 17,7 @@ extern "C"
#include <btstack_defines.h>
}
-namespace Bt
+namespace bluetooth
{
HSP::HSP() : pimpl(std::make_unique<HSPImpl>(HSPImpl()))
{}
@@ 204,7 204,7 @@ namespace Bt
LOG_INFO("HSP init done!");
- return Bt::Error::Success;
+ return bluetooth::Error::Success;
}
void HSP::HSPImpl::start()
M module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.hpp => module-bluetooth/Bluetooth/interface/profiles/HSP/HSP.hpp +1 -1
@@ 6,7 6,7 @@
#include "Profile.hpp"
#include <service-bluetooth/BluetoothMessage.hpp>
-namespace Bt
+namespace bluetooth
{
class HSP : public Profile
M module-bluetooth/Bluetooth/interface/profiles/HSP/HSPImpl.hpp => module-bluetooth/Bluetooth/interface/profiles/HSP/HSPImpl.hpp +1 -1
@@ 7,7 7,7 @@
#include "SCO.hpp"
#include <Audio/AudioCommon.hpp>
-namespace Bt
+namespace bluetooth
{
static constexpr int serviceBufferLength = 150;
static constexpr int commandBufferLength = 150;
M module-bluetooth/Bluetooth/interface/profiles/HSP/SCO.cpp => module-bluetooth/Bluetooth/interface/profiles/HSP/SCO.cpp +2 -2
@@ 19,7 19,7 @@ extern "C"
#include "hci.h"
}
-namespace Bt
+namespace bluetooth
{
class SCO::SCOImpl
@@ 94,7 94,7 @@ namespace Bt
SCO::~SCO() = default;
} // namespace Bt
-using namespace Bt;
+using namespace bluetooth;
btstack_cvsd_plc_state_t SCO::SCOImpl::cvsdPlcState;
QueueHandle_t SCO::SCOImpl::sinkQueue;
M module-bluetooth/Bluetooth/interface/profiles/HSP/SCO.hpp => module-bluetooth/Bluetooth/interface/profiles/HSP/SCO.hpp +1 -1
@@ 11,7 11,7 @@ extern "C"
{
#include <module-bluetooth/lib/btstack/src/bluetooth.h>
};
-namespace Bt
+namespace bluetooth
{
class SCO
M module-bluetooth/Bluetooth/interface/profiles/PAN.cpp => module-bluetooth/Bluetooth/interface/profiles/PAN.cpp +1 -1
@@ 106,7 106,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
}
}
-namespace Bt
+namespace bluetooth
{
// Set local name with a template Bluetooth address, that will be automatically
M module-bluetooth/Bluetooth/interface/profiles/Profile.hpp => module-bluetooth/Bluetooth/interface/profiles/Profile.hpp +1 -1
@@ 7,7 7,7 @@
#include <Service/Message.hpp>
#include <service-bluetooth/ServiceBluetoothCommon.hpp>
#include <memory>
-namespace Bt
+namespace bluetooth
{
class Profile
{
M module-bluetooth/CMakeLists.txt => module-bluetooth/CMakeLists.txt +3 -2
@@ 6,14 6,15 @@ set(CMAKE_CXX_STANDARD 17)
set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/BluetoothWorker.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/BtstackWorker.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/glucode/BluetoothRunLoop.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/interface/BluetoothDriver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/BtKeysStorage.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/interface/profiles/A2DP/A2DP.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/interface/profiles/A2DP/AVRCP.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/interface/profiles/A2DP/AVDTP.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/interface/profiles/HSP/HSP.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Bluetooth/interface/profiles/HSP/SCO.cpp
- )
+)
message("Build with BlueKitchen")
include(lib/btstack.cmake)
M module-bsp/board/rt1051/bluetooth/BlueKitchen.cpp => module-bsp/board/rt1051/bluetooth/BlueKitchen.cpp +4 -4
@@ 47,12 47,12 @@ BTdev::Error BlueKitchen::read(uint8_t *buf, size_t nbytes)
read_len = nbytes;
if (BluetoothCommon::read(buf, nbytes) == Success) {
- val = Bt::Message::EvtReceiving;
+ val = bluetooth::Message::EvtReceiving;
xQueueSend(qHandle, &val, portMAX_DELAY);
return BTdev::Success;
}
else {
- val = Bt::Message::EvtReceivingError;
+ val = bluetooth::Message::EvtReceivingError;
xQueueSend(qHandle, &val, portMAX_DELAY);
return BTdev::ErrorBSP;
}
@@ 65,12 65,12 @@ BTdev::Error BlueKitchen::write(const uint8_t *buf, size_t size)
logHciStack("BlueKitchen sends %d bytes", size);
if (BluetoothCommon::write(buf, size) == Success) {
- val = Bt::Message::EvtSending;
+ val = bluetooth::Message::EvtSending;
xQueueSend(qHandle, &val, portMAX_DELAY);
return BTdev::Success;
}
else {
- val = Bt::Message::EvtSendingError;
+ val = bluetooth::Message::EvtSendingError;
xQueueSend(qHandle, &val, portMAX_DELAY);
return BTdev::ErrorBSP;
}
M module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp => module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp +4 -4
@@ 273,7 273,7 @@ void BluetoothCommon::uartDmaCallback(LPUART_Type *base, lpuart_edma_handle_t *h
case kStatus_LPUART_TxIdle: {
logHciComs("DMA irq: TX done");
LPUART_EnableTx(BSP_BLUETOOTH_UART_BASE, false);
- val = Bt::Message::EvtSent;
+ val = bluetooth::Message::EvtSent;
xQueueSendFromISR(bt->qHandle, &val, &taskwoken);
portEND_SWITCHING_ISR(taskwoken);
break;
@@ 281,7 281,7 @@ void BluetoothCommon::uartDmaCallback(LPUART_Type *base, lpuart_edma_handle_t *h
case kStatus_LPUART_RxIdle:
logHciComs("DMA irq: RX done");
LPUART_EnableRx(BSP_BLUETOOTH_UART_BASE, false);
- val = Bt::Message::EvtReceived;
+ val = bluetooth::Message::EvtReceived;
xQueueSendFromISR(bt->qHandle, &val, &taskwoken);
portEND_SWITCHING_ISR(taskwoken);
break;
@@ 316,7 316,7 @@ extern "C"
{
uint32_t isrReg = LPUART_GetStatusFlags(BSP_BLUETOOTH_UART_BASE);
BaseType_t taskwoken = 0;
- uint8_t val = Bt::Message::EvtReceived;
+ uint8_t val = bluetooth::Message::EvtReceived;
bsp::BlueKitchen *bt = bsp::BlueKitchen::getInstance();
if (isrReg & kLPUART_RxDataRegFullFlag) {
@@ 324,7 324,7 @@ extern "C"
}
if (isrReg & kLPUART_RxOverrunFlag) {
LOG_WARN("LPUART IRQ RX overrun");
- val = Bt::Message::EvtUartError;
+ val = bluetooth::Message::EvtUartError;
xQueueSendFromISR(bt->qHandle, &val, &taskwoken);
}
LPUART_ClearStatusFlags(BSP_BLUETOOTH_UART_BASE, isrReg);
M module-services/service-bluetooth/ServiceBluetooth.cpp => module-services/service-bluetooth/ServiceBluetooth.cpp +9 -9
@@ 25,7 25,7 @@
ServiceBluetooth::ServiceBluetooth() : sys::Service(service::name::bluetooth)
{
auto settings = std::make_unique<settings::Settings>(this);
- settingsHolder = std::make_shared<Bluetooth::SettingsHolder>(std::move(settings));
+ settingsHolder = std::make_shared<bluetooth::SettingsHolder>(std::move(settings));
LOG_INFO("[ServiceBluetooth] Initializing");
}
@@ 43,7 43,7 @@ sys::ReturnCodes ServiceBluetooth::InitHandler()
connect(message::bluetooth::RequestBondedDevices(), [&](sys::Message *msg) {
auto bondedDevicesStr =
- std::visit(Bluetooth::StringVisitor(), this->settingsHolder->getValue(Bluetooth::Settings::BondedDevices));
+ std::visit(bluetooth::StringVisitor(), this->settingsHolder->getValue(bluetooth::Settings::BondedDevices));
return std::make_shared<message::bluetooth::ResponseBondedDevices>(
SettingsSerializer::fromString(bondedDevicesStr));
@@ 52,9 52,9 @@ sys::ReturnCodes ServiceBluetooth::InitHandler()
connect(message::bluetooth::RequestStatus(), [&](sys::Message *msg) {
BluetoothStatus status;
- auto state = std::visit(Bluetooth::IntVisitor(), settingsHolder->getValue(Bluetooth::Settings::State));
+ auto state = std::visit(bluetooth::IntVisitor(), settingsHolder->getValue(bluetooth::Settings::State));
auto visibility =
- std::visit(Bluetooth::BoolVisitor(), settingsHolder->getValue(Bluetooth::Settings::Visibility));
+ std::visit(bluetooth::BoolVisitor(), settingsHolder->getValue(bluetooth::Settings::Visibility));
status.state = static_cast<BluetoothStatus::State>(state);
status.visibility = visibility;
@@ 82,7 82,7 @@ sys::ReturnCodes ServiceBluetooth::InitHandler()
settingsHolder->onStateChange = [this]() {
auto initialState =
- std::visit(Bluetooth::IntVisitor(), this->settingsHolder->getValue(Bluetooth::Settings::State));
+ std::visit(bluetooth::IntVisitor(), this->settingsHolder->getValue(bluetooth::Settings::State));
if (static_cast<BluetoothStatus::State>(initialState) == BluetoothStatus::State::On) {
this->worker->run();
}
@@ 117,7 117,7 @@ sys::MessagePointer ServiceBluetooth::DataReceivedHandler(sys::DataMessage *msg,
return std::make_shared<sys::ResponseMessage>(sys::ReturnCodes::Failure);
}
case BluetoothMessage::StopScan:
- sendWorkerCommand(Bt::StopScan);
+ sendWorkerCommand(bluetooth::StopScan);
break;
case BluetoothMessage::PAN: {
/// TODO request lwip first...
@@ 140,10 140,10 @@ sys::MessagePointer ServiceBluetooth::DataReceivedHandler(sys::DataMessage *msg,
} break;
case BluetoothMessage::Play:
- sendWorkerCommand(Bt::ConnectAudio);
+ sendWorkerCommand(bluetooth::ConnectAudio);
break;
case BluetoothMessage::Stop:
- sendWorkerCommand(Bt::DisconnectAudio);
+ sendWorkerCommand(bluetooth::DisconnectAudio);
break;
default:
@@ 177,7 177,7 @@ sys::ReturnCodes ServiceBluetooth::SwitchPowerModeHandler(const sys::ServicePowe
LOG_ERROR("TODO");
return sys::ReturnCodes::Success;
}
-void ServiceBluetooth::sendWorkerCommand(Bt::Command command)
+void ServiceBluetooth::sendWorkerCommand(bluetooth::Command command)
{
xQueueSend(workerQueue, &command, portMAX_DELAY);
}
M module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp => module-services/service-bluetooth/service-bluetooth/ServiceBluetooth.hpp +2 -2
@@ 29,9 29,9 @@ class ServiceBluetooth : public sys::Service
sys::ReturnCodes InitHandler() override;
sys::ReturnCodes DeinitHandler() override;
virtual sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override;
- void sendWorkerCommand(Bt::Command command);
+ void sendWorkerCommand(bluetooth::Command command);
QueueHandle_t workerQueue = nullptr;
- std::shared_ptr<Bluetooth::SettingsHolder> settingsHolder;
+ std::shared_ptr<bluetooth::SettingsHolder> settingsHolder;
private:
std::unique_ptr<BluetoothWorker> worker;
M module-services/service-bluetooth/service-bluetooth/SettingsHolder.cpp => module-services/service-bluetooth/service-bluetooth/SettingsHolder.cpp +1 -1
@@ 2,7 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "SettingsHolder.hpp"
-namespace Bluetooth
+namespace bluetooth
{
std::map<Settings, std::string> SettingsHolder::settingString{
{Settings::DeviceName, settings::Bluetooth::deviceName},
M module-services/service-bluetooth/service-bluetooth/SettingsHolder.hpp => module-services/service-bluetooth/service-bluetooth/SettingsHolder.hpp +1 -1
@@ 9,7 9,7 @@
#include <module-utils/Utils.hpp>
#include "SettingsSerializer.hpp"
-namespace Bluetooth
+namespace bluetooth
{
enum class Settings