109 lines
3.6 KiB
C++
109 lines
3.6 KiB
C++
// This is a personal academic project. Dear PVS-Studio, please check it.
|
|
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: https://pvs-studio.com
|
|
|
|
#include "BluetoothDispatcher.hpp"
|
|
|
|
static DeviceConnectedCb deviceConnectedCallback = nullptr;
|
|
|
|
static void deviceConnectedStaticCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param);
|
|
|
|
BluetoothDispatcher::BluetoothDispatcher(BluetoothSerial *controller, const char *device_name) {
|
|
assert(controller != nullptr);
|
|
assert(device_name != nullptr);
|
|
|
|
_device_name = device_name;
|
|
_controller = controller;
|
|
}
|
|
|
|
bool BluetoothDispatcher::initialize(volatile bool loop_on_fail, int readTimeoutMS) {
|
|
_controller->enableSSP();
|
|
_controller->onConfirmRequest([this](uint16_t pin) {
|
|
_onConfirmRequest(pin);
|
|
});
|
|
_controller->onAuthComplete([this](boolean success) {
|
|
_onAuthComplete(success);
|
|
});
|
|
_controller->register_callback(deviceConnectedStaticCallback);
|
|
deviceConnectedCallback = [this](BTAddress device) {
|
|
_onDeviceConnected(device);
|
|
};
|
|
_controller->setTimeout(50);
|
|
bool success = _controller->begin(_device_name, false);
|
|
if (!success) {
|
|
ESP_LOGI(_tag, "Failed to initialize Bluetooth controller!");
|
|
while (loop_on_fail);
|
|
return false;
|
|
} else {
|
|
ESP_LOGI(_tag, "Bluetooth host initialized");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void BluetoothDispatcher::onNewPackageReceived(NewPackageCallback newPackageReceivedCb) {
|
|
_newPackageReceivedCb = newPackageReceivedCb;
|
|
}
|
|
|
|
void BluetoothDispatcher::tick(const char message_delimeter) {
|
|
/* Call the callback, if new package received */
|
|
while (_controller->available()) { _buffer += (char) _controller->read(); }
|
|
if (_buffer.lastIndexOf(message_delimeter) != -1) {
|
|
char buffer[_buffer_size];
|
|
auto messageEnd = _buffer.indexOf(message_delimeter) - 1;
|
|
if (messageEnd == -1) {
|
|
_buffer.clear();
|
|
} else {
|
|
_buffer.substring(0, messageEnd, buffer);
|
|
}
|
|
ESP_LOGD(_tag, "Received new buffer %s", buffer);
|
|
if (_newPackageReceivedCb) {
|
|
_newPackageReceivedCb(buffer);
|
|
}
|
|
_buffer.clear();
|
|
}
|
|
if (_buffer.length() > _real_buffer_size) {
|
|
_buffer.clear();
|
|
}
|
|
}
|
|
|
|
BluetoothDispatcher::~BluetoothDispatcher() {
|
|
_controller->end();
|
|
delete _controller;
|
|
}
|
|
|
|
void BluetoothDispatcher::_onConfirmRequest(uint16_t pin) {
|
|
ESP_LOGI(_tag, "The Bluetooth PIN is: %06lu", (long unsigned int) pin);
|
|
_controller->confirmReply(true);
|
|
}
|
|
|
|
void BluetoothDispatcher::_onAuthComplete(boolean success) const {
|
|
if (success) {
|
|
ESP_LOGI(_tag, "Pairing success!");
|
|
} else {
|
|
ESP_LOGI(_tag, "Pairing failed, rejected by user!");
|
|
}
|
|
}
|
|
|
|
void BluetoothDispatcher::_onDeviceConnected(BTAddress device) {
|
|
ESP_LOGI(_tag, "New device connected: %s", device.toString(true).c_str());
|
|
_buffer.clear();
|
|
if (_deviceConnectedCallback) {
|
|
_deviceConnectedCallback(device);
|
|
}
|
|
}
|
|
|
|
void BluetoothDispatcher::onNewDeviceConnected(DeviceConnectedCb deviceConnectedCb) {
|
|
/* Callback called if device connected successfully. */
|
|
_deviceConnectedCallback = deviceConnectedCb;
|
|
}
|
|
|
|
void BluetoothDispatcher::sendPackage(const char *package, size_t size) {
|
|
_controller->write((uint8_t *) package, size);
|
|
}
|
|
|
|
|
|
static void deviceConnectedStaticCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
|
|
if (event == ESP_SPP_SRV_OPEN_EVT and param->srv_open.status == ESP_SPP_SUCCESS
|
|
and deviceConnectedCallback) {
|
|
deviceConnectedCallback(BTAddress(param->srv_open.rem_bda));
|
|
}
|
|
} |