Networking-for-Arduino / EthernetENC

Ethernet library for ENC28J60. This is a modern version of the UIPEthernet library. EthernetENC library is compatible with all Arduino architectures with Arduino SPI library with transactions support. Only include EthernetENC.h instead of Ethernet.h
127 stars 28 forks source link

Network connection goes deaf. #35

Open pvrfr opened 2 years ago

pvrfr commented 2 years ago

Hello;

I am having the same problem with EthernetENC as I did with UIPEthernet. That is the stack stops receiving packets. You fixed the problem and afterwards the code ran without problems. Perhaps there is a similar bug in your new code. The processor is an ESP-12N. The code is part of the OpenSprinkler project.

The issue was previously discussed here: https://github.com/UIPEthernet/UIPEthernet/issues/129

JAndrassy commented 2 years ago

the error I found 'hidden in plain sight' was not an error, but my confusion about if (*this) (which executes the bool operator). I replaced it with if (data) and after I realized my misunderstanding of if (*this) I changed it back.

UIPClient::operator bool()
{
  UIPEthernetClass::tick();
  return data && (!(data->state & UIP_CLIENT_REMOTECLOSED) || data->packets_in[0] != NOBLOCK);
}

data is not null if the client is initialized. !(data->state & UIP_CLIENT_REMOTECLOSED) is that it is connected data->packets_in[0] != NOBLOCK is that it has data. so it is initialized and (connected or has_data)

if (*this) is used to skip available(), peek(), read() and discardReceived() (which is flush() n UIPEthernet).

pvrfr commented 2 years ago

The "fix" really did solve the problem in my case. The idea that I had was that the fix prevented dereferencing an invalid pointer, which generally results in difficult to understand bugs.

I am very fluent in C but not so much with C++. I tried to get GDB running on the ESP chip but was not successful, so debugging required using printf. Can you suggest some debug test that I can do to help find this problem.

JAndrassy commented 2 years ago

the difference is tick() and this part of the bool operator implementation: (!(data->state & UIP_CLIENT_REMOTECLOSED) || data->packets_in[0] != NOBLOCK) instead of *this in available(), peek(), read() try data && (!(data->state & UIP_CLIENT_REMOTECLOSED) || data->packets_in[0] != NOBLOCK) this will remove tick() from available(), peek(), read()