Skip to content

Commit 065fc1d

Browse files
author
unknownconstant
authored
Merge pull request #3 from unknownconstant/pairing
Write encryption & visible LTK / IRK
2 parents f364628 + fa42bb2 commit 065fc1d

22 files changed

+855
-76
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/*
2+
Battery Monitor
3+
4+
This example creates a BLE peripheral with the standard battery service and
5+
level characteristic. The A0 pin is used to calculate the battery level.
6+
7+
The circuit:
8+
- Arduino MKR WiFi 1010, Arduino Uno WiFi Rev2 board, Arduino Nano 33 IoT,
9+
Arduino Nano 33 BLE, or Arduino Nano 33 BLE Sense board.
10+
11+
You can use a generic BLE central app, like LightBlue (iOS and Android) or
12+
nRF Connect (Android), to interact with the services and characteristics
13+
created in this sketch.
14+
15+
This example code is in the public domain.
16+
*/
17+
18+
#include <ArduinoBLE.h>
19+
20+
21+
// BLE Battery Service
22+
BLEService batteryService("180F");
23+
24+
// BLE Battery Level Characteristic
25+
BLEUnsignedCharCharacteristic batteryLevelChar("2A19", // standard 16-bit characteristic UUID
26+
BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
27+
BLEStringCharacteristic stringcharacteristic("183E", BLERead | BLEWrite, 31);
28+
29+
30+
// Add BLEEncryption tag to require pairing. This controls the LED.
31+
BLEUnsignedCharCharacteristic secretValue("2a3F", BLERead | BLEWrite | BLEEncryption);
32+
33+
int oldBatteryLevel = 0; // last battery level reading from analog input
34+
long previousMillis = 0; // last time the battery level was checked, in ms
35+
36+
void setup() {
37+
Serial.begin(9600); // initialize serial communication
38+
while (!Serial);
39+
40+
pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected
41+
42+
43+
Serial.println("Serial connected");
44+
45+
// IRKs are keys that identify the true owner of a random mac address.
46+
// Add IRKs of devices you are bonded with.
47+
BLE.setGetIRKs([](uint8_t* nIRKs, uint8_t** BADDR_TYPES, uint8_t*** BDAddrs, uint8_t*** IRKs){
48+
// Set to number of devices
49+
*nIRKs = 2;
50+
51+
*BDAddrs = new uint8_t*[*nIRKs];
52+
*IRKs = new uint8_t*[*nIRKs];
53+
*BADDR_TYPES = new uint8_t[*nIRKs];
54+
55+
// Set these to the mac and IRK for your bonded devices as printed in the serial console after bonding.
56+
uint8_t iPhoneMac [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
57+
uint8_t iPhoneIRK[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
58+
59+
uint8_t iPadMac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
60+
uint8_t iPadIRK[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
61+
62+
63+
(*BADDR_TYPES)[0] = 0;
64+
(*IRKs)[0] = new uint8_t[16];
65+
memcpy((*IRKs)[0],iPhoneIRK,16);
66+
(*BDAddrs)[0] = new uint8_t[6];
67+
memcpy((*BDAddrs)[0], iPhoneMac, 6);
68+
69+
70+
(*BADDR_TYPES)[1] = 0;
71+
(*IRKs)[1] = new uint8_t[16];
72+
memcpy((*IRKs)[1],iPadIRK,16);
73+
(*BDAddrs)[1] = new uint8_t[6];
74+
memcpy((*BDAddrs)[1], iPadMac, 6);
75+
76+
77+
return 1;
78+
});
79+
// The LTK is the secret key which is used to encrypt bluetooth traffic
80+
BLE.setGetLTK([](uint8_t* address, uint8_t* LTK){
81+
// address is input
82+
Serial.print("Recieved request for address: ");
83+
btct.printBytes(address,6);
84+
85+
// Set these to the MAC and LTK of your devices after bonding.
86+
uint8_t iPhoneMac [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
87+
uint8_t iPhoneLTK[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
88+
uint8_t iPadMac [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
89+
uint8_t iPadLTK[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
90+
91+
92+
if(memcmp(iPhoneMac, address, 6)==0){
93+
memcpy(LTK, iPhoneLTK, 16);
94+
return 1;
95+
}else if(memcmp(iPadMac, address, 6)==0){
96+
memcpy(LTK, iPadLTK, 16);
97+
}
98+
return 0;
99+
});
100+
BLE.setStoreIRK([](uint8_t* address, uint8_t* IRK){
101+
Serial.print(F("New device with MAC : "));
102+
btct.printBytes(address,6);
103+
Serial.print(F("Need to store IRK : "));
104+
btct.printBytes(IRK,16);
105+
return 1;
106+
});
107+
BLE.setStoreLTK([](uint8_t* address, uint8_t* LTK){
108+
Serial.print(F("New device with MAC : "));
109+
btct.printBytes(address,6);
110+
Serial.print(F("Need to store LTK : "));
111+
btct.printBytes(LTK,16);
112+
return 1;
113+
});
114+
115+
while(1){// begin initialization
116+
if (!BLE.begin()) {
117+
Serial.println("starting BLE failed!");
118+
delay(200);
119+
continue;
120+
}
121+
Serial.println("BT init");
122+
delay(200);
123+
124+
/* Set a local name for the BLE device
125+
This name will appear in advertising packets
126+
and can be used by remote devices to identify this BLE device
127+
The name can be changed but maybe be truncated based on space left in advertisement packet
128+
*/
129+
130+
BLE.setDeviceName("Arduino");
131+
BLE.setLocalName("BatteryMonitor");
132+
133+
BLE.setAdvertisedService(batteryService); // add the service UUID
134+
batteryService.addCharacteristic(batteryLevelChar); // add the battery level characteristic
135+
batteryService.addCharacteristic(stringcharacteristic);
136+
batteryService.addCharacteristic(secretValue);
137+
138+
BLE.addService(batteryService); // Add the battery service
139+
batteryLevelChar.writeValue(oldBatteryLevel); // set initial value for this characteristic
140+
char* stringCharValue = new char[32];
141+
stringCharValue = "string";
142+
stringcharacteristic.writeValue(stringCharValue);
143+
secretValue.writeValue(0);
144+
145+
delay(1000);
146+
147+
/* Start advertising BLE. It will start continuously transmitting BLE
148+
advertising packets and will be visible to remote BLE central devices
149+
until it receives a new connection */
150+
151+
// start advertising
152+
if(!BLE.advertise()){
153+
Serial.println("failed to advertise bluetooth.");
154+
BLE.stopAdvertise();
155+
delay(500);
156+
}else{
157+
Serial.println("advertising...");
158+
break;
159+
}
160+
BLE.end();
161+
delay(100);
162+
}
163+
}
164+
165+
166+
void loop() {
167+
// wait for a BLE central
168+
BLEDevice central = BLE.central();
169+
170+
// if a central is connected to the peripheral:
171+
if (central) {
172+
Serial.print("Connected to central: ");
173+
// print the central's BT address:
174+
Serial.println(central.address());
175+
176+
// check the battery level every 200ms
177+
// while the central is connected:
178+
while (central.connected()) {
179+
long currentMillis = millis();
180+
// if 200ms have passed, check the battery level:
181+
if (currentMillis - previousMillis >= 1000) {
182+
previousMillis = currentMillis;
183+
updateBatteryLevel();
184+
if(secretValue.value()>0){
185+
digitalWrite(13,HIGH);
186+
}else{
187+
digitalWrite(13,LOW);
188+
}
189+
}
190+
}
191+
Serial.print("Disconnected from central: ");
192+
Serial.println(central.address());
193+
}
194+
}
195+
196+
void updateBatteryLevel() {
197+
/* Read the current voltage level on the A0 analog input pin.
198+
This is used here to simulate the charge level of a battery.
199+
*/
200+
int battery = analogRead(A0);
201+
int batteryLevel = map(battery, 0, 1023, 0, 100);
202+
203+
if (batteryLevel != oldBatteryLevel) { // if the battery level has changed
204+
// Serial.print("Battery Level % is now: "); // print it
205+
// Serial.println(batteryLevel);
206+
batteryLevelChar.writeValue(batteryLevel); // and update the battery level characteristic
207+
oldBatteryLevel = batteryLevel; // save the level for next comparison
208+
}
209+
}

src/BLECharacteristic.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ BLECharacteristic::BLECharacteristic(BLERemoteCharacteristic* remote) :
4747
}
4848
}
4949

50-
BLECharacteristic::BLECharacteristic(const char* uuid, uint8_t properties, int valueSize, bool fixedLength) :
51-
BLECharacteristic(new BLELocalCharacteristic(uuid, properties, valueSize, fixedLength))
50+
BLECharacteristic::BLECharacteristic(const char* uuid, uint16_t permissions, int valueSize, bool fixedLength) :
51+
BLECharacteristic(new BLELocalCharacteristic(uuid, permissions, valueSize, fixedLength))
5252
{
5353
}
5454

55-
BLECharacteristic::BLECharacteristic(const char* uuid, uint8_t properties, const char* value) :
56-
BLECharacteristic(new BLELocalCharacteristic(uuid, properties, value))
55+
BLECharacteristic::BLECharacteristic(const char* uuid, uint16_t permissions, const char* value) :
56+
BLECharacteristic(new BLELocalCharacteristic(uuid, permissions, value))
5757
{
5858
}
5959

src/BLECharacteristic.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class BLERemoteCharacteristic;
4545
class BLECharacteristic {
4646
public:
4747
BLECharacteristic();
48-
BLECharacteristic(const char* uuid, uint8_t properties, int valueSize, bool fixedLength = false);
49-
BLECharacteristic(const char* uuid, uint8_t properties, const char* value);
48+
BLECharacteristic(const char* uuid, uint16_t permissions, int valueSize, bool fixedLength = false);
49+
BLECharacteristic(const char* uuid, uint16_t permissions, const char* value);
5050
BLECharacteristic(const BLECharacteristic& other);
5151
virtual ~BLECharacteristic();
5252

src/BLEProperty.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,19 @@ enum BLEProperty {
2929
BLEWrite = 0x08,
3030
BLENotify = 0x10,
3131
BLEIndicate = 0x20,
32-
BLEAuth = 1 << 6,
32+
BLEAuthSignedWrite = 1 << 6,
3333
BLEExtProp = 1 << 7,
3434
};
3535

36+
enum BLEPermission {
37+
BLEEncryption = 1 << 9,
38+
BLEAuthentication = 1 << 10,
39+
BLEAuthorization = 1 << 11,
40+
// BLEWriteEncryption = 1 << 11,
41+
// BLEWriteAuthentication = 1 << 12,
42+
// BLEWriteAuthorization = 1 << 13,
43+
};
44+
3645
#define ESP_GATT_CHAR_PROP_BIT_BROADCAST (1 << 0) /* 0x01 */ /* relate to BTA_GATT_CHAR_PROP_BIT_BROADCAST in bta/bta_gatt_api.h */
3746
#define ESP_GATT_CHAR_PROP_BIT_READ (1 << 1) /* 0x02 */ /* relate to BTA_GATT_CHAR_PROP_BIT_READ in bta/bta_gatt_api.h */
3847
#define ESP_GATT_CHAR_PROP_BIT_WRITE_NR (1 << 2) /* 0x04 */ /* relate to BTA_GATT_CHAR_PROP_BIT_WRITE_NR in bta/bta_gatt_api.h */

src/BLETypedCharacteristic.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
template<typename T> class BLETypedCharacteristic : public BLECharacteristic
2626
{
2727
public:
28-
BLETypedCharacteristic(const char* uuid, unsigned char properties);
28+
BLETypedCharacteristic(const char* uuid, unsigned int permissions);
2929

3030
int writeValue(T value);
3131
int setValue(T value) { return writeValue(value); }
@@ -43,8 +43,8 @@ template<typename T> class BLETypedCharacteristic : public BLECharacteristic
4343
T byteSwap(T value);
4444
};
4545

46-
template<typename T> BLETypedCharacteristic<T>::BLETypedCharacteristic(const char* uuid, unsigned char properties) :
47-
BLECharacteristic(uuid, properties, sizeof(T), true)
46+
template<typename T> BLETypedCharacteristic<T>::BLETypedCharacteristic(const char* uuid, unsigned int permissions) :
47+
BLECharacteristic(uuid, permissions, sizeof(T), true)
4848
{
4949
T value;
5050
memset(&value, 0x00, sizeof(value));

src/BLETypedCharacteristics.cpp

+14-14
Original file line numberDiff line numberDiff line change
@@ -21,72 +21,72 @@
2121

2222
#include "BLETypedCharacteristics.h"
2323

24-
BLEBoolCharacteristic::BLEBoolCharacteristic(const char* uuid, unsigned char properties) :
24+
BLEBoolCharacteristic::BLEBoolCharacteristic(const char* uuid, unsigned int properties) :
2525
BLETypedCharacteristic<bool>(uuid, properties)
2626
{
2727
}
2828

29-
BLEBooleanCharacteristic::BLEBooleanCharacteristic(const char* uuid, unsigned char properties) :
29+
BLEBooleanCharacteristic::BLEBooleanCharacteristic(const char* uuid, unsigned int properties) :
3030
BLETypedCharacteristic<bool>(uuid, properties)
3131
{
3232
}
3333

34-
BLECharCharacteristic::BLECharCharacteristic(const char* uuid, unsigned char properties) :
34+
BLECharCharacteristic::BLECharCharacteristic(const char* uuid, unsigned int properties) :
3535
BLETypedCharacteristic<char>(uuid, properties)
3636
{
3737
}
3838

39-
BLEUnsignedCharCharacteristic::BLEUnsignedCharCharacteristic(const char* uuid, unsigned char properties) :
39+
BLEUnsignedCharCharacteristic::BLEUnsignedCharCharacteristic(const char* uuid, unsigned int properties) :
4040
BLETypedCharacteristic<unsigned char>(uuid, properties)
4141
{
4242
}
4343

44-
BLEByteCharacteristic::BLEByteCharacteristic(const char* uuid, unsigned char properties) :
44+
BLEByteCharacteristic::BLEByteCharacteristic(const char* uuid, unsigned int properties) :
4545
BLETypedCharacteristic<byte>(uuid, properties)
4646
{
4747
}
4848

49-
BLEShortCharacteristic::BLEShortCharacteristic(const char* uuid, unsigned char properties) :
49+
BLEShortCharacteristic::BLEShortCharacteristic(const char* uuid, unsigned int properties) :
5050
BLETypedCharacteristic<short>(uuid, properties)
5151
{
5252
}
5353

54-
BLEUnsignedShortCharacteristic::BLEUnsignedShortCharacteristic(const char* uuid, unsigned char properties) :
54+
BLEUnsignedShortCharacteristic::BLEUnsignedShortCharacteristic(const char* uuid, unsigned int properties) :
5555
BLETypedCharacteristic<unsigned short>(uuid, properties)
5656
{
5757
}
5858

59-
BLEWordCharacteristic::BLEWordCharacteristic(const char* uuid, unsigned char properties) :
59+
BLEWordCharacteristic::BLEWordCharacteristic(const char* uuid, unsigned int properties) :
6060
BLETypedCharacteristic<word>(uuid, properties)
6161
{
6262
}
6363

64-
BLEIntCharacteristic::BLEIntCharacteristic(const char* uuid, unsigned char properties) :
64+
BLEIntCharacteristic::BLEIntCharacteristic(const char* uuid, unsigned int properties) :
6565
BLETypedCharacteristic<int>(uuid, properties)
6666
{
6767
}
6868

69-
BLEUnsignedIntCharacteristic::BLEUnsignedIntCharacteristic(const char* uuid, unsigned char properties) :
69+
BLEUnsignedIntCharacteristic::BLEUnsignedIntCharacteristic(const char* uuid, unsigned int properties) :
7070
BLETypedCharacteristic<unsigned int>(uuid, properties)
7171
{
7272
}
7373

74-
BLELongCharacteristic::BLELongCharacteristic(const char* uuid, unsigned char properties) :
74+
BLELongCharacteristic::BLELongCharacteristic(const char* uuid, unsigned int properties) :
7575
BLETypedCharacteristic<long>(uuid, properties)
7676
{
7777
}
7878

79-
BLEUnsignedLongCharacteristic::BLEUnsignedLongCharacteristic(const char* uuid, unsigned char properties) :
79+
BLEUnsignedLongCharacteristic::BLEUnsignedLongCharacteristic(const char* uuid, unsigned int properties) :
8080
BLETypedCharacteristic<unsigned long>(uuid, properties)
8181
{
8282
}
8383

84-
BLEFloatCharacteristic::BLEFloatCharacteristic(const char* uuid, unsigned char properties) :
84+
BLEFloatCharacteristic::BLEFloatCharacteristic(const char* uuid, unsigned int properties) :
8585
BLETypedCharacteristic<float>(uuid, properties)
8686
{
8787
}
8888

89-
BLEDoubleCharacteristic::BLEDoubleCharacteristic(const char* uuid, unsigned char properties) :
89+
BLEDoubleCharacteristic::BLEDoubleCharacteristic(const char* uuid, unsigned int properties) :
9090
BLETypedCharacteristic<double>(uuid, properties)
9191
{
9292
}

0 commit comments

Comments
 (0)