LedDisplay/firmware/src/LedDisplay.cpp

249 lines
7.3 KiB
C++

#include "LedDisplay.h"
//LedDisplay::LedDisplay(String deviceName, Adafruit_NeoMatrix *ledDisplayMatrix)
void LedDisplay::loop()
{
if (millis() - lastKeepAlive > this->maximumKeepAliveDelay)
{
this->lastKeepAlive = millis();
this->bleServer->disconnectCurrentDevice();
}
}
void LedDisplay::onDeviceConnectedChanged(bool deviceConnected)
{
if (deviceConnected)
{
Serial.println("Device connected");
this->lastKeepAlive = millis();
}
else
{
Serial.println("Device disconnected");
this->lastKeepAlive = -1;
this->sessionAuthorized = false;
}
}
void LedDisplay::onDataReceived(String dataString)
{
// process JSON
const size_t capacity = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 200;
DynamicJsonDocument requestDoc(capacity);
DeserializationError error = deserializeJson(requestDoc, dataString);
// return on error
if (error != DeserializationError::Ok)
return;
// get reuqest data
DisplayCommand requestHeader = requestDoc["header"];
JsonObject requestData = requestDoc["data"];
// prepare reply data
DynamicJsonDocument replyDoc(capacity);
replyDoc["header"] = requestHeader;
DisplayStatusCode replyStatus = InternalError;
JsonObject replyData = replyDoc.createNestedObject("data");
if (requestHeader > KeepAliveCommand && !this->sessionAuthorized)
replyStatus = Unauthorized;
else
switch (requestHeader)
{
case AuthenticateCommand:
{
String combinedCode = String(this->properties.deviceCode); //this->bleServer->getDeviceAddress() + String(this->properties.deviceCode);
String secret = this->sha256(combinedCode);
if (this->sessionAuthorized)
{
replyStatus = Success;
}
else if (requestData["secret"] == secret)
{
replyStatus = Success;
this->sessionAuthorized = true;
}
else
{
replyStatus = Unauthorized;
this->sessionAuthorized = false;
break;
}
// for future use: add some variables of the display
}
case KeepAliveCommand:
{
replyStatus = Success;
this->lastKeepAlive = millis();
break;
}
case GetAllTextSetsCommand:
{
replyStatus = Success;
replyData["maximumTextSets"] = LedDisplayController::maximumTextSets;
replyData["maximumTextLength"] = LedDisplayController::maximumTextLength;
break;
}
case GetDisplayBrightnessCommand:
{
replyData["displayBrightness"] = this->ledDisplayController->getBrightness();
replyData["automaticBrightnessAdjustment"] = this->ledDisplayController->getAutomaticBrightnessAdjustment();
replyStatus = Success;
break;
}
case GetTextSetParameterCommand:
{
int index = requestData["index"];
LedDisplayController::DisplayTextSetParameter parameter = requestData["parameter"];
// send each parameter to the client
replyData["index"] = index;
replyData["parameter"] = parameter;
replyStatus = Success;
replyData["value"] = this->ledDisplayController->getTextSetParameter(
index,
parameter);
Serial.println("sending parameter: " + String(parameter) + " with value: '" + this->ledDisplayController->getTextSetParameter(
index,
parameter) + "'");
break;
}
case SetTextSetParameterCommand:
{
int index = requestData["index"];
int parameter = requestData["parameter"];
String value = requestData["value"];
LedDisplayController::GetSetTextSetParameterExitCode res = this->ledDisplayController->setTextSetParameter(index, LedDisplayController::DisplayTextSetParameter(parameter), value);
if (res == LedDisplayController::Success)
replyStatus = Success;
else
{
replyStatus = DisplayControllerError;
replyData["displayControllerError"] = res;
}
break;
}
case SetDisplayBrightnessCommand:
{
this->ledDisplayController->setBrightness(requestData["displayBrightness"]);
this->ledDisplayController->setAutomaticBrightnessAdjustment(requestData["automaticBrightnessAdjustment"]);
replyStatus = Success;
break;
}
case SetDisplayCodeCommand: {
String code = requestData["displayCode"];
if(code.length() != 4) {
replyStatus = BadRequestError;
break;
}
strncpy(this->properties.deviceCode, code.c_str(), sizeof(this->properties.deviceCode));
this->storeProperties();
replyStatus = Success;
break;
}
case SetDisplayNameCommand: {
String name = requestData["displayName"];
if(name.length() <= 0) {
replyStatus = BadRequestError;
break;
}
strncpy(this->properties.deviceName, name.c_str(), sizeof(this->properties.deviceName));
this->storeProperties();
replyStatus = Success;
break;
}
default:
break;
}
// reply to the client
replyDoc["status"] = replyStatus;
String json;
serializeJson(replyDoc, json);
Serial.println("Primary JSON: '" + json + "'");
this->bleServer->sendData(json);
}
bool LedDisplay::loadProperties()
{
if (this->eepromUnit == nullptr)
return false;
DisplayProperties buf = {};
// read conf from EEPROM
this->eepromUnit->read(buf);
if (strcmp(buf.valid, "OK") == 0)
{
memcpy(&this->properties, &buf, sizeof(DisplayProperties));
}
else
{
// There was an error reading the properties -> rebuild with default values!
DisplayProperties defaultProperties{
"Led Display",
"1234",
"OK"};
memcpy(&this->properties, &defaultProperties, sizeof(DisplayProperties));
this->storeProperties();
}
return true;
}
bool LedDisplay::storeProperties()
{
if (this->eepromUnit == nullptr)
return false;
strncpy(this->properties.valid, "OK", sizeof(this->properties.valid));
this->eepromUnit->write(this->properties);
return true;
}
String LedDisplay::sha256(String payload)
{
byte shaResult[32];
mbedtls_md_context_t ctx;
mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256;
const size_t payloadLength = strlen(payload.c_str());
mbedtls_md_init(&ctx);
mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0);
mbedtls_md_starts(&ctx);
mbedtls_md_update(&ctx, (const unsigned char *)payload.c_str(), payloadLength);
mbedtls_md_finish(&ctx, shaResult);
mbedtls_md_free(&ctx);
String resultString = "";
for (int i = 0; i < sizeof(shaResult); i++)
{
char str[3];
sprintf(str, "%02x", (int)shaResult[i]);
resultString += str;
}
return resultString;
}