2021-11-21 00:56:28 +01:00
# include "webserver_displaycontrol.h"
2022-06-25 22:16:21 +02:00
// system includes
# include <utility>
2021-12-28 20:27:16 +01:00
// esp-idf includes
# include <esp_http_server.h>
# include <esp_log.h>
// 3rdparty lib includes
# include <htmlbuilder.h>
# include <fmt/core.h>
# include <espcppmacros.h>
# include <numberparsing.h>
# include <esphttpdutils.h>
# include <textinterface.h>
# include <menudisplay.h>
# include <changevaluedisplay.h>
2021-12-30 00:00:31 +01:00
# include <changevaluedisplay_string.h>
2021-12-28 20:27:16 +01:00
# include <lockhelper.h>
# include <tickchrono.h>
# include <screenmanager.h>
// local includes
2021-12-30 00:00:31 +01:00
# include "bobbybuttons.h"
2022-06-23 21:50:58 +02:00
# include "globals.h"
2021-12-29 06:19:09 +01:00
# include "newsettings.h"
2022-06-23 21:50:58 +02:00
# include "webserver_lock.h"
2021-12-28 20:27:16 +01:00
2021-11-21 00:56:28 +01:00
using esphttpdutils : : HtmlTag ;
2021-12-14 12:23:54 +01:00
using namespace std : : chrono_literals ;
2021-11-21 00:56:28 +01:00
namespace {
constexpr const char * const TAG = " BOBBYWEB " ;
} // namespace
esp_err_t webserver_root_handler ( httpd_req_t * req )
{
std : : string body ;
2021-12-09 00:33:40 +01:00
std : : string wants_json_query ;
if ( auto result = esphttpdutils : : webserver_get_query ( req ) )
wants_json_query = * result ;
else
{
ESP_LOGE ( TAG , " %.*s " , result . error ( ) . size ( ) , result . error ( ) . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , result . error ( ) ) ;
}
char tmpBuf [ 256 ] ;
const auto key_result = httpd_query_key_value ( wants_json_query . data ( ) , " json " , tmpBuf , 256 ) ;
2022-04-29 22:40:49 +02:00
if ( key_result = = ESP_OK & & ( configs . webserverPassword . value ( ) . empty ( ) | | configs . webserverPassword . value ( ) = = tmpBuf ) )
2021-12-09 00:33:40 +01:00
{
2021-12-11 05:05:46 +01:00
2021-12-09 00:33:40 +01:00
body + = " { " ;
if ( auto currentDisplay = static_cast < const espgui : : Display * > ( espgui : : currentDisplay . get ( ) ) )
{
body . reserve ( 4096 ) ;
if ( const auto * textInterface = currentDisplay - > asTextInterface ( ) )
{
2021-12-10 07:25:16 +01:00
body + = fmt : : format ( " \" name \" : \" {} \" , " , textInterface - > text ( ) ) ;
2021-12-09 00:33:40 +01:00
}
if ( const auto * menuDisplay = currentDisplay - > asMenuDisplay ( ) )
{
body + = fmt : : format ( " \" index \" :{}, \" items \" :[ " , menuDisplay - > selectedIndex ( ) ) ;
menuDisplay - > runForEveryMenuItem ( [ & , selectedIndex = menuDisplay - > selectedIndex ( ) ] ( const espgui : : MenuItem & menuItem ) {
body + = " { " ;
2021-12-10 10:01:49 +01:00
const auto itemName = menuItem . text ( ) ;
std : : string color { } ;
std : : string font { } ;
switch ( menuItem . color ( ) ) {
case TFT_RED :
color = " &1 " ;
break ;
case TFT_GREEN :
color = " &2 " ;
break ;
case TFT_BLUE :
color = " &3 " ;
break ;
case TFT_YELLOW :
color = " &4 " ;
break ;
case TFT_BLACK :
color = " &5 " ;
break ;
case TFT_WHITE :
color = " &6 " ;
break ;
case TFT_GREY :
case TFT_DARKGREY :
color = " &7 " ;
break ;
default :
color = " " ;
break ;
}
switch ( menuItem . font ( ) )
{
case 2 :
font = " &s " ;
break ;
case 4 :
font = " &m " ;
break ;
default :
font = " " ;
break ;
}
std : : string menuItemName = font + color + itemName ;
body + = fmt : : format ( " \" name \" : \" {} \" , \" icon \" : \" {} \" , \" index \" :{} " , menuItemName , ( menuItem . icon ( ) ) ? menuItem . icon ( ) - > name : " " , selectedIndex ) ;
2021-12-09 00:33:40 +01:00
body + = " }, " ;
} ) ;
body + = " ], " ;
}
else if ( const auto * changeValueDisplay = currentDisplay - > asChangeValueDisplayInterface ( ) )
{
body + = fmt : : format ( " \" value \" : \" {} \" , " , changeValueDisplay - > shownValue ( ) ) ;
}
else
{
2021-12-11 01:28:57 +01:00
body + = " \" err \" : \" Screen not implemented yet. \" " ;
2021-12-09 00:33:40 +01:00
}
}
else
{
2021-12-11 01:28:57 +01:00
body + = " \" err \" : \" Currently no screen instantiated. \" " ;
2021-12-09 00:33:40 +01:00
}
body + = " } " ;
2021-12-10 10:01:49 +01:00
size_t lastGesch = body . rfind ( " }, " ) ;
if ( std : : string : : npos ! = lastGesch )
body = body . erase ( lastGesch + 1 , 1 ) ;
size_t lastEckig = body . rfind ( " ], " ) ;
if ( std : : string : : npos ! = lastEckig )
body = body . erase ( lastEckig + 1 , 1 ) ;
2021-12-11 01:28:57 +01:00
2021-12-09 00:33:40 +01:00
}
2022-04-29 22:40:49 +02:00
else if ( key_result ! = ESP_ERR_NOT_FOUND & & tmpBuf ! = configs . webserverPassword . value ( ) )
2021-12-09 14:56:06 +01:00
{
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : Unauthorized , " text/plain " , " " ) ;
}
2021-12-09 00:33:40 +01:00
else
2021-11-21 00:56:28 +01:00
{
HtmlTag htmlTag { " html " , body } ;
{
HtmlTag headTag { " head " , body } ;
{
HtmlTag titleTag { " title " , body } ;
body + = " Display control " ;
}
body + = " <meta name= \" viewport \" content= \" width=device-width, initial-scale=1, shrink-to-fit=no \" /> " ;
}
{
HtmlTag bodyTag { " body " , body } ;
{
HtmlTag h1Tag { " h1 " , body } ;
body + = " Display control " ;
}
{
HtmlTag pTag { " p " , body } ;
body + = " <b>Display control</b> - "
" <a href= \" /ota \" >Update</a> - "
" <a href= \" /settings \" >Settings</a> - "
2021-12-28 22:01:49 +01:00
" <a href= \" /newSettings \" >New Settings</a> - "
2021-11-21 00:56:28 +01:00
" <a href= \" /dumpnvs \" >Dump NVS</a> " ;
}
{
HtmlTag pTag { " p " , body } ;
2021-12-30 00:00:31 +01:00
body + = " Trigger raw button: "
" <a href= \" /triggerRawButton?button=0 \" >Button0</a> "
" <a href= \" /triggerRawButton?button=1 \" >Button1</a> "
" <a href= \" /triggerRawButton?button=2 \" >Button2</a> "
" <a href= \" /triggerRawButton?button=3 \" >Button3</a> "
" <a href= \" /triggerRawButton?button=4 \" >Button4</a> "
" <a href= \" /triggerRawButton?button=5 \" >Button5</a> "
" <a href= \" /triggerRawButton?button=6 \" >Button6</a> "
" <a href= \" /triggerRawButton?button=7 \" >Button7</a> "
" <a href= \" /triggerRawButton?button=8 \" >Button8</a> "
" <a href= \" /triggerRawButton?button=9 \" >Button9</a> "
" <a href= \" /triggerRawButton?button=10 \" >Button10</a> "
2022-06-12 20:15:31 +02:00
" <a href= \" /triggerRawButton?button=11 \" >Button11</a> "
" <a href= \" /triggerRawButton?button=12 \" >Button12</a> "
" <a href= \" /triggerRawButton?button=13 \" >Button13</a> "
" <a href= \" /triggerRawButton?button=14 \" >Button14</a> "
" <a href= \" /triggerRawButton?button=15 \" >Button15</a> " ;
2021-12-30 00:00:31 +01:00
}
{
HtmlTag pTag { " p " , body } ;
body + = fmt : : format ( " Trigger button: "
" <a href= \" /triggerButton?button={} \" >Left</a> "
" <a href= \" /triggerButton?button={} \" >Right</a> "
" <a href= \" /triggerButton?button={} \" >Up</a> "
" <a href= \" /triggerButton?button={} \" >Down</a> "
" <a href= \" /triggerButton?button={} \" >Profile0</a> "
" <a href= \" /triggerButton?button={} \" >Profile1</a> "
" <a href= \" /triggerButton?button={} \" >Profile2</a> "
" <a href= \" /triggerButton?button={} \" >Profile3</a> "
" <a href= \" /triggerButton?button={} \" >Left2</a> "
" <a href= \" /triggerButton?button={} \" >Right2</a> "
" <a href= \" /triggerButton?button={} \" >Up2</a> "
2022-06-12 20:15:31 +02:00
" <a href= \" /triggerButton?button={} \" >Down2</a> "
" <a href= \" /triggerButton?button={} \" >Extra1</a> "
" <a href= \" /triggerButton?button={} \" >Extra2</a> "
" <a href= \" /triggerButton?button={} \" >Extra3</a> "
" <a href= \" /triggerButton?button={} \" >Extra4</a> " ,
2021-12-30 00:00:31 +01:00
std : : to_underlying ( espgui : : Button : : Left ) ,
std : : to_underlying ( espgui : : Button : : Right ) ,
std : : to_underlying ( espgui : : Button : : Up ) ,
std : : to_underlying ( espgui : : Button : : Down ) ,
std : : to_underlying ( BobbyButton : : Profile0 ) ,
std : : to_underlying ( BobbyButton : : Profile1 ) ,
std : : to_underlying ( BobbyButton : : Profile2 ) ,
std : : to_underlying ( BobbyButton : : Profile3 ) ,
std : : to_underlying ( BobbyButton : : Left2 ) ,
std : : to_underlying ( BobbyButton : : Right2 ) ,
std : : to_underlying ( BobbyButton : : Up2 ) ,
2022-06-12 20:15:31 +02:00
std : : to_underlying ( BobbyButton : : Down2 ) ,
std : : to_underlying ( BobbyButton : : Extra1 ) ,
std : : to_underlying ( BobbyButton : : Extra2 ) ,
std : : to_underlying ( BobbyButton : : Extra3 ) ,
std : : to_underlying ( BobbyButton : : Extra4 ) ) ;
2021-11-21 00:56:28 +01:00
}
if ( auto currentDisplay = static_cast < const espgui : : Display * > ( espgui : : currentDisplay . get ( ) ) )
{
if ( const auto * textInterface = currentDisplay - > asTextInterface ( ) )
{
HtmlTag h2Tag { " h2 " , body } ;
body + = esphttpdutils : : htmlentities ( textInterface - > text ( ) ) ;
}
if ( const auto * menuDisplay = currentDisplay - > asMenuDisplay ( ) )
{
HtmlTag ulTag { " ul " , body } ;
int i { 0 } ;
menuDisplay - > runForEveryMenuItem ( [ & , selectedIndex = menuDisplay - > selectedIndex ( ) ] ( const espgui : : MenuItem & menuItem ) {
HtmlTag liTag = i = = selectedIndex ?
HtmlTag { " li " , " style= \" border: 1px solid black; \" " , body } :
HtmlTag { " li " , body } ;
body + = fmt : : format ( " <a href= \" /triggerItem?index={} \" >{}</a> " , i , esphttpdutils : : htmlentities ( menuItem . text ( ) ) ) ;
i + + ;
} ) ;
}
else if ( const auto * changeValueDisplay = currentDisplay - > asChangeValueDisplayInterface ( ) )
{
HtmlTag formTag { " form " , " action= \" /setValue \" method= \" GET \" " , body } ;
body + = fmt : : format ( " <input type= \" number \" name= \" value \" value= \" {} \" /> " , changeValueDisplay - > shownValue ( ) ) ;
body + = " <button type= \" submit \" >Update</button> " ;
}
2021-12-30 00:00:31 +01:00
else if ( const auto * changeValueDisplay = currentDisplay - > asChangeValueDisplayString ( ) )
{
HtmlTag formTag { " form " , " action= \" /setValue \" method= \" GET \" " , body } ;
body + = fmt : : format ( " <input type= \" text \" name= \" value \" value= \" {} \" /> " , changeValueDisplay - > shownValue ( ) ) ;
body + = " <button type= \" submit \" >Update</button> " ;
}
2021-11-21 00:56:28 +01:00
else
{
body + = " No web control implemented for current display. " ;
}
}
else
{
body + = " Currently no screen instantiated. " ;
}
}
}
2022-01-29 03:28:40 +01:00
CALL_AND_EXIT_ON_ERROR ( httpd_resp_set_hdr , req , " Access-Control-Allow-Origin " , " http://web.bobbycar.cloud " ) ;
2021-12-09 00:33:40 +01:00
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : Ok , ( key_result = = ESP_OK ) ? " application/json " : " text/html " , body )
2021-11-21 00:56:28 +01:00
}
2021-12-30 00:00:31 +01:00
esp_err_t webserver_triggerRawButton_handler ( httpd_req_t * req )
2021-11-21 00:56:28 +01:00
{
std : : string query ;
if ( auto result = esphttpdutils : : webserver_get_query ( req ) )
query = * result ;
else
{
ESP_LOGE ( TAG , " %.*s " , result . error ( ) . size ( ) , result . error ( ) . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , result . error ( ) ) ;
}
2022-06-23 21:50:58 +02:00
int8_t button ;
2021-11-21 00:56:28 +01:00
constexpr const std : : string_view buttonParamName { " button " } ;
{
char valueBufEncoded [ 256 ] ;
if ( const auto result = httpd_query_key_value ( query . data ( ) , buttonParamName . data ( ) , valueBufEncoded , 256 ) ; result ! = ESP_OK )
{
if ( result = = ESP_ERR_NOT_FOUND )
{
const auto msg = fmt : : format ( " {} not set " , buttonParamName ) ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
else
{
const auto msg = fmt : : format ( " httpd_query_key_value() {} failed with {} " , buttonParamName , esp_err_to_name ( result ) ) ;
ESP_LOGE ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
}
char valueBuf [ 257 ] ;
esphttpdutils : : urldecode ( valueBuf , valueBufEncoded ) ;
2021-12-30 00:00:31 +01:00
std : : string_view value { valueBuf } ;
if ( auto parsed = cpputils : : fromString < decltype ( button ) > ( value ) )
{
button = * parsed ;
}
else
{
const auto msg = fmt : : format ( " could not parse {} {} " , buttonParamName , value ) ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
2021-11-21 00:56:28 +01:00
}
2022-06-23 21:50:58 +02:00
rawButtonRequest . store ( button ) ;
2021-11-21 00:56:28 +01:00
2021-12-30 00:00:31 +01:00
CALL_AND_EXIT_ON_ERROR ( httpd_resp_set_hdr , req , " Location " , " / " )
2022-01-29 03:28:40 +01:00
CALL_AND_EXIT_ON_ERROR ( httpd_resp_set_hdr , req , " Access-Control-Allow-Origin " , " http://web.bobbycar.cloud " ) ;
2021-12-30 00:00:31 +01:00
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : TemporaryRedirect , " text/html " , " Ok, continue at <a href= \" / \" >/</a> " )
}
2021-11-21 00:56:28 +01:00
2021-12-30 00:00:31 +01:00
esp_err_t webserver_triggerButton_handler ( httpd_req_t * req )
{
2021-11-21 00:56:28 +01:00
2021-12-30 00:00:31 +01:00
std : : string query ;
if ( auto result = esphttpdutils : : webserver_get_query ( req ) )
query = * result ;
else
2021-11-21 00:56:28 +01:00
{
2021-12-30 00:00:31 +01:00
ESP_LOGE ( TAG , " %.*s " , result . error ( ) . size ( ) , result . error ( ) . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , result . error ( ) ) ;
2021-11-21 00:56:28 +01:00
}
2021-12-30 00:00:31 +01:00
2022-06-23 21:50:58 +02:00
int8_t button ;
2021-12-30 00:00:31 +01:00
constexpr const std : : string_view buttonParamName { " button " } ;
2021-11-21 00:56:28 +01:00
{
2021-12-30 00:00:31 +01:00
char valueBufEncoded [ 256 ] ;
if ( const auto result = httpd_query_key_value ( query . data ( ) , buttonParamName . data ( ) , valueBufEncoded , 256 ) ; result ! = ESP_OK )
{
if ( result = = ESP_ERR_NOT_FOUND )
{
const auto msg = fmt : : format ( " {} not set " , buttonParamName ) ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
else
{
const auto msg = fmt : : format ( " httpd_query_key_value() {} failed with {} " , buttonParamName , esp_err_to_name ( result ) ) ;
ESP_LOGE ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
}
char valueBuf [ 257 ] ;
esphttpdutils : : urldecode ( valueBuf , valueBufEncoded ) ;
2021-11-21 00:56:28 +01:00
2021-12-30 00:00:31 +01:00
std : : string_view value { valueBuf } ;
2022-06-23 21:50:58 +02:00
if ( auto parsed = cpputils : : fromString < int8_t > ( value ) )
2021-12-30 00:00:31 +01:00
{
2022-06-23 21:50:58 +02:00
button = * parsed ;
2021-12-30 00:00:31 +01:00
}
else
{
const auto msg = fmt : : format ( " could not parse {} {} " , buttonParamName , value ) ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
2021-11-21 00:56:28 +01:00
}
2021-12-30 00:00:31 +01:00
2022-06-23 21:50:58 +02:00
buttonRequest . store ( button ) ;
2021-12-30 00:00:31 +01:00
CALL_AND_EXIT_ON_ERROR ( httpd_resp_set_hdr , req , " Location " , " / " )
2022-01-29 03:28:40 +01:00
CALL_AND_EXIT_ON_ERROR ( httpd_resp_set_hdr , req , " Access-Control-Allow-Origin " , " http://web.bobbycar.cloud " ) ;
2021-12-30 00:00:31 +01:00
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : TemporaryRedirect , " text/html " , " Ok, continue at <a href= \" / \" >/</a> " )
2021-11-21 00:56:28 +01:00
}
esp_err_t webserver_triggerItem_handler ( httpd_req_t * req )
{
2022-01-17 11:23:22 +01:00
2022-01-29 03:28:40 +01:00
CALL_AND_EXIT_ON_ERROR ( httpd_resp_set_hdr , req , " Access-Control-Allow-Origin " , " http://web.bobbycar.cloud " ) ;
2021-11-21 00:56:28 +01:00
std : : string query ;
if ( auto result = esphttpdutils : : webserver_get_query ( req ) )
query = * result ;
else
{
ESP_LOGE ( TAG , " %.*s " , result . error ( ) . size ( ) , result . error ( ) . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , result . error ( ) ) ;
}
std : : size_t index ;
constexpr const std : : string_view indexParamName { " index " } ;
{
char valueBufEncoded [ 256 ] ;
if ( const auto result = httpd_query_key_value ( query . data ( ) , indexParamName . data ( ) , valueBufEncoded , 256 ) ; result ! = ESP_OK )
{
if ( result = = ESP_ERR_NOT_FOUND )
{
const auto msg = fmt : : format ( " {} not set " , indexParamName ) ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
else
{
const auto msg = fmt : : format ( " httpd_query_key_value() {} failed with {} " , indexParamName , esp_err_to_name ( result ) ) ;
ESP_LOGE ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
}
char valueBuf [ 257 ] ;
esphttpdutils : : urldecode ( valueBuf , valueBufEncoded ) ;
std : : string_view value { valueBuf } ;
if ( auto parsed = cpputils : : fromString < typeof ( index ) > ( value ) )
{
index = * parsed ;
}
else
{
const auto msg = fmt : : format ( " could not parse {} {} " , indexParamName , value ) ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
}
if ( ! espgui : : currentDisplay )
{
constexpr const std : : string_view msg = " espgui::currentDisplay is null " ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
auto * menuDisplay = espgui : : currentDisplay - > asMenuDisplay ( ) ;
if ( ! menuDisplay )
{
constexpr const std : : string_view msg = " espgui::currentDisplay is not a menu display " ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
if ( /*index < 0 ||*/ index > = menuDisplay - > menuItemCount ( ) )
{
const auto msg = fmt : : format ( " {} {} out of range (must be smaller than {}) " , indexParamName , index , menuDisplay - > menuItemCount ( ) ) ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
menuDisplay - > getMenuItem ( index ) . triggered ( ) ;
CALL_AND_EXIT_ON_ERROR ( httpd_resp_set_hdr , req , " Location " , " / " )
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : TemporaryRedirect , " text/html " , " Ok, continue at <a href= \" / \" >/</a> " )
}
esp_err_t webserver_setValue_handler ( httpd_req_t * req )
{
2022-01-29 03:28:40 +01:00
CALL_AND_EXIT_ON_ERROR ( httpd_resp_set_hdr , req , " Access-Control-Allow-Origin " , " http://web.bobbycar.cloud " ) ;
2021-11-21 00:56:28 +01:00
std : : string query ;
if ( auto result = esphttpdutils : : webserver_get_query ( req ) )
query = * result ;
else
{
ESP_LOGE ( TAG , " %.*s " , result . error ( ) . size ( ) , result . error ( ) . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , result . error ( ) ) ;
}
2021-12-30 00:00:31 +01:00
char valueBuf [ 257 ] ;
2021-11-21 00:56:28 +01:00
constexpr const std : : string_view valueParamName { " value " } ;
{
char valueBufEncoded [ 256 ] ;
if ( const auto result = httpd_query_key_value ( query . data ( ) , valueParamName . data ( ) , valueBufEncoded , 256 ) ; result ! = ESP_OK )
{
if ( result = = ESP_ERR_NOT_FOUND )
{
const auto msg = fmt : : format ( " {} not set " , valueParamName ) ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
else
{
const auto msg = fmt : : format ( " httpd_query_key_value() {} failed with {} " , valueParamName , esp_err_to_name ( result ) ) ;
ESP_LOGE ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
}
esphttpdutils : : urldecode ( valueBuf , valueBufEncoded ) ;
2021-12-30 00:00:31 +01:00
}
2021-11-21 00:56:28 +01:00
2021-12-30 00:00:31 +01:00
std : : string_view value { valueBuf } ;
2021-11-21 00:56:28 +01:00
2021-12-30 00:00:31 +01:00
if ( ! espgui : : currentDisplay )
{
constexpr const std : : string_view msg = " espgui::currentDisplay is null " ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
if ( auto * changeValueDisplay = espgui : : currentDisplay - > asChangeValueDisplayInterface ( ) )
{
int newValue ;
2021-11-21 00:56:28 +01:00
if ( auto parsed = cpputils : : fromString < typeof ( newValue ) > ( value ) )
{
newValue = * parsed ;
}
else
{
const auto msg = fmt : : format ( " could not parse {} {} " , valueParamName , value ) ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
2021-12-30 00:00:31 +01:00
changeValueDisplay - > setShownValue ( newValue ) ;
}
else if ( auto * changeValueDisplay = espgui : : currentDisplay - > asChangeValueDisplayString ( ) )
2021-11-21 00:56:28 +01:00
{
2021-12-30 00:00:31 +01:00
changeValueDisplay - > setShownValue ( std : : string { value } ) ;
2021-11-21 00:56:28 +01:00
}
2021-12-30 00:00:31 +01:00
else
2021-11-21 00:56:28 +01:00
{
constexpr const std : : string_view msg = " espgui::currentDisplay is not a change value display " ;
ESP_LOGW ( TAG , " %.*s " , msg . size ( ) , msg . data ( ) ) ;
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : BadRequest , " text/plain " , msg ) ;
}
CALL_AND_EXIT_ON_ERROR ( httpd_resp_set_hdr , req , " Location " , " / " )
CALL_AND_EXIT ( esphttpdutils : : webserver_resp_send , req , esphttpdutils : : ResponseStatus : : TemporaryRedirect , " text/html " , " Ok, continue at <a href= \" / \" >/</a> " )
}