Begin integration of hapStream into HAP.ccp

This commit is contained in:
Gregg 2023-12-30 11:37:56 -06:00
parent 7282c2a8c9
commit fb5c9e1e29
5 changed files with 189 additions and 121 deletions

View File

@ -1131,10 +1131,6 @@ int HAPClient::putPrepareURL(char *json){
int HAPClient::getStatusURL(){ int HAPClient::getStatusURL(){
// StreamBuffer *sBuf = new StreamBuffer(&client); // create buffered stream that will output to screen and client
StreamBuffer sBuf(&client);
std::ostream out(&sBuf);
char clocktime[33]; char clocktime[33];
if(homeSpan.webLog.timeInit){ if(homeSpan.webLog.timeInit){
@ -1156,79 +1152,81 @@ int HAPClient::getStatusURL(){
LOG2("\n>>>>>>>>>> %s >>>>>>>>>>\n",client.remoteIP().toString().c_str()); LOG2("\n>>>>>>>>>> %s >>>>>>>>>>\n",client.remoteIP().toString().c_str());
out << "HTTP/1.1 200 OK\r\nContent-type: text/html; charset=utf-8\r\n\r\n"; hapStream.setHapClient(this);
out << "<html><head><title>" << homeSpan.displayName << "</title>\n";
out << "<style>body {background-color:lightblue;} th, td {padding-right: 10px; padding-left: 10px; border:1px solid black;}" << homeSpan.webLog.css << "</style></head>\n";
out << "<body class=bod1><h2>" << homeSpan.displayName << "</h2>\n";
out << "<table class=tab1>\n"; hapOut << "HTTP/1.1 200 OK\r\nContent-type: text/html; charset=utf-8\r\n\r\n";
out << "<tr><td>Up Time:</td><td>" << uptime << "</td></tr>\n"; hapOut << "<html><head><title>" << homeSpan.displayName << "</title>\n";
out << "<tr><td>Current Time:</td><td>" << clocktime << "</td></tr>\n"; hapOut << "<style>body {background-color:lightblue;} th, td {padding-right: 10px; padding-left: 10px; border:1px solid black;}" << homeSpan.webLog.css << "</style></head>\n";
out << "<tr><td>Boot Time:</td><td>" << homeSpan.webLog.bootTime << "</td></tr>\n"; hapOut << "<body class=bod1><h2>" << homeSpan.displayName << "</h2>\n";
out << "<tr><td>Reset Reason:</td><td>";
hapOut << "<table class=tab1>\n";
hapOut << "<tr><td>Up Time:</td><td>" << uptime << "</td></tr>\n";
hapOut << "<tr><td>Current Time:</td><td>" << clocktime << "</td></tr>\n";
hapOut << "<tr><td>Boot Time:</td><td>" << homeSpan.webLog.bootTime << "</td></tr>\n";
hapOut << "<tr><td>Reset Reason:</td><td>";
switch(esp_reset_reason()) { switch(esp_reset_reason()) {
case ESP_RST_UNKNOWN: case ESP_RST_UNKNOWN:
out << "Cannot be determined"; hapOut << "Cannot be determined";
break; break;
case ESP_RST_POWERON: case ESP_RST_POWERON:
out << "Power-on event"; hapOut << "Power-on event";
break; break;
case ESP_RST_EXT: case ESP_RST_EXT:
out << "External pin"; hapOut << "External pin";
break; break;
case ESP_RST_SW: case ESP_RST_SW:
out << "Software reboot via esp_restart"; hapOut << "Software reboot via esp_restart";
break; break;
case ESP_RST_PANIC: case ESP_RST_PANIC:
out << "Software Exception/Panic"; hapOut << "Software Exception/Panic";
break; break;
case ESP_RST_INT_WDT: case ESP_RST_INT_WDT:
out << "Interrupt watchdog"; hapOut << "Interrupt watchdog";
break; break;
case ESP_RST_TASK_WDT: case ESP_RST_TASK_WDT:
out << "Task watchdog"; hapOut << "Task watchdog";
break; break;
case ESP_RST_WDT: case ESP_RST_WDT:
out << "Other watchdogs"; hapOut << "Other watchdogs";
break; break;
case ESP_RST_DEEPSLEEP: case ESP_RST_DEEPSLEEP:
out << "Exiting deep sleep mode"; hapOut << "Exiting deep sleep mode";
break; break;
case ESP_RST_BROWNOUT: case ESP_RST_BROWNOUT:
out << "Brownout"; hapOut << "Brownout";
break; break;
case ESP_RST_SDIO: case ESP_RST_SDIO:
out << "SDIO"; hapOut << "SDIO";
break; break;
default: default:
out << "Unknown Reset Code"; hapOut << "Unknown Reset Code";
} }
out << " (" << esp_reset_reason() << ")</td></tr>\n"; hapOut << " (" << esp_reset_reason() << ")</td></tr>\n";
out << "<tr><td>WiFi Disconnects:</td><td>" << homeSpan.connected/2 << "</td></tr>\n"; hapOut << "<tr><td>WiFi Disconnects:</td><td>" << homeSpan.connected/2 << "</td></tr>\n";
out << "<tr><td>WiFi Signal:</td><td>" << (int)WiFi.RSSI() << " dBm</td></tr>\n"; hapOut << "<tr><td>WiFi Signal:</td><td>" << (int)WiFi.RSSI() << " dBm</td></tr>\n";
out << "<tr><td>WiFi Gateway:</td><td>" << WiFi.gatewayIP().toString().c_str() << "</td></tr>\n"; hapOut << "<tr><td>WiFi Gateway:</td><td>" << WiFi.gatewayIP().toString().c_str() << "</td></tr>\n";
out << "<tr><td>ESP32 Board:</td><td>" << ARDUINO_BOARD << "</td></tr>\n"; hapOut << "<tr><td>ESP32 Board:</td><td>" << ARDUINO_BOARD << "</td></tr>\n";
out << "<tr><td>Arduino-ESP Version:</td><td>" << ARDUINO_ESP_VERSION << "</td></tr>\n"; hapOut << "<tr><td>Arduino-ESP Version:</td><td>" << ARDUINO_ESP_VERSION << "</td></tr>\n";
out << "<tr><td>ESP-IDF Version:</td><td>" << ESP_IDF_VERSION_MAJOR << "." << ESP_IDF_VERSION_MINOR << "." << ESP_IDF_VERSION_PATCH << "</td></tr>\n"; hapOut << "<tr><td>ESP-IDF Version:</td><td>" << ESP_IDF_VERSION_MAJOR << "." << ESP_IDF_VERSION_MINOR << "." << ESP_IDF_VERSION_PATCH << "</td></tr>\n";
out << "<tr><td>HomeSpan Version:</td><td>" << HOMESPAN_VERSION << "</td></tr>\n"; hapOut << "<tr><td>HomeSpan Version:</td><td>" << HOMESPAN_VERSION << "</td></tr>\n";
out << "<tr><td>Sketch Version:</td><td>" << homeSpan.getSketchVersion() << "</td></tr>\n"; hapOut << "<tr><td>Sketch Version:</td><td>" << homeSpan.getSketchVersion() << "</td></tr>\n";
out << "<tr><td>Sodium Version:</td><td>" << sodium_version_string() << " Lib " << sodium_library_version_major() << "." << sodium_library_version_minor() << "</td></tr>\n"; hapOut << "<tr><td>Sodium Version:</td><td>" << sodium_version_string() << " Lib " << sodium_library_version_major() << "." << sodium_library_version_minor() << "</td></tr>\n";
char mbtlsv[64]; char mbtlsv[64];
mbedtls_version_get_string_full(mbtlsv); mbedtls_version_get_string_full(mbtlsv);
out << "<tr><td>MbedTLS Version:</td><td>" << mbtlsv << "</td></tr>\n"; hapOut << "<tr><td>MbedTLS Version:</td><td>" << mbtlsv << "</td></tr>\n";
out << "<tr><td>HomeKit Status:</td><td>" << (HAPClient::nAdminControllers()?"PAIRED":"NOT PAIRED") << "</td></tr>\n"; hapOut << "<tr><td>HomeKit Status:</td><td>" << (HAPClient::nAdminControllers()?"PAIRED":"NOT PAIRED") << "</td></tr>\n";
out << "<tr><td>Max Log Entries:</td><td>" << homeSpan.webLog.maxEntries << "</td></tr>\n"; hapOut << "<tr><td>Max Log Entries:</td><td>" << homeSpan.webLog.maxEntries << "</td></tr>\n";
out << "</table>\n"; hapOut << "</table>\n";
out << "<p></p>"; hapOut << "<p></p>";
if(homeSpan.webLog.maxEntries>0){ if(homeSpan.webLog.maxEntries>0){
out << "<table class=tab2><tr><th>Entry</th><th>Up Time</th><th>Log Time</th><th>Client</th><th>Message</th></tr>\n"; hapOut << "<table class=tab2><tr><th>Entry</th><th>Up Time</th><th>Log Time</th><th>Client</th><th>Message</th></tr>\n";
int lastIndex=homeSpan.webLog.nEntries-homeSpan.webLog.maxEntries; int lastIndex=homeSpan.webLog.nEntries-homeSpan.webLog.maxEntries;
if(lastIndex<0) if(lastIndex<0)
lastIndex=0; lastIndex=0;
@ -1247,12 +1245,12 @@ int HAPClient::getStatusURL(){
else else
sprintf(clocktime,"Unknown"); sprintf(clocktime,"Unknown");
out << "<tr><td>" << i+1 << "</td><td>" << uptime << "</td><td>" << clocktime << "</td><td>" << homeSpan.webLog.log[index].clientIP << "</td><td>" << homeSpan.webLog.log[index].message << "</td></tr>\n"; hapOut << "<tr><td>" << i+1 << "</td><td>" << uptime << "</td><td>" << clocktime << "</td><td>" << homeSpan.webLog.log[index].clientIP << "</td><td>" << homeSpan.webLog.log[index].message << "</td></tr>\n";
} }
out << "</table>\n"; hapOut << "</table>\n";
} }
out << "</body></html>" << std::endl; hapOut << "</body></html>" << std::endl;
LOG2("------------ SENT! --------------\n"); LOG2("------------ SENT! --------------\n");
@ -1607,6 +1605,7 @@ void HAPClient::saveControllers(){
} }
//////////////////////////////////////
////////////////////////////////////// //////////////////////////////////////
Nonce::Nonce(){ Nonce::Nonce(){
@ -1633,6 +1632,65 @@ void Nonce::inc(){
x[5]++; x[5]++;
} }
//////////////////////////////////////
//////////////////////////////////////
StreamBuffer::StreamBuffer(){
buffer=(char *)HS_MALLOC(bufSize);
setp(buffer, buffer+bufSize-1);
}
//////////////////////////////////////
StreamBuffer::~StreamBuffer(){
sync();
free(buffer);
}
//////////////////////////////////////
int StreamBuffer::flushBuffer(){
int num=pptr()-pbase();
if(logLevel<=homeSpan.getLogLevel()){
write(1,buffer,num);
}
if(hapClient!=NULL){
hapClient->client.write(buffer,num);
}
delay(1);
pbump(-num);
return(num);
}
//////////////////////////////////////
StreamBuffer::int_type StreamBuffer::overflow(StreamBuffer::int_type c){
if(c!=EOF){
*pptr() = c;
pbump(1);
}
if(flushBuffer()==EOF)
return(EOF);
return(c);
}
//////////////////////////////////////
int StreamBuffer::sync(){
if(flushBuffer()==EOF)
return(-1);
return(0);
}
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////

View File

@ -27,6 +27,7 @@
#pragma once #pragma once
#include <sstream>
#include <WiFi.h> #include <WiFi.h>
#include "HomeSpan.h" #include "HomeSpan.h"
@ -178,7 +179,36 @@ struct HAPClient {
}; };
/////////////////////////////////////////////////
// StreamBuffer Structure
class StreamBuffer : public std::streambuf {
private:
const size_t bufSize=1024;
char *buffer;
HAPClient *hapClient=NULL;
int logLevel=0;
boolean enablePrettyPrint=false;
int flushBuffer() ;
int_type overflow(int_type c) override;
int sync() override;
public:
StreamBuffer();
~StreamBuffer();
StreamBuffer& setHapClient(HAPClient *hapClient){this->hapClient=hapClient;return(*this);}
StreamBuffer& setLogLevel(int logLevel){this->logLevel=logLevel;return(*this);}
StreamBuffer& prettyPrint(){enablePrettyPrint=true;return(*this);}
};
///////////////////////////////////////////////// /////////////////////////////////////////////////
// Extern Variables // Extern Variables
extern HAPClient **hap; extern HAPClient **hap;
extern std::ostream hapOut;
extern StreamBuffer hapStream;

View File

@ -45,6 +45,9 @@ const __attribute__((section(".rodata_custom_desc"))) SpanPartition spanPartitio
using namespace Utils; using namespace Utils;
StreamBuffer hapStream;
std::ostream hapOut(&hapStream);
HAPClient **hap; // HAP Client structure containing HTTP client connections, parsing routines, and state variables (global-scoped variable) HAPClient **hap; // HAP Client structure containing HTTP client connections, parsing routines, and state variables (global-scoped variable)
Span homeSpan; // HAP Attributes database and all related control functions for this Accessory (global-scoped variable) Span homeSpan; // HAP Attributes database and all related control functions for this Accessory (global-scoped variable)
HapCharacteristics hapChars; // Instantiation of all HAP Characteristics (used to create SpanCharacteristics) HapCharacteristics hapChars; // Instantiation of all HAP Characteristics (used to create SpanCharacteristics)

View File

@ -38,7 +38,6 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <list> #include <list>
#include <sstream>
#include <nvs.h> #include <nvs.h>
#include <ArduinoOTA.h> #include <ArduinoOTA.h>
#include <esp_now.h> #include <esp_now.h>
@ -68,27 +67,6 @@ enum {
GET_VALUE=128 GET_VALUE=128
}; };
///////////////////////////////
class StreamBuffer : public std::streambuf {
private:
char *buffer;
WiFiClient *client;
int flushBuffer() ;
int_type overflow(int_type c) override;
int sync() override;
public:
StreamBuffer(WiFiClient *client, size_t bufSize=1024);
~StreamBuffer();
};
/////////////////////////////// ///////////////////////////////
template <class T> template <class T>

View File

@ -25,57 +25,56 @@
* *
********************************************************************************/ ********************************************************************************/
#include "HomeSpan.h" //#include "HAP.h"
//
StreamBuffer::StreamBuffer(WiFiClient *client, size_t bufSize){ //StreamBuffer::StreamBuffer(){
//
this->client=client; // buffer=(char *)HS_MALLOC(bufSize);
buffer=(char *)HS_MALLOC(bufSize); // setp(buffer, buffer+bufSize-1);
setp (buffer, buffer+bufSize-1); //}
} //
////////////////////////////////////////
////////////////////////////////////// //
//StreamBuffer::~StreamBuffer(){
StreamBuffer::~StreamBuffer(){ //
// free(buffer);
free(buffer); // sync();
sync(); //}
} //
////////////////////////////////////////
////////////////////////////////////// //
//int StreamBuffer::flushBuffer(){
int StreamBuffer::flushBuffer(){ // int num=pptr()-pbase();
int num=pptr()-pbase(); //
// write(1,buffer,num);
write(1,buffer,num); // client->write(buffer,num);
client->write(buffer,num); // delay(1);
delay(1); //
// pbump(-num);
pbump(-num); // return num;
return num; //}
} //
////////////////////////////////////////
////////////////////////////////////// //
//StreamBuffer::int_type StreamBuffer::overflow(StreamBuffer::int_type c){
StreamBuffer::int_type StreamBuffer::overflow(StreamBuffer::int_type c){ //
// if(c!=EOF){
if(c!=EOF){ // *pptr() = c;
*pptr() = c; // pbump(1);
pbump(1); // }
} //
// if(flushBuffer()==EOF)
if(flushBuffer()==EOF) // return EOF;
return EOF; // return c;
return c; //}
} //
////////////////////////////////////////
////////////////////////////////////// //
//int StreamBuffer::sync(){
int StreamBuffer::sync(){ //
// if(flushBuffer()==EOF)
if(flushBuffer()==EOF) // return -1;
return -1; // return 0;
return 0; //}
} //
////////////////////////////////////////
//////////////////////////////////////