Finish socket operations
This commit is contained in:
parent
9b49c3565d
commit
4c23565b9c
@ -31,9 +31,6 @@ struct EthernetConfiguration {
|
||||
// The IP address of the DNS server, if DHCP fails
|
||||
uint8_t manualDnsAddress[4];
|
||||
|
||||
uint32_t socketHeartbeatIntervalMs;
|
||||
uint32_t socketHeartbeatTimeoutMs;
|
||||
uint8_t socketHeartbeatFailureReconnectCount;
|
||||
};
|
||||
|
||||
struct KeyConfiguration {
|
||||
@ -88,23 +85,11 @@ private:
|
||||
currentChallengeExpiry = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an error Response over the web socket.
|
||||
*
|
||||
* @param result The error result to send
|
||||
* @param discardMessage Indicate if the stored message should be cleared.
|
||||
*
|
||||
* Note: Only clear the message if no other operation is in progress.
|
||||
*/
|
||||
void sendErrorResponseToServer(MessageResult result, bool discardMessage = true);
|
||||
|
||||
void ensureWebSocketConnection();
|
||||
// MARK: Local client callbacks
|
||||
|
||||
void handleLocalMessage(AsyncWebServerRequest *request);
|
||||
|
||||
bool convertHexMessageToBinary(const char* str);
|
||||
|
||||
void handleServerMessage(uint8_t* payload, size_t length);
|
||||
// MARK: Socket Callbacks
|
||||
|
||||
/**
|
||||
* @brief Callback to send an error back to the server via the web socket.
|
||||
@ -115,13 +100,60 @@ private:
|
||||
*/
|
||||
void sendServerError(MessageResult event);
|
||||
|
||||
void processMessage(SignedMessage* message);
|
||||
MessageResult verifyAndProcessReceivedMessage(SignedMessage* message);
|
||||
void handleServerMessage(uint8_t* payload, size_t length);
|
||||
|
||||
// MARK: Message processing
|
||||
|
||||
/**
|
||||
* @brief Process a received message (local or socket).
|
||||
*
|
||||
* @param message The message to process.
|
||||
*
|
||||
* Note: Prepares the response in the outgoing message buffer.
|
||||
*/
|
||||
void processMessage(SignedMessage* message);
|
||||
|
||||
/**
|
||||
* @brief Prepare a server challenge for a local or socket message.
|
||||
*
|
||||
* @param message The message to respond to
|
||||
*
|
||||
* Note: Prepares the response in the outgoing message buffer.
|
||||
*/
|
||||
void prepareChallenge(Message* message);
|
||||
|
||||
/**
|
||||
* @brief Complete an unlock request for a local or socket message.
|
||||
*
|
||||
* @param message The message to respond to
|
||||
*
|
||||
* Note: Prepares the response in the outgoing message buffer.
|
||||
*/
|
||||
void completeUnlockRequest(Message* message);
|
||||
|
||||
// MARK: Responses
|
||||
|
||||
/**
|
||||
* @brief Prepare the outgoing message buffer for both socket and local responses.
|
||||
*
|
||||
* @param event The resulting state to transmit
|
||||
* @param message An optional message to echo
|
||||
*/
|
||||
void prepareResponseBuffer(MessageResult event, Message* message = NULL);
|
||||
|
||||
/**
|
||||
* @brief Send the prepared outgoing message to a locally connected client
|
||||
*
|
||||
* @param request The original request of the client
|
||||
*/
|
||||
void sendPreparedLocalResponse(AsyncWebServerRequest *request);
|
||||
|
||||
/**
|
||||
* @brief Send the prepared outgoing message to the server
|
||||
*/
|
||||
void sendPreparedResponseToServer();
|
||||
|
||||
void prepareChallenge(Message* message);
|
||||
void completeUnlockRequest(Message* message);
|
||||
// MARK: Helper
|
||||
|
||||
bool convertHexMessageToBinary(const char* str);
|
||||
};
|
@ -28,6 +28,10 @@ struct ServerConfiguration {
|
||||
|
||||
uint32_t reconnectTime;
|
||||
|
||||
uint32_t socketHeartbeatIntervalMs;
|
||||
uint32_t socketHeartbeatTimeoutMs;
|
||||
uint8_t socketHeartbeatFailureReconnectCount;
|
||||
|
||||
};
|
||||
|
||||
class ServerConnectionCallbacks {
|
||||
@ -51,11 +55,13 @@ public:
|
||||
*/
|
||||
void configure(ServerConfiguration configuration, ServerConnectionCallbacks* callbacks);
|
||||
|
||||
void connect();
|
||||
|
||||
void disconnect();
|
||||
|
||||
void loop();
|
||||
/**
|
||||
* @brief Call this function regularly to handle socket operations.
|
||||
*
|
||||
* Connecting and disconnecting is done automatically.
|
||||
*
|
||||
*/
|
||||
void loop(uint32_t millis);
|
||||
|
||||
/**
|
||||
* @brief Send a response message over the socket
|
||||
@ -65,11 +71,24 @@ public:
|
||||
*/
|
||||
void sendResponse(uint8_t* buffer, uint16_t length);
|
||||
|
||||
bool isSocketConnected() {
|
||||
private:
|
||||
|
||||
uint32_t currentTime;
|
||||
|
||||
bool socketIsConnected() {
|
||||
return webSocket.isConnected();
|
||||
}
|
||||
|
||||
private:
|
||||
void connect();
|
||||
|
||||
void disconnect();
|
||||
|
||||
bool shouldReconnect = true;
|
||||
uint32_t nextReconnectAttemptMs = 0;
|
||||
|
||||
void didDisconnect();
|
||||
void didConnect();
|
||||
|
||||
|
||||
ServerConfiguration configuration;
|
||||
|
||||
|
@ -20,3 +20,4 @@ lib_deps =
|
||||
https://github.com/christophhagen/arduinoWebSockets#master
|
||||
|
||||
monitor_speed = 115200
|
||||
build_flags= -D WEBSOCKETS_NETWORK_TYPE=NETWORK_W5100
|
@ -62,10 +62,8 @@ void SesameController::configure(ServoConfiguration servoConfig, ServerConfigura
|
||||
|
||||
void SesameController::loop(uint32_t millis) {
|
||||
currentTime = millis;
|
||||
server.loop();
|
||||
server.loop(millis);
|
||||
servo.loop(millis);
|
||||
|
||||
ensureWebSocketConnection();
|
||||
}
|
||||
|
||||
// MARK: Local
|
||||
@ -199,20 +197,6 @@ void SesameController::prepareResponseBuffer(MessageResult result, Message* mess
|
||||
}
|
||||
}
|
||||
|
||||
void SesameController::ensureWebSocketConnection() {
|
||||
/*
|
||||
if (isReconnecting && WiFi.status() == WL_CONNECTED) {
|
||||
isReconnecting = false;
|
||||
Serial.print("WiFi IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
server.connect();
|
||||
timeCheck.startNTP();
|
||||
timeCheck.printLocalTime();
|
||||
localWebServer.begin();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// MARK: Helper
|
||||
|
||||
/**
|
||||
|
15
src/main.cpp
15
src/main.cpp
@ -4,6 +4,15 @@
|
||||
*
|
||||
* The code for a simple door unlock mechanism where a servo pushes on an existing
|
||||
* physical button.
|
||||
*
|
||||
* On compile error:
|
||||
*
|
||||
* In <Server.h>
|
||||
*
|
||||
* change:
|
||||
* virtual void begin(uint16_t port=0) =0;
|
||||
* to:
|
||||
* virtual void begin() =0;
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
|
||||
@ -35,6 +44,9 @@ void setup() {
|
||||
.path = serverPath,
|
||||
.key = serverAccessKey,
|
||||
.reconnectTime = 5000,
|
||||
.socketHeartbeatIntervalMs = socketHeartbeatIntervalMs,
|
||||
.socketHeartbeatTimeoutMs = socketHeartbeatTimeoutMs,
|
||||
.socketHeartbeatFailureReconnectCount = socketHeartbeatFailureReconnectCount,
|
||||
};
|
||||
|
||||
EthernetConfiguration ethernetConfig {
|
||||
@ -47,9 +59,6 @@ void setup() {
|
||||
.dhcpLeaseResponseTimeoutMs = dhcpLeaseResponseTimeoutMs,
|
||||
.manualIp = manualIpAddress,
|
||||
.manualDnsAddress = manualDnsServerAddress,
|
||||
.socketHeartbeatIntervalMs = socketHeartbeatIntervalMs,
|
||||
.socketHeartbeatTimeoutMs = socketHeartbeatTimeoutMs,
|
||||
.socketHeartbeatFailureReconnectCount = socketHeartbeatFailureReconnectCount,
|
||||
};
|
||||
|
||||
KeyConfiguration keyConfig {
|
||||
|
@ -20,7 +20,8 @@ void ServerConnection::connect() {
|
||||
return;
|
||||
}
|
||||
|
||||
webSocket.beginSSL(configuration.url, configuration.port, configuration.path);
|
||||
webSocket.begin(configuration.url, configuration.port, configuration.path);
|
||||
webSocket.setAuthorization(configuration.key);
|
||||
|
||||
std::function<void(WStype_t, uint8_t *, size_t)> f = [this](WStype_t type, uint8_t *payload, size_t length) {
|
||||
this->webSocketEventHandler(type, payload, length);
|
||||
@ -29,23 +30,41 @@ void ServerConnection::connect() {
|
||||
webSocket.setReconnectInterval(configuration.reconnectTime);
|
||||
}
|
||||
|
||||
void ServerConnection::didDisconnect() {
|
||||
if (shouldReconnect) {
|
||||
return; // Disconnect already registered.
|
||||
}
|
||||
Serial.println("[INFO] Socket disconnected");
|
||||
nextReconnectAttemptMs = currentTime + configuration.socketHeartbeatIntervalMs;
|
||||
shouldReconnect = true;
|
||||
}
|
||||
|
||||
void ServerConnection::didConnect() {
|
||||
Serial.println("[INFO] Socket connected");
|
||||
webSocket.sendTXT(configuration.key);
|
||||
webSocket.enableHeartbeat(configuration.socketHeartbeatIntervalMs, configuration.socketHeartbeatTimeoutMs, configuration.socketHeartbeatFailureReconnectCount);
|
||||
}
|
||||
|
||||
void ServerConnection::disconnect() {
|
||||
webSocket.disconnect();
|
||||
}
|
||||
|
||||
void ServerConnection::loop() {
|
||||
void ServerConnection::loop(uint32_t millis) {
|
||||
currentTime = millis;
|
||||
webSocket.loop();
|
||||
if (shouldReconnect) {
|
||||
shouldReconnect = false;
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConnection::webSocketEventHandler(WStype_t type, uint8_t * payload, size_t length) {
|
||||
switch(type) {
|
||||
case WStype_DISCONNECTED:
|
||||
Serial.println("[INFO] Socket disconnected.");
|
||||
didDisconnect();
|
||||
break;
|
||||
case WStype_CONNECTED:
|
||||
webSocket.sendTXT(configuration.key);
|
||||
Serial.printf("[INFO] Socket connected to url: %s\n", payload);
|
||||
webSocket.enableHeartbeat(pingInterval, pongTimeout, disconnectTimeoutCount);
|
||||
didConnect();
|
||||
break;
|
||||
case WStype_TEXT:
|
||||
controller->sendServerError(MessageResult::TextReceived);
|
||||
@ -67,5 +86,7 @@ switch(type) {
|
||||
}
|
||||
|
||||
void ServerConnection::sendResponse(uint8_t* buffer, uint16_t length) {
|
||||
webSocket.sendBIN(buffer, length);
|
||||
if (socketIsConnected()) {
|
||||
webSocket.sendBIN(buffer, length);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user