Skip to content

Write encryption & visible LTK / IRK #3

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

Merged
merged 1 commit into from
Jan 2, 2021
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/*
Battery Monitor

This example creates a BLE peripheral with the standard battery service and
level characteristic. The A0 pin is used to calculate the battery level.

The circuit:
- Arduino MKR WiFi 1010, Arduino Uno WiFi Rev2 board, Arduino Nano 33 IoT,
Arduino Nano 33 BLE, or Arduino Nano 33 BLE Sense board.

You can use a generic BLE central app, like LightBlue (iOS and Android) or
nRF Connect (Android), to interact with the services and characteristics
created in this sketch.

This example code is in the public domain.
*/

#include <ArduinoBLE.h>


// BLE Battery Service
BLEService batteryService("180F");

// BLE Battery Level Characteristic
BLEUnsignedCharCharacteristic batteryLevelChar("2A19", // standard 16-bit characteristic UUID
BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes
BLEStringCharacteristic stringcharacteristic("183E", BLERead | BLEWrite, 31);


// Add BLEEncryption tag to require pairing. This controls the LED.
BLEUnsignedCharCharacteristic secretValue("2a3F", BLERead | BLEWrite | BLEEncryption);

int oldBatteryLevel = 0; // last battery level reading from analog input
long previousMillis = 0; // last time the battery level was checked, in ms

void setup() {
Serial.begin(9600); // initialize serial communication
while (!Serial);

pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected


Serial.println("Serial connected");

// IRKs are keys that identify the true owner of a random mac address.
// Add IRKs of devices you are bonded with.
BLE.setGetIRKs([](uint8_t* nIRKs, uint8_t** BADDR_TYPES, uint8_t*** BDAddrs, uint8_t*** IRKs){
// Set to number of devices
*nIRKs = 2;

*BDAddrs = new uint8_t*[*nIRKs];
*IRKs = new uint8_t*[*nIRKs];
*BADDR_TYPES = new uint8_t[*nIRKs];

// Set these to the mac and IRK for your bonded devices as printed in the serial console after bonding.
uint8_t iPhoneMac [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t iPhoneIRK[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

uint8_t iPadMac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t iPadIRK[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };


(*BADDR_TYPES)[0] = 0;
(*IRKs)[0] = new uint8_t[16];
memcpy((*IRKs)[0],iPhoneIRK,16);
(*BDAddrs)[0] = new uint8_t[6];
memcpy((*BDAddrs)[0], iPhoneMac, 6);


(*BADDR_TYPES)[1] = 0;
(*IRKs)[1] = new uint8_t[16];
memcpy((*IRKs)[1],iPadIRK,16);
(*BDAddrs)[1] = new uint8_t[6];
memcpy((*BDAddrs)[1], iPadMac, 6);


return 1;
});
// The LTK is the secret key which is used to encrypt bluetooth traffic
BLE.setGetLTK([](uint8_t* address, uint8_t* LTK){
// address is input
Serial.print("Recieved request for address: ");
btct.printBytes(address,6);

// Set these to the MAC and LTK of your devices after bonding.
uint8_t iPhoneMac [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t iPhoneLTK[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t iPadMac [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t iPadLTK[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


if(memcmp(iPhoneMac, address, 6)==0){
memcpy(LTK, iPhoneLTK, 16);
return 1;
}else if(memcmp(iPadMac, address, 6)==0){
memcpy(LTK, iPadLTK, 16);
}
return 0;
});
BLE.setStoreIRK([](uint8_t* address, uint8_t* IRK){
Serial.print(F("New device with MAC : "));
btct.printBytes(address,6);
Serial.print(F("Need to store IRK : "));
btct.printBytes(IRK,16);
return 1;
});
BLE.setStoreLTK([](uint8_t* address, uint8_t* LTK){
Serial.print(F("New device with MAC : "));
btct.printBytes(address,6);
Serial.print(F("Need to store LTK : "));
btct.printBytes(LTK,16);
return 1;
});

while(1){// begin initialization
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
delay(200);
continue;
}
Serial.println("BT init");
delay(200);

/* Set a local name for the BLE device
This name will appear in advertising packets
and can be used by remote devices to identify this BLE device
The name can be changed but maybe be truncated based on space left in advertisement packet
*/

BLE.setDeviceName("Arduino");
BLE.setLocalName("BatteryMonitor");

BLE.setAdvertisedService(batteryService); // add the service UUID
batteryService.addCharacteristic(batteryLevelChar); // add the battery level characteristic
batteryService.addCharacteristic(stringcharacteristic);
batteryService.addCharacteristic(secretValue);

BLE.addService(batteryService); // Add the battery service
batteryLevelChar.writeValue(oldBatteryLevel); // set initial value for this characteristic
char* stringCharValue = new char[32];
stringCharValue = "string";
stringcharacteristic.writeValue(stringCharValue);
secretValue.writeValue(0);

delay(1000);

/* Start advertising BLE. It will start continuously transmitting BLE
advertising packets and will be visible to remote BLE central devices
until it receives a new connection */

// start advertising
if(!BLE.advertise()){
Serial.println("failed to advertise bluetooth.");
BLE.stopAdvertise();
delay(500);
}else{
Serial.println("advertising...");
break;
}
BLE.end();
delay(100);
}
}


void loop() {
// wait for a BLE central
BLEDevice central = BLE.central();

// if a central is connected to the peripheral:
if (central) {
Serial.print("Connected to central: ");
// print the central's BT address:
Serial.println(central.address());

// check the battery level every 200ms
// while the central is connected:
while (central.connected()) {
long currentMillis = millis();
// if 200ms have passed, check the battery level:
if (currentMillis - previousMillis >= 1000) {
previousMillis = currentMillis;
updateBatteryLevel();
if(secretValue.value()>0){
digitalWrite(13,HIGH);
}else{
digitalWrite(13,LOW);
}
}
}
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
}

void updateBatteryLevel() {
/* Read the current voltage level on the A0 analog input pin.
This is used here to simulate the charge level of a battery.
*/
int battery = analogRead(A0);
int batteryLevel = map(battery, 0, 1023, 0, 100);

if (batteryLevel != oldBatteryLevel) { // if the battery level has changed
// Serial.print("Battery Level % is now: "); // print it
// Serial.println(batteryLevel);
batteryLevelChar.writeValue(batteryLevel); // and update the battery level characteristic
oldBatteryLevel = batteryLevel; // save the level for next comparison
}
}
8 changes: 4 additions & 4 deletions src/BLECharacteristic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ BLECharacteristic::BLECharacteristic(BLERemoteCharacteristic* remote) :
}
}

BLECharacteristic::BLECharacteristic(const char* uuid, uint8_t properties, int valueSize, bool fixedLength) :
BLECharacteristic(new BLELocalCharacteristic(uuid, properties, valueSize, fixedLength))
BLECharacteristic::BLECharacteristic(const char* uuid, uint16_t permissions, int valueSize, bool fixedLength) :
BLECharacteristic(new BLELocalCharacteristic(uuid, permissions, valueSize, fixedLength))
{
}

BLECharacteristic::BLECharacteristic(const char* uuid, uint8_t properties, const char* value) :
BLECharacteristic(new BLELocalCharacteristic(uuid, properties, value))
BLECharacteristic::BLECharacteristic(const char* uuid, uint16_t permissions, const char* value) :
BLECharacteristic(new BLELocalCharacteristic(uuid, permissions, value))
{
}

Expand Down
4 changes: 2 additions & 2 deletions src/BLECharacteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class BLERemoteCharacteristic;
class BLECharacteristic {
public:
BLECharacteristic();
BLECharacteristic(const char* uuid, uint8_t properties, int valueSize, bool fixedLength = false);
BLECharacteristic(const char* uuid, uint8_t properties, const char* value);
BLECharacteristic(const char* uuid, uint16_t permissions, int valueSize, bool fixedLength = false);
BLECharacteristic(const char* uuid, uint16_t permissions, const char* value);
BLECharacteristic(const BLECharacteristic& other);
virtual ~BLECharacteristic();

Expand Down
11 changes: 10 additions & 1 deletion src/BLEProperty.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,19 @@ enum BLEProperty {
BLEWrite = 0x08,
BLENotify = 0x10,
BLEIndicate = 0x20,
BLEAuth = 1 << 6,
BLEAuthSignedWrite = 1 << 6,
BLEExtProp = 1 << 7,
};

enum BLEPermission {
BLEEncryption = 1 << 9,
BLEAuthentication = 1 << 10,
BLEAuthorization = 1 << 11,
// BLEWriteEncryption = 1 << 11,
// BLEWriteAuthentication = 1 << 12,
// BLEWriteAuthorization = 1 << 13,
};

#define ESP_GATT_CHAR_PROP_BIT_BROADCAST (1 << 0) /* 0x01 */ /* relate to BTA_GATT_CHAR_PROP_BIT_BROADCAST in bta/bta_gatt_api.h */
#define ESP_GATT_CHAR_PROP_BIT_READ (1 << 1) /* 0x02 */ /* relate to BTA_GATT_CHAR_PROP_BIT_READ in bta/bta_gatt_api.h */
#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 */
Expand Down
6 changes: 3 additions & 3 deletions src/BLETypedCharacteristic.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
template<typename T> class BLETypedCharacteristic : public BLECharacteristic
{
public:
BLETypedCharacteristic(const char* uuid, unsigned char properties);
BLETypedCharacteristic(const char* uuid, unsigned int permissions);

int writeValue(T value);
int setValue(T value) { return writeValue(value); }
Expand All @@ -43,8 +43,8 @@ template<typename T> class BLETypedCharacteristic : public BLECharacteristic
T byteSwap(T value);
};

template<typename T> BLETypedCharacteristic<T>::BLETypedCharacteristic(const char* uuid, unsigned char properties) :
BLECharacteristic(uuid, properties, sizeof(T), true)
template<typename T> BLETypedCharacteristic<T>::BLETypedCharacteristic(const char* uuid, unsigned int permissions) :
BLECharacteristic(uuid, permissions, sizeof(T), true)
{
T value;
memset(&value, 0x00, sizeof(value));
Expand Down
28 changes: 14 additions & 14 deletions src/BLETypedCharacteristics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,72 +21,72 @@

#include "BLETypedCharacteristics.h"

BLEBoolCharacteristic::BLEBoolCharacteristic(const char* uuid, unsigned char properties) :
BLEBoolCharacteristic::BLEBoolCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<bool>(uuid, properties)
{
}

BLEBooleanCharacteristic::BLEBooleanCharacteristic(const char* uuid, unsigned char properties) :
BLEBooleanCharacteristic::BLEBooleanCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<bool>(uuid, properties)
{
}

BLECharCharacteristic::BLECharCharacteristic(const char* uuid, unsigned char properties) :
BLECharCharacteristic::BLECharCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<char>(uuid, properties)
{
}

BLEUnsignedCharCharacteristic::BLEUnsignedCharCharacteristic(const char* uuid, unsigned char properties) :
BLEUnsignedCharCharacteristic::BLEUnsignedCharCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<unsigned char>(uuid, properties)
{
}

BLEByteCharacteristic::BLEByteCharacteristic(const char* uuid, unsigned char properties) :
BLEByteCharacteristic::BLEByteCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<byte>(uuid, properties)
{
}

BLEShortCharacteristic::BLEShortCharacteristic(const char* uuid, unsigned char properties) :
BLEShortCharacteristic::BLEShortCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<short>(uuid, properties)
{
}

BLEUnsignedShortCharacteristic::BLEUnsignedShortCharacteristic(const char* uuid, unsigned char properties) :
BLEUnsignedShortCharacteristic::BLEUnsignedShortCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<unsigned short>(uuid, properties)
{
}

BLEWordCharacteristic::BLEWordCharacteristic(const char* uuid, unsigned char properties) :
BLEWordCharacteristic::BLEWordCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<word>(uuid, properties)
{
}

BLEIntCharacteristic::BLEIntCharacteristic(const char* uuid, unsigned char properties) :
BLEIntCharacteristic::BLEIntCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<int>(uuid, properties)
{
}

BLEUnsignedIntCharacteristic::BLEUnsignedIntCharacteristic(const char* uuid, unsigned char properties) :
BLEUnsignedIntCharacteristic::BLEUnsignedIntCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<unsigned int>(uuid, properties)
{
}

BLELongCharacteristic::BLELongCharacteristic(const char* uuid, unsigned char properties) :
BLELongCharacteristic::BLELongCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<long>(uuid, properties)
{
}

BLEUnsignedLongCharacteristic::BLEUnsignedLongCharacteristic(const char* uuid, unsigned char properties) :
BLEUnsignedLongCharacteristic::BLEUnsignedLongCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<unsigned long>(uuid, properties)
{
}

BLEFloatCharacteristic::BLEFloatCharacteristic(const char* uuid, unsigned char properties) :
BLEFloatCharacteristic::BLEFloatCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<float>(uuid, properties)
{
}

BLEDoubleCharacteristic::BLEDoubleCharacteristic(const char* uuid, unsigned char properties) :
BLEDoubleCharacteristic::BLEDoubleCharacteristic(const char* uuid, unsigned int properties) :
BLETypedCharacteristic<double>(uuid, properties)
{
}
Loading