Compare commits

..

1 Commits

Author SHA1 Message Date
6cf15dc7b8 Changes for esp-idf 2021-05-31 19:33:08 +02:00
22 changed files with 236 additions and 878 deletions

View File

@ -36,13 +36,16 @@ jobs:
echo -en "::set-output name=matrix::"
echo -en "["
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Serial1,lvl=SSL,wipe=none,baud=115200
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80
echo -en ","
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.19 esp8266com:esp8266:generic:xtal=80,vt=flash,exception=disabled,stacksmash=disabled,ssl=all,mmu=3232,non32xfer=fast,ResetMethod=nodemcu,CrystalFreq=26,FlashFreq=80,FlashMode=qio,eesz=4M2M,led=2,sdk=nonosdk_190703,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.6.13 esp8266com:esp8266:generic:xtal=80,dbg=Serial1
echo -en ","
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.19 espressif:esp32:esp32:FlashFreq=80
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp8266 esp8266 1.8.13 esp8266com:esp8266:generic:xtal=80,eesz=1M,FlashMode=qio,FlashFreq=80
echo -en ","
get_sketches_json_matrix arduino $GITHUB_WORKSPACE/examples/esp32 esp32 1.8.13 espressif:esp32:esp32:FlashFreq=80
echo -en "]"
outputs:
@ -53,7 +56,7 @@ jobs:
strategy:
fail-fast: false
matrix:
IDE_VERSION: [1.8.19]
IDE_VERSION: [1.8.13, 1.6.13]
env:
IDE_VERSION: ${{ matrix.IDE_VERSION }}
@ -96,7 +99,7 @@ jobs:
get_core esp8266
- name: download esp32
if: steps.cache_all.outputs.cache-hit != 'true'
if: steps.cache_all.outputs.cache-hit != 'true' && matrix.IDE_VERSION != '1.6.13'
run: |
source $GITHUB_WORKSPACE/travis/common.sh
get_core esp32
@ -161,18 +164,15 @@ jobs:
- name: config IDE
run: |
set +x
export DISPLAY=:1.0
export PATH="$HOME/arduino_ide:$PATH"
arduino --board $BOARD --save-prefs
arduino --pref update.check=false --pref build.verbose=false --pref cache.enable=true --pref compiler.cache_core=true --pref compiler.warning_level=default --save-prefs
arduino --get-pref sketchbook.path
arduino --get-pref
arduino --pref update.check=false
- name: build example
timeout-minutes: 20
run: |
set -ex
export DISPLAY=:1.0
export PATH="$HOME/arduino_ide:$PATH"
source $GITHUB_WORKSPACE/travis/common.sh

47
CMakeLists.txt Normal file
View File

@ -0,0 +1,47 @@
set(headers
src/SocketIOclient.h
src/WebSockets.h
src/WebSockets4WebServer.h
src/WebSocketsClient.h
src/WebSocketsServer.h
src/WebSocketsVersion.h
src/libb64/cdecode_inc.h
src/libb64/cencode_inc.h
src/libsha1/libsha1.h
)
set(sources
src/SocketIOclient.cpp
src/WebSockets.cpp
src/WebSocketsClient.cpp
src/WebSocketsServer.cpp
src/libb64/cdecode.c
src/libb64/cencode.c
src/libsha1/libsha1.c
)
set(dependencies
)
idf_component_register(
INCLUDE_DIRS
src
SRCS
${headers}
${sources}
REQUIRES
${dependencies}
)
target_compile_options(${COMPONENT_TARGET}
PUBLIC
-DESP32
-DWEBSOCKETS_NETWORK_TYPE=NETWORK_ESP32
PRIVATE
-fstack-reuse=all
-fstack-protector-all
-Wno-unused-function
-Wno-deprecated-declarations
-Wno-missing-field-initializers
-Wno-parentheses
)

View File

@ -1,155 +0,0 @@
/*
* WebSocketClientSocketIOack.ino
*
* Created on: 20.07.2019
*
*/
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <WebSocketsClient.h>
#include <SocketIOclient.h>
WiFiMulti WiFiMulti;
SocketIOclient socketIO;
#define USE_SERIAL Serial
void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) {
switch(type) {
case sIOtype_DISCONNECT:
USE_SERIAL.printf("[IOc] Disconnected!\n");
break;
case sIOtype_CONNECT:
USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload);
// join default namespace (no auto join in Socket.IO V3)
socketIO.send(sIOtype_CONNECT, "/");
break;
case sIOtype_EVENT:
{
char * sptr = NULL;
int id = strtol((char *)payload, &sptr, 10);
USE_SERIAL.printf("[IOc] get event: %s id: %d\n", payload, id);
if(id) {
payload = (uint8_t *)sptr;
}
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, payload, length);
if(error) {
USE_SERIAL.print(F("deserializeJson() failed: "));
USE_SERIAL.println(error.c_str());
return;
}
String eventName = doc[0];
USE_SERIAL.printf("[IOc] event name: %s\n", eventName.c_str());
// Message Includes a ID for a ACK (callback)
if(id) {
// creat JSON message for Socket.IO (ack)
DynamicJsonDocument docOut(1024);
JsonArray array = docOut.to<JsonArray>();
// add payload (parameters) for the ack (callback function)
JsonObject param1 = array.createNestedObject();
param1["now"] = millis();
// JSON to String (serializion)
String output;
output += id;
serializeJson(docOut, output);
// Send event
socketIO.send(sIOtype_ACK, output);
}
}
break;
case sIOtype_ACK:
USE_SERIAL.printf("[IOc] get ack: %u\n", length);
break;
case sIOtype_ERROR:
USE_SERIAL.printf("[IOc] get error: %u\n", length);
break;
case sIOtype_BINARY_EVENT:
USE_SERIAL.printf("[IOc] get binary: %u\n", length);
break;
case sIOtype_BINARY_ACK:
USE_SERIAL.printf("[IOc] get binary ack: %u\n", length);
break;
}
}
void setup() {
//USE_SERIAL.begin(921600);
USE_SERIAL.begin(115200);
//Serial.setDebugOutput(true);
USE_SERIAL.setDebugOutput(true);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
WiFiMulti.addAP("SSID", "passpasspass");
//WiFi.disconnect();
while(WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
String ip = WiFi.localIP().toString();
USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str());
// server address, port and URL
socketIO.begin("10.11.100.100", 8880, "/socket.io/?EIO=4");
// event handler
socketIO.onEvent(socketIOEvent);
}
unsigned long messageTimestamp = 0;
void loop() {
socketIO.loop();
uint64_t now = millis();
if(now - messageTimestamp > 2000) {
messageTimestamp = now;
// creat JSON message for Socket.IO (event)
DynamicJsonDocument doc(1024);
JsonArray array = doc.to<JsonArray>();
// add evnet name
// Hint: socket.on('event_name', ....
array.add("event_name");
// add payload (parameters) for the event
JsonObject param1 = array.createNestedObject();
param1["now"] = (uint32_t) now;
// JSON to String (serializion)
String output;
serializeJson(doc, output);
// Send event
socketIO.sendEVENT(output);
// Print JSON for debugging
USE_SERIAL.println(output);
}
}

View File

@ -1,27 +0,0 @@
## Minimal example of WebsocketClientOTA and Python server
Take this as small example, how achieve OTA update on ESP8266 and ESP32.
Python server was wrote from train so take it only as bare example.
It's working, but it's not mean to run in production.
### Usage:
Start server:
```bash
cd python_ota_server
python3 -m venv .venv
source .venv/bin/activate
pip3 install -r requirements.txt
python3 main.py
```
Flash ESP with example sketch and start it.
Change version inside example sketch to higher and compile it and save it to bin file.
Rename it to `mydevice-1.0.1-esp8266.bin` and place it inside new folder firmware (server create it).
When the ESP connect to server, it check if version flashed is equal to fw in firmware folder. If higher FW version is present,
start the flash process.

View File

@ -1,263 +0,0 @@
/*
* WebSocketClientOTA.ino
*
* Created on: 25.10.2021
*
*/
#include <Arduino.h>
#include <ArduinoJson.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <Updater.h>
#endif
#ifdef ESP32
#include "WiFi.h"
#include "ESPmDNS.h"
#include <Update.h>
#endif
#include <WiFiUdp.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsClient.h>
#include <Hash.h>
ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
#define USE_SERIAL Serial
// Variables:
// Settable:
const char *version = "1.0.0";
const char *name = "mydevice";
// Others:
#ifdef ESP8266
const char *chip = "esp8266";
#endif
#ifdef ESP32
const char *chip = "esp32";
#endif
uint32_t maxSketchSpace = 0;
int SketchSize = 0;
bool ws_conn = false;
String IpAddress2String(const IPAddress& ipAddress)
{
return String(ipAddress[0]) + String(".") +
String(ipAddress[1]) + String(".") +
String(ipAddress[2]) + String(".") +
String(ipAddress[3]);
}
void greetings_(){
StaticJsonDocument<200> doc;
doc["type"] = "greetings";
doc["mac"] = WiFi.macAddress();
doc["ip"] = IpAddress2String(WiFi.localIP());
doc["version"] = version;
doc["name"] = name;
doc["chip"] = chip;
char data[200];
serializeJson(doc, data);
webSocket.sendTXT(data);
}
void register_(){
StaticJsonDocument<200> doc;
doc["type"] = "register";
doc["mac"] = WiFi.macAddress();
char data[200];
serializeJson(doc, data);
webSocket.sendTXT(data);
ws_conn = true;
}
typedef void (*CALLBACK_FUNCTION)(JsonDocument &msg);
typedef struct {
char type[50];
CALLBACK_FUNCTION func;
} RESPONSES_STRUCT;
void OTA(JsonDocument &msg){
USE_SERIAL.print(F("[WSc] OTA mode: "));
const char* go = "go";
const char* ok = "ok";
if(strncmp( msg["value"], go, strlen(go)) == 0 ) {
USE_SERIAL.print(F("go\n"));
SketchSize = int(msg["size"]);
maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
USE_SERIAL.printf("[WSc] Max sketch size: %u\n", maxSketchSpace);
USE_SERIAL.printf("[WSc] Sketch size: %d\n", SketchSize);
USE_SERIAL.setDebugOutput(true);
if (!Update.begin(maxSketchSpace)) { //start with max available size
Update.printError(Serial);
ESP.restart();
}
} else if (strncmp( msg["value"], ok, strlen(ok)) == 0) {
USE_SERIAL.print(F("OK\n"));
register_();
} else {
USE_SERIAL.print(F("unknown value : "));
USE_SERIAL.print(msg["value"].as<char>());
USE_SERIAL.print(F("\n"));
}
}
void STATE(JsonDocument &msg){
// Do something with message
}
RESPONSES_STRUCT responses[] = {
{"ota", OTA},
{"state", STATE},
};
void text(uint8_t * payload, size_t length){
// Convert mesage to something usable
char msgch[length];
for (unsigned int i = 0; i < length; i++)
{
USE_SERIAL.print((char)payload[i]);
msgch[i] = ((char)payload[i]);
}
msgch[length] = '\0';
// Parse Json
StaticJsonDocument<200> doc_in;
DeserializationError error = deserializeJson(doc_in, msgch);
if (error) {
USE_SERIAL.print(F("deserializeJson() failed: "));
USE_SERIAL.println(error.c_str());
return;
}
// Handle each TYPE of message
int b = 0;
for( b=0 ; strlen(responses[b].type) ; b++ )
{
if( strncmp(doc_in["type"], responses[b].type, strlen(responses[b].type)) == 0 ) {
responses[b].func(doc_in);
}
}
}
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
switch(type) {
case WStype_DISCONNECTED:
USE_SERIAL.printf("[WSc] Disconnected!\n");
break;
case WStype_CONNECTED: {
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
// send message to server when Connected
// webSocket.sendTXT("Connected");
greetings_();
}
break;
case WStype_TEXT:
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
// send message to server
// webSocket.sendTXT("message here");
text(payload, length);
break;
case WStype_BIN:
USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
// hexdump(payload, length);
if (Update.write(payload, length) != length) {
Update.printError(Serial);
ESP.restart();
}
yield();
SketchSize -= length;
USE_SERIAL.printf("[WSc] Sketch size left: %u\n", SketchSize);
if (SketchSize < 1){
if (Update.end(true)) { //true to set the size to the current progress
USE_SERIAL.printf("Update Success: \nRebooting...\n");
delay(5);
yield();
ESP.restart();
} else {
Update.printError(USE_SERIAL);
ESP.restart();
}
USE_SERIAL.setDebugOutput(false);
}
// send data to server
// webSocket.sendBIN(payload, length);
break;
case WStype_PING:
// pong will be send automatically
USE_SERIAL.printf("[WSc] get ping\n");
break;
case WStype_PONG:
// answer to a ping we send
USE_SERIAL.printf("[WSc] get pong\n");
break;
}
}
void setup() {
// USE_SERIAL.begin(921600);
USE_SERIAL.begin(115200);
//Serial.setDebugOutput(true);
USE_SERIAL.setDebugOutput(true);
USE_SERIAL.print(F("\nMAC: "));
USE_SERIAL.println(WiFi.macAddress());
USE_SERIAL.print(F("\nDevice: "));
USE_SERIAL.println(name);
USE_SERIAL.printf("\nVersion: %s\n", version);
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
WiFiMulti.addAP("SSID", "PASS");
//WiFi.disconnect();
while(WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
// server address, port and URL
webSocket.begin("10.0.1.5", 8081, "/");
// event handler
webSocket.onEvent(webSocketEvent);
// use HTTP Basic Authorization this is optional remove if not needed
// webSocket.setAuthorization("USER", "PASS");
// try ever 5000 again if connection has failed
webSocket.setReconnectInterval(5000);
// start heartbeat (optional)
// ping server every 15000 ms
// expect pong from server within 3000 ms
// consider connection disconnected if pong is not received 2 times
webSocket.enableHeartbeat(15000, 3000, 2);
}
void loop() {
webSocket.loop();
}

View File

@ -1,235 +0,0 @@
"""Minimal example of Python websocket server
handling OTA updates for ESP32 amd ESP8266
Check and upload of firmware works.
Register and state function are jus for example.
"""
# pylint: disable=W0703,E1101
import asyncio
import copy
import json
import logging
import subprocess
import threading
import time
from os import listdir
from os.path import join as join_pth
from pathlib import Path
import websockets
from packaging import version
# Logger settings
logging.basicConfig(filename="ws_server.log")
Logger = logging.getLogger('WS-OTA')
Logger.addHandler(logging.StreamHandler())
Logger.setLevel(logging.INFO)
# Path to directory with FW
fw_path = join_pth(Path().absolute(), "firmware")
def create_path(path: str) -> None:
"""Check if path exist or create it"""
Path(path).mkdir(parents=True, exist_ok=True)
def shell(command):
"""Handle execution of shell commands"""
with subprocess.Popen(command, shell=True,
stdout=subprocess.PIPE,
universal_newlines=True
) as process:
for stdout_line in iter(process.stdout.readline, ""):
Logger.debug(stdout_line)
process.stdout.close()
return_code = process.wait()
Logger.debug("Shell returned: %s", return_code)
return process.returncode
return None
async def binary_send(websocket, fw_file):
"""Read firmware file, divide it to chunks and send them"""
with open(fw_file, "rb") as binaryfile:
while True:
chunk = binaryfile.read(2048)
if not chunk:
break
try:
await websocket.send(chunk)
except Exception as exception:
Logger.exception(exception)
return False
time.sleep(0.2)
def version_checker(name, vdev, vapp):
"""Parse and compare FW version"""
if version.parse(vdev) < version.parse(vapp):
Logger.info("Client(%s) version %s is smaller than %s: Go for update", name, vdev, vapp)
return True
Logger.info("Client(%s) version %s is greater or equal to %s: Not updating", name, vdev, vapp)
return False
class WsOtaHandler (threading.Thread):
"""Thread handling ota update
Runing ota directly from message would kill WS
as message bus would timeout.
"""
def __init__(self, name, message, websocket):
threading.Thread.__init__(self, daemon=True)
self.name = name
self.msg = message
self.websocket = websocket
def run(self, ):
try:
asyncio.run(self.start_)
except Exception as exception:
Logger.exception(exception)
finally:
pass
async def start_(self):
"""Start _ota se asyncio future"""
msg_task = asyncio.ensure_future(
self._ota())
done, pending = await asyncio.wait(
[msg_task],
return_when=asyncio.FIRST_COMPLETED,
)
Logger.info("WS Ota Handler done: %s", done)
for task in pending:
task.cancel()
async def _ota(self):
"""Check for new fw and update or pass"""
device_name = self.msg['name']
device_chip = self.msg['chip']
device_version = self.msg['version']
fw_version = ''
fw_name = ''
fw_device = ''
for filename in listdir(fw_path):
fw_info = filename.split("-")
fw_device = fw_info[0]
if fw_device == device_name:
fw_version = fw_info[1]
fw_name = filename
break
if not fw_version:
Logger.info("Client(%s): No fw found!", device_name)
msg = '{"type": "ota", "value":"ok"}'
await self.websocket.send(msg)
return
if not version_checker(device_name, device_version, fw_version):
return
fw_file = join_pth(fw_path, fw_name)
if device_chip == 'esp8266' and not fw_file.endswith('.gz'):
# We can compress fw to make it smaller for upload
fw_cpress = fw_file
fw_file = fw_cpress + ".gz"
cpress = f"gzip -9 {fw_cpress}"
cstate = shell(cpress)
if cstate:
Logger.error("Cannot compress firmware: %s", fw_name)
return
# Get size of fw
size = Path(fw_file).stat().st_size
# Request ota mode
msg = '{"type": "ota", "value":"go", "size":' + str(size) + '}'
await self.websocket.send(msg)
# send file by chunks trough websocket
await binary_send(self.websocket, fw_file)
async def _register(websocket, message):
mac = message.get('mac')
name = message.get('name')
Logger.info("Client(%s) mac: %s", name, mac)
# Some code
response = {'response_type': 'registry', 'state': 'ok'}
await websocket.send(json.dumps(response))
async def _state(websocket, message):
mac = message.get('mac')
name = message.get('name')
Logger.info("Client(%s) mac: %s", name, mac)
# Some code
response = {'response_type': 'state', 'state': 'ok'}
await websocket.send(json.dumps(response))
async def _unhandleld(websocket, msg):
Logger.info("Unhandled message from device: %s", str(msg))
response = {'response_type': 'response', 'state': 'nok'}
await websocket.send(json.dumps(response))
async def _greetings(websocket, message):
WsOtaHandler('thread_ota', copy.deepcopy(message), websocket).start()
async def message_received(websocket, message) -> None:
"""Handle incoming messages
Check if message contain json and run waned function
"""
switcher = {"greetings": _greetings,
"register": _register,
"state": _state
}
if message[0:1] == "{":
try:
msg_json = json.loads(message)
except Exception as exception:
Logger.error(exception)
return
type_ = msg_json.get('type')
name = msg_json.get('name')
func = switcher.get(type_, _unhandleld)
Logger.debug("Client(%s)said: %s", name, type_)
try:
await func(websocket, msg_json)
except Exception as exception:
Logger.error(exception)
# pylint: disable=W0613
async def ws_server(websocket, path) -> None:
"""Run in cycle and wait for new messages"""
async for message in websocket:
await message_received(websocket, message)
async def main():
"""Server starter
Normal user can bind only port nubers greater than 1024
"""
async with websockets.serve(ws_server, "10.0.1.5", 8081):
await asyncio.Future() # run forever
create_path(fw_path)
asyncio.run(main())

View File

@ -1,2 +0,0 @@
packaging
websockets

View File

@ -88,7 +88,7 @@ void setup() {
USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str());
// server address, port and URL
socketIO.begin("10.11.100.100", 8880, "/socket.io/?EIO=4");
socketIO.begin("10.11.100.100", 8880);
// event handler
socketIO.onEvent(socketIOEvent);
@ -106,7 +106,7 @@ void loop() {
// creat JSON message for Socket.IO (event)
DynamicJsonDocument doc(1024);
JsonArray array = doc.to<JsonArray>();
// add evnet name
// Hint: socket.on('event_name', ....
array.add("event_name");
@ -119,7 +119,7 @@ void loop() {
String output;
serializeJson(doc, output);
// Send event
// Send event
socketIO.sendEVENT(output);
// Print JSON for debugging

View File

@ -49,7 +49,7 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length)
USE_SERIAL.println(error.c_str());
return;
}
String eventName = doc[0];
USE_SERIAL.printf("[IOc] event name: %s\n", eventName.c_str());
@ -58,7 +58,7 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length)
// creat JSON message for Socket.IO (ack)
DynamicJsonDocument docOut(1024);
JsonArray array = docOut.to<JsonArray>();
// add payload (parameters) for the ack (callback function)
JsonObject param1 = array.createNestedObject();
param1["now"] = millis();
@ -68,7 +68,7 @@ void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length)
output += id;
serializeJson(docOut, output);
// Send event
// Send event
socketIO.send(sIOtype_ACK, output);
}
}
@ -125,7 +125,7 @@ void setup() {
USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str());
// server address, port and URL
socketIO.begin("10.11.100.100", 8880, "/socket.io/?EIO=4");
socketIO.begin("10.11.100.100", 8880);
// event handler
socketIO.onEvent(socketIOEvent);
@ -143,7 +143,7 @@ void loop() {
// creat JSON message for Socket.IO (event)
DynamicJsonDocument doc(1024);
JsonArray array = doc.to<JsonArray>();
// add evnet name
// Hint: socket.on('event_name', ....
array.add("event_name");
@ -156,7 +156,7 @@ void loop() {
String output;
serializeJson(doc, output);
// Send event
// Send event
socketIO.sendEVENT(output);
// Print JSON for debugging

View File

@ -21,5 +21,5 @@
"type": "git",
"url": "https://github.com/Links2004/arduinoWebSockets.git"
},
"version": "2.3.7"
"version": "2.3.6"
}

View File

@ -1,5 +1,5 @@
name=WebSockets
version=2.3.7
version=2.3.6
author=Markus Sattler
maintainer=Markus Sattler
sentence=WebSockets for Arduino (Server + Client)

View File

@ -5,9 +5,12 @@
* Author: links
*/
#include "SocketIOclient.h"
#include <string>
#include "WebSockets.h"
#include "WebSocketsClient.h"
#include "SocketIOclient.h"
SocketIOclient::SocketIOclient() {
}
@ -21,7 +24,7 @@ void SocketIOclient::begin(const char * host, uint16_t port, const char * url, c
initClient();
}
void SocketIOclient::begin(String host, uint16_t port, String url, String protocol) {
void SocketIOclient::begin(std::string host, uint16_t port, std::string url, std::string protocol) {
WebSocketsClient::beginSocketIO(host, port, url, protocol);
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
initClient();
@ -33,7 +36,7 @@ void SocketIOclient::beginSSL(const char * host, uint16_t port, const char * url
initClient();
}
void SocketIOclient::beginSSL(String host, uint16_t port, String url, String protocol) {
void SocketIOclient::beginSSL(std::string host, uint16_t port, std::string url, std::string protocol) {
WebSocketsClient::beginSocketIOSSL(host, port, url, protocol);
WebSocketsClient::enableHeartbeat(60 * 1000, 90 * 1000, 5);
initClient();
@ -85,14 +88,6 @@ bool SocketIOclient::isConnected(void) {
return WebSocketsClient::isConnected();
}
void SocketIOclient::setExtraHeaders(const char * extraHeaders) {
return WebSocketsClient::setExtraHeaders(extraHeaders);
}
void SocketIOclient::setReconnectInterval(unsigned long time) {
return WebSocketsClient::setReconnectInterval(time);
}
/**
* send text data to client
* @param num uint8_t client id
@ -139,7 +134,7 @@ bool SocketIOclient::send(socketIOmessageType_t type, const char * payload, size
return send(type, (uint8_t *)payload, length);
}
bool SocketIOclient::send(socketIOmessageType_t type, String & payload) {
bool SocketIOclient::send(socketIOmessageType_t type, std::string & payload) {
return send(type, (uint8_t *)payload.c_str(), payload.length());
}
@ -167,7 +162,7 @@ bool SocketIOclient::sendEVENT(const char * payload, size_t length) {
return sendEVENT((uint8_t *)payload, length);
}
bool SocketIOclient::sendEVENT(String & payload) {
bool SocketIOclient::sendEVENT(std::string & payload) {
return sendEVENT((uint8_t *)payload.c_str(), payload.length());
}

View File

@ -8,8 +8,9 @@
#ifndef SOCKETIOCLIENT_H_
#define SOCKETIOCLIENT_H_
#include <string>
#include "WebSockets.h"
#include "WebSocketsClient.h"
#define EIO_HEARTBEAT_INTERVAL 20000
@ -48,11 +49,11 @@ class SocketIOclient : protected WebSocketsClient {
virtual ~SocketIOclient(void);
void begin(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
void begin(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
void begin(std::string host, uint16_t port, std::string url = "/socket.io/?EIO=3", std::string protocol = "arduino");
#ifdef HAS_SSL
void beginSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
void beginSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
void beginSSL(std::string host, uint16_t port, std::string url = "/socket.io/?EIO=3", std::string protocol = "arduino");
#ifndef SSL_AXTLS
void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino");
void beginSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino");
@ -68,16 +69,13 @@ class SocketIOclient : protected WebSocketsClient {
bool sendEVENT(const uint8_t * payload, size_t length = 0);
bool sendEVENT(char * payload, size_t length = 0, bool headerToPayload = false);
bool sendEVENT(const char * payload, size_t length = 0);
bool sendEVENT(String & payload);
bool sendEVENT(std::string & payload);
bool send(socketIOmessageType_t type, uint8_t * payload, size_t length = 0, bool headerToPayload = false);
bool send(socketIOmessageType_t type, const uint8_t * payload, size_t length = 0);
bool send(socketIOmessageType_t type, char * payload, size_t length = 0, bool headerToPayload = false);
bool send(socketIOmessageType_t type, const char * payload, size_t length = 0);
bool send(socketIOmessageType_t type, String & payload);
void setExtraHeaders(const char * extraHeaders = NULL);
void setReconnectInterval(unsigned long time);
bool send(socketIOmessageType_t type, std::string & payload);
void loop(void);

View File

@ -24,6 +24,8 @@
#include "WebSockets.h"
#include <string>
#ifdef ESP8266
#include <core_esp8266_features.h>
#endif
@ -42,11 +44,7 @@ extern "C" {
#include <esp_system.h>
#if ESP_IDF_VERSION_MAJOR >= 4
#if(ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(1, 0, 6))
#include "sha/sha_parallel_engine.h"
#else
#include <esp32/sha.h>
#endif
#else
#include <hwcrypto/sha.h>
#endif
@ -472,7 +470,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t
payload[header->payloadLen] = 0x00;
if(header->mask) {
// decode XOR
//decode XOR
for(size_t i = 0; i < header->payloadLen; i++) {
payload[i] = (payload[i] ^ header->maskKey[i % 4]);
}
@ -526,7 +524,7 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t
// reset input
client->cWsRXsize = 0;
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
// register callback for next message
//register callback for next message
handleWebsocketWaitFor(client, 2);
#endif
@ -539,15 +537,15 @@ void WebSockets::handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t
/**
* generate the key for Sec-WebSocket-Accept
* @param clientKey String
* @return String Accept Key
* @param clientKey std::string
* @return std::string Accept Key
*/
String WebSockets::acceptKey(String & clientKey) {
std::string WebSockets::acceptKey(std::string & clientKey) {
uint8_t sha1HashBin[20] = { 0 };
#ifdef ESP8266
sha1(clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", &sha1HashBin[0]);
#elif defined(ESP32)
String data = clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
std::string data = clientKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
esp_sha(SHA1, (unsigned char *)data.c_str(), data.length(), &sha1HashBin[0]);
#else
clientKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@ -557,7 +555,7 @@ String WebSockets::acceptKey(String & clientKey) {
SHA1Final(&sha1HashBin[0], &ctx);
#endif
String key = base64_encode(sha1HashBin, 20);
std::string key = base64_encode(sha1HashBin, 20);
key.trim();
return key;
@ -567,9 +565,9 @@ String WebSockets::acceptKey(String & clientKey) {
* base64_encode
* @param data uint8_t *
* @param length size_t
* @return base64 encoded String
* @return base64 encoded std::string
*/
String WebSockets::base64_encode(uint8_t * data, size_t length) {
std::string WebSockets::base64_encode(uint8_t * data, size_t length) {
size_t size = ((length * 1.6f) + 1);
char * buffer = (char *)malloc(size);
if(buffer) {
@ -578,11 +576,11 @@ String WebSockets::base64_encode(uint8_t * data, size_t length) {
int len = base64_encode_block((const char *)&data[0], length, &buffer[0], &_state);
len = base64_encode_blockend((buffer + len), &_state);
String base64 = String(buffer);
std::string base64 = std::string(buffer);
free(buffer);
return base64;
}
return String("-FAIL-");
return std::string("-FAIL-");
}
/**
@ -644,9 +642,9 @@ bool WebSockets::readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWait
t = millis();
out += len;
n -= len;
// DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n);
//DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n);
} else {
// DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n);
//DEBUG_WEBSOCKETS("Receive %d left %d!\n", len, n);
}
if(n > 0) {
WEBSOCKETS_YIELD();
@ -698,7 +696,7 @@ size_t WebSockets::write(WSclient_t * client, uint8_t * out, size_t n) {
out += len;
n -= len;
total += len;
// DEBUG_WEBSOCKETS("write %d left %d!\n", len, n);
//DEBUG_WEBSOCKETS("write %d left %d!\n", len, n);
} else {
DEBUG_WEBSOCKETS("WS write %d failed left %d!\n", len, n);
}

View File

@ -25,12 +25,14 @@
#ifndef WEBSOCKETS_H_
#define WEBSOCKETS_H_
#include <string>
#ifdef STM32_DEVICE
#include <application.h>
#define bit(b) (1UL << (b)) // Taken directly from Arduino.h
#else
#include <Arduino.h>
#include <IPAddress.h>
//#include <Arduino.h>
//#include <IPAddress.h>
#endif
#ifdef ARDUINO_ARCH_AVR
@ -86,7 +88,7 @@
#define WEBSOCKETS_YIELD_MORE()
#else
// atmega328p has only 2KB ram!
//atmega328p has only 2KB ram!
#define WEBSOCKETS_MAX_DATA_SIZE (1024)
// moves all Header strings to Flash
#define WEBSOCKETS_SAVE_RAM
@ -186,8 +188,8 @@
#elif(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP32)
#include <WiFi.h>
#include <WiFiClientSecure.h>
//#include <WiFi.h>
//#include <WiFiClientSecure.h>
#define SSL_AXTLS
#define WEBSOCKETS_NETWORK_CLASS WiFiClient
#define WEBSOCKETS_NETWORK_SSL_CLASS WiFiClientSecure
@ -284,28 +286,28 @@ typedef struct {
WEBSOCKETS_NETWORK_SSL_CLASS * ssl;
#endif
String cUrl; ///< http url
std::string cUrl; ///< http url
uint16_t cCode = 0; ///< http code
bool cIsClient = false; ///< will be used for masking
bool cIsUpgrade = false; ///< Connection == Upgrade
bool cIsWebsocket = false; ///< Upgrade == websocket
String cSessionId; ///< client Set-Cookie (session id)
String cKey; ///< client Sec-WebSocket-Key
String cAccept; ///< client Sec-WebSocket-Accept
String cProtocol; ///< client Sec-WebSocket-Protocol
String cExtensions; ///< client Sec-WebSocket-Extensions
std::string cSessionId; ///< client Set-Cookie (session id)
std::string cKey; ///< client Sec-WebSocket-Key
std::string cAccept; ///< client Sec-WebSocket-Accept
std::string cProtocol; ///< client Sec-WebSocket-Protocol
std::string cExtensions; ///< client Sec-WebSocket-Extensions
uint16_t cVersion = 0; ///< client Sec-WebSocket-Version
uint8_t cWsRXsize = 0; ///< State of the RX
uint8_t cWsHeader[WEBSOCKETS_MAX_HEADER_SIZE]; ///< RX WS Message buffer
WSMessageHeader_t cWsHeaderDecode;
String base64Authorization; ///< Base64 encoded Auth request
String plainAuthorization; ///< Base64 encoded Auth request
std::string base64Authorization; ///< Base64 encoded Auth request
std::string plainAuthorization; ///< Base64 encoded Auth request
String extraHeaders;
std::string extraHeaders;
bool cHttpHeadersValid = false; ///< non-websocket http header validity indicator
size_t cMandatoryHeadersCount; ///< non-websocket mandatory http headers present count
@ -318,7 +320,7 @@ typedef struct {
uint8_t pongTimeoutCount = 0; // current pong timeout count
#if(WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC)
String cHttpLine; ///< HTTP header lines
std::string cHttpLine; ///< HTTP header lines
#endif
} WSclient_t;
@ -350,8 +352,8 @@ class WebSockets {
void handleWebsocketCb(WSclient_t * client);
void handleWebsocketPayloadCb(WSclient_t * client, bool ok, uint8_t * payload);
String acceptKey(String & clientKey);
String base64_encode(uint8_t * data, size_t length);
std::string acceptKey(std::string & clientKey);
std::string base64_encode(uint8_t * data, size_t length);
bool readCb(WSclient_t * client, uint8_t * out, size_t n, WSreadWaitCb cb);
virtual size_t write(WSclient_t * client, uint8_t * out, size_t n);

View File

@ -25,6 +25,8 @@
#ifndef __WEBSOCKETS4WEBSERVER_H
#define __WEBSOCKETS4WEBSERVER_H
#include <string>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
@ -32,15 +34,15 @@
class WebSockets4WebServer : public WebSocketsServerCore {
public:
WebSockets4WebServer(const String & origin = "", const String & protocol = "arduino")
WebSockets4WebServer(const std::string & origin = "", const std::string & protocol = "arduino")
: WebSocketsServerCore(origin, protocol) {
begin();
}
ESP8266WebServer::HookFunction hookForWebserver(const String & wsRootDir, WebSocketServerEvent event) {
ESP8266WebServer::HookFunction hookForWebserver(const std::string & wsRootDir, WebSocketServerEvent event) {
onEvent(event);
return [&, wsRootDir](const String & method, const String & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) {
return [&, wsRootDir](const std::string & method, const std::string & url, WiFiClient * tcpClient, ESP8266WebServer::ContentTypeFunction contentType) {
(void)contentType;
if(!(method == "GET" && url.indexOf(wsRootDir) == 0)) {
@ -55,7 +57,7 @@ class WebSockets4WebServer : public WebSocketsServerCore {
if(client) {
// give "GET <url>"
String headerLine;
std::string headerLine;
headerLine.reserve(url.length() + 5);
headerLine = "GET ";
headerLine += url;

View File

@ -22,9 +22,12 @@
*
*/
#include "WebSockets.h"
#include "WebSocketsClient.h"
#include <string>
#include "WebSockets.h"
WebSocketsClient::WebSocketsClient() {
_cbEvent = NULL;
_client.num = 0;
@ -90,7 +93,7 @@ void WebSocketsClient::begin(const char * host, uint16_t port, const char * url,
DEBUG_WEBSOCKETS("[WS-Client] Websocket Version: " WEBSOCKETS_VERSION "\n");
}
void WebSocketsClient::begin(String host, uint16_t port, String url, String protocol) {
void WebSocketsClient::begin(std::string host, uint16_t port, std::string url, std::string protocol) {
begin(host.c_str(), port, url.c_str(), protocol.c_str());
}
@ -107,7 +110,7 @@ void WebSocketsClient::beginSSL(const char * host, uint16_t port, const char * u
_CA_cert = NULL;
}
void WebSocketsClient::beginSSL(String host, uint16_t port, String url, String fingerprint, String protocol) {
void WebSocketsClient::beginSSL(std::string host, uint16_t port, std::string url, std::string fingerprint, std::string protocol) {
beginSSL(host.c_str(), port, url.c_str(), fingerprint.c_str(), protocol.c_str());
}
@ -153,7 +156,7 @@ void WebSocketsClient::beginSocketIO(const char * host, uint16_t port, const cha
_client.isSocketIO = true;
}
void WebSocketsClient::beginSocketIO(String host, uint16_t port, String url, String protocol) {
void WebSocketsClient::beginSocketIO(std::string host, uint16_t port, std::string url, std::string protocol) {
beginSocketIO(host.c_str(), port, url.c_str(), protocol.c_str());
}
@ -165,7 +168,7 @@ void WebSocketsClient::beginSocketIOSSL(const char * host, uint16_t port, const
_fingerprint = SSL_FINGERPRINT_NULL;
}
void WebSocketsClient::beginSocketIOSSL(String host, uint16_t port, String url, String protocol) {
void WebSocketsClient::beginSocketIOSSL(std::string host, uint16_t port, std::string url, std::string protocol) {
beginSocketIOSSL(host.c_str(), port, url.c_str(), protocol.c_str());
}
@ -320,7 +323,7 @@ bool WebSocketsClient::sendTXT(const char * payload, size_t length) {
return sendTXT((uint8_t *)payload, length);
}
bool WebSocketsClient::sendTXT(String & payload) {
bool WebSocketsClient::sendTXT(std::string & payload) {
return sendTXT((uint8_t *)payload.c_str(), payload.length());
}
@ -365,7 +368,7 @@ bool WebSocketsClient::sendPing(uint8_t * payload, size_t length) {
return false;
}
bool WebSocketsClient::sendPing(String & payload) {
bool WebSocketsClient::sendPing(std::string & payload) {
return sendPing((uint8_t *)payload.c_str(), payload.length());
}
@ -386,7 +389,7 @@ void WebSocketsClient::disconnect(void) {
*/
void WebSocketsClient::setAuthorization(const char * user, const char * password) {
if(user && password) {
String auth = user;
std::string auth = user;
auth += ":";
auth += password;
_client.base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length());
@ -565,13 +568,13 @@ void WebSocketsClient::handleClientData(void) {
if(len > 0) {
switch(_client.status) {
case WSC_HEADER: {
String headerLine = _client.tcp->readStringUntil('\n');
std::string headerLine = _client.tcp->readStringUntil('\n');
handleHeader(&_client, &headerLine);
} break;
case WSC_BODY: {
char buf[256] = { 0 };
_client.tcp->readBytes(&buf[0], std::min((size_t)len, sizeof(buf)));
String bodyLine = buf;
std::string bodyLine = buf;
handleHeader(&_client, &bodyLine);
} break;
case WSC_CONNECTED:
@ -607,9 +610,9 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
unsigned long start = micros();
#endif
String handshake;
std::string handshake;
bool ws_header = true;
String url = client->cUrl;
std::string url = client->cUrl;
if(client->isSocketIO) {
if(client->cSessionId.length() == 0) {
@ -682,13 +685,13 @@ void WebSocketsClient::sendHeader(WSclient_t * client) {
* handle the WebSocket header reading
* @param client WSclient_t * ptr to the client struct
*/
void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
void WebSocketsClient::handleHeader(WSclient_t * client, std::string * headerLine) {
headerLine->trim(); // remove \r
// this code handels the http body for Socket.IO V3 requests
if(headerLine->length() > 0 && client->isSocketIO && client->status == WSC_BODY && client->cSessionId.length() == 0) {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] socket.io json: %s\n", headerLine->c_str());
String sid_begin = WEBSOCKETS_STRING("\"sid\":\"");
std::string sid_begin = WEBSOCKETS_STRING("\"sid\":\"");
if(headerLine->indexOf(sid_begin) > -1) {
int start = headerLine->indexOf(sid_begin) + sid_begin.length();
int end = headerLine->indexOf('"', start);
@ -708,8 +711,8 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
// "HTTP/1.1 101 Switching Protocols"
client->cCode = headerLine->substring(9, headerLine->indexOf(' ', 9)).toInt();
} else if(headerLine->indexOf(':') >= 0) {
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
String headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
std::string headerName = headerLine->substring(0, headerLine->indexOf(':'));
std::string headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
// remove space in the beginning (RFC2616)
if(headerValue[0] == ' ') {
@ -784,11 +787,9 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
if(client->isSocketIO) {
break;
}
// falls through
case 403: ///< Forbidden
// todo handle login
// falls through
default: ///< Server dont unterstand requrst
// todo handle login
default: ///< Server dont unterstand requrst
ok = false;
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] serverCode is not 101 (%d)\n", client->cCode);
clientDisconnect(client);
@ -802,7 +803,7 @@ void WebSocketsClient::handleHeader(WSclient_t * client, String * headerLine) {
ok = false;
} else {
// generate Sec-WebSocket-Accept key for check
String sKey = acceptKey(client->cKey);
std::string sKey = acceptKey(client->cKey);
if(sKey != client->cAccept) {
DEBUG_WEBSOCKETS("[WS-Client][handleHeader] Sec-WebSocket-Accept is wrong\n");
ok = false;

View File

@ -25,6 +25,8 @@
#ifndef WEBSOCKETSCLIENT_H_
#define WEBSOCKETSCLIENT_H_
#include <string>
#include "WebSockets.h"
class WebSocketsClient : protected WebSockets {
@ -39,13 +41,13 @@ class WebSocketsClient : protected WebSockets {
virtual ~WebSocketsClient(void);
void begin(const char * host, uint16_t port, const char * url = "/", const char * protocol = "arduino");
void begin(String host, uint16_t port, String url = "/", String protocol = "arduino");
void begin(std::string host, uint16_t port, std::string url = "/", std::string protocol = "arduino");
void begin(IPAddress host, uint16_t port, const char * url = "/", const char * protocol = "arduino");
#if defined(HAS_SSL)
#ifdef SSL_AXTLS
void beginSSL(const char * host, uint16_t port, const char * url = "/", const char * fingerprint = "", const char * protocol = "arduino");
void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino");
void beginSSL(std::string host, uint16_t port, std::string url = "/", std::string fingerprint = "", std::string protocol = "arduino");
#else
void beginSSL(const char * host, uint16_t port, const char * url = "/", const uint8_t * fingerprint = NULL, const char * protocol = "arduino");
void beginSslWithCA(const char * host, uint16_t port, const char * url = "/", BearSSL::X509List * CA_cert = NULL, const char * protocol = "arduino");
@ -56,11 +58,11 @@ class WebSocketsClient : protected WebSockets {
#endif
void beginSocketIO(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
void beginSocketIO(std::string host, uint16_t port, std::string url = "/socket.io/?EIO=3", std::string protocol = "arduino");
#if defined(HAS_SSL)
void beginSocketIOSSL(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino");
void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino");
void beginSocketIOSSL(std::string host, uint16_t port, std::string url = "/socket.io/?EIO=3", std::string protocol = "arduino");
void beginSocketIOSSLWithCA(const char * host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * CA_cert = NULL, const char * protocol = "arduino");
#if defined(SSL_BARESSL)
@ -81,14 +83,14 @@ class WebSocketsClient : protected WebSockets {
bool sendTXT(const uint8_t * payload, size_t length = 0);
bool sendTXT(char * payload, size_t length = 0, bool headerToPayload = false);
bool sendTXT(const char * payload, size_t length = 0);
bool sendTXT(String & payload);
bool sendTXT(std::string & payload);
bool sendTXT(char payload);
bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false);
bool sendBIN(const uint8_t * payload, size_t length);
bool sendPing(uint8_t * payload = NULL, size_t length = 0);
bool sendPing(String & payload);
bool sendPing(std::string & payload);
void disconnect(void);
@ -105,12 +107,12 @@ class WebSocketsClient : protected WebSockets {
bool isConnected(void);
protected:
String _host;
std::string _host;
uint16_t _port;
#if defined(HAS_SSL)
#ifdef SSL_AXTLS
String _fingerprint;
std::string _fingerprint;
const char * _CA_cert;
#define SSL_FINGERPRINT_IS_SET (_fingerprint.length())
#define SSL_FINGERPRINT_NULL ""
@ -142,7 +144,7 @@ class WebSocketsClient : protected WebSockets {
#endif
void sendHeader(WSclient_t * client);
void handleHeader(WSclient_t * client, String * headerLine);
void handleHeader(WSclient_t * client, std::string * headerLine);
void connectedCb();
void connectFailedCb();
@ -154,11 +156,11 @@ class WebSocketsClient : protected WebSockets {
#endif
/**
* called for sending a Event to the app
* @param type WStype_t
* @param payload uint8_t *
* @param length size_t
*/
* called for sending a Event to the app
* @param type WStype_t
* @param payload uint8_t *
* @param length size_t
*/
virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) {
if(_cbEvent) {
_cbEvent(type, payload, length);

View File

@ -22,10 +22,13 @@
*
*/
#include "WebSockets.h"
#include "WebSocketsServer.h"
WebSocketsServerCore::WebSocketsServerCore(const String & origin, const String & protocol) {
#include <string>
#include "WebSockets.h"
WebSocketsServerCore::WebSocketsServerCore(const std::string & origin, const std::string & protocol) {
_origin = origin;
_protocol = protocol;
_runnning = false;
@ -40,7 +43,7 @@ WebSocketsServerCore::WebSocketsServerCore(const String & origin, const String &
_mandatoryHttpHeaderCount = 0;
}
WebSocketsServer::WebSocketsServer(uint16_t port, const String & origin, const String & protocol)
WebSocketsServer::WebSocketsServer(uint16_t port, const std::string & origin, const std::string & protocol)
: WebSocketsServerCore(origin, protocol) {
_port = port;
@ -130,7 +133,7 @@ void WebSocketsServerCore::onValidateHttpHeader(
delete[] _mandatoryHttpHeaders;
_mandatoryHttpHeaderCount = mandatoryHttpHeaderCount;
_mandatoryHttpHeaders = new String[_mandatoryHttpHeaderCount];
_mandatoryHttpHeaders = new std::string[_mandatoryHttpHeaderCount];
for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) {
_mandatoryHttpHeaders[i] = mandatoryHttpHeaders[i];
@ -171,7 +174,7 @@ bool WebSocketsServerCore::sendTXT(uint8_t num, const char * payload, size_t len
return sendTXT(num, (uint8_t *)payload, length);
}
bool WebSocketsServerCore::sendTXT(uint8_t num, String & payload) {
bool WebSocketsServerCore::sendTXT(uint8_t num, std::string & payload) {
return sendTXT(num, (uint8_t *)payload.c_str(), payload.length());
}
@ -213,7 +216,7 @@ bool WebSocketsServerCore::broadcastTXT(const char * payload, size_t length) {
return broadcastTXT((uint8_t *)payload, length);
}
bool WebSocketsServerCore::broadcastTXT(String & payload) {
bool WebSocketsServerCore::broadcastTXT(std::string & payload) {
return broadcastTXT((uint8_t *)payload.c_str(), payload.length());
}
@ -284,7 +287,7 @@ bool WebSocketsServerCore::sendPing(uint8_t num, uint8_t * payload, size_t lengt
return false;
}
bool WebSocketsServerCore::sendPing(uint8_t num, String & payload) {
bool WebSocketsServerCore::sendPing(uint8_t num, std::string & payload) {
return sendPing(num, (uint8_t *)payload.c_str(), payload.length());
}
@ -309,7 +312,7 @@ bool WebSocketsServerCore::broadcastPing(uint8_t * payload, size_t length) {
return ret;
}
bool WebSocketsServerCore::broadcastPing(String & payload) {
bool WebSocketsServerCore::broadcastPing(std::string & payload) {
return broadcastPing((uint8_t *)payload.c_str(), payload.length());
}
@ -347,7 +350,7 @@ void WebSocketsServerCore::disconnect(uint8_t num) {
*/
void WebSocketsServerCore::setAuthorization(const char * user, const char * password) {
if(user && password) {
String auth = user;
std::string auth = user;
auth += ":";
auth += password;
_base64Authorization = base64_encode((uint8_t *)auth.c_str(), auth.length());
@ -516,9 +519,6 @@ void WebSocketsServerCore::messageReceived(WSclient_t * client, WSopcode_t opcod
* @param client WSclient_t * ptr to the client struct contaning the native client "->tcp"
*/
void WebSocketsServerCore::dropNativeClient(WSclient_t * client) {
if(!client) {
return;
}
if(client->tcp) {
if(client->tcp->connected()) {
#if(WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) && (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP32)
@ -622,10 +622,6 @@ WSclient_t * WebSocketsServerCore::handleNewClient(WEBSOCKETS_NETWORK_CLASS * tc
#else
DEBUG_WEBSOCKETS("[WS-Server] no free space new client\n");
#endif
// no client! => create dummy!
WSclient_t dummy = WSclient_t();
client = &dummy;
client->tcp = tcpClient;
dropNativeClient(client);
}
@ -666,10 +662,10 @@ void WebSocketsServerCore::handleClientData(void) {
if(clientIsConnected(client)) {
int len = client->tcp->available();
if(len > 0) {
// DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] len: %d\n", client->num, len);
//DEBUG_WEBSOCKETS("[WS-Server][%d][handleClientData] len: %d\n", client->num, len);
switch(client->status) {
case WSC_HEADER: {
String headerLine = client->tcp->readStringUntil('\n');
std::string headerLine = client->tcp->readStringUntil('\n');
handleHeader(client, &headerLine);
} break;
case WSC_CONNECTED:
@ -692,9 +688,9 @@ void WebSocketsServerCore::handleClientData(void) {
/*
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
* @param headerName String ///< the name of the header being checked
* @param headerName std::string ///< the name of the header being checked
*/
bool WebSocketsServerCore::hasMandatoryHeader(String headerName) {
bool WebSocketsServerCore::hasMandatoryHeader(std::string headerName) {
for(size_t i = 0; i < _mandatoryHttpHeaderCount; i++) {
if(_mandatoryHttpHeaders[i].equalsIgnoreCase(headerName))
return true;
@ -705,9 +701,9 @@ bool WebSocketsServerCore::hasMandatoryHeader(String headerName) {
/**
* handles http header reading for WebSocket upgrade
* @param client WSclient_t * ///< pointer to the client struct
* @param headerLine String ///< the header being read / processed
* @param headerLine std::string ///< the header being read / processed
*/
void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine) {
void WebSocketsServerCore::handleHeader(WSclient_t * client, std::string * headerLine) {
static const char * NEW_LINE = "\r\n";
headerLine->trim(); // remove \r
@ -720,13 +716,13 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine
// cut URL out
client->cUrl = headerLine->substring(4, headerLine->indexOf(' ', 4));
// reset non-websocket http header validation state for this client
//reset non-websocket http header validation state for this client
client->cHttpHeadersValid = true;
client->cMandatoryHeadersCount = 0;
} else if(headerLine->indexOf(':') >= 0) {
String headerName = headerLine->substring(0, headerLine->indexOf(':'));
String headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
std::string headerName = headerLine->substring(0, headerLine->indexOf(':'));
std::string headerValue = headerLine->substring(headerLine->indexOf(':') + 1);
// remove space in the beginning (RFC2616)
if(headerValue[0] == ' ') {
@ -802,7 +798,7 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine
}
if(_base64Authorization.length() > 0) {
String auth = WEBSOCKETS_STRING("Basic ");
std::string auth = WEBSOCKETS_STRING("Basic ");
auth += _base64Authorization;
if(auth != client->base64Authorization) {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] HTTP Authorization failed!\n", client->num);
@ -815,13 +811,13 @@ void WebSocketsServerCore::handleHeader(WSclient_t * client, String * headerLine
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] Websocket connection incoming.\n", client->num);
// generate Sec-WebSocket-Accept key
String sKey = acceptKey(client->cKey);
std::string sKey = acceptKey(client->cKey);
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] - sKey: %s\n", client->num, sKey.c_str());
client->status = WSC_CONNECTED;
String handshake = WEBSOCKETS_STRING(
std::string handshake = WEBSOCKETS_STRING(
"HTTP/1.1 101 Switching Protocols\r\n"
"Server: arduino-WebSocketsServer\r\n"
"Upgrade: websocket\r\n"

View File

@ -25,6 +25,8 @@
#ifndef WEBSOCKETSSERVER_H_
#define WEBSOCKETSSERVER_H_
#include <string>
#include "WebSockets.h"
#ifndef WEBSOCKETS_SERVER_CLIENT_MAX
@ -33,7 +35,7 @@
class WebSocketsServerCore : protected WebSockets {
public:
WebSocketsServerCore(const String & origin = "", const String & protocol = "arduino");
WebSocketsServerCore(const std::string & origin = "", const std::string & protocol = "arduino");
virtual ~WebSocketsServerCore(void);
void begin(void);
@ -41,10 +43,10 @@ class WebSocketsServerCore : protected WebSockets {
#ifdef __AVR__
typedef void (*WebSocketServerEvent)(uint8_t num, WStype_t type, uint8_t * payload, size_t length);
typedef bool (*WebSocketServerHttpHeaderValFunc)(String headerName, String headerValue);
typedef bool (*WebSocketServerHttpHeaderValFunc)(std::string headerName, std::string headerValue);
#else
typedef std::function<void(uint8_t num, WStype_t type, uint8_t * payload, size_t length)> WebSocketServerEvent;
typedef std::function<bool(String headerName, String headerValue)> WebSocketServerHttpHeaderValFunc;
typedef std::function<bool(std::string headerName, std::string headerValue)> WebSocketServerHttpHeaderValFunc;
#endif
void onEvent(WebSocketServerEvent cbEvent);
@ -57,13 +59,13 @@ class WebSocketsServerCore : protected WebSockets {
bool sendTXT(uint8_t num, const uint8_t * payload, size_t length = 0);
bool sendTXT(uint8_t num, char * payload, size_t length = 0, bool headerToPayload = false);
bool sendTXT(uint8_t num, const char * payload, size_t length = 0);
bool sendTXT(uint8_t num, String & payload);
bool sendTXT(uint8_t num, std::string & payload);
bool broadcastTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false);
bool broadcastTXT(const uint8_t * payload, size_t length = 0);
bool broadcastTXT(char * payload, size_t length = 0, bool headerToPayload = false);
bool broadcastTXT(const char * payload, size_t length = 0);
bool broadcastTXT(String & payload);
bool broadcastTXT(std::string & payload);
bool sendBIN(uint8_t num, uint8_t * payload, size_t length, bool headerToPayload = false);
bool sendBIN(uint8_t num, const uint8_t * payload, size_t length);
@ -72,10 +74,10 @@ class WebSocketsServerCore : protected WebSockets {
bool broadcastBIN(const uint8_t * payload, size_t length);
bool sendPing(uint8_t num, uint8_t * payload = NULL, size_t length = 0);
bool sendPing(uint8_t num, String & payload);
bool sendPing(uint8_t num, std::string & payload);
bool broadcastPing(uint8_t * payload = NULL, size_t length = 0);
bool broadcastPing(String & payload);
bool broadcastPing(std::string & payload);
void disconnect(void);
void disconnect(uint8_t num);
@ -101,10 +103,10 @@ class WebSocketsServerCore : protected WebSockets {
WSclient_t * newClient(WEBSOCKETS_NETWORK_CLASS * TCPclient);
protected:
String _origin;
String _protocol;
String _base64Authorization; ///< Base64 encoded Auth request
String * _mandatoryHttpHeaders;
std::string _origin;
std::string _protocol;
std::string _base64Authorization; ///< Base64 encoded Auth request
std::string * _mandatoryHttpHeaders;
size_t _mandatoryHttpHeaderCount;
WSclient_t _clients[WEBSOCKETS_SERVER_CLIENT_MAX];
@ -127,15 +129,15 @@ class WebSocketsServerCore : protected WebSockets {
void handleClientData(void);
#endif
void handleHeader(WSclient_t * client, String * headerLine);
void handleHeader(WSclient_t * client, std::string * headerLine);
void handleHBPing(WSclient_t * client); // send ping in specified intervals
/**
* called if a non Websocket connection is coming in.
* Note: can be override
* @param client WSclient_t * ptr to the client struct
*/
* called if a non Websocket connection is coming in.
* Note: can be override
* @param client WSclient_t * ptr to the client struct
*/
virtual void handleNonWebsocketConnection(WSclient_t * client) {
DEBUG_WEBSOCKETS("[WS-Server][%d][handleHeader] no Websocket connection close.\n", client->num);
client->tcp->write(
@ -151,10 +153,10 @@ class WebSocketsServerCore : protected WebSockets {
}
/**
* called if a non Authorization connection is coming in.
* Note: can be override
* @param client WSclient_t * ptr to the client struct
*/
* called if a non Authorization connection is coming in.
* Note: can be override
* @param client WSclient_t * ptr to the client struct
*/
virtual void handleAuthorizationFailed(WSclient_t * client) {
client->tcp->write(
"HTTP/1.1 401 Unauthorized\r\n"
@ -170,12 +172,12 @@ class WebSocketsServerCore : protected WebSockets {
}
/**
* called for sending a Event to the app
* @param num uint8_t
* @param type WStype_t
* @param payload uint8_t *
* @param length size_t
*/
* called for sending a Event to the app
* @param num uint8_t
* @param type WStype_t
* @param payload uint8_t *
* @param length size_t
*/
virtual void runCbEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
if(_cbEvent) {
_cbEvent(num, type, payload, length);
@ -183,19 +185,19 @@ class WebSocketsServerCore : protected WebSockets {
}
/*
* Called at client socket connect handshake negotiation time for each http header that is not
* a websocket specific http header (not Connection, Upgrade, Sec-WebSocket-*)
* If the custom httpHeaderValidationFunc returns false for any headerName / headerValue passed, the
* socket negotiation is considered invalid and the upgrade to websockets request is denied / rejected
* This mechanism can be used to enable custom authentication schemes e.g. test the value
* of a session cookie to determine if a user is logged on / authenticated
*/
virtual bool execHttpHeaderValidation(String headerName, String headerValue) {
* Called at client socket connect handshake negotiation time for each http header that is not
* a websocket specific http header (not Connection, Upgrade, Sec-WebSocket-*)
* If the custom httpHeaderValidationFunc returns false for any headerName / headerValue passed, the
* socket negotiation is considered invalid and the upgrade to websockets request is denied / rejected
* This mechanism can be used to enable custom authentication schemes e.g. test the value
* of a session cookie to determine if a user is logged on / authenticated
*/
virtual bool execHttpHeaderValidation(std::string headerName, std::string headerValue) {
if(_httpHeaderValidationFunc) {
// return the value of the custom http header validation function
//return the value of the custom http header validation function
return _httpHeaderValidationFunc(headerName, headerValue);
}
// no custom http header validation so just assume all is good
//no custom http header validation so just assume all is good
return true;
}
@ -205,20 +207,20 @@ class WebSocketsServerCore : protected WebSockets {
/**
* drop native tcp connection (client->tcp)
*/
*/
void dropNativeClient(WSclient_t * client);
private:
/*
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
* @param headerName String ///< the name of the header being checked
*/
bool hasMandatoryHeader(String headerName);
* returns an indicator whether the given named header exists in the configured _mandatoryHttpHeaders collection
* @param headerName std::string ///< the name of the header being checked
*/
bool hasMandatoryHeader(std::string headerName);
};
class WebSocketsServer : public WebSocketsServerCore {
public:
WebSocketsServer(uint16_t port, const String & origin = "", const String & protocol = "arduino");
WebSocketsServer(uint16_t port, const std::string & origin = "", const std::string & protocol = "arduino");
virtual ~WebSocketsServer(void);
void begin(void);

View File

@ -1,6 +1,6 @@
/**
* @file WebSocketsVersion.h
* @date 05.04.2022
* @date 08.03.2021
* @author Markus Sattler
*
* Copyright (c) 2015 Markus Sattler. All rights reserved.
@ -25,12 +25,12 @@
#ifndef WEBSOCKETSVERSION_H_
#define WEBSOCKETSVERSION_H_
#define WEBSOCKETS_VERSION "2.3.7"
#define WEBSOCKETS_VERSION "2.3.6"
#define WEBSOCKETS_VERSION_MAJOR 2
#define WEBSOCKETS_VERSION_MINOR 3
#define WEBSOCKETS_VERSION_PATCH 7
#define WEBSOCKETS_VERSION_PATCH 6
#define WEBSOCKETS_VERSION_INT 2003007
#define WEBSOCKETS_VERSION_INT 2003006
#endif /* WEBSOCKETSVERSION_H_ */

View File

@ -1,7 +1,5 @@
#!/bin/bash
set -x
function build_sketches()
{
local arduino=$1
@ -30,10 +28,10 @@ function build_sketches()
}
function build_sketch()
{
{
local arduino=$1
local sketch=$2
$arduino --verify --verbose $sketch;
$arduino --verify $sketch;
local result=$?
if [ $result -ne 0 ]; then
echo "Build failed ($sketch) build verbose..."
@ -62,7 +60,7 @@ function get_sketches_json()
if [[ $sketch != ${sketches[-1]} ]] ; then
echo -en ","
fi
done
echo -en "]"
}
@ -99,7 +97,6 @@ function get_core()
cd esp8266com
git clone --depth 1 https://github.com/esp8266/Arduino.git esp8266
cd esp8266/
git submodule update --init
rm -rf .git
cd tools
python get.py
@ -130,5 +127,5 @@ function clone_library() {
function hash_library_names() {
cd $HOME/Arduino/libraries
ls | sha1sum -z | cut -c1-5
ls | sha1sum -z | cut -c1-5
}