diff --git a/docs/Reference.md b/docs/Reference.md index b725400..ac4e7d8 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -63,6 +63,12 @@ The following **optional** `homeSpan` methods override various HomeSpan initiali * setting *suffix* to a null string "" is permitted. * example: `homeSpan.begin(Category::Fans, "Living Room Ceiling Fan", "LivingRoomFan");` will yield a default *hostName* of the form *LivingRoomFan-A1B2C3D4E5F6.local*. Calling `homeSpan.setHostNameSuffix("v2")` prior to `homeSpan.begin()` will instead yield a *hostName* of *LivingRoomFanv2.local* +* `void setQRID(const char *ID)` + * changes the Setup ID from the HomeSpan default ("HSPN") to *ID* + * *ID* must be exactly 4 alphanumeric characters. If not, the request to change the Setup ID is silently ignored and remains "HSPN" + * The Setup ID is an optional parameter used when pairing the device to HomeKit with a QR Code (instead of the usual Setup Code) + + ## *SpanAccessory(uint32_t aid)* Creating an instance of this **class** adds a new HAP Accessory to the HomeSpan HAP Database. diff --git a/src/HAP.cpp b/src/HAP.cpp index f788d6a..09c74b8 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -63,8 +63,8 @@ void HAPClient::init(){ 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("Setup Payload for Optional QR Code: "); + Serial.print(homeSpan.qrCode.get(atoi(homeSpan.defaultSetupCode),homeSpan.qrID,atoi(homeSpan.category))); Serial.print("\n\n"); } diff --git a/src/HapQR.h b/src/HapQR.h new file mode 100644 index 0000000..9b47938 --- /dev/null +++ b/src/HapQR.h @@ -0,0 +1,59 @@ +/********************************************************************************* + * MIT License + * + * Copyright (c) 2020-2021 Gregg E. Berman + * + * https://github.com/HomeSpan/HomeSpan + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + ********************************************************************************/ + +class HapQR { + private: + char qrCode[21]; + + public: + enum { + NFC=1, + IP=2, + BLTE=4 + }; + + char *get(uint32_t setupCode, const char *setupID, uint8_t category, uint8_t protocols=IP, uint8_t qVersion=0, uint8_t qReserved=0){ + + setupCode&=0x07FFFFFF; // valid values: 0-99999999 + qVersion&=0x7; // valid values: 0-7 + qReserved&=0xF; // valid values: 0-15 + protocols&=0x7; // valid values: 0-7 + + uint64_t n=((uint64_t) qVersion<<43) | ((uint64_t) qReserved<<39) | ((uint64_t) category<<31) | (protocols<<27) | setupCode; + sprintf(qrCode,"X-HM://"); + + for(int i=15;i>=7;i--){ + qrCode[i]=n%36+48; + if(qrCode[i]>57) + qrCode[i]+=7; + n/=36; + } + + sprintf(qrCode+16,"%-4.4s",setupID); + return(qrCode); + } // create +}; diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index caab137..7f106d2 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -540,8 +540,8 @@ void Span::processSerialCommand(const char *c){ nvs_commit(HAPClient::srpNVS); // commit to NVS Serial.print("New Code Saved!\n"); - Serial.print("Optional QR Code: "); - Serial.print(getQRCode(setupCode)); + Serial.print("Setup Payload for Optional QR Code: "); + Serial.print(qrCode.get(atoi(setupCode),qrID,atoi(category))); Serial.print("\n\n"); } } @@ -753,32 +753,6 @@ 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; diff --git a/src/HomeSpan.h b/src/HomeSpan.h index 3ead256..281ee36 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -38,6 +38,7 @@ #include "Utils.h" #include "Network.h" #include "HAPConstants.h" +#include "HapQR.h" using std::vector; using std::unordered_map; @@ -85,7 +86,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 + HapQR 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 @@ -149,7 +150,6 @@ struct Span{ 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 }; ///////////////////////////////