Added QR Code logic
HomeSpan now broadcasts a Hashed Setup ID as MDNS "sh", which is used when pairing with a QR Code instead of a Setup Code. A text version of the resulting QR code is output to the Serial Monitor whenever the 9-digit Setup Code is generated or changed. The text version of the QR code can then be input into any QR Code Generator to create a pairable QR Code. The default Setup ID used to create the Hashed Setup ID is "HSPN". This can be changed with homeSpan.setQRCode(const char *id), where id is exactly 4 alphanumeric characters. If not, the request to change the Setup ID is silently ignored and remains "HSPN."
This commit is contained in:
parent
78cbd926f1
commit
9b71d6928a
|
|
@ -58,11 +58,14 @@ void HAPClient::init(){
|
|||
} else {
|
||||
|
||||
char c[128];
|
||||
sprintf(c,"Generating SRP verification data for default Setup Code: %.3s-%.2s-%.3s\n\n",homeSpan.defaultSetupCode,homeSpan.defaultSetupCode+3,homeSpan.defaultSetupCode+5);
|
||||
sprintf(c,"Generating SRP verification data for default Setup Code: %.3s-%.2s-%.3s\n",homeSpan.defaultSetupCode,homeSpan.defaultSetupCode+3,homeSpan.defaultSetupCode+5);
|
||||
Serial.print(c);
|
||||
srp.createVerifyCode(homeSpan.defaultSetupCode,verifyData.verifyCode,verifyData.salt); // create verification code from default Setup Code and random salt
|
||||
nvs_set_blob(srpNVS,"VERIFYDATA",&verifyData,sizeof(verifyData)); // update data
|
||||
nvs_commit(srpNVS); // commit to NVS
|
||||
Serial.print("Optional QR Code: ");
|
||||
Serial.print(homeSpan.getQRCode(homeSpan.defaultSetupCode));
|
||||
Serial.print("\n\n");
|
||||
}
|
||||
|
||||
if(!nvs_get_blob(hapNVS,"ACCESSORY",NULL,&len)){ // if found long-term Accessory data in NVS
|
||||
|
|
|
|||
|
|
@ -410,6 +410,17 @@ void Span::checkConnect(){
|
|||
else
|
||||
mdns_service_txt_item_set("_hap","_tcp","sf","0"); // set Status Flag = 0
|
||||
|
||||
uint8_t hashInput[22];
|
||||
uint8_t hashOutput[64];
|
||||
char setupHash[9];
|
||||
size_t len;
|
||||
|
||||
memcpy(hashInput,qrID,4); // Create the Seup ID for use with optional QR Codes. This is an undocumented feature of HAP R2!
|
||||
memcpy(hashInput+4,id,17); // Step 1: Concatenate 4-character Setup ID and 17-character Accessory ID into hashInput
|
||||
mbedtls_sha512_ret(hashInput,21,hashOutput,0); // Step 2: Perform SHA-512 hash on combined 21-byte hashInput to create 64-byte hashOutput
|
||||
mbedtls_base64_encode((uint8_t *)setupHash,9,&len,hashOutput,4); // Step 3: Encode the first 4 bytes of hashOutput in base64, which results in an 8-character, null-terminated, setupHash
|
||||
mdns_service_txt_item_set("_hap","_tcp","sh",setupHash); // Step 4: broadcast the resulting Setup Hash
|
||||
|
||||
Serial.print("\nStarting Web (HTTP) Server supporting up to ");
|
||||
Serial.print(maxConnections);
|
||||
Serial.print(" simultaneous connections...\n\n");
|
||||
|
|
@ -426,6 +437,19 @@ void Span::checkConnect(){
|
|||
|
||||
///////////////////////////////
|
||||
|
||||
void Span::setQRID(const char *id){
|
||||
|
||||
char tBuf[5];
|
||||
sscanf(id,"%4[0-9A-Za-z]",tBuf);
|
||||
|
||||
if(strlen(id)==4 && strlen(tBuf)==4){
|
||||
qrID=id;
|
||||
}
|
||||
|
||||
} // setQRID
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void Span::processSerialCommand(const char *c){
|
||||
|
||||
switch(c[0]){
|
||||
|
|
@ -515,6 +539,10 @@ void Span::processSerialCommand(const char *c){
|
|||
nvs_set_blob(HAPClient::srpNVS,"VERIFYDATA",&verifyData,sizeof(verifyData)); // update data
|
||||
nvs_commit(HAPClient::srpNVS); // commit to NVS
|
||||
Serial.print("New Code Saved!\n");
|
||||
|
||||
Serial.print("Optional QR Code: ");
|
||||
Serial.print(getQRCode(setupCode));
|
||||
Serial.print("\n\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -725,6 +753,32 @@ void Span::processSerialCommand(const char *c){
|
|||
|
||||
///////////////////////////////
|
||||
|
||||
const char *Span::getQRCode(const char *setupCode){
|
||||
|
||||
uint64_t n;
|
||||
uint64_t iSetupCode;
|
||||
uint64_t iCategory;
|
||||
|
||||
sscanf(category,"%llu",&iCategory);
|
||||
sscanf(setupCode,"%llu",&iSetupCode);
|
||||
|
||||
n=(iCategory << 31) | (0xA << 27) | iSetupCode;
|
||||
|
||||
qrCode="";
|
||||
|
||||
while(n>0){
|
||||
char c=n%36+48;
|
||||
if(c>57)
|
||||
c+=7;
|
||||
qrCode=c+qrCode;
|
||||
n/=36;
|
||||
}
|
||||
qrCode="X-HM://00" + qrCode + qrID;
|
||||
return(qrCode.c_str());
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
int Span::sprintfAttributes(char *cBuf){
|
||||
|
||||
int nBytes=0;
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ struct Span{
|
|||
int nFatalErrors=0; // number of fatal errors in user-defined configuration
|
||||
String configLog; // log of configuration process, including any errors
|
||||
boolean isBridge=true; // flag indicating whether device is configured as a bridge (i.e. first Accessory contains nothing but AccessoryInformation and HAPProtocolInformation)
|
||||
String qrCode; // optional QR Code to use for pairing
|
||||
|
||||
boolean connected=false; // WiFi connection status
|
||||
unsigned long waitTime=60000; // time to wait (in milliseconds) between WiFi connection attempts
|
||||
|
|
@ -97,6 +98,7 @@ struct Span{
|
|||
uint8_t maxConnections=DEFAULT_MAX_CONNECTIONS; // number of simultaneous HAP connections
|
||||
unsigned long comModeLife=DEFAULT_COMMAND_TIMEOUT*1000; // length of time (in milliseconds) to keep Command Mode alive before resuming normal operations
|
||||
uint16_t tcpPortNum=DEFAULT_TCP_PORT; // port for TCP communications between HomeKit and HomeSpan
|
||||
const char *qrID=DEFAULT_QR_ID; // optional Setup ID used to pair with QR Code
|
||||
|
||||
WiFiServer *hapServer; // pointer to the HAP Server connection
|
||||
Blinker statusLED; // indicates HomeSpan status
|
||||
|
|
@ -146,6 +148,8 @@ struct Span{
|
|||
void setMaxConnections(uint8_t nCon){maxConnections=nCon;} // sets maximum number of simultaneous HAP connections (HAP requires devices support at least 8)
|
||||
void setHostNameSuffix(const char *suffix){hostNameSuffix=suffix;} // sets the hostName suffix to be used instead of the 6-byte AccessoryID
|
||||
void setPortNum(uint16_t port){tcpPortNum=port;} // sets the TCP port number to use for communications between HomeKit and HomeSpan
|
||||
void setQRID(const char *id); // sets the Setup ID for optional pairing with a QR Code
|
||||
const char *getQRCode(const char *setupCode); // gets an optional QR code from setupCode
|
||||
};
|
||||
|
||||
///////////////////////////////
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <mbedtls/sha512.h>
|
||||
#include <mbedtls/bignum.h>
|
||||
#include <mbedtls/base64.h>
|
||||
|
||||
#include "HAPConstants.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@
|
|||
|
||||
#define DEFAULT_SETUP_CODE "46637726" // changed during network setup or with 'S' command
|
||||
|
||||
#define DEFAULT_QR_ID "HSPN" // change with homeSpan.setQRID(qrID);
|
||||
|
||||
#define DEFAULT_CONTROL_PIN 21 // change with homeSpan.setControlPin(pin)
|
||||
#define DEFAULT_STATUS_PIN 13 // change with homeSpan.setStatusPin(pin)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,7 @@ void setup() {
|
|||
|
||||
Serial.begin(115200);
|
||||
|
||||
homeSpan.setLogLevel(2);
|
||||
|
||||
homeSpan.setHostNameSuffix("");
|
||||
homeSpan.setPortNum(1200);
|
||||
homeSpan.setLogLevel(1);
|
||||
|
||||
homeSpan.begin(Category::Lighting,"HomeSpanTest");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue