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
10 changes: 10 additions & 0 deletions .github/scripts/tests_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ function run_multi_device_test {
if [ -n "$wifi_password" ]; then
pytest_cmd+=(--wifi-password "$wifi_password")
fi
if [ "$skip_autoflash" -eq 1 ]; then
pytest_cmd+=(--skip-autoflash y)
fi

result=0
printf "\033[95m%s\033[0m\n" "${pytest_cmd[*]}"
Expand Down Expand Up @@ -346,6 +349,9 @@ function run_test {
if [ -n "$wifi_password" ]; then
pytest_cmd+=(--wifi-password "$wifi_password")
fi
if [ "$skip_autoflash" -eq 1 ]; then
pytest_cmd+=(--skip-autoflash y)
fi

result=0
printf "\033[95m%s\033[0m\n" "${pytest_cmd[*]}"
Expand Down Expand Up @@ -379,6 +385,7 @@ platform="hardware"
chunk_run=0
options=0
erase=0
skip_autoflash=0
wifi_ssid=""
wifi_password=""

Expand Down Expand Up @@ -450,6 +457,9 @@ while [ -n "$1" ]; do
-e )
erase=1
;;
--skip-autoflash )
skip_autoflash=1
;;
-h )
echo "$USAGE"
exit 0
Expand Down
92 changes: 55 additions & 37 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ endif()

set(CORE_SRCS
cores/esp32/base64.cpp
cores/esp32/BTAddress.cpp
cores/esp32/BTStatus.cpp
cores/esp32/cbuf.cpp
cores/esp32/ColorFormat.c
cores/esp32/chip-debug-report.cpp
Expand Down Expand Up @@ -131,11 +133,60 @@ set(ARDUINO_LIBRARY_ArduinoOTA_SRCS libraries/ArduinoOTA/src/ArduinoOTA.cpp)

set(ARDUINO_LIBRARY_AsyncUDP_SRCS libraries/AsyncUDP/src/AsyncUDP.cpp)

set(ARDUINO_LIBRARY_BLE_SRCS
libraries/BLE/src/BLE.cpp
libraries/BLE/src/BLEAdvertisedDevice.cpp
libraries/BLE/src/BLEAdvertisementData.cpp
libraries/BLE/src/BLEAdvertising.cpp
libraries/BLE/src/BLEAdvTypes.cpp
libraries/BLE/src/BLEBeacon.cpp
libraries/BLE/src/BLECharacteristic.cpp
libraries/BLE/src/BLEClient.cpp
libraries/BLE/src/BLEConnInfo.cpp
libraries/BLE/src/BLEDescriptor.cpp
libraries/BLE/src/BLEEddystone.cpp
libraries/BLE/src/BLEHIDDevice.cpp
libraries/BLE/src/BLEL2CAP.cpp
libraries/BLE/src/BLERemoteCharacteristic.cpp
libraries/BLE/src/BLERemoteDescriptor.cpp
libraries/BLE/src/BLERemoteService.cpp
libraries/BLE/src/BLEScan.cpp
libraries/BLE/src/BLESecurity.cpp
libraries/BLE/src/BLEServer.cpp
libraries/BLE/src/BLEService.cpp
libraries/BLE/src/BLEStream.cpp
libraries/BLE/src/BLEUUID.cpp
libraries/BLE/src/impl/BLECharacteristicValidation.cpp
libraries/BLE/src/impl/BLESync.cpp
libraries/BLE/src/impl/bluedroid/BluedroidAdvertising.cpp
libraries/BLE/src/impl/bluedroid/BluedroidCharacteristic.cpp
libraries/BLE/src/impl/bluedroid/BluedroidClient.cpp
libraries/BLE/src/impl/bluedroid/BluedroidCore.cpp
libraries/BLE/src/impl/bluedroid/BluedroidDescriptor.cpp
libraries/BLE/src/impl/bluedroid/BluedroidRemoteCharacteristic.cpp
libraries/BLE/src/impl/bluedroid/BluedroidRemoteDescriptor.cpp
libraries/BLE/src/impl/bluedroid/BluedroidRemoteService.cpp
libraries/BLE/src/impl/bluedroid/BluedroidScan.cpp
libraries/BLE/src/impl/bluedroid/BluedroidSecurity.cpp
libraries/BLE/src/impl/bluedroid/BluedroidServer.cpp
libraries/BLE/src/impl/nimble/NimBLEAdvertisedDevice.cpp
libraries/BLE/src/impl/nimble/NimBLEAdvertisementData.cpp
libraries/BLE/src/impl/nimble/NimBLEAdvertising.cpp
libraries/BLE/src/impl/nimble/NimBLECharacteristic.cpp
libraries/BLE/src/impl/nimble/NimBLEClient.cpp
libraries/BLE/src/impl/nimble/NimBLECore.cpp
libraries/BLE/src/impl/nimble/NimBLEDescriptor.cpp
libraries/BLE/src/impl/nimble/NimBLEL2CAP.cpp
libraries/BLE/src/impl/nimble/NimBLERemoteCharacteristic.cpp
libraries/BLE/src/impl/nimble/NimBLERemoteDescriptor.cpp
libraries/BLE/src/impl/nimble/NimBLERemoteService.cpp
libraries/BLE/src/impl/nimble/NimBLEScan.cpp
libraries/BLE/src/impl/nimble/NimBLESecurity.cpp
libraries/BLE/src/impl/nimble/NimBLEServer.cpp
)

set(ARDUINO_LIBRARY_BluetoothSerial_SRCS
libraries/BluetoothSerial/src/BluetoothSerial.cpp
libraries/BluetoothSerial/src/BTAddress.cpp
libraries/BluetoothSerial/src/BTAdvertisedDeviceSet.cpp
libraries/BluetoothSerial/src/BTScanResultsSet.cpp)
libraries/BluetoothSerial/src/BluetoothSerial.cpp)

set(ARDUINO_LIBRARY_Console_SRCS libraries/Console/src/Console.cpp)
set(ARDUINO_LIBRARY_Console_REQUIRES console)
Expand Down Expand Up @@ -337,39 +388,6 @@ set(ARDUINO_LIBRARY_Zigbee_SRCS
libraries/Zigbee/src/ep/ZigbeeMultistate.cpp
)

set(ARDUINO_LIBRARY_BLE_SRCS
libraries/BLE/src/BLE2901.cpp
libraries/BLE/src/BLE2902.cpp
libraries/BLE/src/BLE2904.cpp
libraries/BLE/src/BLEAddress.cpp
libraries/BLE/src/BLEAdvertisedDevice.cpp
libraries/BLE/src/BLEAdvertising.cpp
libraries/BLE/src/BLEBeacon.cpp
libraries/BLE/src/BLECharacteristic.cpp
libraries/BLE/src/BLECharacteristicMap.cpp
libraries/BLE/src/BLEClient.cpp
libraries/BLE/src/BLEDescriptor.cpp
libraries/BLE/src/BLEDescriptorMap.cpp
libraries/BLE/src/BLEDevice.cpp
libraries/BLE/src/BLEEddystoneTLM.cpp
libraries/BLE/src/BLEEddystoneURL.cpp
libraries/BLE/src/BLEExceptions.cpp
libraries/BLE/src/BLEHIDDevice.cpp
libraries/BLE/src/BLERemoteCharacteristic.cpp
libraries/BLE/src/BLERemoteDescriptor.cpp
libraries/BLE/src/BLERemoteService.cpp
libraries/BLE/src/BLEScan.cpp
libraries/BLE/src/BLESecurity.cpp
libraries/BLE/src/BLEServer.cpp
libraries/BLE/src/BLEService.cpp
libraries/BLE/src/BLEServiceMap.cpp
libraries/BLE/src/BLEUtils.cpp
libraries/BLE/src/BLEUUID.cpp
libraries/BLE/src/BLEValue.cpp
libraries/BLE/src/FreeRTOS.cpp
libraries/BLE/src/GeneralUtils.cpp
)

set(ARDUINO_LIBRARIES_SRCS)
set(ARDUINO_LIBRARIES_REQUIRES)
set(ARDUINO_LIBRARIES_INCLUDEDIRS)
Expand Down
116 changes: 116 additions & 0 deletions cores/esp32/BTAddress.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright 2017-2026 Espressif Systems (Shanghai) PTE LTD
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
* Copyright 2017 Neil Kolban
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "BTAddress.h"
#include <stdio.h>
#include <ctype.h>

BTAddress::BTAddress() {
memset(_addr, 0, sizeof(_addr));
_type = Public;
}

BTAddress::BTAddress(const uint8_t addr[6], Type type) : _type(type) {
memcpy(_addr, addr, 6);
}

BTAddress::BTAddress(const char *str) {
memset(_addr, 0, sizeof(_addr));
_type = Public;
if (str) {
parseString(str);
}
}

BTAddress::BTAddress(const String &str) {
memset(_addr, 0, sizeof(_addr));
_type = Public;
parseString(str.c_str());
}

void BTAddress::parseString(const char *str) {
if (!str) {
return;
}
size_t len = strlen(str);

if (len == 17 && str[2] == ':') {
// "AA:BB:CC:DD:EE:FF" format -- MSB first in string, stored LSB first
unsigned int d[6];
if (sscanf(str, "%x:%x:%x:%x:%x:%x", &d[0], &d[1], &d[2], &d[3], &d[4], &d[5]) == 6) {
_addr[0] = (uint8_t)d[5];
_addr[1] = (uint8_t)d[4];
_addr[2] = (uint8_t)d[3];
_addr[3] = (uint8_t)d[2];
_addr[4] = (uint8_t)d[1];
_addr[5] = (uint8_t)d[0];
}
} else if (len == 12) {
// "AABBCCDDEEFF" format (no separators) -- MSB first in string
unsigned int d[6];
if (sscanf(str, "%2x%2x%2x%2x%2x%2x", &d[0], &d[1], &d[2], &d[3], &d[4], &d[5]) == 6) {
_addr[0] = (uint8_t)d[5];
_addr[1] = (uint8_t)d[4];
_addr[2] = (uint8_t)d[3];
_addr[3] = (uint8_t)d[2];
_addr[4] = (uint8_t)d[1];
_addr[5] = (uint8_t)d[0];
}
}
}

bool BTAddress::operator==(const BTAddress &other) const {
return _type == other._type && memcmp(_addr, other._addr, 6) == 0;
}

bool BTAddress::operator!=(const BTAddress &other) const {
return !(*this == other);
}

bool BTAddress::operator<(const BTAddress &other) const {
int cmp = memcmp(_addr, other._addr, 6);
if (cmp != 0) {
return cmp < 0;
}
return _type < other._type;
}

BTAddress::operator bool() const {
return !isZero();
}

const uint8_t *BTAddress::data() const {
return _addr;
}

BTAddress::Type BTAddress::type() const {
return _type;
}

String BTAddress::toString(bool uppercase) const {
char buf[18];
const char *fmt = uppercase ? "%02X:%02X:%02X:%02X:%02X:%02X" : "%02x:%02x:%02x:%02x:%02x:%02x";
snprintf(buf, sizeof(buf), fmt, _addr[5], _addr[4], _addr[3], _addr[2], _addr[1], _addr[0]);
return String(buf);
}

bool BTAddress::isZero() const {
static const uint8_t zero[6] = {};
return memcmp(_addr, zero, 6) == 0;
}
92 changes: 92 additions & 0 deletions cores/esp32/BTAddress.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2017-2026 Espressif Systems (Shanghai) PTE LTD
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
* Copyright 2017 Neil Kolban
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <stdint.h>
#include <string.h>
#include "WString.h"

/**
* @brief Unified Bluetooth address type for both BLE and BT Classic.
*
* Replaces the separate BLEAddress and BTAddress classes.
* Internally stores 6 bytes in LSB-first (Bluetooth standard) order,
* matching NimBLE's native format.
*
* Displayed as "AA:BB:CC:DD:EE:FF" (MSB-first, human-readable convention).
*/
class BTAddress {
public:
/** @brief Address types per Bluetooth Core Spec Vol 6, Part B, 1.3. */
enum Type : uint8_t {
Public = 0,
Random = 1,
PublicID = 2,
RandomID = 3,
};

/** @brief Constructs a zero address (all bytes 0x00, type Public). */
BTAddress();

/**
* @brief Construct from raw 6-byte array in LSB-first order.
* @param addr 6-byte address array (addr[0] = LSB).
* @param type Address type.
*/
BTAddress(const uint8_t addr[6], Type type = Public);

/**
* @brief Construct from "AA:BB:CC:DD:EE:FF" string.
* Also accepts "AABBCCDDEEFF" (no separators).
* @param str Address string (case-insensitive).
*/
BTAddress(const char *str);

/** @brief Construct from Arduino String. */
BTAddress(const String &str);

bool operator==(const BTAddress &other) const;
bool operator!=(const BTAddress &other) const;
bool operator<(const BTAddress &other) const;

/** @brief Returns true if the address is non-zero. */
explicit operator bool() const;

/** @brief Returns pointer to the internal 6-byte array (LSB-first). */
const uint8_t *data() const;

/** @brief Returns the address type. */
Type type() const;

/**
* @brief Convert to "AA:BB:CC:DD:EE:FF" string representation.
* @param uppercase If true, use uppercase hex digits.
*/
String toString(bool uppercase = false) const;

/** @brief Returns true if all 6 address bytes are zero. */
bool isZero() const;

private:
uint8_t _addr[6]{};
Type _type = Public;

void parseString(const char *str);
};
37 changes: 37 additions & 0 deletions cores/esp32/BTStatus.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2017-2026 Espressif Systems (Shanghai) PTE LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "BTStatus.h"

const char *BTStatus::toString() const {
switch (_code) {
case OK: return "OK";
case Fail: return "Fail";
case NotInitialized: return "NotInitialized";
case InvalidParam: return "InvalidParam";
case InvalidState: return "InvalidState";
case NoMemory: return "NoMemory";
case Timeout: return "Timeout";
case NotConnected: return "NotConnected";
case AlreadyConnected: return "AlreadyConnected";
case NotFound: return "NotFound";
case AuthFailed: return "AuthFailed";
case PermissionDenied: return "PermissionDenied";
case Busy: return "Busy";
case NotSupported: return "NotSupported";
default: return "Unknown";
}
}
Loading
Loading