From 74f7f1a81e394c3ba8ed2f8c6c977ff5bde93a20 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 7 Oct 2024 12:35:25 +0200 Subject: [PATCH] zephyr raw hci porting --- src/utility/HCIUartTransport.cpp | 2 +- src/utility/HCIVirtualTransportZephyr.cpp | 111 ++++++++++++++++++++++ src/utility/HCIVirtualTransportZephyr.h | 49 ++++++++++ src/utility/HCIVirtualZephyrMacros.c | 43 +++++++++ 4 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/utility/HCIVirtualTransportZephyr.cpp create mode 100644 src/utility/HCIVirtualTransportZephyr.h create mode 100644 src/utility/HCIVirtualZephyrMacros.c diff --git a/src/utility/HCIUartTransport.cpp b/src/utility/HCIUartTransport.cpp index 191811a7..0e308338 100644 --- a/src/utility/HCIUartTransport.cpp +++ b/src/utility/HCIUartTransport.cpp @@ -17,7 +17,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) && !defined(ARDUINO_SILABS) && !defined(ARDUINO_UNOR4_WIFI) || defined(TARGET_NANO_RP2040_CONNECT) //|| defined(CORE_CM4) +#if !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) && !defined(ARDUINO_SILABS) && !defined(ARDUINO_UNOR4_WIFI) && !defined(__ZEPHYR__) || defined(TARGET_NANO_RP2040_CONNECT) //|| defined(CORE_CM4) #include "HCIUartTransport.h" diff --git a/src/utility/HCIVirtualTransportZephyr.cpp b/src/utility/HCIVirtualTransportZephyr.cpp new file mode 100644 index 00000000..1b650714 --- /dev/null +++ b/src/utility/HCIVirtualTransportZephyr.cpp @@ -0,0 +1,111 @@ +/* + This file is part of the ArduinoBLE library. + Copyright (c) 2018 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(__ZEPHYR__) + +#include "HCIVirtualTransportZephyr.h" + +extern "C" struct k_fifo* __rx_queue; + +HCIVirtualTransportZephyrClass::HCIVirtualTransportZephyrClass() +{ +} + +HCIVirtualTransportZephyrClass::~HCIVirtualTransportZephyrClass() +{ +} + +extern "C" void set_public_address(struct k_fifo *rx_queue); +int HCIVirtualTransportZephyrClass::begin() +{ + bt_enable_raw(__rx_queue); + //bt_hci_raw_set_mode(BT_HCI_RAW_MODE_PASSTHROUGH); + set_public_address(__rx_queue); + bt_hci_raw_set_mode(BT_HCI_RAW_MODE_H4); + rxbuf.clear(); + return 1; +} + +void HCIVirtualTransportZephyrClass::end() +{ +} + +void HCIVirtualTransportZephyrClass::wait(unsigned long timeout) +{ + delay(timeout); +} + +int HCIVirtualTransportZephyrClass::available() +{ + if (rxbuf.available()) { + return rxbuf.available(); + } + + static struct net_buf *buf; + buf = net_buf_get(__rx_queue, K_MSEC(10)); + if (!buf) { + return 0; + } + + for (int i = 0; i < buf->len; i++) { + rxbuf.store_char((uint8_t)buf->data[i]); + } + net_buf_pull(buf, buf->len); + if (!buf->len) { + net_buf_unref(buf); + buf = NULL; + } + + return rxbuf.available(); +} + +// never called +int HCIVirtualTransportZephyrClass::peek() +{ + return -1; +} + +int HCIVirtualTransportZephyrClass::read() +{ + + if (rxbuf.available()) { + return rxbuf.read_char(); + } + + return -1; +} + +size_t HCIVirtualTransportZephyrClass::write(const uint8_t* data, size_t length) +{ + struct net_buf *__net_buf = bt_buf_get_tx(BT_BUF_H4, K_MSEC(10), data, length); + if (__net_buf) { + auto err = bt_send(__net_buf); + if (err) { + net_buf_unref(__net_buf); + } + return length; + } + return 0; +} + +HCIVirtualTransportZephyrClass HCIVirtualTransportZephyr; + +HCITransportInterface& HCITransport = HCIVirtualTransportZephyr; + +#endif diff --git a/src/utility/HCIVirtualTransportZephyr.h b/src/utility/HCIVirtualTransportZephyr.h new file mode 100644 index 00000000..b213aede --- /dev/null +++ b/src/utility/HCIVirtualTransportZephyr.h @@ -0,0 +1,49 @@ +/* + This file is part of the ArduinoBLE library. + Copyright (c) 2018 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 +*/ + +#include "HCITransport.h" +#include "api/RingBuffer.h" +#include +#include +#include + +extern "C" { +#include +#include +} + +class HCIVirtualTransportZephyrClass : public HCITransportInterface { +public: + HCIVirtualTransportZephyrClass(); + virtual ~HCIVirtualTransportZephyrClass(); + + 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; +}; \ No newline at end of file diff --git a/src/utility/HCIVirtualZephyrMacros.c b/src/utility/HCIVirtualZephyrMacros.c new file mode 100644 index 00000000..ac44a880 --- /dev/null +++ b/src/utility/HCIVirtualZephyrMacros.c @@ -0,0 +1,43 @@ +#if defined(__ZEPHYR__) + +#include +#include +#include + +static K_FIFO_DEFINE(rx_queue); +struct k_fifo* __rx_queue = &rx_queue; + + +// from https://github.com/thomasstenersen/sdk-zephyr/commit/df546a0eb9b96b453373f38483959d2363a83cae#diff-217778ef1d0638c89207786f06425396891f987713120e83db724d26b9813eebR331 +// referenced by https://devzone.nordicsemi.com/f/nordic-q-a/73310/incompatibility-between-mcumgr-cli-and-hci_usb-when-running-with-bt_ll_softdevice-enabled + +void set_public_address(struct k_fifo *rx_queue) +{ + const struct bt_hci_cp_vs_write_bd_addr cmd = { + .bdaddr.val = {0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA} + }; + const struct bt_hci_cmd_hdr cmd_header = { + .opcode = BT_HCI_OP_VS_WRITE_BD_ADDR, + .param_len = sizeof(cmd) + }; + struct net_buf *buf; + int err; + buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, + &cmd_header, sizeof(cmd_header)); + net_buf_add_mem(buf, &cmd, sizeof(cmd)); + err = bt_send(buf); + __ASSERT_NO_MSG(err == 0); + /* Pull out the command complete. */ + buf = net_buf_get(rx_queue, K_SECONDS(10)); /* 10s == HCI_CMD_TIMEOUT */ + struct bt_hci_evt_hdr *hdr; + __ASSERT_NO_MSG(buf != NULL); + __ASSERT_NO_MSG(buf->len >= sizeof(*hdr)); + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + __ASSERT_NO_MSG(hdr->evt == BT_HCI_EVT_CMD_COMPLETE); + struct bt_hci_evt_cmd_complete *evt; + evt = net_buf_pull_mem(buf, sizeof(*evt)); + __ASSERT_NO_MSG(sys_le16_to_cpu(evt->opcode) == BT_HCI_OP_VS_WRITE_BD_ADDR); + net_buf_unref(buf); +} + +#endif \ No newline at end of file