various fixes, improvements, documentation
This commit is contained in:
parent
300ca56d3b
commit
3818e5b6c3
4 changed files with 179 additions and 55 deletions
131
src/main.cpp
131
src/main.cpp
|
@ -1,20 +1,11 @@
|
|||
#define LED_COUNT 10
|
||||
#define LED_BRIGHTNESS 100
|
||||
#define LED_PIN 12
|
||||
#include <config.h>
|
||||
|
||||
#define WIFI_SSID ""
|
||||
#define WIFI_PASS ""
|
||||
|
||||
#define OBS_HOST ""
|
||||
#define OBS_PORT 4444
|
||||
//#define OBS_PASS ""
|
||||
|
||||
#define OBS_SOURCE "ATEM"
|
||||
static_assert(sizeof(WIFI_SSID) > 1, "WIFI_SSID is empty");
|
||||
static_assert(sizeof(OBS_HOST) > 1, "OBS_HOST is empty");
|
||||
static_assert(sizeof(OBS_SOURCE) > 1, "OBS_SOURCE is empty");
|
||||
|
||||
#define FASTLED_ESP8266_RAW_PIN_ORDER
|
||||
|
||||
// END CONFIGURATION
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Hash.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
|
@ -27,6 +18,8 @@ CRGB leds[LED_COUNT];
|
|||
WebSocketsClient webSocket;
|
||||
|
||||
#ifdef OBS_PASS
|
||||
static_assert(sizeof(OBS_PASS) > 1, "OBS_PASS must be non-empty if defined");
|
||||
|
||||
#include <SHA256.h>
|
||||
#define HASH_SIZE 32
|
||||
|
||||
|
@ -35,6 +28,7 @@ SHA256 sha256;
|
|||
|
||||
bool is_currently_live = false;
|
||||
bool is_currently_preview = false;
|
||||
bool is_currently_connected = false;
|
||||
|
||||
void set_program() {
|
||||
Serial.println("[Tally] PROGRAM");
|
||||
|
@ -73,23 +67,19 @@ void handleWebSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
|||
We can't set the LEDs to "error", because if someone
|
||||
quits OBS, we will get disconnected.
|
||||
*/
|
||||
is_currently_connected = false;
|
||||
break;
|
||||
|
||||
case WStype_CONNECTED:
|
||||
Serial.printf("[WS] connected to %s\n", payload);
|
||||
#ifdef OBS_PASS
|
||||
// Find out if we need authentication
|
||||
webSocket.sendTXT("{\"request-type\":\"GetAuthRequired\",\"message-id\":\"1\"}");
|
||||
#else
|
||||
webSocket.sendTXT("{\"request-type\":\"GetCurrentScene\",\"message-id\":\"3\"}");
|
||||
webSocket.sendTXT("{\"request-type\":\"GetPreviewScene\",\"message-id\":\"4\"}");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case WStype_TEXT: {
|
||||
Serial.printf("[WS] %s\n", payload);
|
||||
|
||||
StaticJsonDocument<5000> doc;
|
||||
StaticJsonDocument<10000> doc;
|
||||
DeserializationError error = deserializeJson(doc, payload);
|
||||
|
||||
if (error) {
|
||||
|
@ -98,59 +88,77 @@ void handleWebSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef OBS_PASS
|
||||
if (doc.containsKey("authRequired")) {
|
||||
Serial.println("[OBS] auth requested");
|
||||
if (doc["authRequired"]) {
|
||||
#ifdef OBS_PASS
|
||||
Serial.println("[OBS] auth requested");
|
||||
|
||||
sha256.reset();
|
||||
sha256.update(OBS_PASS, strlen(OBS_PASS));
|
||||
const char* salt = doc["salt"];
|
||||
sha256.update(salt, strlen(salt));
|
||||
char value[HASH_SIZE];
|
||||
sha256.finalize(value, HASH_SIZE);
|
||||
sha256.reset();
|
||||
sha256.update(OBS_PASS, strlen(OBS_PASS));
|
||||
const char* salt = doc["salt"];
|
||||
sha256.update(salt, strlen(salt));
|
||||
char value[HASH_SIZE];
|
||||
sha256.finalize(value, HASH_SIZE);
|
||||
|
||||
Serial.print("[OBS] sha256 authentication hash is: ");
|
||||
for (size_t i = 0; i < HASH_SIZE; i++) {
|
||||
Serial.print(static_cast<unsigned int>(value[i]), HEX);
|
||||
Serial.print("[OBS] sha256 authentication hash is: ");
|
||||
for (size_t i = 0; i < HASH_SIZE; i++) {
|
||||
Serial.print(static_cast<unsigned int>(value[i]), HEX);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
int encodedLength = Base64.encodedLength(HASH_SIZE);
|
||||
char encodedPassSaltHash[encodedLength];
|
||||
Base64.encode(encodedPassSaltHash, value, HASH_SIZE);
|
||||
|
||||
const char* challenge = doc["challenge"];
|
||||
sha256.reset();
|
||||
sha256.update(encodedPassSaltHash, encodedLength);
|
||||
sha256.update(challenge, strlen(challenge));
|
||||
sha256.finalize(value, HASH_SIZE);
|
||||
|
||||
Serial.print("[OBS] sha256 challenge hash is: ");
|
||||
for (size_t i = 0; i < HASH_SIZE; i++) {
|
||||
Serial.print(static_cast<unsigned int>(value[i]), HEX);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
char encodedAuthString[encodedLength];
|
||||
Base64.encode(encodedAuthString, value, HASH_SIZE);
|
||||
|
||||
String authRequest = String("{\"request-type\":\"Authenticate\",\"message-id\":\"2\",\"auth\":\"") + encodedAuthString + "\"}";
|
||||
webSocket.sendTXT(authRequest);
|
||||
#else
|
||||
Serial.println("[OBS] auth requested, but not configured!");
|
||||
set_error();
|
||||
delay(10000);
|
||||
ESP.restart();
|
||||
#endif
|
||||
} else {
|
||||
#ifdef OBS_PASS
|
||||
Serial.println("[OBS] auth configured, but not needed");
|
||||
#endif
|
||||
webSocket.sendTXT("{\"request-type\":\"GetCurrentScene\",\"message-id\":\"3\"}");
|
||||
webSocket.sendTXT("{\"request-type\":\"GetPreviewScene\",\"message-id\":\"4\"}");
|
||||
is_currently_connected = true;
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
int encodedLength = Base64.encodedLength(HASH_SIZE);
|
||||
char encodedPassSaltHash[encodedLength];
|
||||
Base64.encode(encodedPassSaltHash, value, HASH_SIZE);
|
||||
|
||||
const char* challenge = doc["challenge"];
|
||||
sha256.reset();
|
||||
sha256.update(encodedPassSaltHash, encodedLength);
|
||||
sha256.update(challenge, strlen(challenge));
|
||||
sha256.finalize(value, HASH_SIZE);
|
||||
|
||||
Serial.print("[OBS] sha256 challenge hash is: ");
|
||||
for (size_t i = 0; i < HASH_SIZE; i++) {
|
||||
Serial.print(static_cast<unsigned int>(value[i]), HEX);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
char encodedAuthString[encodedLength];
|
||||
Base64.encode(encodedAuthString, value, HASH_SIZE);
|
||||
|
||||
String authRequest = String("{\"request-type\":\"Authenticate\",\"message-id\":\"2\",\"auth\":\"") + encodedAuthString + "\"}";
|
||||
webSocket.sendTXT(authRequest);
|
||||
break;
|
||||
|
||||
#ifdef OBS_PASS
|
||||
} else if (doc.containsKey("message-id") && doc["message-id"] == "2") {
|
||||
if (strcmp(doc["status"], "ok") == 0) {
|
||||
Serial.println("[OBS] authentication successful");
|
||||
webSocket.sendTXT("{\"request-type\":\"GetCurrentScene\",\"message-id\":\"3\"}");
|
||||
webSocket.sendTXT("{\"request-type\":\"GetPreviewScene\",\"message-id\":\"4\"}");
|
||||
is_currently_connected = true;
|
||||
} else {
|
||||
Serial.println("[OBS] authentication FAILED");
|
||||
set_error();
|
||||
delay(10000);
|
||||
ESP.restart();
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (doc.containsKey("sources")) {
|
||||
} else if (doc.containsKey("sources")) {
|
||||
bool my_source_in_current_event = false;
|
||||
|
||||
for (uint8_t i = 0; i < doc["sources"].size(); i++) {
|
||||
|
@ -180,6 +188,7 @@ void handleWebSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
|||
Serial.println("[OBS] quit");
|
||||
is_currently_preview = false;
|
||||
is_currently_live = false;
|
||||
is_currently_connected = false;
|
||||
} else if (strcmp(doc["update-type"], "StudioModeSwitched") == 0 && !doc["new-state"]) {
|
||||
Serial.println("[OBS] studio mode disabled");
|
||||
is_currently_preview = false;
|
||||
|
@ -210,6 +219,14 @@ void handleWebSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
|
|||
case WStype_FRAGMENT_FIN:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef STATUS_LED
|
||||
if (is_currently_connected) {
|
||||
digitalWrite(STATUS_LED, LOW);
|
||||
} else {
|
||||
digitalWrite(STATUS_LED, HIGH);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void setup() {
|
||||
|
@ -220,6 +237,10 @@ void setup() {
|
|||
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, LED_COUNT);
|
||||
FastLED.setBrightness(LED_BRIGHTNESS);
|
||||
|
||||
#ifdef STATUS_LED
|
||||
pinMode(STATUS_LED, OUTPUT);
|
||||
#endif
|
||||
|
||||
set_error();
|
||||
delay(100);
|
||||
set_idle();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue