Have nodes broadcast an ibeacon advertisement (#763)
This commit is contained in:
parent
77373d83cb
commit
c1cc621fb7
|
@ -14,6 +14,7 @@ const BLEUUID miThermUUID(uint16_t(0x181A));
|
||||||
const BLEUUID trackrUUID((uint16_t)0x0F3E);
|
const BLEUUID trackrUUID((uint16_t)0x0F3E);
|
||||||
const BLEUUID vanmoofUUID(0x6acc5540, 0xe631, 0x4069, 0x944db8ca7598ad50);
|
const BLEUUID vanmoofUUID(0x6acc5540, 0xe631, 0x4069, 0x944db8ca7598ad50);
|
||||||
const BLEUUID tractiveUUID(0x20130001, 0x0719, 0x4b6e, 0xbe5d158ab92fa5a4);
|
const BLEUUID tractiveUUID(0x20130001, 0x0719, 0x4b6e, 0xbe5d158ab92fa5a4);
|
||||||
|
const BLEUUID espresenseUUID(0xe5ca1ade, 0xf007, 0xba11, 0x0000000000000000);
|
||||||
|
|
||||||
const BLEUUID nutUUID((uint16_t)0x1803);
|
const BLEUUID nutUUID((uint16_t)0x1803);
|
||||||
|
|
||||||
|
|
|
@ -1,292 +1,277 @@
|
||||||
#include "Enrollment.h"
|
#include "Enrollment.h"
|
||||||
#include "globals.h"
|
|
||||||
#include "mqtt.h"
|
|
||||||
#include "HttpWebServer.h"
|
|
||||||
|
|
||||||
#include <NimBLEDevice.h>
|
|
||||||
#include <NimBLEAdvertisedDevice.h>
|
#include <NimBLEAdvertisedDevice.h>
|
||||||
#include <NimBLEService.h>
|
|
||||||
#include <NimBLECharacteristic.h>
|
#include <NimBLECharacteristic.h>
|
||||||
#include <NimBLEDescriptor.h>
|
#include <NimBLEDescriptor.h>
|
||||||
|
#include <NimBLEDevice.h>
|
||||||
|
#include <NimBLEService.h>
|
||||||
|
|
||||||
namespace Enrollment
|
#include "HttpWebServer.h"
|
||||||
{
|
#include "globals.h"
|
||||||
static const char hex_digits[] = "0123456789abcdef";
|
#include "mqtt.h"
|
||||||
static bool lastEnrolling = false;
|
#include "util.h"
|
||||||
static NimBLEServer *pServer;
|
|
||||||
static String id;
|
|
||||||
static unsigned long lastLoop = 0;
|
|
||||||
static int connectionToEnroll = -1;
|
|
||||||
|
|
||||||
class ServerCallbacks : public NimBLEServerCallbacks
|
namespace Enrollment {
|
||||||
{
|
static const char hex_digits[] = "0123456789abcdef";
|
||||||
void onConnect(NimBLEServer *pServer)
|
static bool lastEnrolling = true;
|
||||||
{
|
static String name;
|
||||||
Serial.println("Client connected");
|
static unsigned long lastLoop = 0;
|
||||||
if (enrolling)
|
static int connectionToEnroll = -1;
|
||||||
{
|
static uint16_t major, minor;
|
||||||
Serial.println("Multi-connect support: start advertising");
|
static NimBLEServer *pServer;
|
||||||
NimBLEDevice::startAdvertising();
|
static NimBLEAdvertisementData *oAdvertisementData;
|
||||||
}
|
static NimBLEService *heartRate;
|
||||||
};
|
static NimBLEService *deviceInfo;
|
||||||
|
|
||||||
void onConnect(NimBLEServer *pServer, ble_gap_conn_desc *desc)
|
class ServerCallbacks : public NimBLEServerCallbacks {
|
||||||
{
|
void onConnect(NimBLEServer *pServer) {
|
||||||
Serial.print("Client address: ");
|
Serial.println("Client connected");
|
||||||
Serial.println(NimBLEAddress(desc->peer_ota_addr).toString().c_str());
|
if (enrolling) {
|
||||||
if (enrolling) {
|
Serial.println("Multi-connect support: start advertising");
|
||||||
NimBLEDevice::startSecurity(desc->conn_handle);
|
NimBLEDevice::startAdvertising();
|
||||||
connectionToEnroll = desc->conn_handle;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void onDisconnect(NimBLEServer *pServer)
|
|
||||||
{
|
|
||||||
if (enrolling) {
|
|
||||||
Serial.println("Client disconnected - start advertising");
|
|
||||||
NimBLEDevice::startAdvertising();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void onMTUChange(uint16_t MTU, ble_gap_conn_desc *desc)
|
|
||||||
{
|
|
||||||
Serial.printf("MTU updated: %u for connection ID: %u\n", MTU, desc->conn_handle);
|
|
||||||
};
|
|
||||||
|
|
||||||
void onAuthenticationComplete(ble_gap_conn_desc *desc)
|
|
||||||
{
|
|
||||||
if (!desc->sec_state.encrypted) Serial.printf("Encrypt connection failed conn: %d!\n", desc->conn_handle);
|
|
||||||
else Serial.printf("Encrypt connection success conn: %d!\n", desc->conn_handle);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class CharacteristicCallbacks : public NimBLECharacteristicCallbacks
|
|
||||||
{
|
|
||||||
void onRead(NimBLECharacteristic *pCharacteristic)
|
|
||||||
{
|
|
||||||
Serial.print(pCharacteristic->getUUID().toString().c_str());
|
|
||||||
Serial.print(": onRead(), value: ");
|
|
||||||
Serial.println(pCharacteristic->getValue().c_str());
|
|
||||||
};
|
|
||||||
|
|
||||||
void onWrite(NimBLECharacteristic *pCharacteristic)
|
|
||||||
{
|
|
||||||
Serial.print(pCharacteristic->getUUID().toString().c_str());
|
|
||||||
Serial.print(": onWrite(), value: ");
|
|
||||||
Serial.println(pCharacteristic->getValue().c_str());
|
|
||||||
};
|
|
||||||
|
|
||||||
void onNotify(NimBLECharacteristic *pCharacteristic)
|
|
||||||
{
|
|
||||||
//Serial.println("Sending notification to clients");
|
|
||||||
};
|
|
||||||
|
|
||||||
void onStatus(NimBLECharacteristic *pCharacteristic, Status status, int code)
|
|
||||||
{
|
|
||||||
/* String str = ("Notification/Indication status code: ");
|
|
||||||
str += status;
|
|
||||||
str += ", return code: ";
|
|
||||||
str += code;
|
|
||||||
str += ", ";
|
|
||||||
str += NimBLEUtils::returnCodeToString(code);
|
|
||||||
Serial.println(str); */
|
|
||||||
};
|
|
||||||
|
|
||||||
void onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue)
|
|
||||||
{
|
|
||||||
String str = "Client ID: ";
|
|
||||||
str += desc->conn_handle;
|
|
||||||
str += " Address: ";
|
|
||||||
str += std::string(NimBLEAddress(desc->peer_ota_addr)).c_str();
|
|
||||||
if (subValue == 0)
|
|
||||||
{
|
|
||||||
str += " Unsubscribed to ";
|
|
||||||
}
|
|
||||||
else if (subValue == 1)
|
|
||||||
{
|
|
||||||
str += " Subscribed to notfications for ";
|
|
||||||
}
|
|
||||||
else if (subValue == 2)
|
|
||||||
{
|
|
||||||
str += " Subscribed to indications for ";
|
|
||||||
}
|
|
||||||
else if (subValue == 3)
|
|
||||||
{
|
|
||||||
str += " Subscribed to notifications and indications for ";
|
|
||||||
}
|
|
||||||
str += std::string(pCharacteristic->getUUID()).c_str();
|
|
||||||
Serial.println(str);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class DescriptorCallbacks : public NimBLEDescriptorCallbacks
|
|
||||||
{
|
|
||||||
void onWrite(NimBLEDescriptor *pDescriptor)
|
|
||||||
{
|
|
||||||
std::string dscVal = pDescriptor->getValue();
|
|
||||||
Serial.print("Descriptor witten value:");
|
|
||||||
Serial.println(dscVal.c_str());
|
|
||||||
};
|
|
||||||
|
|
||||||
void onRead(NimBLEDescriptor *pDescriptor)
|
|
||||||
{
|
|
||||||
Serial.print(pDescriptor->getUUID().toString().c_str());
|
|
||||||
Serial.println(" Descriptor read");
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static DescriptorCallbacks dscCallbacks;
|
|
||||||
static CharacteristicCallbacks chrCallbacks;
|
|
||||||
|
|
||||||
static int ble_sm_read_bond(uint16_t conn_handle, struct ble_store_value_sec *out_bond)
|
|
||||||
{
|
|
||||||
struct ble_store_key_sec key_sec;
|
|
||||||
struct ble_gap_conn_desc desc;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = ble_gap_conn_find(conn_handle, &desc);
|
|
||||||
if (rc != 0)
|
|
||||||
{
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
memset(&key_sec, 0, sizeof key_sec);
|
void onConnect(NimBLEServer *pServer, ble_gap_conn_desc *desc) {
|
||||||
key_sec.peer_addr = desc.peer_id_addr;
|
Serial.print("Client address: ");
|
||||||
|
Serial.println(NimBLEAddress(desc->peer_ota_addr).toString().c_str());
|
||||||
|
if (enrolling) {
|
||||||
|
NimBLEDevice::startSecurity(desc->conn_handle);
|
||||||
|
connectionToEnroll = desc->conn_handle;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
rc = ble_store_read_peer_sec(&key_sec, out_bond);
|
void onDisconnect(NimBLEServer *pServer) {
|
||||||
|
if (enrolling) {
|
||||||
|
Serial.println("Client disconnected - start advertising");
|
||||||
|
NimBLEDevice::startAdvertising();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void onMTUChange(uint16_t MTU, ble_gap_conn_desc *desc) {
|
||||||
|
Serial.printf("MTU updated: %u for connection ID: %u\n", MTU, desc->conn_handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
void onAuthenticationComplete(ble_gap_conn_desc *desc) {
|
||||||
|
if (!desc->sec_state.encrypted)
|
||||||
|
Serial.printf("Encrypt connection failed conn: %d!\n", desc->conn_handle);
|
||||||
|
else
|
||||||
|
Serial.printf("Encrypt connection success conn: %d!\n", desc->conn_handle);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CharacteristicCallbacks : public NimBLECharacteristicCallbacks {
|
||||||
|
void onRead(NimBLECharacteristic *pCharacteristic) {
|
||||||
|
Serial.print(pCharacteristic->getUUID().toString().c_str());
|
||||||
|
Serial.print(": onRead(), value: ");
|
||||||
|
Serial.println(pCharacteristic->getValue().c_str());
|
||||||
|
};
|
||||||
|
|
||||||
|
void onWrite(NimBLECharacteristic *pCharacteristic) {
|
||||||
|
Serial.print(pCharacteristic->getUUID().toString().c_str());
|
||||||
|
Serial.print(": onWrite(), value: ");
|
||||||
|
Serial.println(pCharacteristic->getValue().c_str());
|
||||||
|
};
|
||||||
|
|
||||||
|
void onNotify(NimBLECharacteristic *pCharacteristic){
|
||||||
|
// Serial.println("Sending notification to clients");
|
||||||
|
};
|
||||||
|
|
||||||
|
void onStatus(NimBLECharacteristic *pCharacteristic, Status status, int code){
|
||||||
|
/* String str = ("Notification/Indication status code: ");
|
||||||
|
str += status;
|
||||||
|
str += ", return code: ";
|
||||||
|
str += code;
|
||||||
|
str += ", ";
|
||||||
|
str += NimBLEUtils::returnCodeToString(code);
|
||||||
|
Serial.println(str); */
|
||||||
|
};
|
||||||
|
|
||||||
|
void onSubscribe(NimBLECharacteristic *pCharacteristic, ble_gap_conn_desc *desc, uint16_t subValue) {
|
||||||
|
String str = "Client ID: ";
|
||||||
|
str += desc->conn_handle;
|
||||||
|
str += " Address: ";
|
||||||
|
str += std::string(NimBLEAddress(desc->peer_ota_addr)).c_str();
|
||||||
|
if (subValue == 0) {
|
||||||
|
str += " Unsubscribed to ";
|
||||||
|
} else if (subValue == 1) {
|
||||||
|
str += " Subscribed to notfications for ";
|
||||||
|
} else if (subValue == 2) {
|
||||||
|
str += " Subscribed to indications for ";
|
||||||
|
} else if (subValue == 3) {
|
||||||
|
str += " Subscribed to notifications and indications for ";
|
||||||
|
}
|
||||||
|
str += std::string(pCharacteristic->getUUID()).c_str();
|
||||||
|
Serial.println(str);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class DescriptorCallbacks : public NimBLEDescriptorCallbacks {
|
||||||
|
void onWrite(NimBLEDescriptor *pDescriptor) {
|
||||||
|
std::string dscVal = pDescriptor->getValue();
|
||||||
|
Serial.print("Descriptor witten value:");
|
||||||
|
Serial.println(dscVal.c_str());
|
||||||
|
};
|
||||||
|
|
||||||
|
void onRead(NimBLEDescriptor *pDescriptor) {
|
||||||
|
Serial.print(pDescriptor->getUUID().toString().c_str());
|
||||||
|
Serial.println(" Descriptor read");
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static DescriptorCallbacks dscCallbacks;
|
||||||
|
static CharacteristicCallbacks chrCallbacks;
|
||||||
|
|
||||||
|
static int ble_sm_read_bond(uint16_t conn_handle, struct ble_store_value_sec *out_bond) {
|
||||||
|
struct ble_store_key_sec key_sec;
|
||||||
|
struct ble_gap_conn_desc desc;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ble_gap_conn_find(conn_handle, &desc);
|
||||||
|
if (rc != 0) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tryGetIrkFromConnection(uint16_t conn_handle, std::string &irk)
|
memset(&key_sec, 0, sizeof key_sec);
|
||||||
{
|
key_sec.peer_addr = desc.peer_id_addr;
|
||||||
struct ble_store_value_sec bond;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = ble_sm_read_bond(conn_handle, &bond);
|
rc = ble_store_read_peer_sec(&key_sec, out_bond);
|
||||||
if (rc != 0)
|
return rc;
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!bond.irk_present)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string output;
|
|
||||||
output.reserve(32);
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
auto c = bond.irk[15 - i];
|
|
||||||
output.push_back(hex_digits[c >> 4]);
|
|
||||||
output.push_back(hex_digits[c & 15]);
|
|
||||||
}
|
|
||||||
irk = output;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Setup() {
|
|
||||||
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_NO_INPUT_OUTPUT);
|
|
||||||
NimBLEDevice::setSecurityAuth(true, true, true);
|
|
||||||
|
|
||||||
pServer = NimBLEDevice::createServer();
|
|
||||||
pServer->setCallbacks(new ServerCallbacks());
|
|
||||||
|
|
||||||
NimBLEService *heartRate = pServer->createService("180D");
|
|
||||||
NimBLECharacteristic *bpm = heartRate->createCharacteristic("2A37", NIMBLE_PROPERTY::NOTIFY, 2);
|
|
||||||
bpm->setCallbacks(&chrCallbacks);
|
|
||||||
|
|
||||||
NimBLEService *deviceInfo = pServer->createService("180A");
|
|
||||||
NimBLECharacteristic *manufName = deviceInfo->createCharacteristic("2A29", NIMBLE_PROPERTY::READ);
|
|
||||||
manufName->setValue("ESPresense");
|
|
||||||
manufName->setCallbacks(&chrCallbacks);
|
|
||||||
NimBLECharacteristic *appearance = deviceInfo->createCharacteristic("2A01", NIMBLE_PROPERTY::READ, 2);
|
|
||||||
appearance->setValue((int16_t) 0x4142);
|
|
||||||
appearance->setCallbacks(&chrCallbacks);
|
|
||||||
NimBLECharacteristic *modelNum = deviceInfo->createCharacteristic("2A24", NIMBLE_PROPERTY::READ);
|
|
||||||
modelNum->setValue(std::string(room.c_str()));
|
|
||||||
modelNum->setCallbacks(&chrCallbacks);
|
|
||||||
|
|
||||||
heartRate->start();
|
|
||||||
deviceInfo->start();
|
|
||||||
|
|
||||||
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
|
|
||||||
pAdvertising->addServiceUUID(heartRate->getUUID());
|
|
||||||
pAdvertising->setScanResponse(true);
|
|
||||||
|
|
||||||
pServer->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Loop()
|
|
||||||
{
|
|
||||||
if (enrolling != lastEnrolling)
|
|
||||||
{
|
|
||||||
HttpWebServer::SendState();
|
|
||||||
auto pAdvertising = NimBLEDevice::getAdvertising();
|
|
||||||
if (enrolling)
|
|
||||||
{
|
|
||||||
pAdvertising->start();
|
|
||||||
Serial.println("Advertising started");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pAdvertising->stop();
|
|
||||||
Serial.println("Advertising stopped");
|
|
||||||
}
|
|
||||||
lastEnrolling = enrolling;
|
|
||||||
if (enrolling) enrollingEndMillis = millis() + 120000;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enrolling && enrollingEndMillis < millis())
|
|
||||||
{
|
|
||||||
enrolling = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (millis() - lastLoop > 1000)
|
|
||||||
{
|
|
||||||
lastLoop = millis();
|
|
||||||
|
|
||||||
if (enrolling) HttpWebServer::SendState();
|
|
||||||
if (pServer->getConnectedCount())
|
|
||||||
{
|
|
||||||
NimBLEService *pSvc = pServer->getServiceByUUID("180D");
|
|
||||||
if (pSvc)
|
|
||||||
{
|
|
||||||
NimBLECharacteristic *pChr = pSvc->getCharacteristic("2A37");
|
|
||||||
if (pChr)
|
|
||||||
{
|
|
||||||
pChr->setValue((short) (micros() && 0x00FF));
|
|
||||||
pChr->notify(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enrolling && connectionToEnroll > -1)
|
|
||||||
{
|
|
||||||
std::string irk;
|
|
||||||
if (tryGetIrkFromConnection(connectionToEnroll, irk))
|
|
||||||
{
|
|
||||||
alias(String("irk:") + irk.c_str(), id.isEmpty() ? (String("irk:") + irk.c_str()) : id);
|
|
||||||
enrolling = false;
|
|
||||||
pServer->disconnect(connectionToEnroll);
|
|
||||||
connectionToEnroll = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Command(String& command, String& pay)
|
|
||||||
{
|
|
||||||
if (command == "enroll")
|
|
||||||
{
|
|
||||||
id = pay.equals("PRESS") ? "" : pay;
|
|
||||||
enrolling = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SendDiscovery()
|
|
||||||
{
|
|
||||||
return sendButtonDiscovery("Enroll", EC_CONFIG);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tryGetIrkFromConnection(uint16_t conn_handle, std::string &irk) {
|
||||||
|
struct ble_store_value_sec bond;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ble_sm_read_bond(conn_handle, &bond);
|
||||||
|
if (rc != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!bond.irk_present)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string output;
|
||||||
|
output.reserve(32);
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
auto c = bond.irk[15 - i];
|
||||||
|
output.push_back(hex_digits[c >> 4]);
|
||||||
|
output.push_back(hex_digits[c & 15]);
|
||||||
|
}
|
||||||
|
irk = output;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Setup() {
|
||||||
|
NimBLEDevice::setSecurityIOCap(BLE_HS_IO_NO_INPUT_OUTPUT);
|
||||||
|
NimBLEDevice::setSecurityAuth(true, true, true);
|
||||||
|
|
||||||
|
pServer = NimBLEDevice::createServer();
|
||||||
|
pServer->setCallbacks(new ServerCallbacks());
|
||||||
|
|
||||||
|
heartRate = pServer->createService("180D");
|
||||||
|
NimBLECharacteristic *bpm = heartRate->createCharacteristic("2A37", NIMBLE_PROPERTY::NOTIFY, 2);
|
||||||
|
bpm->setCallbacks(&chrCallbacks);
|
||||||
|
|
||||||
|
deviceInfo = pServer->createService("180A");
|
||||||
|
NimBLECharacteristic *manufName = deviceInfo->createCharacteristic("2A29", NIMBLE_PROPERTY::READ);
|
||||||
|
manufName->setValue("ESPresense");
|
||||||
|
manufName->setCallbacks(&chrCallbacks);
|
||||||
|
NimBLECharacteristic *appearance = deviceInfo->createCharacteristic("2A01", NIMBLE_PROPERTY::READ, 2);
|
||||||
|
appearance->setValue((int16_t)0x4142);
|
||||||
|
appearance->setCallbacks(&chrCallbacks);
|
||||||
|
NimBLECharacteristic *modelNum = deviceInfo->createCharacteristic("2A24", NIMBLE_PROPERTY::READ);
|
||||||
|
modelNum->setValue(std::string(room.c_str()));
|
||||||
|
modelNum->setCallbacks(&chrCallbacks);
|
||||||
|
|
||||||
|
heartRate->start();
|
||||||
|
deviceInfo->start();
|
||||||
|
|
||||||
|
uint32_t nodeId = (uint32_t)(ESP.getEfuseMac() >> 24);
|
||||||
|
major = (nodeId & 0xFFFF0000) >> 16;
|
||||||
|
minor = nodeId & 0xFFFF;
|
||||||
|
|
||||||
|
BLEBeacon oBeacon = BLEBeacon();
|
||||||
|
oBeacon.setManufacturerId(0x4C00);
|
||||||
|
oBeacon.setProximityUUID(espresenseUUID);
|
||||||
|
oBeacon.setMajor(major);
|
||||||
|
oBeacon.setMinor(minor);
|
||||||
|
oBeacon.setSignalPower(-59);
|
||||||
|
oAdvertisementData = new NimBLEAdvertisementData();
|
||||||
|
oAdvertisementData->setFlags(BLE_HS_ADV_F_BREDR_UNSUP);
|
||||||
|
oAdvertisementData->setManufacturerData(oBeacon.getData());
|
||||||
|
|
||||||
|
pServer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Loop() {
|
||||||
|
if (enrolling != lastEnrolling) {
|
||||||
|
HttpWebServer::SendState();
|
||||||
|
auto pAdvertising = NimBLEDevice::getAdvertising();
|
||||||
|
if (enrolling) {
|
||||||
|
pAdvertising->reset();
|
||||||
|
pAdvertising->setScanResponse(true);
|
||||||
|
pAdvertising->setAdvertisementType(BLE_GAP_CONN_MODE_UND);
|
||||||
|
pAdvertising->addServiceUUID(heartRate->getUUID());
|
||||||
|
pAdvertising->start();
|
||||||
|
Serial.println("Advertising HRM");
|
||||||
|
} else {
|
||||||
|
alias(Sprintf("iBeacon:e5ca1ade-f007-ba11-0000-000000000000-%hu-%hu", major, minor), "node:" + id, room);
|
||||||
|
|
||||||
|
pAdvertising->reset();
|
||||||
|
pAdvertising->setScanResponse(false);
|
||||||
|
pAdvertising->setAdvertisementType(BLE_GAP_CONN_MODE_NON);
|
||||||
|
pAdvertising->setAdvertisementData(*oAdvertisementData);
|
||||||
|
pAdvertising->start();
|
||||||
|
Serial.println("Advertising iBeacon");
|
||||||
|
}
|
||||||
|
lastEnrolling = enrolling;
|
||||||
|
if (enrolling) enrollingEndMillis = millis() + 120000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enrolling && enrollingEndMillis < millis()) {
|
||||||
|
enrolling = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (millis() - lastLoop > 1000) {
|
||||||
|
lastLoop = millis();
|
||||||
|
|
||||||
|
if (enrolling) HttpWebServer::SendState();
|
||||||
|
if (pServer->getConnectedCount()) {
|
||||||
|
NimBLEService *pSvc = pServer->getServiceByUUID("180D");
|
||||||
|
if (pSvc) {
|
||||||
|
NimBLECharacteristic *pChr = pSvc->getCharacteristic("2A37");
|
||||||
|
if (pChr) {
|
||||||
|
pChr->setValue((short)(micros() && 0x00FF));
|
||||||
|
pChr->notify(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enrolling && connectionToEnroll > -1) {
|
||||||
|
std::string irk;
|
||||||
|
if (tryGetIrkFromConnection(connectionToEnroll, irk)) {
|
||||||
|
auto id = name.isEmpty() ? "" : slugify(name);
|
||||||
|
alias(String("irk:") + irk.c_str(), id.isEmpty() ? (String("irk:") + irk.c_str()) : id, name);
|
||||||
|
enrolling = false;
|
||||||
|
pServer->disconnect(connectionToEnroll);
|
||||||
|
connectionToEnroll = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Command(String &command, String &pay) {
|
||||||
|
if (command == "enroll") {
|
||||||
|
name = pay.equals("PRESS") ? "" : pay;
|
||||||
|
enrolling = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SendDiscovery() {
|
||||||
|
return sendButtonDiscovery("Enroll", EC_CONFIG);
|
||||||
|
}
|
||||||
|
} // namespace Enrollment
|
||||||
|
|
|
@ -212,11 +212,12 @@ bool sendDeleteDiscovery(const String &domain, const String &name)
|
||||||
return pub(discoveryTopic.c_str(), 0, false, "");
|
return pub(discoveryTopic.c_str(), 0, false, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alias(const String &alias, const String &id)
|
bool alias(const String &alias, const String &id, const String &name = "")
|
||||||
{
|
{
|
||||||
Serial.printf("Setting %s->%s\n", alias.c_str(), id.c_str());
|
Serial.printf("Setting %s->%s\n", alias.c_str(), id.c_str());
|
||||||
doc.clear();
|
doc.clear();
|
||||||
doc["id"] = id;
|
doc["id"] = id;
|
||||||
|
doc["name"] = name;
|
||||||
serializeJson(doc, buffer);
|
serializeJson(doc, buffer);
|
||||||
String settingsTopic = CHANNEL + String("/settings/") + alias + "/config";
|
String settingsTopic = CHANNEL + String("/settings/") + alias + "/config";
|
||||||
return pub(settingsTopic.c_str(), 0, true, buffer);
|
return pub(settingsTopic.c_str(), 0, true, buffer);
|
||||||
|
|
|
@ -25,4 +25,4 @@ bool sendLightDiscovery(const String &name, const String &entityCategory, bool r
|
||||||
|
|
||||||
bool sendDeleteDiscovery(const String &domain, const String &name);
|
bool sendDeleteDiscovery(const String &domain, const String &name);
|
||||||
|
|
||||||
bool alias(const String &alias, const String &id);
|
bool alias(const String &alias, const String &id, const String &name);
|
||||||
|
|
Loading…
Reference in New Issue