Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bricks/_common/qstrdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ Q(pybricks.ev3devices)
Q(pybricks.experimental)
#endif

#if PYBRICKS_PY_COMMON_BTC
Q(pybricks.experimental.btc)
#endif

#if MICROPY_PY_BUILTINS_FLOAT // backwards compatibility with Pybricks V3.2, maps to pybricks.tools
Q(pybricks.geometry)
#endif
Expand Down
2 changes: 2 additions & 0 deletions bricks/_common/sources.mk
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ PYBRICKS_PYBRICKS_SRC_C = $(addprefix pybricks/,\
ev3devices/pb_type_ev3devices_infraredsensor.c \
ev3devices/pb_type_ev3devices_touchsensor.c \
ev3devices/pb_type_ev3devices_ultrasonicsensor.c \
experimental/pb_module_btc.c \
experimental/pb_module_experimental.c \
hubs/pb_module_hubs.c \
hubs/pb_type_buildhat.c \
Expand Down Expand Up @@ -116,6 +117,7 @@ PBIO_SRC_C = $(addprefix lib/pbio/,\
drv/bluetooth/bluetooth.c \
drv/bluetooth/bluetooth_btstack_stm32_hal.c \
drv/bluetooth/bluetooth_btstack.c \
drv/bluetooth/bluetooth_btstack_classic.c \
drv/bluetooth/bluetooth_btstack_ev3.c \
drv/bluetooth/bluetooth_simulation.c \
drv/bluetooth/bluetooth_stm32_bluenrg.c \
Expand Down
1 change: 1 addition & 0 deletions bricks/ev3/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// Pybricks modules
#define PYBRICKS_PY_COMMON (1)
#define PYBRICKS_PY_COMMON_BLE (0)
#define PYBRICKS_PY_COMMON_BTC (1)
#define PYBRICKS_PY_COMMON_CHARGER (0)
#define PYBRICKS_PY_COMMON_COLOR_LIGHT (1)
#define PYBRICKS_PY_COMMON_CONTROL (1)
Expand Down
5 changes: 5 additions & 0 deletions lib/pbio/drv/bluetooth/bluetooth_btstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

#include "bluetooth.h"
#include "bluetooth_btstack.h"
#include "bluetooth_btstack_classic.h"

#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE
#include "genhdr/pybricks_service.h"
Expand Down Expand Up @@ -1181,6 +1182,10 @@ void pbdrv_bluetooth_init_hci(void) {
nordic_spp_service_server_init(nordic_spp_packet_handler);
#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_LE

#if PBDRV_CONFIG_BLUETOOTH_CLASSIC
pbdrv_bluetooth_classic_init();
#endif

bluetooth_thread_err = PBIO_ERROR_AGAIN;
bluetooth_thread_state = 0;
pbio_os_process_start(&pbdrv_bluetooth_hci_process, pbdrv_bluetooth_hci_process_thread, NULL);
Expand Down
101 changes: 101 additions & 0 deletions lib/pbio/drv/bluetooth/bluetooth_btstack_classic.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2025 The Pybricks Authors

// This file defines the functions required to implement Pybricks' Bluetooth
// classic functionality using BTStack.

#include <pbdrv/config.h>

#if PBDRV_CONFIG_BLUETOOTH_BTSTACK_CLASSIC

#include <pbdrv/bluetooth.h>

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>

#include <btstack.h>

#include <pbdrv/bluetooth.h>

static int32_t pending_inquiry_response_count;
static int32_t pending_inquiry_response_limit;
static void *pending_inquiry_result_handler_context;
static pbdrv_bluetooth_inquiry_result_handler_t pending_inquiry_result_handler;

static void handle_hci_event_packet(uint8_t *packet, uint16_t size);

void pbdrv_bluetooth_classic_handle_packet(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
switch (packet_type) {
case HCI_EVENT_PACKET:
handle_hci_event_packet(packet, size);
}
}

static void handle_hci_event_packet(uint8_t *packet, uint16_t size) {
switch (hci_event_packet_get_type(packet)) {
case GAP_EVENT_INQUIRY_RESULT: {
if (!pending_inquiry_result_handler) {
return;
}
pbdrv_bluetooth_inquiry_result_t result;
gap_event_inquiry_result_get_bd_addr(packet, result.bdaddr);
if (gap_event_inquiry_result_get_rssi_available(packet)) {
result.rssi = gap_event_inquiry_result_get_rssi(packet);
}
if (gap_event_inquiry_result_get_name_available(packet)) {
const uint8_t *name = gap_event_inquiry_result_get_name(packet);
const size_t name_len = gap_event_inquiry_result_get_name_len(packet);
snprintf(result.name, sizeof(result.name), "%.*s", (int)name_len, name);
}
result.class_of_device = gap_event_inquiry_result_get_class_of_device(packet);
pending_inquiry_result_handler(pending_inquiry_result_handler_context, &result);
if (pending_inquiry_response_limit > 0) {
pending_inquiry_response_count++;
if (pending_inquiry_response_count >= pending_inquiry_response_limit) {
gap_inquiry_stop();
}
}
break;
}
case GAP_EVENT_INQUIRY_COMPLETE: {
if (pending_inquiry_result_handler) {
pending_inquiry_result_handler = NULL;
pending_inquiry_result_handler_context = NULL;
pbio_os_request_poll();
}
break;
}
default:
break;
}
}

void pbdrv_bluetooth_classic_init() {
static btstack_packet_callback_registration_t hci_event_handler_registration;
hci_event_handler_registration.callback = pbdrv_bluetooth_classic_handle_packet;
hci_add_event_handler(&hci_event_handler_registration);
}

pbio_error_t pbdrv_bluetooth_inquiry_scan(
pbio_os_state_t *state,
int32_t max_responses,
int32_t timeout,
void *context,
pbdrv_bluetooth_inquiry_result_handler_t result_handler) {
PBIO_OS_ASYNC_BEGIN(state);
if (pending_inquiry_result_handler) {
return PBIO_ERROR_BUSY;
}
PBIO_OS_AWAIT_UNTIL(state, hci_get_state() == HCI_STATE_WORKING);
pending_inquiry_response_count = 0;
pending_inquiry_response_limit = max_responses;
pending_inquiry_result_handler = result_handler;
pending_inquiry_result_handler_context = context;
gap_inquiry_start(timeout);

PBIO_OS_AWAIT_UNTIL(state, !pending_inquiry_result_handler);
PBIO_OS_ASYNC_END(PBIO_SUCCESS);
}

#endif // PBDRV_CONFIG_BLUETOOTH_BTSTACK_CLASSIC
13 changes: 13 additions & 0 deletions lib/pbio/drv/bluetooth/bluetooth_btstack_classic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef PBDRV_BLUETOOTH_BLUETOOTH_BTSTACK_CLASSIC_H
#define PBDRV_BLUETOOTH_BLUETOOTH_BTSTACK_CLASSIC_H
#include <pbdrvconfig.h>

#if PBDRV_CONFIG_BLUETOOTH_CLASSIC

#include <stdint.h>

void pbdrv_bluetooth_classic_init();

#endif // PBDRV_CONFIG_BLUETOOTH_CLASSIC

#endif // PBDRV_BLUETOOTH_BLUETOOTH_BTSTACK_CLASSIC_H
43 changes: 42 additions & 1 deletion lib/pbio/include/pbdrv/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,9 +607,50 @@ static inline pbio_error_t pbdrv_bluetooth_close_user_tasks(pbio_os_state_t *sta
return PBIO_SUCCESS;
}


#endif // PBDRV_CONFIG_BLUETOOTH

#if PBDRV_CONFIG_BLUETOOTH_CLASSIC

// A single result from an inquiry scan.
typedef struct {
uint8_t bdaddr[6];
int8_t rssi;
char name[249];
uint32_t class_of_device;
} pbdrv_bluetooth_inquiry_result_t;

// Callback for handling inquiry results.
typedef void (*pbdrv_bluetooth_inquiry_result_handler_t)(void *context, const pbdrv_bluetooth_inquiry_result_t *result);

/**
* Runs a bluetooth inquiry scan. Only one such scan can be active at a time.
*
* @param [in] state Protothread state.
* @param [in] max_responses Maximum number of responses to report. Use -1 for unlimited.
* @param [in] timeout Timeout in units of 1.28 seconds. Values less than one will be coerced to one.
* @param [in] context Context pointer to be passed to the result handler.
* @param [in] result_handler Callback that will be called for each inquiry result.
*/
pbio_error_t pbdrv_bluetooth_inquiry_scan(
pbio_os_state_t *state,
int32_t max_responses,
int32_t timeout,
void *context,
pbdrv_bluetooth_inquiry_result_handler_t result_handler);

#else // PBDRV_CONFIG_BLUETOOTH_CLASSIC

static inline pbio_error_t pbdrv_bluetooth_inquiry_scan(
pbio_os_state_t *state,
int32_t max_responses,
int32_t timeout,
void *context,
void *result_handler) {
return PBIO_ERROR_NOT_SUPPORTED;
}

#endif // PBDRV_CONFIG_BLUETOOTH_CLASSIC

#endif // _PBDRV_BLUETOOTH_H_

/** @} */
1 change: 1 addition & 0 deletions lib/pbio/platform/ev3/pbdrvconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#define PBDRV_CONFIG_I2C_EV3 (1)

#define PBDRV_CONFIG_BLUETOOTH (1)
#define PBDRV_CONFIG_BLUETOOTH_CLASSIC (1)
#define PBDRV_CONFIG_BLUETOOTH_MAX_MTU_SIZE 515
#define PBDRV_CONFIG_BLUETOOTH_BTSTACK (1)
#define PBDRV_CONFIG_BLUETOOTH_BTSTACK_CLASSIC (1)
Expand Down
Loading