diff --git a/src/HAP.cpp b/src/HAP.cpp index 118da3e..6e27e36 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -62,16 +62,11 @@ void HAPClient::init(){ nvs_get_blob(srpNVS,"VERIFYDATA",&verifyData,&len); // retrieve data srp.loadVerifyCode(verifyData.verifyCode,verifyData.salt); // load verification code and salt into SRP structure } else { - - char c[128]; - 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); + LOG0("Generating SRP verification data for default Setup Code: %.3s-%.2s-%.3s\n",homeSpan.defaultSetupCode,homeSpan.defaultSetupCode+3,homeSpan.defaultSetupCode+5); 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("Setup Payload for Optional QR Code: "); - Serial.print(homeSpan.qrCode.get(atoi(homeSpan.defaultSetupCode),homeSpan.qrID,atoi(homeSpan.category))); - Serial.print("\n\n"); + LOG0("Setup Payload for Optional QR Code: %s\n\n",homeSpan.qrCode.get(atoi(homeSpan.defaultSetupCode),homeSpan.qrID,atoi(homeSpan.category))); } if(!strlen(homeSpan.qrID)){ // Setup ID has not been specified in sketch @@ -85,7 +80,7 @@ void HAPClient::init(){ if(!nvs_get_blob(hapNVS,"ACCESSORY",NULL,&len)){ // if found long-term Accessory data in NVS nvs_get_blob(hapNVS,"ACCESSORY",&accessory,&len); // retrieve data } else { - Serial.print("Generating new random Accessory ID and Long-Term Ed25519 Signature Keys...\n"); + LOG0("Generating new random Accessory ID and Long-Term Ed25519 Signature Keys...\n"); uint8_t buf[6]; char cBuf[18]; @@ -103,7 +98,7 @@ void HAPClient::init(){ if(!nvs_get_blob(hapNVS,"CONTROLLERS",NULL,&len)){ // if found long-term Controller Pairings data from NVS nvs_get_blob(hapNVS,"CONTROLLERS",controllers,&len); // retrieve data } else { - Serial.print("Initializing storage for Paired Controllers data...\n\n"); + LOG0("Initializing storage for Paired Controllers data...\n\n"); HAPClient::removeControllers(); // clear all Controller data @@ -111,11 +106,11 @@ void HAPClient::init(){ nvs_commit(hapNVS); // commit to NVS } - Serial.print("Accessory ID: "); + LOG0("Accessory ID: "); charPrintRow(accessory.ID,17); - Serial.print(" LTPK: "); + LOG0(" LTPK: "); hexPrintRow(accessory.LTPK,32); - Serial.print("\n"); + LOG0("\n"); printControllers(); @@ -139,17 +134,19 @@ void HAPClient::init(){ if(!nvs_get_blob(hapNVS,"HAPHASH",NULL,&len)){ // if found HAP HASH structure nvs_get_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,&len); // retrieve data } else { - Serial.print("Resetting Database Hash...\n"); + LOG0("Resetting Database Hash...\n"); nvs_set_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,sizeof(homeSpan.hapConfig)); // save data (will default to all zero values, which will then be updated below) nvs_commit(hapNVS); // commit to NVS } - if(homeSpan.updateDatabase(false)) // create Configuration Number and Loop vector - Serial.printf("\nAccessory configuration has changed. Updating configuration number to %d\n",homeSpan.hapConfig.configNumber); - else - Serial.printf("\nAccessory configuration number: %d\n",homeSpan.hapConfig.configNumber); + if(homeSpan.updateDatabase(false)){ // create Configuration Number and Loop vector + LOG0("\nAccessory configuration has changed. Updating configuration number to %d\n",homeSpan.hapConfig.configNumber); + } + else{ + LOG0("\nAccessory configuration number: %d\n",homeSpan.hapConfig.configNumber); + } - Serial.print("\n"); + LOG0("\n"); } @@ -180,7 +177,7 @@ void HAPClient::processRequest(){ if(nBytes>MAX_HTTP){ // exceeded maximum number of bytes allowed badRequestError(); - Serial.print("\n*** ERROR: Exceeded maximum HTTP message length\n\n"); + LOG0("\n*** ERROR: Exceeded maximum HTTP message length\n\n"); return; } @@ -193,7 +190,7 @@ void HAPClient::processRequest(){ if(!(p=strstr((char *)httpBuf,"\r\n\r\n"))){ badRequestError(); - Serial.print("\n*** ERROR: Malformed HTTP request (can't find blank line indicating end of BODY)\n\n"); + LOG0("\n*** ERROR: Malformed HTTP request (can't find blank line indicating end of BODY)\n\n"); return; } @@ -205,7 +202,7 @@ void HAPClient::processRequest(){ cLen=atoi(p+16); if(nBytes!=strlen(body)+4+cLen){ badRequestError(); - Serial.print("\n*** ERROR: Malformed HTTP request (Content-Length plus Body Length does not equal total number of bytes read)\n\n"); + LOG0("\n*** ERROR: Malformed HTTP request (Content-Length plus Body Length does not equal total number of bytes read)\n\n"); return; } @@ -216,7 +213,7 @@ void HAPClient::processRequest(){ if(cLen==0){ badRequestError(); - Serial.print("\n*** ERROR: HTTP POST request contains no Content\n\n"); + LOG0("\n*** ERROR: HTTP POST request contains no Content\n\n"); return; } @@ -261,7 +258,7 @@ void HAPClient::processRequest(){ } notFoundError(); - Serial.print("\n*** ERROR: Bad POST request - URL not found\n\n"); + LOG0("\n*** ERROR: Bad POST request - URL not found\n\n"); return; } // POST request @@ -270,7 +267,7 @@ void HAPClient::processRequest(){ if(cLen==0){ badRequestError(); - Serial.print("\n*** ERROR: HTTP PUT request contains no Content\n\n"); + LOG0("\n*** ERROR: HTTP PUT request contains no Content\n\n"); return; } @@ -297,7 +294,7 @@ void HAPClient::processRequest(){ } notFoundError(); - Serial.print("\n*** ERROR: Bad PUT request - URL not found\n\n"); + LOG0("\n*** ERROR: Bad PUT request - URL not found\n\n"); return; } // PUT request @@ -320,13 +317,13 @@ void HAPClient::processRequest(){ } notFoundError(); - Serial.print("\n*** ERROR: Bad GET request - URL not found\n\n"); + LOG0("\n*** ERROR: Bad GET request - URL not found\n\n"); return; } // GET request badRequestError(); - Serial.print("\n*** ERROR: Unknown or malformed HTTP request\n\n"); + LOG0("\n*** ERROR: Unknown or malformed HTTP request\n\n"); } // processHAP @@ -394,13 +391,13 @@ int HAPClient::postPairSetupURL(){ char buf[64]; if(tlvState==-1){ // missing STATE TLV - Serial.print("\n*** ERROR: Missing State TLV\n\n"); + LOG0("\n*** ERROR: Missing State TLV\n\n"); badRequestError(); // return with 400 error, which closes connection return(0); } if(nAdminControllers()){ // error: Device already paired (i.e. there is at least one admin Controller). We should not be receiving any requests for Pair-Setup! - Serial.print("\n*** ERROR: Device already paired!\n\n"); + LOG0("\n*** ERROR: Device already paired!\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,tlvState+1); // set response STATE to requested state+1 (which should match the state that was expected by the controller) tlv8.val(kTLVType_Error,tagError_Unavailable); // set Error=Unavailable @@ -412,7 +409,7 @@ int HAPClient::postPairSetupURL(){ LOG2(buf); if(tlvState!=pairStatus){ // error: Device is not yet paired, but out-of-sequence pair-setup STATE was received - Serial.print("\n*** ERROR: Out-of-Sequence Pair-Setup request!\n\n"); + LOG0("\n*** ERROR: Out-of-Sequence Pair-Setup request!\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,tlvState+1); // set response STATE to requested state+1 (which should match the state that was expected by the controller) tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for out-of-sequence steps) @@ -426,7 +423,7 @@ int HAPClient::postPairSetupURL(){ case pairState_M1: // 'SRP Start Request' if(tlv8.val(kTLVType_Method)!=0){ // error: "Pair Setup" method must always be 0 to indicate setup without MiFi Authentification (HAP Table 5-3) - Serial.print("\n*** ERROR: Pair Method not set to 0\n\n"); + LOG0("\n*** ERROR: Pair Method not set to 0\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M2); // set State= tlv8.val(kTLVType_Error,tagError_Unavailable); // set Error=Unavailable @@ -451,7 +448,7 @@ int HAPClient::postPairSetupURL(){ if(!srp.writeTLV(kTLVType_PublicKey,&srp.A) || // try to write TLVs into mpi structures !srp.writeTLV(kTLVType_Proof,&srp.M1)){ - Serial.print("\n*** ERROR: One or both of the required 'PublicKey' and 'Proof' TLV records for this step is bad or missing\n\n"); + LOG0("\n*** ERROR: One or both of the required 'PublicKey' and 'Proof' TLV records for this step is bad or missing\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M4); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -463,7 +460,7 @@ int HAPClient::postPairSetupURL(){ srp.createSessionKey(); // create session key, K, from receipt of HAP Client public key, A if(!srp.verifyProof()){ // verify proof, M1, received from HAP Client - Serial.print("\n*** ERROR: SRP Proof Verification Failed\n\n"); + LOG0("\n*** ERROR: SRP Proof Verification Failed\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M4); // set State= tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication @@ -486,7 +483,7 @@ int HAPClient::postPairSetupURL(){ case pairState_M5: // 'Exchange Request' if(!tlv8.buf(kTLVType_EncryptedData)){ - Serial.print("\n*** ERROR: Required 'EncryptedData' TLV record for this step is bad or missing\n\n"); + LOG0("\n*** ERROR: Required 'EncryptedData' TLV record for this step is bad or missing\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M6); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -513,7 +510,7 @@ int HAPClient::postPairSetupURL(){ tlv8.buf(kTLVType_EncryptedData), tlv8.len(kTLVType_EncryptedData), NULL, 0, (unsigned char *)"\x00\x00\x00\x00PS-Msg05", sessionKey)==-1){ - Serial.print("\n*** ERROR: Exchange-Request Authentication Failed\n\n"); + LOG0("\n*** ERROR: Exchange-Request Authentication Failed\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M6); // set State= tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication @@ -523,7 +520,7 @@ int HAPClient::postPairSetupURL(){ } if(!tlv8.unpack(decrypted,decryptedLen)){ - Serial.print("\n*** ERROR: Can't parse decrypted data into separate TLV records\n\n"); + LOG0("\n*** ERROR: Can't parse decrypted data into separate TLV records\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M6); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -536,7 +533,7 @@ int HAPClient::postPairSetupURL(){ LOG2("------- END DECRYPTED TLVS! -------\n"); if(!tlv8.buf(kTLVType_Identifier) || !tlv8.buf(kTLVType_PublicKey) || !tlv8.buf(kTLVType_Signature)){ - Serial.print("\n*** ERROR: One or more of required 'Identifier,' 'PublicKey,' and 'Signature' TLV records for this step is bad or missing\n\n"); + LOG0("\n*** ERROR: One or more of required 'Identifier,' 'PublicKey,' and 'Signature' TLV records for this step is bad or missing\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M6); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -570,7 +567,7 @@ int HAPClient::postPairSetupURL(){ uint8_t *iosDeviceSignature = tlv8.buf(kTLVType_Signature); // set iosDeviceSignature from TLV record (an Ed25519 should always be 64 bytes) if(crypto_sign_verify_detached(iosDeviceSignature, iosDeviceInfo, iosDeviceInfoLen, iosDeviceLTPK) != 0){ // verify signature of iosDeviceInfo using iosDeviceLTPK - Serial.print("\n*** ERROR: LPTK Signature Verification Failed\n\n"); + LOG0("\n*** ERROR: LPTK Signature Verification Failed\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M6); // set State= tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication @@ -667,13 +664,13 @@ int HAPClient::postPairVerifyURL(){ int tlvState=tlv8.val(kTLVType_State); if(tlvState==-1){ // missing STATE TLV - Serial.print("\n*** ERROR: Missing State TLV\n\n"); + LOG0("\n*** ERROR: Missing State TLV\n\n"); badRequestError(); // return with 400 error, which closes connection return(0); } if(!nAdminControllers()){ // error: Device not yet paired - we should not be receiving any requests for Pair-Verify! - Serial.print("\n*** ERROR: Device not yet paired!\n\n"); + LOG0("\n*** ERROR: Device not yet paired!\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,tlvState+1); // set response STATE to requested state+1 (which should match the state that was expected by the controller) tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown @@ -689,7 +686,7 @@ int HAPClient::postPairVerifyURL(){ case pairState_M1: // 'Verify Start Request' if(!tlv8.buf(kTLVType_PublicKey)){ - Serial.print("\n*** ERROR: Required 'PublicKey' TLV record for this step is bad or missing\n\n"); + LOG0("\n*** ERROR: Required 'PublicKey' TLV record for this step is bad or missing\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M2); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -755,7 +752,7 @@ int HAPClient::postPairVerifyURL(){ case pairState_M3: // 'Verify Finish Request' if(!tlv8.buf(kTLVType_EncryptedData)){ - Serial.print("\n*** ERROR: Required 'EncryptedData' TLV record for this step is bad or missing\n\n"); + LOG0("\n*** ERROR: Required 'EncryptedData' TLV record for this step is bad or missing\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M4); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -771,7 +768,7 @@ int HAPClient::postPairVerifyURL(){ tlv8.buf(kTLVType_EncryptedData), tlv8.len(kTLVType_EncryptedData), NULL, 0, (unsigned char *)"\x00\x00\x00\x00PV-Msg03", sessionKey)==-1){ - Serial.print("\n*** ERROR: Verify Authentication Failed\n\n"); + LOG0("\n*** ERROR: Verify Authentication Failed\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M4); // set State= tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication @@ -780,7 +777,7 @@ int HAPClient::postPairVerifyURL(){ } if(!tlv8.unpack(decrypted,decryptedLen)){ - Serial.print("\n*** ERROR: Can't parse decrypted data into separate TLV records\n\n"); + LOG0("\n*** ERROR: Can't parse decrypted data into separate TLV records\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M4); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -792,7 +789,7 @@ int HAPClient::postPairVerifyURL(){ LOG2("------- END DECRYPTED TLVS! -------\n"); if(!tlv8.buf(kTLVType_Identifier) || !tlv8.buf(kTLVType_Signature)){ - Serial.print("\n*** ERROR: One or more of required 'Identifier,' and 'Signature' TLV records for this step is bad or missing\n\n"); + LOG0("\n*** ERROR: One or more of required 'Identifier,' and 'Signature' TLV records for this step is bad or missing\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M4); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -803,7 +800,7 @@ int HAPClient::postPairVerifyURL(){ Controller *tPair; // temporary pointer to Controller if(!(tPair=findController(tlv8.buf(kTLVType_Identifier)))){ - Serial.print("\n*** ERROR: Unrecognized Controller PairingID\n\n"); + LOG0("\n*** ERROR: Unrecognized Controller PairingID\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M4); // set State= tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication @@ -819,7 +816,7 @@ int HAPClient::postPairVerifyURL(){ memcpy(iosDeviceInfo+32+36,publicCurveKey,32); if(crypto_sign_verify_detached(tlv8.buf(kTLVType_Signature), iosDeviceInfo, iosDeviceInfoLen, tPair->LTPK) != 0){ // verify signature of iosDeviceInfo using iosDeviceLTPK - Serial.print("\n*** ERROR: LPTK Signature Verification Failed\n\n"); + LOG0("\n*** ERROR: LPTK Signature Verification Failed\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M4); // set State= tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication @@ -904,7 +901,7 @@ int HAPClient::postPairingsURL(){ LOG1(")..."); if(tlv8.val(kTLVType_State)!=1){ - Serial.print("\n*** ERROR: 'State' TLV record is either missing or not set to as required\n\n"); + LOG0("\n*** ERROR: 'State' TLV record is either missing or not set to as required\n\n"); badRequestError(); // return with 400 error, which closes connection return(0); } @@ -915,7 +912,7 @@ int HAPClient::postPairingsURL(){ LOG1("Add...\n"); if(!tlv8.buf(kTLVType_Identifier) || !tlv8.buf(kTLVType_PublicKey) || !tlv8.buf(kTLVType_Permissions)){ - Serial.print("\n*** ERROR: One or more of required 'Identifier,' 'PublicKey,' and 'Permissions' TLV records for this step is bad or missing\n\n"); + LOG0("\n*** ERROR: One or more of required 'Identifier,' 'PublicKey,' and 'Permissions' TLV records for this step is bad or missing\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M2); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -923,7 +920,7 @@ int HAPClient::postPairingsURL(){ } if(!cPair->admin){ - Serial.print("\n*** ERROR: Controller making request does not have admin privileges to add/update other Controllers\n\n"); + LOG0("\n*** ERROR: Controller making request does not have admin privileges to add/update other Controllers\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M2); // set State= tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication @@ -931,7 +928,7 @@ int HAPClient::postPairingsURL(){ } if((newCont=findController(tlv8.buf(kTLVType_Identifier))) && memcmp(tlv8.buf(kTLVType_PublicKey),newCont->LTPK,32)){ // requested Controller already exists, but LTPKs don't match - Serial.print("\n*** ERROR: Invalid request to update the LTPK of an exsiting Controller\n\n"); + LOG0("\n*** ERROR: Invalid request to update the LTPK of an exsiting Controller\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M2); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown @@ -939,9 +936,7 @@ int HAPClient::postPairingsURL(){ } if(!addController(tlv8.buf(kTLVType_Identifier),tlv8.buf(kTLVType_PublicKey),tlv8.val(kTLVType_Permissions)==1?true:false)){ - Serial.print("\n*** ERROR: Can't pair more than "); - Serial.print(MAX_CONTROLLERS); - Serial.print(" Controllers\n\n"); + LOG0("\n*** ERROR: Can't pair more than %d Controllers\n\n",MAX_CONTROLLERS); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M2); // set State= tlv8.val(kTLVType_Error,tagError_MaxPeers); // set Error=MaxPeers @@ -956,7 +951,7 @@ int HAPClient::postPairingsURL(){ LOG1("Remove...\n"); if(!tlv8.buf(kTLVType_Identifier)){ - Serial.print("\n*** ERROR: Required 'Identifier' TLV record for this step is bad or missing\n\n"); + LOG0("\n*** ERROR: Required 'Identifier' TLV record for this step is bad or missing\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M2); // set State= tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) @@ -964,7 +959,7 @@ int HAPClient::postPairingsURL(){ } if(!cPair->admin){ - Serial.print("\n*** ERROR: Controller making request does not have admin privileges to remove Controllers\n\n"); + LOG0("\n*** ERROR: Controller making request does not have admin privileges to remove Controllers\n\n"); tlv8.clear(); // clear TLV records tlv8.val(kTLVType_State,pairState_M2); // set State= tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication @@ -987,7 +982,7 @@ int HAPClient::postPairingsURL(){ break; default: - Serial.print("\n*** ERROR: 'Method' TLV record is either missing or not set to either 3, 4, or 5 as required\n\n"); + LOG0("\n*** ERROR: 'Method' TLV record is either missing or not set to either 3, 4, or 5 as required\n\n"); badRequestError(); // return with 400 error, which closes connection return(0); break; @@ -1458,17 +1453,17 @@ int HAPClient::receiveEncrypted(){ int n=buf[0]+buf[1]*256; // compute number of bytes expected in encoded message if(nBytes+n>MAX_HTTP){ // exceeded maximum number of bytes allowed in plaintext message - Serial.print("\n\n*** ERROR: Exceeded maximum HTTP message length\n\n"); + LOG0("\n\n*** ERROR: Exceeded maximum HTTP message length\n\n"); return(0); } if(client.read(buf+2,n+16)!=n+16){ // read expected number of total bytes = n bytes in encoded message + 16 bytes for appended authentication tag - Serial.print("\n\n*** ERROR: Malformed encrypted message frame\n\n"); + LOG0("\n\n*** ERROR: Malformed encrypted message frame\n\n"); return(0); } if(crypto_aead_chacha20poly1305_ietf_decrypt(httpBuf+nBytes, NULL, NULL, buf+2, n+16, buf, 2, c2aNonce.get(), c2aKey)==-1){ - Serial.print("\n\n*** ERROR: Can't Decrypt Message\n\n"); + LOG0("\n\n*** ERROR: Can't Decrypt Message\n\n"); return(0); } @@ -1537,40 +1532,25 @@ void HAPClient::sendEncrypted(char *body, uint8_t *dataBuf, int dataLen){ ///////////////////////////////////////////////////////////////////////////////// void HAPClient::hexPrintColumn(uint8_t *buf, int n){ - - char c[16]; - for(int i=0;i\n\n"); - Serial.print("Message Logs: Level "); - Serial.print(logLevel); - Serial.print("\nStatus LED: Pin "); + LOG0("Message Logs: Level %d",logLevel); + LOG0("\nStatus LED: Pin "); if(getStatusPin()>=0){ - Serial.print(getStatusPin()); + LOG0(getStatusPin()); if(autoOffLED>0) - Serial.printf(" (Auto Off=%d sec)",autoOffLED); + LOG0(" (Auto Off=%d sec)",autoOffLED); } else - Serial.print("- *** WARNING: Status LED Pin is UNDEFINED"); - Serial.print("\nDevice Control: Pin "); - if(getControlPin()>=0) - Serial.print(getControlPin()); - else - Serial.print("- *** WARNING: Device Control Pin is UNDEFINED"); - Serial.print("\nSketch Version: "); - Serial.print(getSketchVersion()); - Serial.print("\nHomeSpan Version: "); - Serial.print(HOMESPAN_VERSION); - Serial.print("\nArduino-ESP Ver.: "); - Serial.print(ARDUINO_ESP_VERSION); - Serial.printf("\nESP-IDF Version: %d.%d.%d",ESP_IDF_VERSION_MAJOR,ESP_IDF_VERSION_MINOR,ESP_IDF_VERSION_PATCH); - Serial.printf("\nESP32 Chip: %s Rev %d %s-core %dMB Flash", ESP.getChipModel(),ESP.getChipRevision(), + LOG0("- *** WARNING: Status LED Pin is UNDEFINED"); + LOG0("\nDevice Control: Pin "); + if(getControlPin()>=0){ + LOG0(getControlPin()); + } + else{ + LOG0("- *** WARNING: Device Control Pin is UNDEFINED"); + } + LOG0("\nSketch Version: %s",getSketchVersion()); + LOG0("\nHomeSpan Version: %s",HOMESPAN_VERSION); + LOG0("\nArduino-ESP Ver.: %s",ARDUINO_ESP_VERSION); + LOG0("\nESP-IDF Version: %d.%d.%d",ESP_IDF_VERSION_MAJOR,ESP_IDF_VERSION_MINOR,ESP_IDF_VERSION_PATCH); + LOG0("\nESP32 Chip: %s Rev %d %s-core %dMB Flash", ESP.getChipModel(),ESP.getChipRevision(), ESP.getChipCores()==1?"single":"dual",ESP.getFlashChipSize()/1024/1024); #ifdef ARDUINO_VARIANT - Serial.print("\nESP32 Board: "); - Serial.print(ARDUINO_VARIANT); + LOG0("\nESP32 Board: "); + LOG0(ARDUINO_VARIANT); #endif - Serial.printf("\nPWM Resources: %d channels, %d timers, max %d-bit duty resolution", + LOG0("\nPWM Resources: %d channels, %d timers, max %d-bit duty resolution", LEDC_SPEED_MODE_MAX*LEDC_CHANNEL_MAX,LEDC_SPEED_MODE_MAX*LEDC_TIMER_MAX,LEDC_TIMER_BIT_MAX-1); - Serial.printf("\nSodium Version: %s Lib %d.%d",sodium_version_string(),sodium_library_version_major(),sodium_library_version_minor()); + LOG0("\nSodium Version: %s Lib %d.%d",sodium_version_string(),sodium_library_version_major(),sodium_library_version_minor()); char mbtlsv[64]; mbedtls_version_get_string_full(mbtlsv); - Serial.printf("\nMbedTLS Version: %s",mbtlsv); + LOG0("\nMbedTLS Version: %s",mbtlsv); - Serial.print("\nSketch Compiled: "); - Serial.print(__DATE__); - Serial.print(" "); - Serial.print(__TIME__); - - Serial.printf("\nPartition: %s",esp_ota_get_running_partition()->label); - Serial.printf("\nMAC Address: %s",WiFi.macAddress().c_str()); + LOG0("\nSketch Compiled: %s %s",__DATE__,__TIME__); + LOG0("\nPartition: %s",esp_ota_get_running_partition()->label); + LOG0("\nMAC Address: %s",WiFi.macAddress().c_str()); - Serial.print("\n\nDevice Name: "); - Serial.print(displayName); - Serial.print("\n\n"); + LOG0("\n\nDevice Name: %s\n\n",displayName); uint8_t otaRequired=0; nvs_get_u8(otaNVS,"OTA_REQUIRED",&otaRequired); nvs_set_u8(otaNVS,"OTA_REQUIRED",0); nvs_commit(otaNVS); if(otaRequired && !spanOTA.enabled){ - Serial.printf("\n\n*** OTA SAFE MODE ALERT: OTA REQUIRED BUT NOT ENABLED. ROLLING BACK TO PREVIOUS APPLICATION ***\n\n"); + LOG0("\n\n*** OTA SAFE MODE ALERT: OTA REQUIRED BUT NOT ENABLED. ROLLING BACK TO PREVIOUS APPLICATION ***\n\n"); delay(100); esp_ota_mark_app_invalid_rollback_and_reboot(); } @@ -164,7 +156,7 @@ void Span::begin(Category catID, const char *displayName, const char *hostNameBa void Span::poll() { if(pollTaskHandle){ - Serial.print("\n** FATAL ERROR: Do not call homeSpan.poll() directly if homeSpan.start() is used!\n** PROGRAM HALTED **\n\n"); + LOG0("\n** FATAL ERROR: Do not call homeSpan.poll() directly if homeSpan.start() is used!\n** PROGRAM HALTED **\n\n"); vTaskDelete(pollTaskHandle); while(1); } @@ -177,7 +169,7 @@ void Span::poll() { void Span::pollTask() { if(!strlen(category)){ - Serial.print("\n** FATAL ERROR: Cannot start homeSpan polling without an initial call to homeSpan.begin()!\n** PROGRAM HALTED **\n\n"); + LOG0("\n** FATAL ERROR: Cannot start homeSpan polling without an initial call to homeSpan.begin()!\n** PROGRAM HALTED **\n\n"); while(1); } @@ -188,12 +180,12 @@ void Span::pollTask() { HAPClient::init(); // read NVS and load HAP settings if(!strlen(network.wifiData.ssid)){ - Serial.print("*** WIFI CREDENTIALS DATA NOT FOUND. "); + LOG0("*** WIFI CREDENTIALS DATA NOT FOUND. "); if(autoStartAPEnabled){ - Serial.print("AUTO-START OF ACCESS POINT ENABLED...\n\n"); + LOG0("AUTO-START OF ACCESS POINT ENABLED...\n\n"); processSerialCommand("A"); } else { - Serial.print("YOU MAY CONFIGURE BY TYPING 'W '.\n\n"); + LOG0("YOU MAY CONFIGURE BY TYPING 'W '.\n\n"); STATUS_UPDATE(start(LED_WIFI_NEEDED),HS_WIFI_NEEDED) } } else { @@ -203,8 +195,7 @@ void Span::pollTask() { if(controlButton) controlButton->reset(); - Serial.print(displayName); - Serial.print(" is READY!\n\n"); + LOG0("%s is READY!\n\n",displayName); isInitialized=true; } // isInitialized @@ -331,11 +322,11 @@ int Span::getFreeSlot(){ void Span::commandMode(){ if(!statusDevice && !statusCallback){ - Serial.print("*** ERROR: CAN'T ENTER COMMAND MODE WITHOUT A DEFINED STATUS LED OR EVENT HANDLER CALLBACK***\n\n"); + LOG0("*** ERROR: CAN'T ENTER COMMAND MODE WITHOUT A DEFINED STATUS LED OR EVENT HANDLER CALLBACK***\n\n"); return; } - Serial.print("*** COMMAND MODE ***\n\n"); + LOG0("*** COMMAND MODE ***\n\n"); int mode=1; boolean done=false; STATUS_UPDATE(start(500,0.3,mode,1000),static_cast(HS_ENTERING_CONFIG_MODE+mode)) @@ -343,9 +334,7 @@ void Span::commandMode(){ while(!done){ if(millis()>alarmTime){ - Serial.print("*** Command Mode: Timed Out ("); - Serial.print(comModeLife/1000); - Serial.print(" seconds).\n\n"); + LOG0("*** Command Mode: Timed Out (%ld seconds)",comModeLife/1000); mode=1; done=true; } else @@ -388,7 +377,7 @@ void Span::commandMode(){ } // switch - Serial.print("*** EXITING COMMAND MODE ***\n\n"); + LOG0("*** EXITING COMMAND MODE ***\n\n"); } ////////////////////////////////////// @@ -416,9 +405,7 @@ void Span::checkConnect(){ waitTime*=2; if(waitTime==32000){ - Serial.print("\n*** Can't connect to "); - Serial.print(network.wifiData.ssid); - Serial.print(". You may type 'W ' to re-configure WiFi, or 'X ' to erase WiFi credentials. Will try connecting again in 60 seconds.\n\n"); + LOG0("\n*** Can't connect to %s. You may type 'W ' to re-configure WiFi, or 'X ' to erase WiFi credentials. Will try connecting again in 60 seconds.\n\n",network.wifiData.ssid); waitTime=60000; } else { addWebLog(true,"Trying to connect to %s. Waiting %d sec...",network.wifiData.ssid,waitTime/1000); @@ -462,25 +449,18 @@ void Span::checkConnect(){ sscanf(hostName,"%[A-Za-z0-9-]",d); if(strlen(hostName)>255|| hostName[0]=='-' || hostName[strlen(hostName)-1]=='-' || strlen(hostName)!=strlen(d)){ - Serial.printf("\n*** Error: Can't start MDNS due to invalid hostname '%s'.\n",hostName); - Serial.print("*** Hostname must consist of 255 or less alphanumeric characters or a hyphen, except that the hyphen cannot be the first or last character.\n"); - Serial.print("*** PROGRAM HALTED!\n\n"); + LOG0("\n*** Error: Can't start MDNS due to invalid hostname '%s'.\n",hostName); + LOG0("*** Hostname must consist of 255 or less alphanumeric characters or a hyphen, except that the hyphen cannot be the first or last character.\n"); + LOG0("*** PROGRAM HALTED!\n\n"); while(1); } - Serial.print("\nStarting MDNS...\n\n"); - Serial.print("HostName: "); - Serial.print(hostName); - Serial.print(".local:"); - Serial.print(tcpPortNum); - Serial.print("\nDisplay Name: "); - Serial.print(displayName); - Serial.print("\nModel Name: "); - Serial.print(modelName); - Serial.print("\nSetup ID: "); - Serial.print(qrID); - Serial.print("\n\n"); - + LOG0("\nStarting MDNS...\n\n"); + LOG0("HostName: %s.local:%d\n",hostName,tcpPortNum); + LOG0("Display Name: %s\n",displayName); + LOG0("Model Name: %s\n",modelName); + LOG0("Setup ID: %s\n\n",qrID); + MDNS.begin(hostName); // set server host name (.local implied) MDNS.setInstanceName(displayName); // set server display name MDNS.addService("_hap","_tcp",tcpPortNum); // advertise HAP service on specified port @@ -529,12 +509,8 @@ void Span::checkConnect(){ ArduinoOTA.onStart(spanOTA.start).onEnd(spanOTA.end).onProgress(spanOTA.progress).onError(spanOTA.error); ArduinoOTA.begin(); - Serial.print("Starting OTA Server: "); - Serial.print(displayName); - Serial.print(" at "); - Serial.print(WiFi.localIP()); - Serial.print("\nAuthorization Password: "); - Serial.print(spanOTA.auth?"Enabled\n\n":"DISABLED!\n\n"); + LOG0("Starting OTA Server: %s at %s\n",displayName,WiFi.localIP().toString().c_str()); + LOG0("Authorization Password: %s",spanOTA.auth?"Enabled\n\n":"DISABLED!\n\n"); } mdns_service_txt_item_set("_hap","_tcp","ota",spanOTA.enabled?"yes":"no"); // OTA status (info only - NOT used by HAP) @@ -542,19 +518,19 @@ void Span::checkConnect(){ if(webLog.isEnabled){ mdns_service_txt_item_set("_hap","_tcp","logURL",webLog.statusURL.c_str()+4); // Web Log status (info only - NOT used by HAP) - Serial.printf("Web Logging enabled at http://%s.local:%d%swith max number of entries=%d\n\n",hostName,tcpPortNum,webLog.statusURL.c_str()+4,webLog.maxEntries); + LOG0("Web Logging enabled at http://%s.local:%d%swith max number of entries=%d\n\n",hostName,tcpPortNum,webLog.statusURL.c_str()+4,webLog.maxEntries); if(webLog.timeServer) xTaskCreateUniversal(webLog.initTime, "timeSeverTaskHandle", 8096, &webLog, 1, NULL, 0); } - Serial.printf("Starting HAP Server on port %d supporting %d simultaneous HomeKit Controller Connections...\n\n",tcpPortNum,maxConnections); + LOG0("Starting HAP Server on port %d supporting %d simultaneous HomeKit Controller Connections...\n\n",tcpPortNum,maxConnections); hapServer->begin(); - Serial.print("\n"); + LOG0("\n"); if(!HAPClient::nAdminControllers()) - Serial.print("DEVICE NOT YET PAIRED -- PLEASE PAIR WITH HOMEKIT APP\n\n"); + LOG0("DEVICE NOT YET PAIRED -- PLEASE PAIR WITH HOMEKIT APP\n\n"); if(wifiCallback) wifiCallback(); @@ -582,48 +558,40 @@ void Span::processSerialCommand(const char *c){ case 's': { - Serial.print("\n*** HomeSpan Status ***\n\n"); + LOG0("\n*** HomeSpan Status ***\n\n"); - Serial.print("IP Address: "); - Serial.print(WiFi.localIP()); - Serial.print("\n\n"); - Serial.print("Accessory ID: "); + LOG0("IP Address: %s\n\n",WiFi.localIP().toString().c_str()); + LOG0("Accessory ID: "); HAPClient::charPrintRow(HAPClient::accessory.ID,17); - Serial.print(" LTPK: "); + LOG0(" LTPK: "); HAPClient::hexPrintRow(HAPClient::accessory.LTPK,32); - Serial.print("\n"); + LOG0("\n"); HAPClient::printControllers(); - Serial.print("\n"); + LOG0("\n"); for(int i=0;iclient){ - Serial.print(hap[i]->client.remoteIP()); - Serial.print(" on Socket "); - Serial.print(hap[i]->client.fd()-LWIP_SOCKET_OFFSET+1); - Serial.print("/"); - Serial.print(CONFIG_LWIP_MAX_SOCKETS); + LOG0("%s on Socket %d/%d",hap[i]->client.remoteIP().toString().c_str(),hap[i]->client.fd()-LWIP_SOCKET_OFFSET+1,CONFIG_LWIP_MAX_SOCKETS); if(hap[i]->cPair){ - Serial.print(" ID="); + LOG0(" ID="); HAPClient::charPrintRow(hap[i]->cPair->ID,36); - Serial.print(hap[i]->cPair->admin?" (admin)":" (regular)"); + LOG0(hap[i]->cPair->admin?" (admin)":" (regular)"); } else { - Serial.print(" (unverified)"); + LOG0(" (unverified)"); } } else { - Serial.print("(unconnected)"); + LOG0("(unconnected)"); } - Serial.print("\n"); + LOG0("\n"); } - Serial.print("\n*** End Status ***\n\n"); + LOG0("\n*** End Status ***\n\n"); } break; @@ -632,13 +600,9 @@ void Span::processSerialCommand(const char *c){ TempBuffer qBuf(sprintfAttributes(NULL)+1); sprintfAttributes(qBuf.buf); - Serial.print("\n*** Attributes Database: size="); - Serial.print(qBuf.len()-1); - Serial.print(" configuration="); - Serial.print(hapConfig.configNumber); - Serial.print(" ***\n\n"); + LOG0("\n*** Attributes Database: size=%d configuration=%d ***\n\n",qBuf.len()-1,hapConfig.configNumber); prettyPrint(qBuf.buf); - Serial.print("\n*** End Database ***\n\n"); + LOG0("\n*** End Database ***\n\n"); } break; diff --git a/src/HomeSpan.h b/src/HomeSpan.h index c8a0b9d..53f5f0b 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -225,7 +225,7 @@ class Span{ const char *defaultSetupCode=DEFAULT_SETUP_CODE; // Setup Code used for pairing uint16_t autoOffLED=0; // automatic turn-off duration (in seconds) for Status LED - uint8_t logLevel=DEFAULT_LOG_LEVEL; // level for writing out log messages to serial monitor + int logLevel=DEFAULT_LOG_LEVEL; // level for writing out log messages to serial monitor uint8_t maxConnections=CONFIG_LWIP_MAX_SOCKETS-2; // maximum number of allowed simultaneous HAP connections uint8_t requestedMaxCon=CONFIG_LWIP_MAX_SOCKETS-2; // requested maximum 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 @@ -309,7 +309,7 @@ class Span{ void setApPassword(const char *pwd){network.apPassword=pwd;} // sets Access Point Password void setApTimeout(uint16_t nSec){network.lifetime=nSec*1000;} // sets Access Point Timeout (seconds) void setCommandTimeout(uint16_t nSec){comModeLife=nSec*1000;} // sets Command Mode Timeout (seconds) - void setLogLevel(uint8_t level){logLevel=level;} // sets Log Level for log messages (0=baseline, 1=intermediate, 2=all) + void setLogLevel(int level){logLevel=level;} // sets Log Level for log messages (0=baseline, 1=intermediate, 2=all, -1=disable all serial input/output) int getLogLevel(){return(logLevel);} // get Log Level void reserveSocketConnections(uint8_t n){maxConnections-=n;} // reserves n socket connections *not* to be used for HAP void setHostNameSuffix(const char *suffix){hostNameSuffix=suffix;} // sets the hostName suffix to be used instead of the 6-byte AccessoryID diff --git a/src/Settings.h b/src/Settings.h index 2cffe73..9981f08 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -104,11 +104,11 @@ // Message Log Level Control Macros // // 0=Minimal, 1=Informative, 2=All // -#define LOG0(format,...) Serial.print ##__VA_OPT__(f)(format __VA_OPT__(,) __VA_ARGS__) -#define LOG1(format,...) if(homeSpan.getLogLevel()>0)Serial.print ##__VA_OPT__(f)(format __VA_OPT__(,) __VA_ARGS__) -#define LOG2(format,...) if(homeSpan.getLogLevel()>1)Serial.print ##__VA_OPT__(f)(format __VA_OPT__(,) __VA_ARGS__) +#define LOG0(format,...) if(homeSpan.getLogLevel()>=0)Serial.print ##__VA_OPT__(f)(format __VA_OPT__(,) __VA_ARGS__) +#define LOG1(format,...) if(homeSpan.getLogLevel()>=1)Serial.print ##__VA_OPT__(f)(format __VA_OPT__(,) __VA_ARGS__) +#define LOG2(format,...) if(homeSpan.getLogLevel()>=2)Serial.print ##__VA_OPT__(f)(format __VA_OPT__(,) __VA_ARGS__) -#define WEBLOG(format,...) homeSpan.addWebLog(false, format __VA_OPT__(,) __VA_ARGS__) +#define WEBLOG(format,...) homeSpan.addWebLog(false, format __VA_OPT__(,) __VA_ARGS__); ////////////////////////////////////////////////////// // Types of Accessory Categories // diff --git a/src/src.ino b/src/src.ino index 8f94fe4..8f9391f 100644 --- a/src/src.ino +++ b/src/src.ino @@ -52,7 +52,8 @@ void setup() { Serial.begin(115200); - homeSpan.setLogLevel(2); +// homeSpan.setLogLevel(-1); + homeSpan.enableOTA(); homeSpan.begin(Category::Lighting,"HomeSpan LED");