jeelabs / esp-link

esp8266 wifi-serial bridge, outbound TCP, and arduino/AVR/LPC/NXP programmer
Other
2.82k stars 720 forks source link

TCP socket not delivery data #562

Open alex0732 opened 1 year ago

alex0732 commented 1 year ago

Hi! There is a bunch of arduino MEGA256 - esp8266. It works fine, correctly sends data to the server via MQTT. It is required to remake on TCP-socket. I do as in the example, in debug I see the following output: 185270> SOCKET #0: send dataLen=135 socketData=#A0:20:A6:02:20:9C 185270> #t2#10.7 185270> #h2#63.5 185270> #p2#763.9 185270> #v2#3.04 185270> #t1#-12.5 185270> #h1#84.8 185271> #v1#2.95 185271> #h0#45.6 185271> #t0#21.5 185271> #l0#29 185271> #tr#20.0 185271> #D1#94 185271> #D2#107 185271> ##�n�?( 185271> SOCKET #0: Create connection to ip 185.245.187.136:8283 185271> SOCKET #0: Connect to ip 185.245.187.136:8283 187969> HTTP GET /console/text: 200, 107ms, h=17424 188577> HTTP GET /console/text: 200, 47ms, h=17424 189268> SLIP: start or end len=0 inpkt=0 189268> SLIP: start or end len=10 inpkt=1 189268> cmdParsePacket: cmd=4 argc=0 value=0 189269> cmdExec: Dispatching cmd=WIFI_STATUS 189269> cmdResponse: cmd=2 val=2 argc=0 191558> SOCKET #0: conn reset, err=-11 No data is sent to the server. Confusing extra bytes "�n�?(" after "##", they are not in the original packet. "##" - is the end of packet. The python test script delivers data to the server normally. Tried with firmware esp-link v3.0.14-g963ffbb and v3.2.47-g9c6530d. El-client - last release. What is my problem? err=-11 - is normally closed session?

JDP-Maker commented 1 year ago

This looks like a baud rate problem. Confusing extra bytes "�n�?(" after "##",

alex0732 commented 1 year ago

Thanks for trying to help. I don't think there are any problems with data transfer speed: with the same settings, MQTT works correctly. And all my data in the debugger is shown correctly, only the tail is added. My data is from the first # to two ## in a row, and everything is correct. Baud rate set to 115200. Does transmission via ESP-link using TCP-socket work correctly for anyone?

alex0732 commented 1 year ago

I looked a little El-Clietnt's source. "Extra" bytes are like CRC. So the version of the wrong speed is not accepted. From the source: // output padding uint16_t pad = (4-(len&3))&3; uint8_t temp = 0; while (pad--) { write(temp); crc = crc16Add(temp, crc); Although no more than 3 bytes should be written here: 0 and 2 bytes CRC. I will break further. There is only no time for this.

uzi18 commented 1 year ago

@alex0732 please show your test code

alex0732 commented 1 year ago

My test code very big... Exaple from el-client-master does not work exactly the same. https://github.com/jeelabs/el-client/blob/master/ELClient/examples/tcp_client/tcp_client.ino

alex0732 commented 1 year ago

I will try to make a small test code, later.

alex0732 commented 1 year ago

My small test code:

include

include

char * const tcpServer PROGMEM = "narodmon.ru"; uint16_t const tcpPort PROGMEM = 8283;

ELClient esp(&Serial);

//########################################################### // For boards using the hardware serial port! //########################################################### // Initialize a connection to esp-link using the normal hardware serial port both for // SLIP and for debug messages. //ELClient esp(&Serial, &Serial);

// Initialize a TCP socket client on the connection to esp-link ELClientSocket tcp(&esp); int tcpConnNum;

uint32_t wait; // Timer value to send out data uint32_t waitTime; // Time to wait between sending out data boolean wifiConnected = false; // Flag for wifi connection

// Parse error codes and returns error message as char * // Definitions from error values from espconn.h (Espressif SDK) // #define ESPCONN_OK 0 /< No error, everything OK. */ // #define ESPCONN_MEM -1 /*< Out of memory. / // #define ESPCONN_TIMEOUT -3 /< Timeout. */ // #define ESPCONN_RTE -4 /< Routing problem. */ // #define ESPCONN_INPROGRESS -5 /*< Operation in progress. / // #define ESPCONN_MAXNUM -7 /< Total number exceeds the maximum limitation. */

// #define ESPCONN_ABRT -8 /< Connection aborted. */ // #define ESPCONN_RST -9 /*< Connection reset. / // #define ESPCONN_CLSD -10 /< Connection closed. */ // #define ESPCONN_CONN -11 /*< Not connected. /

// #define ESPCONN_ARG -12 /< Illegal argument. */ // #define ESPCONN_IF -14 /*< UDP send error. / // #define ESPCONN_ISCONN -15 /< Already connected. */

char const errTxt[] PROGMEM = {"No error, everything OK.","Out of memory.","Unknown code.","Timeout.","Routing problem.","Operation in progress.", "Unknown code.","Total number exceeds the maximum limitation.","Connection aborted.","Connection reset.","Connection closed.", "Not connected.","Illegal argument.","Unknown code.","UDP send error.","Already connected."}; char getErrTxt(int16_t commError) { commError = commError-1; if (commError <= 15) { return (char ) pgm_read_word (&errTxt[commError]); } else { return (char *) pgm_read_word (&errTxt[2]); // Unknown code } }

// Callback for TCP socket, called if data was sent or received // Receives socket client number, can be reused for all initialized TCP socket connections void tcpCb(uint8_t resp_type, uint8_t client_num, uint16_t len, char *data) { Serial.println("tcpCb connection #"+String(client_num)); if (resp_type == USERCB_SENT) { Serial.println("\tSent " + String(len) + " bytes over client#" + String(client_num)); } else if (resp_type == USERCB_RECV) { char recvData[len+1]; // Prepare buffer for the received data memcpy(recvData, data, len); // Copy received data into the buffer recvData[len] = '\0'; // Terminate the buffer with 0 for proper printout!

    Serial.println("\tReceived " + String(len) + " bytes over the client on connection #" + String(client_num));
    Serial.println("\tReceived: " + String(recvData));
} else if (resp_type == USERCB_RECO) {
    if (len != -11) { // ignore "not connected" error, handled in USERCB_CONN
        Serial.print("\tConnection problem: ");
        Serial.println(getErrTxt(len));
    }
} else if (resp_type == USERCB_CONN) {
    if (len == 0) {
        Serial.println("\tDisconnected");
    } else {
        Serial.println("\tConnected");
    }
} else {
    Serial.println("Received invalid response type");
}

}

// Callback made from esp-link to notify of wifi status changes // Here we print something out and set a global flag void wifiCb(void response) { ELClientResponse res = (ELClientResponse*)response; if (res->argc() == 1) { uint8_t status; res->popArg(&status, 1);

    if(status == STATION_GOT_IP) {
        Serial.println(F("WIFI CONNECTED"));
        wifiConnected = true;
    } else {
        Serial.print(F("WIFI NOT READY: "));
        Serial.println(status);
        wifiConnected = false;
    }
}

}

void setup() { Serial.begin(9600); Serial.println(F("EL-Client starting!"));

// Sync-up with esp-link, this is required at the start of any sketch and initializes the
// callbacks to the wifi status change callback. The callback gets called with the initial
// status right after Sync() below completes.
esp.wifiCb.attach(wifiCb); // wifi status change callback, optional (delete if not desired)
bool ok;
do {
    ok = esp.Sync();            // sync up with esp-link, blocks for up to 2 seconds
    if (!ok) Serial.println(F("EL-Client sync failed!"));
} while(!ok);
Serial.println(F("EL-Client synced!"));

// Wit for WiFi to be connected. 
esp.GetWifiStatus();
ELClientPacket *packet;
Serial.print(F("Waiting for WiFi "));
if ((packet=esp.WaitReturn()) != NULL) {
    Serial.print(F("."));
    Serial.println(packet->value);
}
Serial.println("");

// Set up the TCP socket client for a connection to <tcpServer> on port <>, this doesn't connect to that server,
// it just sets-up stuff on the esp-link side and waits until we send some data
tcpConnNum = tcp.begin(tcpServer, tcpPort, SOCKET_TCP_CLIENT, tcpCb); // SOCKET_CLIENT ==> we don't expect a response
if (tcpConnNum < 0) {
    Serial.println(F("TCP socket setup failed, try again in 10 seconds after reboot"));
    delay(10000);
    asm volatile ("  jmp 0");
} else {
    Serial.println(String(tcpServer)+":"+String(tcpPort)+" is served over connection number # = "+String(tcpConnNum));
}

Serial.println(F("EL-TCP ready"));
wait = millis()+29000; // Start first sending in 1 second

}

void loop() { // process any callbacks coming from esp_link esp.Process();

// if we're connected send data over TCP socket
if(wifiConnected) {
    if (millis() - wait > 30000) { // Send some data every 30 seconds
        wait = millis();

        // Send message to the previously set-up server #1
        Serial.print(F("Sending message to "));
        Serial.print(tcpServer);
        Serial.print(":");
        Serial.println(tcpPort);
        tcp.send("#A0:20:A6:02:20:9C\n#t1#14.34\n#h1#26\n#p1#715.9\n##");
    }
} else {
    // This is just for demo, you can as well just try to reconnect
    // and setup the connection to esp-link again 
    Serial.println(F("Lost WiFi connection, try to reboot"));
    delay(10000);
    asm volatile ("  jmp 0");
}

}

/ =============================================================== / Result: Console: EL-Client starting! EL-Client synced! Waiting for WiFi WIFI CONNECTED .2

narodmon.ru:8283 is served over connection number # = 1 EL-TCP ready Sending message to narodmon.ru:8283 tcpCb connection #1 / =============================================================== /

Debug: 200818> SLIP: start or end len=37 inpkt=0 200893> SLIP: start or end len=110 inpkt=1 200894> cmdParsePacket: cmd=41 argc=2 value=1 200894> cmdExec: Dispatching cmd=SOCKET_SEND 200894> SOCKET #1: send dataLen=48 socketData=#A0:20:A6:02:20:9C 200894> #t1#14.34 200894> #h1#26 200894> #p1#715.9 200894> ##o�?� 200894> SOCKET #1: Create connection to ip narodmon.ru:8283 200895> SOCKET #1: Connect to host narodmon.ru:8283 200904> SOCKET #1 DNS: found ip 185.245.187.136 200905> SOCKET #1: connecting... 207141> SOCKET #1: conn reset, err=-11 207141> cmdResponse: cmd=3 val=1113 argc=3

alex0732 commented 1 year ago

Script powershell, succefull send data:

$server = 'narodmon.ru' $port = 8283 $message = '#A0:20:A6:02:20:9C\n#t1#14.34\n#h1#26\n#p1#715.9\n##' $ip = [System.Net.Dns]::GetHostAddresses($server) | Where-Object {$PSItem.AddressFamily -eq 'InterNetwork'} $socket = New-Object System.Net.Sockets.TCPClient($ip, $port) $stream = $socket.GetStream() $writer = New-Object System.IO.StreamWriter($stream) foreach ($line in $message){ $writer.WriteLine($line) $writer.Flush() } $stream.Dispose() $stream.Close() $socket.Close()

uzi18 commented 1 year ago

@alex0732 err -11 means not connected

uzi18 commented 1 year ago

@JDP-Maker �o�?� it is print error nothing special.

alex0732 commented 1 year ago

This is CRC - https://github.com/jeelabs/esp-link/issues/562#issuecomment-1379220157. But even if this is not the case - why does the data not go to the server? What is wrong, where?

uzi18 commented 1 year ago

This CRC shouldn't be printed at all I think it is not esp-link fault. Try with raw IP instead hostname.

alex0732 commented 1 year ago

Thanks for the advice. I agree about CRC. I tried to use the unprocessed IP, the same result. In addition, DNS correctly finds IP: 200894> SOCKET #1: Create connection to ip narodmon.ru:8283 200895> SOCKET #1: Connect to host narodmon.ru:8283 200904> SOCKET #1 DNS: found ip 185.245.187.136 Are there any more ideas?