esp8266 / esp8266/Arduino

ArduinoOTA retrieves incorrect IP for TCP transfer

Open
#8,510 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
16.7k
Forks
13.1k
PR merge metrics
No merged PRs in 30d

Description

### Basic Infos

- [x] This issue complies with the [issue POLICY doc](https://github.com/esp8266/Arduino/blob/master/POLICY.md).
- [x] I have read the documentation at [readthedocs](https://arduino-esp8266.readthedocs.io/en/latest) and the issue is not addressed there.
- [x] I have tested that the issue is present in current master branch (aka latest git).
- [x] I have searched the issue tracker for a similar issue.
- [x] If there is a stack dump, I have decoded it.
- [x] I have filled out all fields below.

#### Platform

- Hardware: ESP-8266EX
- Core Version: 3.30002.0
- Development Env: Platformio
- Operating System: Windows

### Settings in IDE

- Module: Wemos D1 mini

### Problem Description

When trying to use OTA updates via internet [this call](https://github.com/esp8266/Arduino/blob/3027acaf11db93e877fca943eb815216d0507744/libraries/ArduinoOTA/ArduinoOTA.cpp#L178) retrieves a wrong, local IP.
The UDP communication works just fine but because of the wrong IP the TCP connection (pushing the actual firmware/payload) fails:

```
10:57:53 [INFO]: Sending invitation to: x.x.x.x
10:58:03 [ERROR]: No Answer
```

Network setup it is: Internet -> Router A -> Router B (in Acces Point mode) -> ESP. The call above yields the local IP address of Router A instead of the correct remote one.

I thought I could use the `--host_ip` argument to set the correct IP but it tries to bind the socket to it which fails. And the cpp side does not use this supplied address, it relies on the remote address of the UDP connection.

So I've added some code to `espota.py` to NOT bind to the to `localAddr` but to [`INADDR_ANY`](https://docs.python.org/3/library/socket.html#socket-families)
```python
server_address = ("", localPort)
```
and append the correct IP localAddr with the message:
```python
message = '%d %d %d %s\n%s\n' % (command, localPort, content_size, file_md5, localAddr)
```

and to read it on the cpp side:
```cpp
String ipstring = readStringUntil('\n');
_ota_ip2.fromString(ipstring);
```

and then I use this for the TCP connection:
```cpp
if (!client.connect(_ota_ip2, _ota_port)) {
```

With this now the OTA update works when explicitly setting the IP, e.g. like this:
```
python espota.py --ip=ESP_IP --host_ip=HOST_IP --host_port=HOST_PORT --file=firmware.bin --debug --progress
```

I wonder if this is due to the network setup (two routers, secondary one set to Access Point mode) or why the address resolution does not work even though communication works just fine.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.