tobozo / ESP32-ENC28J60

ENC28J60 Ethernet driver for ESP32-Arduino 2.0.x / 3.0.x, lwip compliant
MIT License
26 stars 8 forks source link

Example not working #3

Closed simogaspa84 closed 1 year ago

simogaspa84 commented 1 year ago

Hi @tobozo ...

How are you ?

I had time to try your example... .

This is my code...

#include <esp32fota.h>
#include "automatic_ota.h"
#include <ESP32-ENC28J60.h>

const char *firmware_name = "esp32-fota-http";
const bool check_signature = false;
const bool disable_security = true;

#define SPI_HOST 1
#define SPI_CLOCK_MHZ 20
#define INT_GPIO 4
#define MISO_GPIO 12
#define MOSI_GPIO 13
#define SCLK_GPIO 14
#define CS_GPIO 15

int firmware_version_major = 1;
int firmware_version_minor = 0;
int firmware_version_patch = 0;

esp32FOTA FOTA; // empty constructor

static bool eth_connected = false;

// using WiFiEvent to handle Ethernet events :-)
void WiFiEvent(WiFiEvent_t event)
{
    switch (event)
    {
    case ARDUINO_EVENT_ETH_START:
        Serial.println("ETH Started");
        ETH.setHostname("esp32-ethernet");
        break;
    case ARDUINO_EVENT_ETH_CONNECTED:
        Serial.println("ETH Connected");
        break;
    case ARDUINO_EVENT_ETH_GOT_IP:
        Serial.printf("ETH MAC: %s, IPv4: %s%s, %dMbps\n", ETH.macAddress().c_str(), ETH.localIP().toString().c_str(), ETH.fullDuplex() ? ", FULL_DUPLEX" : "", ETH.linkSpeed());
        eth_connected = true;
        break;
    case ARDUINO_EVENT_ETH_DISCONNECTED:
        Serial.println("ETH Disconnected");
        eth_connected = false;
        break;
    case ARDUINO_EVENT_ETH_STOP:
        Serial.println("ETH Stopped");
        eth_connected = false;
        break;
    default:
        break;
    }
}

static bool EthernetConnected()
{
    return eth_connected;
}

/**
 * @brief  Function to do the setup for the ota
 * @param  None
 * @retval None
 */
void Setup_automatic_ota(void)
{
    Serial.begin(115200);
    {
        auto cfg = FOTA.getConfig();
        cfg.name = firmware_name;
        cfg.manifest_url = FOTA_URL;
        cfg.sem = SemverClass(firmware_version_major, firmware_version_minor, firmware_version_patch);
        cfg.check_sig = check_signature;
        cfg.unsafe = disable_security;
        // cfg.root_ca      = MyRootCA;
        // cfg.pub_key      = MyRSAKey;
        FOTA.setConfig(cfg);
        FOTA.setStatusChecker(EthernetConnected);
    }
    WiFi.onEvent(WiFiEvent);
    ETH.begin(MISO_GPIO, MOSI_GPIO, SCLK_GPIO, CS_GPIO, INT_GPIO, SPI_CLOCK_MHZ, SPI_HOST);
}
/**
 * @brief  Function to loop the ota
 * @param  None
 * @retval None
 */
void Loop_automatic_ota(void)
{
    if (!eth_connected)
    {
        Serial.println("Connecting...");
        delay(1000);
        return;
    }
    FOTA.handle();
    delay(20000);
}`

i am getting the following issue..

ETH Started Connecting... Connecting... ETH Connected Connecting... Connecting... Connecting... ETH MAC: 02:00:00:12:34:56, IPv4: 192.168.0.39, FULL_DUPLEX, 10Mbps [ 22066][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29312) SSL - The connection indicated an EOF [ 22067][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -29312 [ 52076][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29312) SSL - The connection indicated an EOF [ 52077][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -29312 [ 84085][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29312) SSL - The connection indicated an EOF [ 84085][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -29312 [126096][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29312) SSL - The connection indicated an EOF [126096][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -29312 [159106][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29312) SSL - The connection indicated an EOF [159106][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -29312 [198119][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-80) UNKNOWN ERROR CODE (0050) [198120][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -80 [236130][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29312) SSL - The connection indicated an EOF [236130][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -29312 [270141][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29312) SSL - The connection indicated an EOF [270141][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -29312 [309151][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-80) UNKNOWN ERROR CODE (0050) [309152][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -80 [342161][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29312) SSL - The connection indicated an EOF [342162][E][WiFiClientSecure.cpp:135] connect(): start_ssl_client: -29312 [376171][E][ssl_client.cpp:37] _handle_error(): [start_ssl_client():276]: (-29312) SS

The ethernet connection seems to work but not the ssl part...

Any idea ?

This is the fota file already tested with the wifi connection . .

{ "type": "esp32-fota-http", "version": "2", "port": 443, "url": "https://systelfota.000webhostapp.com/update.bin" }

Thanks a lot again

tobozo commented 1 year ago

hi @simogaspa84

Looking up the SSL - The connection indicated an EOF error message yielded this. You can verify if it' related to the 000webhostapp server by testing a download from another domain.

If the default binary (a hello world sketch) downloads without errors, then 000webhostapp is most likely the cause.

https://github.com/tobozo/ESP32-ENC28J60/raw/main/examples/FOTA/bin/firmware.bin (this is only a hello world sketch)

Can you try to raise the output level to Debug so that the serial output gives more info?

tobozo commented 1 year ago

btw I had time to test another esp32-based ethernet module : WT32-ETH01

It can do 100MB ethernet, at that speed the OTA updates are finished in less than 5 seconds!!

The ENC28J60 with its sluggish 10MB over SPI takes 2 minutes to do the same.

Moreover, using dupont cables between the ESP and the ENC28J60 can weaken the signal.

Caveat of the WT32-ETH01 : you need a FTDI adapter or a serial bridge to flash it.

simogaspa84 commented 1 year ago

btw I had time to test another esp32-based ethernet module : WT32-ETH01

It can do 100MB ethernet, at that speed the OTA updates are finished in less than 5 seconds!!

The ENC28J60 with its sluggish 10MB over SPI takes 2 minutes to do the same.

Moreover, using dupont cables between the ESP and the ENC28J60 can weaken the signal.

Caveat of the WT32-ETH01 : you need a FTDI adapter or a serial bridge to flash it.

Hi @tobozo ..

Thanks for your quick reply...

When you say

The ENC28J60 with its sluggish 10MB over SPI takes 2 minutes to do the same.

It means that you have already tested the fota with the new lib with the ENC28J60 and esp32..

So probably as you said it is a problem of the web hosting provider...

What do you think?

Thanks again very kind

tobozo commented 1 year ago

yes I have tested my library before publishing it to the Arduino Library Registry :-)

the 2 minutes sluggishness was the worst case scenario though: 15cm dupont cables between my ESP32 and my ENC28J60, downloading a gzipped firmware and using enforced TLS.

simogaspa84 commented 1 year ago

Ok @tobozo I will try directly your demo in my hw.. It should work... and then I will try to update the webhosting.. I keep you updated... thanks

tobozo commented 1 year ago

test idea:

1) create a hello world sketch

void setup()
{
  Serial.begin(115200);
  delay(1000);
  Serial.println("Hello World");
}

void loop()
{
}

2) compile the hello world sketch it and upload the binary on a github repository 3) put the download URL to that binary in your JSON manifest, and also upload the manifest on the same github repo 4) put the download URL to that manifest in your FOTA test sketch 5) post the serial output here

Note that the download URL is either the raw or download link from the github repo path you'll be using.

Json Manifest download URL: image

Firmware download URL: image

simogaspa84 commented 1 year ago

Hi @tobozo ..

I have tried directly your example.. .iit is working in my hw..

ETH Started Connecting... Connecting... ETH Connected Connecting... Connecting... Connecting... Connecting... ETH MAC: 02:00:00:12:34:56, IPv4: 192.168.0.39, FULL_DUPLEX, 10Mbps Opening item https://github.com:443/tobozo/ESP32-ENC28J60/blob/main/examples/FOTA/bin/firmware.bin?raw=true This server supports resume! Accept-Ranges: bytes Begin Firmware OTA. This may take 2 - 5 mins to complete. Things might be quiet for a while.. Patience! ........................................................... Written : 245488 successfully Update successfully completed. Rebooting. ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x12 (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:0x3fff0030,len:1184 load:0x40078000,len:13132 load:0x40080400,len:3036 entry 0x400805e4 [ 48][D][esp32-hal-cpu.c:244] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz


Test suite COMPLETE :-)

It seems to be the webhostinf provider..

tobozo commented 1 year ago

could also be that 000webhostapp uses a fallback cipher suite that isn't supported by esp32

how does it behave when you implement 000webhostapp certificate and set disable_security = false; ?

tobozo commented 1 year ago

ets Jul 29 2019 12:21:46

oh I just remembered some TLS implementation do not tolerate when the client's internal clock isn't set

so maybe the esp32 is sending a TLS response with incorrect timestamps, and the 000webhostapp server closes the connection because it doesn't like three years gap

maybe that could be solved by doing a NTP synchronization right after the network is up, and before doing the first OTA attempt

simogaspa84 commented 1 year ago

i have already tried the connection with 000webhostapp for fota with wifi ...

And it is working with this code

#include <esp32fota.h>
#include "automatic_ota.h"
#include <cloud_connection.h>
#include "machine.h"

const char *firmware_name = "esp32-fota-http";
const bool check_signature = false;
const bool disable_security = true;

int firmware_version_major = 1;
int firmware_version_minor = 0;
int firmware_version_patch = 0;

esp32FOTA FOTA; // empty constructor

/**
 * @brief  Function to do the setup for the ota
 * @param  None
 * @retval None
 */
void Setup_automatic_ota(void)
{
    /*retrieve wifi credentials and start wifi*/
    Retrieve_saved_credentials_and_startwifi();

    Serial.print("entro fota setup");
    {
        auto cfg = FOTA.getConfig();
        cfg.name = firmware_name;
        cfg.manifest_url = FOTA_URL;
        cfg.sem = SemverClass(firmware_version_major, firmware_version_minor, firmware_version_patch);
        cfg.check_sig = check_signature;
        cfg.unsafe = disable_security;
        // cfg.root_ca      = MyRootCA;
        // cfg.pub_key      = MyRSAKey;
        FOTA.setConfig(cfg);
    }
}
/**
 * @brief  Function to loop the ota
 * @param  None
 * @retval None
 */
void Loop_automatic_ota(void)
{

    set_current_event(EVENT_FOTA_IN_PROGRESS);

    bool updatedNeeded = FOTA.execHTTPcheck();
    if (updatedNeeded)
    {
        FOTA.execOTA();
    }
    delay(2000);
}
simogaspa84 commented 1 year ago

ets Jul 29 2019 12:21:46

oh I just remembered some TLS implementation do not tolerate when the client's internal clock isn't set

so maybe the esp32 is sending a TLS response with incorrect timestamps, and the 000webhostapp server closes the connection because it doesn't like three years gap

maybe that could be solved by doing a NTP synchronization right after the network is up, and before doing the first OTA attempt

but what about your demo what is working ? Are you setting the time or maybe github doesn't care ?

Thanks

tobozo commented 1 year ago

github doesn't care, or the cipher algorithm used in less-secure connections uses relative time, or the esp32 available cipher suites have more affinities, or something else ...

I'm not expert enough in crypto to tell, but I know setting the internal clock on the ESP32 can be a game changer with some server using strict or old configurations.

simogaspa84 commented 1 year ago

Ok but still i don't understand why with wifi is working.. I am not waiting a ntp synch also with that.. In any case i will try your suggestions:

1- change web hosting provider 2- wait ntp synch before connecting..

@tobozo thanks a lot for the moment

tobozo commented 1 year ago

why with wifi is working

with WiFi you get much less lag, no packet loss, non blocking communication, with ENC28J60 you get interrupts, SPI signal is weakened by the dupont cables, and probably a lot of packet loss.

sniffing the network with Wireshark while the failure is happening could confirm the packet loss theory.

simogaspa84 commented 1 year ago

@tobozo I have tried again your example and yes it seems it is loosing some packets / very slow

ETH MAC: 02:00:00:12:34:56, IPv4: 192.168.0.39, FULL_DUPLEX, 10Mbps Opening item https://github.com:443/tobozo/ESP32-ENC28J60/blob/main/examples/FOTA/bin/firmware.bin?raw=true This server supports resume! Accept-Ranges: bytes Begin Firmware OTA. This may take 2 - 5 mins to complete. Things might be quiet for a while.. Patience! Written only : 0/245488. Premature end of stream? Opening item https://github.com:443/tobozo/ESP32-ENC28J60/blob/main/examples/FOTA/bin/firmware.bin?raw=true This server supports resume! Accept-Ranges: bytes Begin Firmware OTA. This may take 2 - 5 mins to complete. Things might be quiet for a while.. Patience! Written only : 0/245488. Premature end of stream?

tobozo commented 1 year ago

well this ENC28J60 board may be fun to play with, and offer the opportunity to practice troubleshooting on many layers of the OSI model (which makes is a very good educational material), but I wouldn't use it in any serious project as it is a real bottleneck both to the SPI bus (because it's capped at 20MHz) and the Ethernet (because some packets expire before reaching the network layer).

simogaspa84 commented 1 year ago

ok @tobozo the message is clear... Basically the hw engineer who has chosen this ethernet shield has made a not good evaluation choosing this ethernet shield..

tobozo commented 1 year ago

don't forget the situation is also worsened by the use of flying cables, it's a shield and should be plugged directly to another PCB, knowing that you probably shouldn't mix responsibilities and blame the hw engineer until you know for sure how those responsibilities are spread :-)

simogaspa84 commented 1 year ago

Ok @tobozo but there is no flying cables in our iot board... esp32 and ethernet shield with spi chi are all together very close in the same pcb

simogaspa84 commented 1 year ago

Last question @tobozo and then I can let you free.. :) . If i want to try the synch with the ntp server do you reccomend some libs that suits good this lib ?

https://github.com/tobozo/ESP32-ENC28J60

Thanks a lot again for your huge help

tobozo commented 1 year ago

see this tutorial https://lastminuteengineers.com/esp32-ntp-server-date-time-tutorial/

just turn the void printLocalTime() function into a bool and have it return false when getLocalTime() failed so that you can implement some wait logic