diff --git a/src/HAP.cpp b/src/HAP.cpp index f788d6a..b2bd08e 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -64,7 +64,7 @@ void HAPClient::init(){ 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(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..f983eb7 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -541,7 +541,7 @@ void Span::processSerialCommand(const char *c){ Serial.print("New Code Saved!\n"); Serial.print("Optional QR Code: "); - Serial.print(getQRCode(setupCode)); + 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 }; ///////////////////////////////