From 822af357a2221bcc8b35d469bf316b25ab226e5b Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 10 Oct 2025 11:14:17 +0200 Subject: [PATCH] Add HCI RPC transport. Supports sending raw HCI commands over RPC. Signed-off-by: iabdalkader --- src/local/BLELocalDevice.cpp | 1 + src/utility/HCIVirtualTransportRPC.cpp | 114 ++++++++++++++++++++++ src/utility/HCIVirtualTransportRPC.h | 53 ++++++++++ src/utility/HCIVirtualTransportZephyr.cpp | 2 +- 4 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 src/utility/HCIVirtualTransportRPC.cpp create mode 100644 src/utility/HCIVirtualTransportRPC.h diff --git a/src/local/BLELocalDevice.cpp b/src/local/BLELocalDevice.cpp index 89c7a580..991c50ce 100644 --- a/src/local/BLELocalDevice.cpp +++ b/src/local/BLELocalDevice.cpp @@ -31,6 +31,7 @@ #undef ARDUINO_GIGA #undef ARDUINO_NICLA_VISION #undef ARDUINO_PORTENTA_C33 +#undef ARDUINO_UNO_Q #endif #if defined(PORTENTA_H7_PINS) || defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_OPTA) diff --git a/src/utility/HCIVirtualTransportRPC.cpp b/src/utility/HCIVirtualTransportRPC.cpp new file mode 100644 index 00000000..d1ff9ac9 --- /dev/null +++ b/src/utility/HCIVirtualTransportRPC.cpp @@ -0,0 +1,114 @@ +/* + This file is part of the ArduinoBLE library. + Copyright (c) 2018-2025 Arduino SA. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if defined(ARDUINO_UNO_Q) + +#include "HCIVirtualTransportRPC.h" + +HCIVirtualTransportRPCClass::HCIVirtualTransportRPCClass() : initialized(false) { +} + +HCIVirtualTransportRPCClass::~HCIVirtualTransportRPCClass() { +} + +int HCIVirtualTransportRPCClass::begin() { + // Initialize the Bridge if not already started + if (!Bridge) { + if (!Bridge.begin()) { + return 0; + } + } + + // Open HCI device through Bridge RPC + if (!HCI.begin("hci0")) { + return 0; + } + + rxbuf.clear(); + initialized = true; + + return 1; +} + +void HCIVirtualTransportRPCClass::end() { + if (initialized) { + HCI.end(); + initialized = false; + } +} + +void HCIVirtualTransportRPCClass::wait(unsigned long timeout) { + delay(timeout); +} + +int HCIVirtualTransportRPCClass::available() { + if (!initialized) { + return 0; + } + + // Return buffered data if available + if (rxbuf.available()) { + return rxbuf.available(); + } + + // Check if data is available from Bridge HCI and buffer it + if (HCI.available()) { + uint8_t packet[258]; + int received = HCI.recv(packet, sizeof(packet)); + + if (received > 0) { + // Store received data in ring buffer + for (int i = 0; i < received; i++) { + rxbuf.store_char(packet[i]); + } + } + } + + return rxbuf.available(); +} + +int HCIVirtualTransportRPCClass::peek() { + return -1; +} + +int HCIVirtualTransportRPCClass::read() { + if (rxbuf.available()) { + return rxbuf.read_char(); + } + + return -1; +} + +size_t HCIVirtualTransportRPCClass::write(const uint8_t* data, size_t length) { + if (!initialized) { + return 0; + } + + int sent = HCI.send(data, length); + if (sent < 0) { + return 0; + } + + return sent; +} + +HCIVirtualTransportRPCClass HCIVirtualTransportRPC; +HCITransportInterface& HCITransport = HCIVirtualTransportRPC; + +#endif diff --git a/src/utility/HCIVirtualTransportRPC.h b/src/utility/HCIVirtualTransportRPC.h new file mode 100644 index 00000000..74d04cbc --- /dev/null +++ b/src/utility/HCIVirtualTransportRPC.h @@ -0,0 +1,53 @@ +/* + This file is part of the ArduinoBLE library. + Copyright (c) 2018-2025 Arduino SA. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _HCI_VIRTUAL_TRANSPORT_RPC_H_ +#define _HCI_VIRTUAL_TRANSPORT_RPC_H_ + +#include "HCITransport.h" +#include "api/RingBuffer.h" +#include +#include +#include +#include + +class HCIVirtualTransportRPCClass : public HCITransportInterface { + public: + HCIVirtualTransportRPCClass(); + virtual ~HCIVirtualTransportRPCClass(); + + virtual int begin(); + virtual void end(); + + virtual void wait(unsigned long timeout); + + virtual int available(); + virtual int peek(); + virtual int read(); + + virtual size_t write(const uint8_t* data, size_t length); + + private: + RingBufferN<258> rxbuf; + bool initialized; +}; + +extern HCIVirtualTransportRPCClass HCIVirtualTransportRPC; + +#endif diff --git a/src/utility/HCIVirtualTransportZephyr.cpp b/src/utility/HCIVirtualTransportZephyr.cpp index 7060df3d..7712b077 100644 --- a/src/utility/HCIVirtualTransportZephyr.cpp +++ b/src/utility/HCIVirtualTransportZephyr.cpp @@ -17,7 +17,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if defined(__ZEPHYR__) +#if defined(__ZEPHYR__) && !defined(ARDUINO_UNO_Q) #include "HCIVirtualTransportZephyr.h" #include "HCI.h"