Started work on converting all Serial.print() to LOG0() macro

This commit is contained in:
Gregg 2023-05-08 17:07:21 -05:00
parent d5eb2ceeb8
commit 368ce12c04
5 changed files with 143 additions and 199 deletions

View File

@ -62,16 +62,11 @@ void HAPClient::init(){
nvs_get_blob(srpNVS,"VERIFYDATA",&verifyData,&len); // retrieve data nvs_get_blob(srpNVS,"VERIFYDATA",&verifyData,&len); // retrieve data
srp.loadVerifyCode(verifyData.verifyCode,verifyData.salt); // load verification code and salt into SRP structure srp.loadVerifyCode(verifyData.verifyCode,verifyData.salt); // load verification code and salt into SRP structure
} else { } else {
LOG0("Generating SRP verification data for default Setup Code: %.3s-%.2s-%.3s\n",homeSpan.defaultSetupCode,homeSpan.defaultSetupCode+3,homeSpan.defaultSetupCode+5);
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);
srp.createVerifyCode(homeSpan.defaultSetupCode,verifyData.verifyCode,verifyData.salt); // create verification code from default Setup Code and random salt 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_set_blob(srpNVS,"VERIFYDATA",&verifyData,sizeof(verifyData)); // update data
nvs_commit(srpNVS); // commit to NVS nvs_commit(srpNVS); // commit to NVS
Serial.print("Setup Payload for Optional QR Code: "); LOG0("Setup Payload for Optional QR Code: %s\n\n",homeSpan.qrCode.get(atoi(homeSpan.defaultSetupCode),homeSpan.qrID,atoi(homeSpan.category)));
Serial.print(homeSpan.qrCode.get(atoi(homeSpan.defaultSetupCode),homeSpan.qrID,atoi(homeSpan.category)));
Serial.print("\n\n");
} }
if(!strlen(homeSpan.qrID)){ // Setup ID has not been specified in sketch 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 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 nvs_get_blob(hapNVS,"ACCESSORY",&accessory,&len); // retrieve data
} else { } 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]; uint8_t buf[6];
char cBuf[18]; 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 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 nvs_get_blob(hapNVS,"CONTROLLERS",controllers,&len); // retrieve data
} else { } 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 HAPClient::removeControllers(); // clear all Controller data
@ -111,11 +106,11 @@ void HAPClient::init(){
nvs_commit(hapNVS); // commit to NVS nvs_commit(hapNVS); // commit to NVS
} }
Serial.print("Accessory ID: "); LOG0("Accessory ID: ");
charPrintRow(accessory.ID,17); charPrintRow(accessory.ID,17);
Serial.print(" LTPK: "); LOG0(" LTPK: ");
hexPrintRow(accessory.LTPK,32); hexPrintRow(accessory.LTPK,32);
Serial.print("\n"); LOG0("\n");
printControllers(); printControllers();
@ -139,17 +134,19 @@ void HAPClient::init(){
if(!nvs_get_blob(hapNVS,"HAPHASH",NULL,&len)){ // if found HAP HASH structure if(!nvs_get_blob(hapNVS,"HAPHASH",NULL,&len)){ // if found HAP HASH structure
nvs_get_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,&len); // retrieve data nvs_get_blob(hapNVS,"HAPHASH",&homeSpan.hapConfig,&len); // retrieve data
} else { } 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_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 nvs_commit(hapNVS); // commit to NVS
} }
if(homeSpan.updateDatabase(false)) // create Configuration Number and Loop vector 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); LOG0("\nAccessory configuration has changed. Updating configuration number to %d\n",homeSpan.hapConfig.configNumber);
else }
Serial.printf("\nAccessory configuration number: %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 if(nBytes>MAX_HTTP){ // exceeded maximum number of bytes allowed
badRequestError(); badRequestError();
Serial.print("\n*** ERROR: Exceeded maximum HTTP message length\n\n"); LOG0("\n*** ERROR: Exceeded maximum HTTP message length\n\n");
return; return;
} }
@ -193,7 +190,7 @@ void HAPClient::processRequest(){
if(!(p=strstr((char *)httpBuf,"\r\n\r\n"))){ if(!(p=strstr((char *)httpBuf,"\r\n\r\n"))){
badRequestError(); 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; return;
} }
@ -205,7 +202,7 @@ void HAPClient::processRequest(){
cLen=atoi(p+16); cLen=atoi(p+16);
if(nBytes!=strlen(body)+4+cLen){ if(nBytes!=strlen(body)+4+cLen){
badRequestError(); 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; return;
} }
@ -216,7 +213,7 @@ void HAPClient::processRequest(){
if(cLen==0){ if(cLen==0){
badRequestError(); 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; return;
} }
@ -261,7 +258,7 @@ void HAPClient::processRequest(){
} }
notFoundError(); 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; return;
} // POST request } // POST request
@ -270,7 +267,7 @@ void HAPClient::processRequest(){
if(cLen==0){ if(cLen==0){
badRequestError(); 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; return;
} }
@ -297,7 +294,7 @@ void HAPClient::processRequest(){
} }
notFoundError(); 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; return;
} // PUT request } // PUT request
@ -320,13 +317,13 @@ void HAPClient::processRequest(){
} }
notFoundError(); 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; return;
} // GET request } // GET request
badRequestError(); badRequestError();
Serial.print("\n*** ERROR: Unknown or malformed HTTP request\n\n"); LOG0("\n*** ERROR: Unknown or malformed HTTP request\n\n");
} // processHAP } // processHAP
@ -394,13 +391,13 @@ int HAPClient::postPairSetupURL(){
char buf[64]; char buf[64];
if(tlvState==-1){ // missing STATE TLV if(tlvState==-1){ // missing STATE TLV
Serial.print("\n*** ERROR: Missing <M#> State TLV\n\n"); LOG0("\n*** ERROR: Missing <M#> State TLV\n\n");
badRequestError(); // return with 400 error, which closes connection badRequestError(); // return with 400 error, which closes connection
return(0); 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! 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.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_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 tlv8.val(kTLVType_Error,tagError_Unavailable); // set Error=Unavailable
@ -412,7 +409,7 @@ int HAPClient::postPairSetupURL(){
LOG2(buf); LOG2(buf);
if(tlvState!=pairStatus){ // error: Device is not yet paired, but out-of-sequence pair-setup STATE was received 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.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_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) 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' 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) 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M2); // set State=<M2> tlv8.val(kTLVType_State,pairState_M2); // set State=<M2>
tlv8.val(kTLVType_Error,tagError_Unavailable); // set Error=Unavailable 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 if(!srp.writeTLV(kTLVType_PublicKey,&srp.A) || // try to write TLVs into mpi structures
!srp.writeTLV(kTLVType_Proof,&srp.M1)){ !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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M4); // set State=<M4> tlv8.val(kTLVType_State,pairState_M4); // set State=<M4>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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 srp.createSessionKey(); // create session key, K, from receipt of HAP Client public key, A
if(!srp.verifyProof()){ // verify proof, M1, received from HAP Client 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M4); // set State=<M4> tlv8.val(kTLVType_State,pairState_M4); // set State=<M4>
tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication
@ -486,7 +483,7 @@ int HAPClient::postPairSetupURL(){
case pairState_M5: // 'Exchange Request' case pairState_M5: // 'Exchange Request'
if(!tlv8.buf(kTLVType_EncryptedData)){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M6); // set State=<M6> tlv8.val(kTLVType_State,pairState_M6); // set State=<M6>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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, tlv8.buf(kTLVType_EncryptedData), tlv8.len(kTLVType_EncryptedData), NULL, 0,
(unsigned char *)"\x00\x00\x00\x00PS-Msg05", sessionKey)==-1){ (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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M6); // set State=<M6> tlv8.val(kTLVType_State,pairState_M6); // set State=<M6>
tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication
@ -523,7 +520,7 @@ int HAPClient::postPairSetupURL(){
} }
if(!tlv8.unpack(decrypted,decryptedLen)){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M6); // set State=<M6> tlv8.val(kTLVType_State,pairState_M6); // set State=<M6>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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"); LOG2("------- END DECRYPTED TLVS! -------\n");
if(!tlv8.buf(kTLVType_Identifier) || !tlv8.buf(kTLVType_PublicKey) || !tlv8.buf(kTLVType_Signature)){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M6); // set State=<M6> tlv8.val(kTLVType_State,pairState_M6); // set State=<M6>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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) 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 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M6); // set State=<M6> tlv8.val(kTLVType_State,pairState_M6); // set State=<M6>
tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication
@ -667,13 +664,13 @@ int HAPClient::postPairVerifyURL(){
int tlvState=tlv8.val(kTLVType_State); int tlvState=tlv8.val(kTLVType_State);
if(tlvState==-1){ // missing STATE TLV if(tlvState==-1){ // missing STATE TLV
Serial.print("\n*** ERROR: Missing <M#> State TLV\n\n"); LOG0("\n*** ERROR: Missing <M#> State TLV\n\n");
badRequestError(); // return with 400 error, which closes connection badRequestError(); // return with 400 error, which closes connection
return(0); return(0);
} }
if(!nAdminControllers()){ // error: Device not yet paired - we should not be receiving any requests for Pair-Verify! 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.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_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 tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown
@ -689,7 +686,7 @@ int HAPClient::postPairVerifyURL(){
case pairState_M1: // 'Verify Start Request' case pairState_M1: // 'Verify Start Request'
if(!tlv8.buf(kTLVType_PublicKey)){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M2); // set State=<M2> tlv8.val(kTLVType_State,pairState_M2); // set State=<M2>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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' case pairState_M3: // 'Verify Finish Request'
if(!tlv8.buf(kTLVType_EncryptedData)){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M4); // set State=<M4> tlv8.val(kTLVType_State,pairState_M4); // set State=<M4>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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, tlv8.buf(kTLVType_EncryptedData), tlv8.len(kTLVType_EncryptedData), NULL, 0,
(unsigned char *)"\x00\x00\x00\x00PV-Msg03", sessionKey)==-1){ (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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M4); // set State=<M4> tlv8.val(kTLVType_State,pairState_M4); // set State=<M4>
tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication
@ -780,7 +777,7 @@ int HAPClient::postPairVerifyURL(){
} }
if(!tlv8.unpack(decrypted,decryptedLen)){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M4); // set State=<M4> tlv8.val(kTLVType_State,pairState_M4); // set State=<M4>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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"); LOG2("------- END DECRYPTED TLVS! -------\n");
if(!tlv8.buf(kTLVType_Identifier) || !tlv8.buf(kTLVType_Signature)){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M4); // set State=<M4> tlv8.val(kTLVType_State,pairState_M4); // set State=<M4>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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 Controller *tPair; // temporary pointer to Controller
if(!(tPair=findController(tlv8.buf(kTLVType_Identifier)))){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M4); // set State=<M4> tlv8.val(kTLVType_State,pairState_M4); // set State=<M4>
tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication
@ -819,7 +816,7 @@ int HAPClient::postPairVerifyURL(){
memcpy(iosDeviceInfo+32+36,publicCurveKey,32); 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 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M4); // set State=<M4> tlv8.val(kTLVType_State,pairState_M4); // set State=<M4>
tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication
@ -904,7 +901,7 @@ int HAPClient::postPairingsURL(){
LOG1(")..."); LOG1(")...");
if(tlv8.val(kTLVType_State)!=1){ if(tlv8.val(kTLVType_State)!=1){
Serial.print("\n*** ERROR: 'State' TLV record is either missing or not set to <M1> as required\n\n"); LOG0("\n*** ERROR: 'State' TLV record is either missing or not set to <M1> as required\n\n");
badRequestError(); // return with 400 error, which closes connection badRequestError(); // return with 400 error, which closes connection
return(0); return(0);
} }
@ -915,7 +912,7 @@ int HAPClient::postPairingsURL(){
LOG1("Add...\n"); LOG1("Add...\n");
if(!tlv8.buf(kTLVType_Identifier) || !tlv8.buf(kTLVType_PublicKey) || !tlv8.buf(kTLVType_Permissions)){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M2); // set State=<M2> tlv8.val(kTLVType_State,pairState_M2); // set State=<M2>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M2); // set State=<M2> tlv8.val(kTLVType_State,pairState_M2); // set State=<M2>
tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication 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 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M2); // set State=<M2> tlv8.val(kTLVType_State,pairState_M2); // set State=<M2>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown 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)){ 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 "); LOG0("\n*** ERROR: Can't pair more than %d Controllers\n\n",MAX_CONTROLLERS);
Serial.print(MAX_CONTROLLERS);
Serial.print(" Controllers\n\n");
tlv8.clear(); // clear TLV records tlv8.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M2); // set State=<M2> tlv8.val(kTLVType_State,pairState_M2); // set State=<M2>
tlv8.val(kTLVType_Error,tagError_MaxPeers); // set Error=MaxPeers tlv8.val(kTLVType_Error,tagError_MaxPeers); // set Error=MaxPeers
@ -956,7 +951,7 @@ int HAPClient::postPairingsURL(){
LOG1("Remove...\n"); LOG1("Remove...\n");
if(!tlv8.buf(kTLVType_Identifier)){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M2); // set State=<M2> tlv8.val(kTLVType_State,pairState_M2); // set State=<M2>
tlv8.val(kTLVType_Error,tagError_Unknown); // set Error=Unknown (there is no specific error type for missing/bad TLV data) 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){ 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.clear(); // clear TLV records
tlv8.val(kTLVType_State,pairState_M2); // set State=<M2> tlv8.val(kTLVType_State,pairState_M2); // set State=<M2>
tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication tlv8.val(kTLVType_Error,tagError_Authentication); // set Error=Authentication
@ -987,7 +982,7 @@ int HAPClient::postPairingsURL(){
break; break;
default: 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 badRequestError(); // return with 400 error, which closes connection
return(0); return(0);
break; break;
@ -1458,17 +1453,17 @@ int HAPClient::receiveEncrypted(){
int n=buf[0]+buf[1]*256; // compute number of bytes expected in encoded message 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 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); 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 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); return(0);
} }
if(crypto_aead_chacha20poly1305_ietf_decrypt(httpBuf+nBytes, NULL, NULL, buf+2, n+16, buf, 2, c2aNonce.get(), c2aKey)==-1){ 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); return(0);
} }
@ -1538,39 +1533,24 @@ void HAPClient::sendEncrypted(char *body, uint8_t *dataBuf, int dataLen){
void HAPClient::hexPrintColumn(uint8_t *buf, int n){ void HAPClient::hexPrintColumn(uint8_t *buf, int n){
char c[16]; for(int i=0;i<n;i++)
LOG0("%d) %02X\n",i,buf[i]);
for(int i=0;i<n;i++){
sprintf(c,"%d) %02X",i,buf[i]);
Serial.println(c);
}
} }
////////////////////////////////////// //////////////////////////////////////
void HAPClient::hexPrintRow(uint8_t *buf, int n){ void HAPClient::hexPrintRow(uint8_t *buf, int n){
char c[16]; for(int i=0;i<n;i++)
LOG0("%02X",buf[i]);
for(int i=0;i<n;i++){
sprintf(c,"%02X",buf[i]);
Serial.print(c);
}
} }
////////////////////////////////////// //////////////////////////////////////
void HAPClient::charPrintRow(uint8_t *buf, int n){ void HAPClient::charPrintRow(uint8_t *buf, int n){
char c[16]; for(int i=0;i<n;i++)
LOG0("%c",buf[i]);
for(int i=0;i<n;i++){
sprintf(c,"%c",buf[i]);
Serial.print(c);
}
} }
////////////////////////////////////// //////////////////////////////////////
@ -1686,18 +1666,17 @@ void HAPClient::printControllers(){
for(int i=0;i<MAX_CONTROLLERS;i++){ // loop over all controller slots for(int i=0;i<MAX_CONTROLLERS;i++){ // loop over all controller slots
if(controllers[i].allocated){ if(controllers[i].allocated){
Serial.print("Paired Controller: "); LOG0("Paired Controller: ");
charPrintRow(controllers[i].ID,36); charPrintRow(controllers[i].ID,36);
Serial.print(controllers[i].admin?" (admin)":" (regular)"); LOG0("%s LTPK: ",controllers[i].admin?" (admin)":" (regular)");
Serial.print(" LTPK: ");
hexPrintRow(controllers[i].LTPK,32); hexPrintRow(controllers[i].LTPK,32);
Serial.print("\n"); LOG0("\n");
n++; n++;
} }
} }
if(n==0) if(n==0)
Serial.print("No Paired Controllers\n"); LOG0("No Paired Controllers\n");
} }
////////////////////////////////////// //////////////////////////////////////

View File

@ -91,68 +91,60 @@ void Span::begin(Category catID, const char *displayName, const char *hostNameBa
delay(2000); delay(2000);
Serial.print("\n************************************************************\n" LOG0("\n************************************************************\n"
"Welcome to HomeSpan!\n" "Welcome to HomeSpan!\n"
"Apple HomeKit for the Espressif ESP-32 WROOM and Arduino IDE\n" "Apple HomeKit for the Espressif ESP-32 WROOM and Arduino IDE\n"
"************************************************************\n\n" "************************************************************\n\n"
"** Please ensure serial monitor is set to transmit <newlines>\n\n"); "** Please ensure serial monitor is set to transmit <newlines>\n\n");
Serial.print("Message Logs: Level "); LOG0("Message Logs: Level %d",logLevel);
Serial.print(logLevel); LOG0("\nStatus LED: Pin ");
Serial.print("\nStatus LED: Pin ");
if(getStatusPin()>=0){ if(getStatusPin()>=0){
Serial.print(getStatusPin()); LOG0(getStatusPin());
if(autoOffLED>0) if(autoOffLED>0)
Serial.printf(" (Auto Off=%d sec)",autoOffLED); LOG0(" (Auto Off=%d sec)",autoOffLED);
} }
else else
Serial.print("- *** WARNING: Status LED Pin is UNDEFINED"); LOG0("- *** WARNING: Status LED Pin is UNDEFINED");
Serial.print("\nDevice Control: Pin "); LOG0("\nDevice Control: Pin ");
if(getControlPin()>=0) if(getControlPin()>=0){
Serial.print(getControlPin()); LOG0(getControlPin());
else }
Serial.print("- *** WARNING: Device Control Pin is UNDEFINED"); else{
Serial.print("\nSketch Version: "); LOG0("- *** WARNING: Device Control Pin is UNDEFINED");
Serial.print(getSketchVersion()); }
Serial.print("\nHomeSpan Version: "); LOG0("\nSketch Version: %s",getSketchVersion());
Serial.print(HOMESPAN_VERSION); LOG0("\nHomeSpan Version: %s",HOMESPAN_VERSION);
Serial.print("\nArduino-ESP Ver.: "); LOG0("\nArduino-ESP Ver.: %s",ARDUINO_ESP_VERSION);
Serial.print(ARDUINO_ESP_VERSION); LOG0("\nESP-IDF Version: %d.%d.%d",ESP_IDF_VERSION_MAJOR,ESP_IDF_VERSION_MINOR,ESP_IDF_VERSION_PATCH);
Serial.printf("\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(),
Serial.printf("\nESP32 Chip: %s Rev %d %s-core %dMB Flash", ESP.getChipModel(),ESP.getChipRevision(),
ESP.getChipCores()==1?"single":"dual",ESP.getFlashChipSize()/1024/1024); ESP.getChipCores()==1?"single":"dual",ESP.getFlashChipSize()/1024/1024);
#ifdef ARDUINO_VARIANT #ifdef ARDUINO_VARIANT
Serial.print("\nESP32 Board: "); LOG0("\nESP32 Board: ");
Serial.print(ARDUINO_VARIANT); LOG0(ARDUINO_VARIANT);
#endif #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); 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]; char mbtlsv[64];
mbedtls_version_get_string_full(mbtlsv); mbedtls_version_get_string_full(mbtlsv);
Serial.printf("\nMbedTLS Version: %s",mbtlsv); LOG0("\nMbedTLS Version: %s",mbtlsv);
Serial.print("\nSketch Compiled: "); LOG0("\nSketch Compiled: %s %s",__DATE__,__TIME__);
Serial.print(__DATE__); LOG0("\nPartition: %s",esp_ota_get_running_partition()->label);
Serial.print(" "); LOG0("\nMAC Address: %s",WiFi.macAddress().c_str());
Serial.print(__TIME__);
Serial.printf("\nPartition: %s",esp_ota_get_running_partition()->label); LOG0("\n\nDevice Name: %s\n\n",displayName);
Serial.printf("\nMAC Address: %s",WiFi.macAddress().c_str());
Serial.print("\n\nDevice Name: ");
Serial.print(displayName);
Serial.print("\n\n");
uint8_t otaRequired=0; uint8_t otaRequired=0;
nvs_get_u8(otaNVS,"OTA_REQUIRED",&otaRequired); nvs_get_u8(otaNVS,"OTA_REQUIRED",&otaRequired);
nvs_set_u8(otaNVS,"OTA_REQUIRED",0); nvs_set_u8(otaNVS,"OTA_REQUIRED",0);
nvs_commit(otaNVS); nvs_commit(otaNVS);
if(otaRequired && !spanOTA.enabled){ 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); delay(100);
esp_ota_mark_app_invalid_rollback_and_reboot(); 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() { void Span::poll() {
if(pollTaskHandle){ 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); vTaskDelete(pollTaskHandle);
while(1); while(1);
} }
@ -177,7 +169,7 @@ void Span::poll() {
void Span::pollTask() { void Span::pollTask() {
if(!strlen(category)){ 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); while(1);
} }
@ -188,12 +180,12 @@ void Span::pollTask() {
HAPClient::init(); // read NVS and load HAP settings HAPClient::init(); // read NVS and load HAP settings
if(!strlen(network.wifiData.ssid)){ if(!strlen(network.wifiData.ssid)){
Serial.print("*** WIFI CREDENTIALS DATA NOT FOUND. "); LOG0("*** WIFI CREDENTIALS DATA NOT FOUND. ");
if(autoStartAPEnabled){ if(autoStartAPEnabled){
Serial.print("AUTO-START OF ACCESS POINT ENABLED...\n\n"); LOG0("AUTO-START OF ACCESS POINT ENABLED...\n\n");
processSerialCommand("A"); processSerialCommand("A");
} else { } else {
Serial.print("YOU MAY CONFIGURE BY TYPING 'W <RETURN>'.\n\n"); LOG0("YOU MAY CONFIGURE BY TYPING 'W <RETURN>'.\n\n");
STATUS_UPDATE(start(LED_WIFI_NEEDED),HS_WIFI_NEEDED) STATUS_UPDATE(start(LED_WIFI_NEEDED),HS_WIFI_NEEDED)
} }
} else { } else {
@ -203,8 +195,7 @@ void Span::pollTask() {
if(controlButton) if(controlButton)
controlButton->reset(); controlButton->reset();
Serial.print(displayName); LOG0("%s is READY!\n\n",displayName);
Serial.print(" is READY!\n\n");
isInitialized=true; isInitialized=true;
} // isInitialized } // isInitialized
@ -331,11 +322,11 @@ int Span::getFreeSlot(){
void Span::commandMode(){ void Span::commandMode(){
if(!statusDevice && !statusCallback){ 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; return;
} }
Serial.print("*** COMMAND MODE ***\n\n"); LOG0("*** COMMAND MODE ***\n\n");
int mode=1; int mode=1;
boolean done=false; boolean done=false;
STATUS_UPDATE(start(500,0.3,mode,1000),static_cast<HS_STATUS>(HS_ENTERING_CONFIG_MODE+mode)) STATUS_UPDATE(start(500,0.3,mode,1000),static_cast<HS_STATUS>(HS_ENTERING_CONFIG_MODE+mode))
@ -343,9 +334,7 @@ void Span::commandMode(){
while(!done){ while(!done){
if(millis()>alarmTime){ if(millis()>alarmTime){
Serial.print("*** Command Mode: Timed Out ("); LOG0("*** Command Mode: Timed Out (%ld seconds)",comModeLife/1000);
Serial.print(comModeLife/1000);
Serial.print(" seconds).\n\n");
mode=1; mode=1;
done=true; done=true;
} else } else
@ -388,7 +377,7 @@ void Span::commandMode(){
} // switch } // switch
Serial.print("*** EXITING COMMAND MODE ***\n\n"); LOG0("*** EXITING COMMAND MODE ***\n\n");
} }
////////////////////////////////////// //////////////////////////////////////
@ -416,9 +405,7 @@ void Span::checkConnect(){
waitTime*=2; waitTime*=2;
if(waitTime==32000){ if(waitTime==32000){
Serial.print("\n*** Can't connect to "); LOG0("\n*** Can't connect to %s. You may type 'W <return>' to re-configure WiFi, or 'X <return>' to erase WiFi credentials. Will try connecting again in 60 seconds.\n\n",network.wifiData.ssid);
Serial.print(network.wifiData.ssid);
Serial.print(". You may type 'W <return>' to re-configure WiFi, or 'X <return>' to erase WiFi credentials. Will try connecting again in 60 seconds.\n\n");
waitTime=60000; waitTime=60000;
} else { } else {
addWebLog(true,"Trying to connect to %s. Waiting %d sec...",network.wifiData.ssid,waitTime/1000); addWebLog(true,"Trying to connect to %s. Waiting %d sec...",network.wifiData.ssid,waitTime/1000);
@ -462,24 +449,17 @@ void Span::checkConnect(){
sscanf(hostName,"%[A-Za-z0-9-]",d); sscanf(hostName,"%[A-Za-z0-9-]",d);
if(strlen(hostName)>255|| hostName[0]=='-' || hostName[strlen(hostName)-1]=='-' || strlen(hostName)!=strlen(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); LOG0("\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"); 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");
Serial.print("*** PROGRAM HALTED!\n\n"); LOG0("*** PROGRAM HALTED!\n\n");
while(1); while(1);
} }
Serial.print("\nStarting MDNS...\n\n"); LOG0("\nStarting MDNS...\n\n");
Serial.print("HostName: "); LOG0("HostName: %s.local:%d\n",hostName,tcpPortNum);
Serial.print(hostName); LOG0("Display Name: %s\n",displayName);
Serial.print(".local:"); LOG0("Model Name: %s\n",modelName);
Serial.print(tcpPortNum); LOG0("Setup ID: %s\n\n",qrID);
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");
MDNS.begin(hostName); // set server host name (.local implied) MDNS.begin(hostName); // set server host name (.local implied)
MDNS.setInstanceName(displayName); // set server display name MDNS.setInstanceName(displayName); // set server display name
@ -529,12 +509,8 @@ void Span::checkConnect(){
ArduinoOTA.onStart(spanOTA.start).onEnd(spanOTA.end).onProgress(spanOTA.progress).onError(spanOTA.error); ArduinoOTA.onStart(spanOTA.start).onEnd(spanOTA.end).onProgress(spanOTA.progress).onError(spanOTA.error);
ArduinoOTA.begin(); ArduinoOTA.begin();
Serial.print("Starting OTA Server: "); LOG0("Starting OTA Server: %s at %s\n",displayName,WiFi.localIP().toString().c_str());
Serial.print(displayName); LOG0("Authorization Password: %s",spanOTA.auth?"Enabled\n\n":"DISABLED!\n\n");
Serial.print(" at ");
Serial.print(WiFi.localIP());
Serial.print("\nAuthorization Password: ");
Serial.print(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) 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){ 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) 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) if(webLog.timeServer)
xTaskCreateUniversal(webLog.initTime, "timeSeverTaskHandle", 8096, &webLog, 1, NULL, 0); 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(); hapServer->begin();
Serial.print("\n"); LOG0("\n");
if(!HAPClient::nAdminControllers()) 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) if(wifiCallback)
wifiCallback(); wifiCallback();
@ -582,48 +558,40 @@ void Span::processSerialCommand(const char *c){
case 's': { case 's': {
Serial.print("\n*** HomeSpan Status ***\n\n"); LOG0("\n*** HomeSpan Status ***\n\n");
Serial.print("IP Address: "); LOG0("IP Address: %s\n\n",WiFi.localIP().toString().c_str());
Serial.print(WiFi.localIP()); LOG0("Accessory ID: ");
Serial.print("\n\n");
Serial.print("Accessory ID: ");
HAPClient::charPrintRow(HAPClient::accessory.ID,17); HAPClient::charPrintRow(HAPClient::accessory.ID,17);
Serial.print(" LTPK: "); LOG0(" LTPK: ");
HAPClient::hexPrintRow(HAPClient::accessory.LTPK,32); HAPClient::hexPrintRow(HAPClient::accessory.LTPK,32);
Serial.print("\n"); LOG0("\n");
HAPClient::printControllers(); HAPClient::printControllers();
Serial.print("\n"); LOG0("\n");
for(int i=0;i<maxConnections;i++){ for(int i=0;i<maxConnections;i++){
Serial.print("Connection #"); LOG0("Connection #%d ",i);
Serial.print(i);
Serial.print(" ");
if(hap[i]->client){ if(hap[i]->client){
Serial.print(hap[i]->client.remoteIP()); 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);
Serial.print(" on Socket ");
Serial.print(hap[i]->client.fd()-LWIP_SOCKET_OFFSET+1);
Serial.print("/");
Serial.print(CONFIG_LWIP_MAX_SOCKETS);
if(hap[i]->cPair){ if(hap[i]->cPair){
Serial.print(" ID="); LOG0(" ID=");
HAPClient::charPrintRow(hap[i]->cPair->ID,36); HAPClient::charPrintRow(hap[i]->cPair->ID,36);
Serial.print(hap[i]->cPair->admin?" (admin)":" (regular)"); LOG0(hap[i]->cPair->admin?" (admin)":" (regular)");
} else { } else {
Serial.print(" (unverified)"); LOG0(" (unverified)");
} }
} else { } 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; break;
@ -632,13 +600,9 @@ void Span::processSerialCommand(const char *c){
TempBuffer <char> qBuf(sprintfAttributes(NULL)+1); TempBuffer <char> qBuf(sprintfAttributes(NULL)+1);
sprintfAttributes(qBuf.buf); sprintfAttributes(qBuf.buf);
Serial.print("\n*** Attributes Database: size="); LOG0("\n*** Attributes Database: size=%d configuration=%d ***\n\n",qBuf.len()-1,hapConfig.configNumber);
Serial.print(qBuf.len()-1);
Serial.print(" configuration=");
Serial.print(hapConfig.configNumber);
Serial.print(" ***\n\n");
prettyPrint(qBuf.buf); prettyPrint(qBuf.buf);
Serial.print("\n*** End Database ***\n\n"); LOG0("\n*** End Database ***\n\n");
} }
break; break;

View File

@ -225,7 +225,7 @@ class Span{
const char *defaultSetupCode=DEFAULT_SETUP_CODE; // Setup Code used for pairing const char *defaultSetupCode=DEFAULT_SETUP_CODE; // Setup Code used for pairing
uint16_t autoOffLED=0; // automatic turn-off duration (in seconds) for Status LED 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 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 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 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 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 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 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 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 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 void setHostNameSuffix(const char *suffix){hostNameSuffix=suffix;} // sets the hostName suffix to be used instead of the 6-byte AccessoryID

View File

@ -104,11 +104,11 @@
// Message Log Level Control Macros // // Message Log Level Control Macros //
// 0=Minimal, 1=Informative, 2=All // // 0=Minimal, 1=Informative, 2=All //
#define LOG0(format,...) 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()>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()>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 // // Types of Accessory Categories //

View File

@ -52,7 +52,8 @@ void setup() {
Serial.begin(115200); Serial.begin(115200);
homeSpan.setLogLevel(2); // homeSpan.setLogLevel(-1);
homeSpan.enableOTA();
homeSpan.begin(Category::Lighting,"HomeSpan LED"); homeSpan.begin(Category::Lighting,"HomeSpan LED");