mirror of
https://github.com/lemmingDev/ESP32-BLE-Gamepad.git
synced 2026-03-03 06:44:11 +01:00
198 lines
5.5 KiB
C++
198 lines
5.5 KiB
C++
#include "BleNUS.h"
|
|
#include <NimBLEDevice.h>
|
|
#include "NimBLELog.h"
|
|
|
|
#if defined(CONFIG_ARDUHAL_ESP_LOG)
|
|
#include "esp32-hal-log.h"
|
|
#define LOG_TAG "BleNUS"
|
|
#else
|
|
#include "esp_log.h"
|
|
static const char *LOG_TAG = "BleNUS";
|
|
#endif
|
|
|
|
BleNUS::BleNUS(NimBLEServer* existingServer)
|
|
: pServer(existingServer), pService(nullptr), pTxCharacteristic(nullptr), pRxCharacteristic(nullptr), dataReceivedCallback(nullptr) {}
|
|
|
|
BleNUS::~BleNUS() {
|
|
end();
|
|
}
|
|
|
|
void BleNUS::begin() {
|
|
delay(1000); // Give some time for other services to complete their business
|
|
|
|
if (!pServer) {
|
|
NIMBLE_LOGD(LOG_TAG, "No existing pServer available");
|
|
return;
|
|
}
|
|
|
|
NimBLEAdvertising* pAdvertising = pServer->getAdvertising();
|
|
NIMBLE_LOGD(LOG_TAG, "Stopping main NimBLE server from advertising (shouldn't be at this stage if you set delayAdvertising to true)");
|
|
pAdvertising->stop();
|
|
|
|
NIMBLE_LOGD(LOG_TAG, "Creating Nordic UART Service");
|
|
pService = pServer->createService(NUS_SERVICE_UUID); // This pService is local only to this class. Nothing to do with the ones from BleBamepad
|
|
|
|
NIMBLE_LOGD(LOG_TAG, "Adding Nordic UART Service TX and RX characteristics");
|
|
pTxCharacteristic = pService->createCharacteristic(NUS_TX_CHARACTERISTIC_UUID, NIMBLE_PROPERTY::NOTIFY);
|
|
pRxCharacteristic = pService->createCharacteristic(NUS_RX_CHARACTERISTIC_UUID, NIMBLE_PROPERTY::WRITE);
|
|
NIMBLE_LOGD(LOG_TAG, "Registering Nordic UART Service callbacks");
|
|
pRxCharacteristic->setCallbacks(this);
|
|
|
|
NIMBLE_LOGD(LOG_TAG, "Starting Nordic UART Service");
|
|
pService->start();
|
|
|
|
// Can't add Nordic UART Service UUID to the main advertisement as it makes it larger than 31 bytes
|
|
// It's not strictly needed anyway
|
|
//NIMBLE_LOGD(LOG_TAG, "Adding Nordic UART Service UUID to main NimBLE server advertising");
|
|
//pAdvertising->addServiceUUID(pService->getUUID());
|
|
|
|
// Get around the above issue by adding Nordic UART Service UUID to NimBLEAdvertisementData scanResponseData;
|
|
// Add it in a scan response instead so devices can still see it has that capability
|
|
// https://github.com/h2zero/NimBLE-Arduino/issues/135
|
|
NIMBLE_LOGD(LOG_TAG, "Adding Nordic UART Service UUID to advertising scan response data");
|
|
NimBLEAdvertisementData scanResponseData; // Create NimBLEAdvertisementData object
|
|
scanResponseData.addServiceUUID(pService->getUUID()); // Add UUID
|
|
pAdvertising->setScanResponseData(scanResponseData); // Assign the scan response data
|
|
|
|
NIMBLE_LOGD(LOG_TAG, "Main NimBLE server advertising started!");
|
|
pAdvertising->start();
|
|
}
|
|
|
|
void BleNUS::end() {
|
|
if (pService) {
|
|
// Nothing I can think of
|
|
}
|
|
}
|
|
|
|
void BleNUS::sendData(const uint8_t* data, size_t length) {
|
|
if (pTxCharacteristic && pServer->getConnectedCount() > 0) {
|
|
pTxCharacteristic->setValue(data, length);
|
|
pTxCharacteristic->notify();
|
|
}
|
|
}
|
|
|
|
void BleNUS::setDataReceivedCallback(void (*callback)(const uint8_t* data, size_t length)) {
|
|
dataReceivedCallback = callback;
|
|
}
|
|
|
|
void BleNUS::onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo) {
|
|
if (dataReceivedCallback) {
|
|
std::string value = pCharacteristic->getValue();
|
|
buffer += value; // Append to internal buffer
|
|
dataReceivedCallback((const uint8_t*)value.data(), value.length());
|
|
}
|
|
}
|
|
|
|
size_t BleNUS::available() {
|
|
return buffer.length(); // Check the length of data in the internal buffer
|
|
}
|
|
|
|
int BleNUS::read() {
|
|
if (buffer.length() > 0) {
|
|
char c = buffer[0];
|
|
buffer.erase(0, 1); // Remove the first byte after reading
|
|
return c;
|
|
}
|
|
return -1; // No data available
|
|
}
|
|
|
|
int BleNUS::peek() {
|
|
if (buffer.length() > 0) {
|
|
return buffer[0]; // Peek at the first byte without removing it
|
|
}
|
|
return -1; // No data available to peek
|
|
}
|
|
|
|
void BleNUS::flush() {
|
|
buffer.clear(); // Clear the internal buffer
|
|
}
|
|
|
|
void BleNUS::print(const char* str) {
|
|
sendData((const uint8_t*)str, strlen(str));
|
|
}
|
|
|
|
void BleNUS::print(const String& str) {
|
|
print(str.c_str());
|
|
}
|
|
|
|
void BleNUS::print(int i) {
|
|
char buf[32];
|
|
itoa(i, buf, 10);
|
|
print(buf);
|
|
}
|
|
|
|
void BleNUS::print(long l) {
|
|
char buf[32];
|
|
ltoa(l, buf, 10);
|
|
print(buf);
|
|
}
|
|
|
|
void BleNUS::print(unsigned long ul) {
|
|
char buf[32];
|
|
ultoa(ul, buf, 10);
|
|
print(buf);
|
|
}
|
|
|
|
void BleNUS::print(float f, int digits) {
|
|
char buf[32];
|
|
dtostrf(f, 6, digits, buf);
|
|
print(buf);
|
|
}
|
|
|
|
void BleNUS::print(double d, int digits) {
|
|
print((float)d, digits);
|
|
}
|
|
|
|
void BleNUS::print(char c) {
|
|
char buf[2] = {c, '\0'};
|
|
print(buf);
|
|
}
|
|
|
|
void BleNUS::println(const char* str) {
|
|
print(str);
|
|
print("\n");
|
|
}
|
|
|
|
void BleNUS::println(const String& str) {
|
|
println(str.c_str());
|
|
}
|
|
|
|
void BleNUS::println(int i) {
|
|
print(i);
|
|
print("\n");
|
|
}
|
|
|
|
void BleNUS::println(long l) {
|
|
print(l);
|
|
print("\n");
|
|
}
|
|
|
|
void BleNUS::println(unsigned long ul) {
|
|
print(ul);
|
|
print("\n");
|
|
}
|
|
|
|
void BleNUS::println(float f, int digits) {
|
|
print(f, digits);
|
|
print("\n");
|
|
}
|
|
|
|
void BleNUS::println(double d, int digits) {
|
|
print(d, digits);
|
|
print("\n");
|
|
}
|
|
|
|
void BleNUS::println(char c) {
|
|
print(c);
|
|
print("\n");
|
|
}
|
|
|
|
void BleNUS::write(uint8_t byte) {
|
|
print(byte); // Just use the print method to send 1 byte
|
|
}
|
|
|
|
void BleNUS::write(const uint8_t *buffer, size_t size) {
|
|
sendData(buffer, size);
|
|
}
|
|
|