Skip to content

Commit

Permalink
zephyr raw hci porting
Browse files Browse the repository at this point in the history
  • Loading branch information
facchinm committed Oct 7, 2024
1 parent 29bef40 commit 74f7f1a
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/utility/HCIUartTransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
111 changes: 111 additions & 0 deletions src/utility/HCIVirtualTransportZephyr.cpp
Original file line number Diff line number Diff line change
@@ -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
49 changes: 49 additions & 0 deletions src/utility/HCIVirtualTransportZephyr.h
Original file line number Diff line number Diff line change
@@ -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 <stdint.h>
#include <stdio.h>
#include <string.h>

extern "C" {
#include <zephyr/bluetooth/hci_raw.h>
#include <zephyr/bluetooth/buf.h>
}

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;
};
43 changes: 43 additions & 0 deletions src/utility/HCIVirtualZephyrMacros.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#if defined(__ZEPHYR__)

#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/buf.h>
#include <zephyr/bluetooth/hci_vs.h>

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

0 comments on commit 74f7f1a

Please sign in to comment.