Simple ESP32 replacement for ESP8266 HTTPUpdateServer - platformio

I have been using ESP8266's for a while now and am now trying ESP32. I have tried to find a drop in replacement for the ESP8266HTTPUpdateServer. I normally use:
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
ESP8266WebServer server(80);
ESP8266HTTPUpdateServer httpUpdater;
const char* update_path = "/firmware";
const char* update_username = "admin";
const char* update_password = "password";
void setup() {
httpUpdater.setup(&server, update_path, update_username, update_password);
}
Void loop() {
server.handleClient();
}
How do I do the equivalent for ESP32? Every example I have seen seems to only have much more elaborate implementations which is unnecessary for my needs as I don't need security or extra checks.

Related

esp32 rest chuncked response

Im trying to know the real wifi speed capabilities of the esp32, and so i created a simple routine using a common library
void speedTest(AsyncWebServerRequest *request)
{
static uint8_t data[1024] = {0};
static uint32_t dataLen = 1*1024*1024;
memcpy(data, "ciao", 4);
AsyncWebServerResponse *response = request->beginChunkedResponse("application/octet-stream", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
size_t len = (dataLen>maxLen)?maxLen:dataLen;
if (len>0)
{
memcpy(buffer, data, len);
dataLen -= len;
index += len;
}
return len;
});
response->setContentLength(dataLen);
request->send(response);
}
but when i make the GET request, the board reset itself and in serial monitor i see the following log:
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
E (17770) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:
E (17770) task_wdt: - async_tcp (CPU 0/1)
E (17770) task_wdt: Tasks currently running:
E (17770) task_wdt: CPU 0: IDLE0
E (17770) task_wdt: CPU 1: loopTask
E (17770) task_wdt: Aborting.
abort() was called at PC 0x40131b44 on core 0
I also have tried to reduce the file size and the download goes fine, but for my purpose is useless.
Someone has already meet and solved this problem ? im not really a lambda lover, alternately a different library more customizable, if is possible I would not like to reimplement all the http protocol over socket.
thanks in adavance for the help.
comeplete code:
#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
IPAddress local_ip(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
AsyncWebServer server(80);
const char* ssid = "testSpeed";
const char* psw = "12345678";
void notFound(AsyncWebServerRequest *request)
{
request->send(404, "text/plain", "Not found");
}
void speedTest(AsyncWebServerRequest *request)
{
#if 1
static uint8_t data[1024] = {0};
static uint32_t dataLen = 1*1024*1024;
memcpy(data, "ciao", 4);
AsyncWebServerResponse *response = request->beginChunkedResponse("application/octet-stream", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t {
size_t len = (dataLen>maxLen)?maxLen:dataLen;
if (len>0)
{
memcpy(buffer, data, len);
dataLen -= len;
index += len;
}
return len;
});
response->setContentLength(dataLen);
request->send(response);
#endif
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(ssid, psw);
WiFi.softAPConfig(local_ip, gateway, subnet);
server.on("/stream", HTTP_GET, speedTest);
server.onNotFound(notFound);
server.begin();
}
void loop() {
}
Looks like the implementation of AsyncWebServer is not meant for long-running transactions, as it never resets the task watchdog. As a workaround you can increase the watchdog timeout to its maximum limit of 60 s or disable it entirely. It's controlled by the following options in sdkconfig:
CONFIG_ESP_TASK_WDT=y # Task Watchdog is enabled
CONFIG_ESP_TASK_WDT_PANIC=y # Panic (reset) is invoked on timeout
CONFIG_ESP_TASK_WDT_TIMEOUT_S=30 # Timeout in seconds
The normal way to change those is to run idf.py menuconfig (where they appear under "Component config", "Common ESP-related") but you can just update the file "sdkconfig" directly.
Undo those changes after you're finished with your experiments, it's usually a good idea to keep the Task Watchdog enabled.

BPF program is not valid - pcap sniffing

Hey everyone I'm trying to sniff packets using the pcap library. I have just one problem that I can not figure out: ERROR: BPF program is not valid.
I'm trying to start the sniffing but this error is blocking me I searched on the web and found nothing.
My code is based after this program: https://github.com/levans248/packetSniffingAndSpoofing/blob/master/sniff.c
It is due to SEED labs I know people do not help when it is homework but I just need to figure why this is happening I have no clue.
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
printf("Got a packet \n");
}
int main()
{
pcap_t *handle;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program fp;
char filter_exp[] = "ip proto icmp";
bpf_u_int32 net;
// Open live pcap session
handle = pcap_open_live("enp0s3", BUFSIZ, 1, 1000, errbuf);
// Compile Filter into the Berkeley Packet Filter (BPF)
pcap_compile(handle, &fp, filter_exp, 0, net);
if (pcap_setfilter(handle, &fp) == -1)
{
pcap_perror(handle, "ERROR");
exit(EXIT_FAILURE);
}
// Sniffing..
pcap_loop(handle, -1, got_packet, NULL);
pcap_close(handle);
return 0;
}
There was a SYNTAX mistake in the filter_exp ,
I was working on C-Shell so was needed to change to ip proto \icmp
Thank you very much everyone !

Sending UDP datagrams from Arduino with EtherCard library

I am currently trying to send UDP datagrams from my Arduino to a server. I researched a bit online and found some code, which helped me to send them via a domain. Which works fine. But in my case I need to send it to a IP address, instead of a domain name (because my server doesn't have a domain). In this case I use the Ethercard library.
#include <EtherCard.h>
static byte mymac[] = { 0x1A,0x2B,0x3C,0x4D,0x5E,0x6F };
byte Ethernet::buffer[700];
static uint32_t timer;
const char website[] PROGMEM = "name.tld";
const int dstPort PROGMEM = 54321;
const int srcPort PROGMEM = 54321;
void setup () {
Serial.begin(9600);
// Change 'SS' to your Slave Select pin, if you arn't using the default pin
if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0)
Serial.println( "Failed to access Ethernet controller");
if (!ether.dhcpSetup())
Serial.println("DHCP failed");
ether.printIp("IP: ", ether.myip);
ether.printIp("GW: ", ether.gwip);
ether.printIp("DNS: ", ether.dnsip);
//if (!ether.dnsLookup(website))
// Serial.println("DNS failed");
ether.printIp("SRV: ", ether.hisip);
}
char textToSend[] = "Hello";
void loop () {
if (millis() > timer) {
timer = millis() + 5000;
//static void sendUdp (char *data,uint8_t len,uint16_t sport, uint8_t *dip, uint16_t dport);
ether.sendUdp(textToSend, sizeof(textToSend), srcPort, ether.hisip, dstPort );
}
}
This is my code for sending something to a domain.
I assume you are using this library.
https://github.com/njh/EtherCard
The README explains how to send UDP datagrams. You want to use uint8_t parseIp(uint8_t *bytestr, const char *str) to format a destination IP address.
char payload[] = "My UDP message";
uint8_t nSourcePort = 1234;
uint8_t nDestinationPort = 5678;
uint8_t ipDestinationAddress[IP_LEN];
ether.parseIp(ipDestinationAddress, "192.168.0.200");
ether.sendUdp(payload, sizeof(payload), nSourcePort, ipDestinationAddress, nDestinationPort);

Simblee/Rfduino Gzll communcation failing

I am attempting to send data from device to host using the Gazelle protocol, however, when reading a time varying signal in on MATLAB the values continuously change elements in the array.
Here is the Simblee/Rfduino host code:
#include <SimbleeGZLL.h>
device_t role = HOST;
char array[5];
void setup() {
Serial.begin(9600);
SimbleeGZLL.begin(role);
timer_one(1); // 1 ms timer
}
void loop() {
Serial.flush();
printf(EMG);
}
void SimbleeGZLL_onReceive(device_t device, int rssi, char *data, int len)
{
if (len > 0) {
digitalWrite(2,HIGH);
array[0] = data[0];
array[1] = data[1];
array[2] = data[2];
array[3] = data[3];
array[4] = '\0';
} else SimbleeGZLL.sendToDevice(device, 'A');
}
And the device code:
include
device_t role = DEVICE1;
volatile int state;
char array[4];
void setup() {
SimbleeGZLL.begin(role);
Serial.begin(9600);
timer_one(1);
}
void loop() {
array[0] = analogRead(2);
array[1] = analogRead(3);
array[2] = analogRead(4);
array[3] = analogRead(5);
SimbleeGZLL.sendToHost(EMG,4);
}
Could someone please provide some assistance to identify where the issue may lie?
Thank you!
Matlab is not super reliable with serial communication. I actually had a similar issue with a serial device where the input values would be out of order. Are you signaling when to start and stop printing? What does your matlab code look like?
I would set up a ring buffer on the host and the device to deal with the asycn time issues.
You are going to get timing issues with the current method. What kind of frequency are you going for? The analogRead is super slow, and double multiple in a row seems to make things even slower. Could you try to set up an ADC interrupt?
Where is your timer code?

How to use a widget plugin in qt 3?

For some reasons, I must work with Qt3 under SLES 11 SP3. I have written the following plugin:
// PixmapButtonPlugin.hpp
#include <qwidgetplugin.h>
class PixmapButtonPlugin : public QWidgetPlugin
{
public:
QStringList keys () const;
QWidget* create (const QString& key, QWidget* parent = 0, const char* name = 0);
QString group (const QString& key) const;
QIconSet iconSet (const QString& key) const;
QString includeFile (const QString& key) const;
QString toolTip (const QString& key) const;
QString whatsThis (const QString& key) const;
bool isContainer (const QString& key) const;
};
Q_EXPORT_PLUGIN(PixmapButtonPlugin)
// PixmapButtonPlugin.cpp
#include "PixmapButtonPlugin.hpp"
#include "PixmapButton.qh"
QStringList PixmapButtonPlugin::keys () const
{
return QStringList() << "PixmapButton";
}
QWidget* PixmapButtonPlugin::create (const QString&, QWidget* parent, const char*)
{
return new PixmapButton(parent);
}
QString PixmapButtonPlugin::group (const QString&) const
{
return "Buttons";
}
QIconSet PixmapButtonPlugin::iconSet (const QString& key) const
{
return QWidgetPlugin::iconSet(key);
}
QString PixmapButtonPlugin::includeFile (const QString&) const
{
return "PixmapButton.qh";
}
QString PixmapButtonPlugin::toolTip (const QString&) const
{
return "Pixmap button";
}
QString PixmapButtonPlugin::whatsThis (const QString&) const
{
return "Button that takes the shape of its pixmap";
}
bool PixmapButtonPlugin::isContainer (const QString&) const
{
return false;
}
I have finally copied the compiled shared library libplugins.so in the folder
/usr/lib/qt3/plugins/designer
The designer doesn't display the plugins anywhere and doesn't tell me that it couldn't create the corresponding widget either. I get absolutely no error.
What should I do?
I got some help at work from a senior developer and actually found a way out of this problem. The main issue here is to make sure that the plugin is ok. How can I check that everything is fine with my plugin? That's pretty simple.
First, compile the following simple application:
// PluginLoader.cpp
#include <iostream>
#include <qlibrary.h>
#include <private/qcom_p.h>
int main(int argc, char *argv[])
{
QLibrary lib("/path-to-my-plugin/myPlugin.so");
std::cout << "Load: " << lib.load() << std::endl;
std::cout << "Resolve: " << (lib.resolve("ucm_instantiate") != 0) << std::endl;
return 0;
}
Second, activate some debugging tools for libraries: type the following commands in a console
export LD_WARN=1
export LD_VERBOSE=1
export LD_DEBUG=all
Note that there are many other options than "all" for the LD_DEBUG variable. Just type
export LD_DEBUG=help
to get more details (you will get the details as soon as you launch the above application).
Then, launch the PluginLoader application
./PluginLoader 2> loader.log
The file loader.log will then contain all the details regarding the libraries that are being loaded, in particular messages starting with
symbol lookup error
which indicate that something is missing in the plugin.
When the PluginLoader is happy, i.e. when it says
Load: 1
Resolve: 1
you are normally ready to use the plugin in the Qt Designer. To use it, copy it in the folder
/usr/lib/qt3/plugins/designer
or
$QTDIR/plugins/designer
which is the default folder for the designer's plugins. You may also be successful by setting the
LD_LIBRARY_PATH
QT_PLUGIN_PATH
appropriately.
Usually, you can also simply
ldd /path-to-your-plugin/myPlugin.so
This will show you which libraries this plugin was linked against. This can provide you with information about libraries that you may have forgotten ...
And a last comment. I am developing on SLES 11 SP3 64 bits. However, I am compiling 32-bits applications. In particular, the plugin is 32 bits. Before trying to let the plugin appear in the designer, make sure that the designer is the 32-bit version. Otherwise, the plugin won't appear in the list.
Note also that this process can also be applied to the production of Qt4 and Qt5 plugins (maybe modulo a few adaptions)!