Skip to content

Cross-platform Bluetooth support #4589

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
47dc28d
all: Add bluetooth module for BLE.
aykevl Jul 23, 2018
4cfa2ff
extmod/modbluetooth: Add Bluetooth.advertise_raw().
aykevl Aug 1, 2018
f246baa
extmod/modbluetooth: Add Bluetooth.add_service().
aykevl Mar 1, 2019
9f701a8
extmod/modbluetooth: Add support for 128-bit UUIDs.
aykevl Mar 1, 2019
523828a
extmod/modbluetooth: Add support for characteristics.
aykevl Mar 3, 2019
81adf55
esp32: improve error message for invalid advertisement data
aykevl Mar 20, 2019
f437b7d
nrf: check for the maximum size of advertisement packets
aykevl Mar 20, 2019
87ccee4
extmod/modbluetooth: Add support for characteristic notifications.
aykevl Mar 28, 2019
84bf3e6
extmod/modbluetooth: Add write callbacks on characteristics.
aykevl Apr 4, 2019
ddd3bb2
extmod/modbluetooth: Run write callbacks on the scheduler.
aykevl Apr 10, 2019
36b897b
extmod/modbluetooth: Rename use .irq() name+signature for .on_update().
aykevl Apr 21, 2019
ee567ac
extmod/modbluetooth: Add .address() to print device address.
aykevl Apr 22, 2019
61ed70b
extmod/modbluetooth: better handling of big BLE packets
aykevl Apr 29, 2019
9a2bbe0
extmod/modbluetooth: make write IRQs work for esp32 and nrf
aykevl Apr 29, 2019
9b7c334
extmod/modbluetooth: implement connect and disconnect events
aykevl Apr 29, 2019
8add37f
extmod/modbluetooth: fix multiple services
aykevl Apr 29, 2019
986eef0
extmod/modbluetooth: implement device.disconnect()
aykevl Apr 29, 2019
cc4a9c8
extmod/modbluetooth: Merge advertise_raw() into advertise().
aykevl Jun 6, 2019
a821b2c
nrf: Enable ubinascii module.
aykevl Jun 12, 2019
5b3afbc
extmod/modbluetooth: Expose raw MAC as .config('mac').
aykevl Jun 12, 2019
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
757 changes: 757 additions & 0 deletions extmod/modbluetooth.c

Large diffs are not rendered by default.

141 changes: 141 additions & 0 deletions extmod/modbluetooth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ayke van Laethem
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

#pragma once

#include <stdbool.h>
#include "bluetooth/bluetooth.h"
#include "py/obj.h"

// A remote device.
typedef struct {
mp_obj_base_t base;
uint8_t address[6];
uint16_t conn_handle;
} mp_bt_device_t;

typedef struct {
mp_obj_base_t base;
mp_bt_uuid_t uuid;
mp_bt_service_handle_t handle;
} mp_bt_service_t;

// A characteristic.
// Object fits in 4 words (1 GC object), with 1 byte unused at the end.
typedef struct {
mp_obj_base_t base;
mp_bt_uuid_t uuid;
mp_bt_service_t *service;
mp_bt_characteristic_handle_t value_handle;
uint8_t flags;
} mp_bt_characteristic_t;

// One entry in the linked list of write callbacks.
typedef struct _mp_bt_characteristic_callback_t {
struct _mp_bt_characteristic_callback_t *next;
mp_bt_characteristic_t *characteristic;
mp_obj_t callback;
uint8_t triggers;
} mp_bt_characteristic_callback_t;

// Enables the Bluetooth stack. Returns errno on failure.
int mp_bt_enable(void);

// Disables the Bluetooth stack. Is a no-op when not enabled.
void mp_bt_disable(void);

// Returns true when the Bluetooth stack is enabled.
bool mp_bt_is_enabled(void);

// Gets the MAC address of this device in LSB format.
void mp_bt_get_address(uint8_t *address);

// Start advertisement. Will re-start advertisement when already enabled.
// Returns errno on failure.
int mp_bt_advertise_start(mp_bt_adv_type_t type, uint16_t interval, const uint8_t *adv_data, size_t adv_data_len, const uint8_t *sr_data, size_t sr_data_len);

// Stop advertisement. No-op when already stopped.
void mp_bt_advertise_stop(void);

// Call this when a central disconnects.
void mp_bt_connected(uint16_t conn_handle, const uint8_t *address);

// Call this when a central connects.
void mp_bt_disconnected(uint16_t conn_handle, const uint8_t *address);

// Add a service with the given list of characteristics.
int mp_bt_add_service(mp_bt_service_t *service, size_t num_characteristics, mp_bt_characteristic_t **characteristics);

// Set the given characteristic to the given value.
int mp_bt_characteristic_value_set(mp_bt_characteristic_t *characteristic, const void *value, size_t value_len);

// Set the given characteristic and notify a central using the given
// connection handle.
int mp_bt_characteristic_value_notify(mp_bt_characteristic_t *characteristic, uint16_t conn_handle, const void *value, size_t value_len);

// Read the characteristic value. The size of the buffer must be given in
// value_len, which will be updated with the actual value.
int mp_bt_characteristic_value_get(mp_bt_characteristic_t *characteristic, void *value, size_t *value_len);

// Call this when a characteristic is written to.
void mp_bt_characteristic_on_write(uint16_t conn_handle, uint16_t value_handle, const void *value, size_t value_len);

// Disconnect a connected central.
int mp_bt_device_disconnect(uint16_t conn_handle);

// Parse an UUID object from the caller and stores the result in the uuid
// parameter. Must accept both strings and integers for 128-bit and 16-bit
// UUIDs.
void mp_bt_parse_uuid(mp_obj_t obj, mp_bt_uuid_t *uuid);

// Format an UUID object to be returned from a .uuid() call. May result in
// a small int or a string.
mp_obj_t mp_bt_format_uuid(mp_bt_uuid_t *uuid);

// Parse a string UUID object into the 16-byte buffer. The string must be
// the correct size, otherwise this function will throw an error.
void mp_bt_parse_uuid_str(mp_obj_t obj, uint8_t *uuid);

// Format a 128-bit UUID from the 16-byte buffer as a string.
mp_obj_t mp_bt_format_uuid_str(const uint8_t *uuid);

// Data types of advertisement packet.
#define MP_BLE_GAP_AD_TYPE_FLAG (0x01)
#define MP_BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME (0x09)

// Flags element of advertisement packet.
#define MP_BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) // discoverable for everyone
#define MP_BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) // BLE only - no classic BT supported
#define MP_BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (MP_BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | MP_BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED)

#define MP_BLE_FLAG_READ (1 << 1)
#define MP_BLE_FLAG_WRITE (1 << 3)
#define MP_BLE_FLAG_NOTIFY (1 << 4)

// IRQ flags to select on which event a callback should be called.
#define MP_BT_IRQ_CONNECT (1 << 1)
#define MP_BT_IRQ_DISCONNECT (1 << 2)
#define MP_BT_IRQ_WRITE (1 << 3)
47 changes: 47 additions & 0 deletions ports/esp32/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ MICROPY_PY_USSL = 0
MICROPY_SSL_AXTLS = 0
MICROPY_FATFS = 1
MICROPY_PY_BTREE = 1
MICROPY_PY_BLUETOOTH = 1

#FROZEN_DIR = scripts
FROZEN_MPY_DIR = modules
Expand Down Expand Up @@ -115,6 +116,26 @@ INC_ESPCOMP += -I$(ESPCOMP)/app_update/include
INC_ESPCOMP += -I$(ESPCOMP)/pthread/include
INC_ESPCOMP += -I$(ESPCOMP)/smartconfig_ack/include
INC_ESPCOMP += -I$(ESPCOMP)/sdmmc/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/api/include/api
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/bta/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/bta/dm/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/bta/gatt/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/bta/sys/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/btc/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/btc/profile/esp/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/btc/profile/esp/blufi/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/btc/profile/std/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/common/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/device/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/hci/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/osi/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/stack/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/stack/btm/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/stack/gap/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/stack/gatt/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/stack/l2cap/include
INC_ESPCOMP += -I$(ESPCOMP)/bt/bluedroid/stack/smp/include

# these flags are common to C and C++ compilation
CFLAGS_COMMON = -Os -ffunction-sections -fdata-sections -fstrict-volatile-bitfields \
Expand Down Expand Up @@ -186,6 +207,7 @@ SRC_C = \
machine_uart.c \
modmachine.c \
modnetwork.c \
bluetooth/bluetooth.c \
network_lan.c \
network_ppp.c \
modsocket.c \
Expand Down Expand Up @@ -354,6 +376,29 @@ ESPIDF_WPA_SUPPLICANT_O = $(patsubst %.c,%.o,\

ESPIDF_SDMMC_O = $(patsubst %.c,%.o,$(wildcard $(ESPCOMP)/sdmmc/*.c))

ESPIDF_BT_O = $(patsubst %.c,%.o,\
$(ESPCOMP)/bt/bt.c \
$(wildcard $(ESPCOMP)/bt/bluedroid/api/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/bta/dm/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/bta/gatt/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/bta/sys/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/btc/core/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/btc/profile/esp/blufi/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/btc/profile/std/gap/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/btc/profile/std/gatt/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/device/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/hci/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/main/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/osi/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/stack/btm/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/stack/btu/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/stack/gap/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/stack/gatt/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/stack/hcic/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/stack/l2cap/*.c) \
$(wildcard $(ESPCOMP)/bt/bluedroid/stack/smp/*.c) \
)

OBJ_ESPIDF =
LIB_ESPIDF =
BUILD_ESPIDF_LIB = $(BUILD)/esp-idf
Expand Down Expand Up @@ -392,6 +437,7 @@ $(eval $(call gen_espidf_lib_rule,lwip,$(ESPIDF_LWIP_O)))
$(eval $(call gen_espidf_lib_rule,mbedtls,$(ESPIDF_MBEDTLS_O)))
$(eval $(call gen_espidf_lib_rule,wpa_supplicant,$(ESPIDF_WPA_SUPPLICANT_O)))
$(eval $(call gen_espidf_lib_rule,sdmmc,$(ESPIDF_SDMMC_O)))
$(eval $(call gen_espidf_lib_rule,bt,$(ESPIDF_BT_O)))

# Create all destination build dirs before compiling IDF source
OBJ_ESPIDF_DIRS = $(sort $(dir $(OBJ_ESPIDF))) $(BUILD_ESPIDF_LIB) $(addprefix $(BUILD_ESPIDF_LIB)/,$(LIB_ESPIDF))
Expand Down Expand Up @@ -471,6 +517,7 @@ APP_LD_ARGS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc
APP_LD_ARGS += -L$(dir $(LIBSTDCXX_FILE_NAME)) -lstdc++
APP_LD_ARGS += $(LIBC_LIBM)
APP_LD_ARGS += $(ESPCOMP)/esp32/libhal.a
APP_LD_ARGS += $(ESPCOMP)/bt/lib/libbtdm_app.a
APP_LD_ARGS += -L$(ESPCOMP)/esp32/lib -lcore -lmesh -lnet80211 -lphy -lrtc -lpp -lwpa -lsmartconfig -lcoexist -lwps -lwpa2
APP_LD_ARGS += $(OBJ)
APP_LD_ARGS += $(LIB)
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy