Skip to content

Commit dc2802a

Browse files
authored
Merge pull request #466 from adafruit/develop
implement comprehensive LESC and Legacy pairing
2 parents 7e64023 + 3bb3223 commit dc2802a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2507
-590
lines changed

.github/workflows/githubci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ jobs:
5454
ln -s $GITHUB_WORKSPACE $HOME/$BSP_PATH/$BSP_VERSION
5555
5656
# Install library dependency
57-
arduino-cli lib install "Adafruit AHRS" "Adafruit APDS9960 Library" "Adafruit BMP280 Library" "Adafruit Circuit Playground" "Adafruit EPD" "Adafruit GFX Library" "Adafruit HX8357 Library" "Adafruit ILI9341" "Adafruit LIS3MDL" "Adafruit LSM6DS" "Adafruit NeoPixel" "Adafruit NeoMatrix" "Adafruit Sensor Calibration" "Adafruit SHT31 Library" "Adafruit SSD1306" "Adafruit ST7735 and ST7789 Library" "SdFat - Adafruit Fork"
58-
57+
arduino-cli lib install "Adafruit AHRS" "Adafruit APDS9960 Library" "Adafruit Arcada Library" "Adafruit BMP280 Library" "Adafruit Circuit Playground" "Adafruit EPD" "Adafruit GFX Library" "Adafruit HX8357 Library" "Adafruit ILI9341" "Adafruit LIS3MDL" "Adafruit LSM6DS" "Adafruit NeoPixel" "Adafruit NeoMatrix" "Adafruit Sensor Calibration" "Adafruit SHT31 Library" "Adafruit SSD1306" "Adafruit ST7735 and ST7789 Library" "SdFat - Adafruit Fork"
58+
5959
# TODO update to support MIDI version 5 later on
6060
arduino-cli lib install "MIDI Library"@4.3.1
6161

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "cores/nRF5/TinyUSB/Adafruit_TinyUSB_ArduinoCore"]
22
path = cores/nRF5/TinyUSB/Adafruit_TinyUSB_ArduinoCore
33
url = https://github.com/adafruit/Adafruit_TinyUSB_ArduinoCore.git
4+
[submodule "libraries/Adafruit_nRFCrypto"]
5+
path = libraries/Adafruit_nRFCrypto
6+
url = https://github.com/adafruit/Adafruit_nRFCrypto.git

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Following boards are also included but are not officially supported:
1616

1717
- [Nordic nRF52840DK PCA10056](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK)
1818
- [Particle Xenon](https://store.particle.io/products/xenon)
19+
- [Raytac MDBT50Q-RX Dongle](https://www.raytac.com/product/ins.php?index_id=89)
1920

2021
## BSP Installation
2122

@@ -49,7 +50,7 @@ There are two methods that you can use to install this BSP. We highly recommend
4950

5051
### Adafruit's nrfutil tools
5152

52-
[adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) (derived from Nordic pc-nrfutil) is needed to upload sketch via serial port.
53+
[adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) (derived from Nordic [pc-nrfutil](https://github.com/NordicSemiconductor/pc-nrfutil)) is needed to upload sketch via serial port.
5354

5455
- For Windows and macOS, pre-built executable binaries are included in the BSP at `tools/adafruit-nrfutil/`. It should work out of the box.
5556
- Linux user need to run follow command to install it from PyPi
@@ -117,8 +118,7 @@ which in turn is based on the [Arduino SAMD Core](https://github.com/arduino/Ard
117118

118119
The following libraries are used:
119120

120-
- adafruit-nrfutil is based on Nordic Semiconductor ASA's [pc-nrfutil](https://github.com/NordicSemiconductor/pc-nrfutil)
121-
- [freeRTOS](https://www.freertos.org/) as operating system
122-
- [tinyusb](https://github.com/hathach/tinyusb) as usb stack
121+
- [FreeRTOS](https://www.freertos.org/) as operating system
122+
- [LittleFS](https://github.com/ARMmbed/littlefs) for internal file system
123123
- [nrfx](https://github.com/NordicSemiconductor/nrfx) for peripherals driver
124-
- [littlefs](https://github.com/ARMmbed/littlefs) for internal file system
124+
- [TinyUSB](https://github.com/hathach/tinyusb) as usb stack

changelog.md

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,55 @@
11
# Adafruit nRF52 Arduino Core Changelog
22

3+
## 0.22.0 - WIP
4+
5+
This version implement comprehensive LESC and Legacy pairing using dynamic & static Passkey.
6+
7+
- Support static passkey (Legacy only)
8+
- Support LESC on nRF52840 using hardware-accelerated ARM CryptoCell CC310 provided by [Adafruit_nRFCypto](https://github.com/adafruit/Adafruit_nRFCrypto). The library is included as submodule and released together with the BSP.
9+
- Rework bonding mechanism to use IRK for peer finding. It is advisable to run `clearbonds` example to clean up bond files of previous version
10+
11+
### BLESecurity
12+
13+
A new class BLESecurity (access with Bluefruit.Security) is added to handle security and pairing.
14+
15+
- **setPIN()** to set static passkey, this will force to use Legacy Pairing
16+
- **setIOCaps()** to congiure IO capacities
17+
- **setMITM()** to enable/disable Man in The Middle protection (passkey), it is auto-enabled when using passkey
18+
- **setPairPasskeyCallback()** to register callback for displaying pairing passkey to user
19+
- **setPairCompleteCallback()** to register callback for the result of pairing procedure (succeeded or failed)
20+
- **setSecuredCallback()** to register callback which invoked when connection is secured. This happens after he pairing procedure is complete, or we re-connect with preivously bonded peer device
21+
22+
### Other Changes
23+
24+
**BLECentral**
25+
26+
- will automatically use stored Long Term Key to secure connection if paired/bonded with device previously
27+
28+
**Bluefruit**
29+
30+
- Bluefruit::requestPairing() is removed, please use the BLEConnection::requestPairing() instead
31+
- Bluefruit::connPaired() is removed, please use BLEConnection::secure() instead
32+
- Default Device name is USB_PRODUCT if available e.g CLUE, Circuit Playground Bluefruit, Feather nRF52840 Express etc ...
33+
34+
**BLEService**
35+
36+
- Added setPermission()
37+
38+
**BLEConnection**
39+
40+
- BLEConnection::requestPairing() is now non-blocking, it will return right after sending request to peer device. Previously it is blocked until the pairing process is complete.
41+
- Added BLEConnection::secured() to check if the connection is secured/encrypted
42+
- Added BLEConnection::bonded() to check if we store Longterm Key with current peer
43+
- Removed BLEConnection:paried(), user should either use secured() or bonded() depending on the context
44+
- If bonded, getPeerAddr() will return peer public address instead of random address.
45+
46+
**New Example Sketches**
47+
48+
- **pairing_pin** to use static PIN for peripheral role
49+
- **pairing_passkey** to use dyanmic Passkey for pairing. On Arcada compatible device such as `CLUE` or `Circuit Playground Bluefruit`, TFT display will also be used to display passkey.
50+
- **cental_pairing** similar to pairing_passkey but for nRF running central role
51+
- **ancs_arcada** for displaying ancs on arcada such CLUE and/or CPB.
52+
353
## 0.21.0 - 2020.08.31
454

555
Special thanks to @henrygab, @pyro9, @Nenik, @orrmany, @thaanstad, @kevinfrei for contributing and helping with this release.
@@ -21,15 +71,15 @@ Special thanks to @henrygab, @pyro9, @Nenik, @orrmany, @thaanstad, @kevinfrei fo
2171

2272
## 0.20.5 - 2020.07.05
2373

24-
Special thanks to @henrygab, @pyro9, @geeksville for contributing and helping with this release.
25-
2674
- Updated toolchain from gcc 7-2017q4 to 9-2019q4
2775
- Fixed GPIOTE channel conflict between libraries
2876
- Added type-safe for arrcount() macros
2977
- Added truncate() and rename() to Internal Filesystem (LittleFS).
3078
- Update CMSIS from v4 to v5 to build with TensorFlow
3179
- Update TinyUSB core to commit 0749077
3280

81+
Special thanks to @henrygab, @pyro9, @geeksville for contributing and helping with this release.
82+
3383
## 0.20.1 - 2020.04.23
3484

3585
- Update TinyUSB to commit c59fa77 due to a bug in the stack

cores/nRF5/Arduino.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ void resumeLoop(void);
134134
#define bit(b) (1UL << (b))
135135

136136
#ifdef NRF_P1
137-
#define digitalPinToPort(P) ( (g_ADigitalPinMap[P] < 32) ? NRF_P0 : NRF_P1 )
137+
#define digitalPinToPort(P) ( (g_ADigitalPinMap[P] < 32) ? NRF_P0 : NRF_P1 )
138138
#else
139-
#define digitalPinToPort(P) ( NRF_P0 )
139+
#define digitalPinToPort(P) ( NRF_P0 )
140140
#endif
141141

142142
#define digitalPinToBitMask(P) ( 1UL << ( g_ADigitalPinMap[P] < 32 ? g_ADigitalPinMap[P] : (g_ADigitalPinMap[P]-32) ) )

cores/nRF5/common_func.h

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -157,19 +157,19 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place
157157

158158

159159
#if CFG_DEBUG
160-
#define LOG_LV1(...) ADALOG(__VA_ARGS__)
161-
#define LOG_LV1_BUFFER(...) ADALOG_BUFFER(__VA_ARGS__)
160+
#define LOG_LV1(...) ADALOG(__VA_ARGS__)
161+
#define LOG_LV1_BUFFER(...) ADALOG_BUFFER(__VA_ARGS__)
162162
#else
163-
#define LOG_LV1(...)
164-
#define LOG_LV1_BUFFER(...)
163+
#define LOG_LV1(...)
164+
#define LOG_LV1_BUFFER(...)
165165
#endif
166166

167167
#if CFG_DEBUG >= 2
168-
#define LOG_LV2(...) ADALOG(__VA_ARGS__)
169-
#define LOG_LV2_BUFFER(...) ADALOG_BUFFER(__VA_ARGS__)
168+
#define LOG_LV2(...) ADALOG(__VA_ARGS__)
169+
#define LOG_LV2_BUFFER(...) ADALOG_BUFFER(__VA_ARGS__)
170170
#else
171-
#define LOG_LV2(...)
172-
#define LOG_LV2_BUFFER(...)
171+
#define LOG_LV2(...)
172+
#define LOG_LV2_BUFFER(...)
173173
#endif
174174

175175
#if CFG_DEBUG
@@ -193,7 +193,10 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place
193193
do {\
194194
uint8_t const* p8 = (uint8_t const*) (buf);\
195195
PRINTF(#buf ": ");\
196-
for(uint32_t i=0; i<(n); i++) PRINTF("%02x ", p8[i]);\
196+
for(uint32_t i=0; i<(n); i++) {\
197+
if (i%16 == 0) PRINTF("\n"); \
198+
PRINTF("%02x ", p8[i]); \
199+
}\
197200
PRINTF("\n");\
198201
}while(0)
199202

@@ -213,15 +216,15 @@ const char* dbg_err_str(int32_t err_id); // TODO move to other place
213216

214217
#else
215218

216-
#define PRINT_LOCATION()
217-
#define PRINT_MESS(x)
218-
#define PRINT_HEAP()
219-
#define PRINT_STR(x)
220-
#define PRINT_INT(x)
221-
#define PRINT_HEX(x)
222-
#define PRINT_FLOAT(x)
223-
#define PRINT_BUFFER(buf, n)
224-
#define ADALOG(...)
219+
#define PRINT_LOCATION()
220+
#define PRINT_MESS(x)
221+
#define PRTNT_HEAP()
222+
#define PRINT_STR(x)
223+
#define PRINT_INT(x)
224+
#define PRINT_HEX(x)
225+
#define PRINT_FLOAT(x)
226+
#define PRINT_BUFFER(buf, n)
227+
#define ADALOG(...)
225228

226229
#endif
227230

cores/nRF5/common_inc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
#include <stdint.h>
4040
#include <stdbool.h>
41+
#include <stddef.h>
4142

4243
#include "compiler_macro.h"
4344
#include "common_func.h"

cores/nRF5/linker/nrf52840_s140_v6.ld

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ MEMORY
77
{
88
FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000
99

10-
/* SRAM required by S132 depend on
10+
/* SRAM required by Softdevice depend on
1111
* - Attribute Table Size (Number of Services and Characteristics)
1212
* - Vendor UUID count
1313
* - Max ATT MTU

cores/nRF5/rtos.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@
5050
#include "queue.h"
5151
#include "semphr.h"
5252

53+
#define DEBUG_MALLOC 1
54+
5355
#define DELAY_FOREVER portMAX_DELAY
56+
5457
enum
5558
{
5659
TASK_PRIO_LOWEST = 0, // Idle task, should not be used
@@ -65,8 +68,11 @@ enum
6568
#define tick2ms(tck) ( ( ((uint64_t)(tck)) * 1000) / configTICK_RATE_HZ )
6669
#define tick2us(tck) ( ( ((uint64_t)(tck)) * 1000000) / configTICK_RATE_HZ )
6770

68-
#define malloc_type(type) rtos_malloc( sizeof(type) )
69-
#define rtos_malloc_type(_type) (_type*) rtos_malloc(sizeof(_type))
71+
#if DEBUG_MALLOC
72+
#define rtos_malloc_type(_type) ({ LOG_LV2("MALLOC", #_type " = %d bytes", sizeof(_type)); ((_type*) rtos_malloc(sizeof(_type))); })
73+
#else
74+
#define rtos_malloc_type(_type) ((_type*) rtos_malloc(sizeof(_type)))
75+
#endif
7076

7177
static inline void* rtos_malloc(size_t _size)
7278
{

cores/nRF5/verify.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ extern "C"
6161
static inline void VERIFY_MESS_impl(int32_t _status, const char* (*_fstr)(int32_t), const char* func_name, int line_number)
6262
{
6363
PRINTF("%s: %d: verify failed, error = ", func_name, line_number);
64-
if (_fstr)
64+
if (_fstr && _fstr(_status))
6565
{
6666
PRINTF(_fstr(_status));
6767
}
6868
else
6969
{
70-
PRINTF("%ld", _status);
70+
PRINTF("0x%lX (%ld)", _status, _status);
7171
}
7272
PRINTF("\n");
7373
}
@@ -107,9 +107,15 @@ extern "C"
107107
* - status value if called with 1 parameter e.g VERIFY_STATUS(status)
108108
* - 2 parameter if called with 2 parameters e.g VERIFY_STATUS(status, errorcode)
109109
*/
110-
#define VERIFY_STATUS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, dbg_err_str)
110+
#define VERIFY_STATUS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, dbg_err_str)
111111

112-
#define VERIFY_ERROR(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, NULL)
112+
#define PRINT_STATUS(_exp) do \
113+
{ \
114+
int32_t _status = (int32_t) _exp; \
115+
if ( 0 != _status ) VERIFY_MESS(_status, dbg_err_str); \
116+
} while(0) \
117+
118+
#define VERIFY_ERROR(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, NULL)
113119

114120
/*------------------------------------------------------------------*/
115121
/* VERIFY

libraries/Adafruit_nRFCrypto

Submodule Adafruit_nRFCrypto added at 48b08a5

libraries/Bluefruit52Lib/examples/Central/central_bleuart/central_bleuart.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ BLEClientUart clientUart; // bleuart client
2525
void setup()
2626
{
2727
Serial.begin(115200);
28-
while ( !Serial ) delay(10); // for nrf52840 with native usb
28+
// while ( !Serial ) delay(10); // for nrf52840 with native usb
2929

3030
Serial.println("Bluefruit52 Central BLEUART Example");
3131
Serial.println("-----------------------------------\n");

libraries/Bluefruit52Lib/examples/Central/central_hid/central_hid.ino

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ hid_mouse_report_t last_mse_report = { 0 };
3030
void setup()
3131
{
3232
Serial.begin(115200);
33-
while ( !Serial ) delay(10); // for nrf52840 with native usb
33+
// while ( !Serial ) delay(10); // for nrf52840 with native usb
3434

3535
Serial.println("Bluefruit52 Central HID (Keyboard + Mouse) Example");
3636
Serial.println("--------------------------------------------------\n");
@@ -55,6 +55,9 @@ void setup()
5555
Bluefruit.Central.setConnectCallback(connect_callback);
5656
Bluefruit.Central.setDisconnectCallback(disconnect_callback);
5757

58+
// Set connection secured callback, invoked when connection is encrypted
59+
Bluefruit.Security.setSecuredCallback(connection_secured_callback);
60+
5861
/* Start Central Scanning
5962
* - Enable auto scan if disconnected
6063
* - Interval = 100 ms, window = 80 ms
@@ -88,6 +91,8 @@ void scan_callback(ble_gap_evt_adv_report_t* report)
8891
*/
8992
void connect_callback(uint16_t conn_handle)
9093
{
94+
BLEConnection* conn = Bluefruit.Connection(conn_handle);
95+
9196
Serial.println("Connected");
9297

9398
Serial.print("Discovering HID Service ... ");
@@ -97,11 +102,31 @@ void connect_callback(uint16_t conn_handle)
97102
Serial.println("Found it");
98103

99104
// HID device mostly require pairing/bonding
100-
if ( !Bluefruit.requestPairing(conn_handle) )
101-
{
102-
Serial.print("Failed to paired");
103-
return;
104-
}
105+
conn->requestPairing();
106+
}else
107+
{
108+
Serial.println("Found NONE");
109+
110+
// disconnect since we couldn't find blehid service
111+
conn->disconnect();
112+
}
113+
}
114+
115+
void connection_secured_callback(uint16_t conn_handle)
116+
{
117+
BLEConnection* conn = Bluefruit.Connection(conn_handle);
118+
119+
if ( !conn->secured() )
120+
{
121+
// It is possible that connection is still not secured by this time.
122+
// This happens (central only) when we try to encrypt connection using stored bond keys
123+
// but peer reject it (probably it remove its stored key).
124+
// Therefore we will request an pairing again --> callback again when encrypted
125+
conn->requestPairing();
126+
}
127+
else
128+
{
129+
Serial.println("Secured");
105130

106131
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.hid_information.xml
107132
uint8_t hidInfo[4];
@@ -120,15 +145,9 @@ void connect_callback(uint16_t conn_handle)
120145

121146
// Enable Mouse report notification if present on prph
122147
if ( hid.mousePresent() ) hid.enableMouse();
123-
148+
124149
Serial.println("Ready to receive from peripheral");
125-
}else
126-
{
127-
Serial.println("Found NONE");
128-
129-
// disconnect since we couldn't find blehid service
130-
Bluefruit.disconnect(conn_handle);
131-
}
150+
}
132151
}
133152

134153
/**

0 commit comments

Comments
 (0)