2021-10-02 01:43:52 +01:00

152 lines
3.8 KiB
C++

#include "main.h"
#include <Arduino.h>
#include <Wire.h>
#include "setup_server.h"
#include <ESP8266WiFi.h>
#include <string>
#include "settings.h"
#include <ChaChaPoly.h>
#include <BLAKE2s.h>
Environment::Settings settings;
utils::byte_buffer passcode(DERIVATION_HASH_SIZE);
void setup()
{
settings.apiID = 11085093266951290551U;
settings.endpoint = std::string("http://192.168.64.244:8080/data/authed/");
settings.passcode = std::string("password");
Serial.begin(9600);
Serial.println("\nSTART");
Serial.print("Last Shutdown: ");
Serial.println(ESP.getResetReason());
Serial.print("Derive Key: ");
DeriveKey();
// put your setup code here, to run once:
screen.begin();
Wire.begin();
bme.begin();
environmentUpdate.attach_scheduled(1, UpdateEnvironment);
environmentPost.attach_scheduled(60, PostEnvironment);
screen.firstPage();
do
{
screen.setFont(FONT);
screen.drawStr(2, LINE_1, "Connecting...");
} while (screen.nextPage());
InitializeWifi();
}
void loop()
{
// put your main code here, to run repeatedly:
screen.firstPage();
do
{
screen.setFont(FONT);
screen.drawStr(2, LINE_1, "Hello World!");
screen.drawStr(2, LINE_2, "Hi Butlersaurus!");
} while (screen.nextPage());
delay(1000);
screen.firstPage();
do
{
screen.setFont(FONT);
screen.drawStr(2, LINE_1, TEMP);
screen.setCursor(screen.getStrWidth(TEMP), LINE_1);
screen.print(temp);
screen.drawStr(2, LINE_2, HUMID);
screen.setCursor(screen.getStrWidth(HUMID), LINE_2);
screen.print(humidity);
} while (screen.nextPage());
delay(1000);
}
void UpdateEnvironment()
{
bme.read(pressure, temp, humidity, tempUnit, presUnit);
}
void PostEnvironment()
{
utils::debug_print("Post");
//requests.begin(client, "http://192.168.64.239/api/environment");
auto endpoint = std::string(settings.endpoint);
endpoint.append(std::to_string(settings.apiID));
requests.begin(client, endpoint.c_str());
requests.addHeader("Content-Type", "application/json");
char dataBuffer[128] = {0};
char formatString[] = "{\"h\":%f,\"t\":%f}";
snprintf(&dataBuffer[0], 128, &formatString[0], humidity, temp);
auto data = Encrypt(std::string(dataBuffer));
auto code = requests.PUT(data.get_ptr(), data.get_length());
if (code > 0)
{
utils::debug_print(code);
}
else
{
utils::debug_print(requests.errorToString(code));
}
requests.end();
utils::debug_print("Posted");
}
utils::byte_buffer Encrypt(std::string data)
{
// struct used by go, with basically no docs :|
// iv (12) | cipher (x) | tag(16)
const uint_fast16_t ivSize = 12;
auto size = ivSize + data.length() + 16;
auto dataOut = utils::byte_buffer(size);
// for the iv
dataOut.fill_random();
// first 12 bytes
auto cipher = ChaChaPoly();
cipher.setKey(passcode.get_ptr(), passcode.get_length());
cipher.setIV(dataOut.get_ptr(), ivSize);
uint_fast16_t buffLen = 0;
auto encryptBuffer = dataOut.get_ptr(ivSize, buffLen);
cipher.encrypt(encryptBuffer, (const uint8_t *)data.c_str(), data.length());
auto tagBuffer = dataOut.get_ptr(ivSize + data.length(), buffLen);
cipher.computeTag(tagBuffer, buffLen);
return dataOut;
}
void InitializeWifi()
{
delay(1);
WiFi.mode(WIFI_STA);
WiFi.begin();
auto ret = WiFi.waitForConnectResult();
if (ret != WL_CONNECTED)
{
utils::debug_print("Could not connect to Wifi");
auto setup = setup_server();
std::string ssid = std::string();
std::string password = std::string();
setup.get_connection(ssid, password);
}
utils::debug_print("Wifi Connected: " + WiFi.SSID());
}
void DeriveKey()
{
BLAKE2s hash = BLAKE2s();
hash.reset();
hash.update(DERIVATION_SALT, strlen(DERIVATION_SALT));
hash.update(settings.passcode.c_str(), settings.passcode.length());
hash.finalize(passcode.get_ptr(), passcode.get_length());
utils::debug_print(passcode.get_base64());
}