Imroy / pubsubclient

A client library for the ESP8266 that provides support for MQTT
MIT License
434 stars 115 forks source link

Wrong data received via payload_stream()->read() #23

Open av1024 opened 9 years ago

av1024 commented 9 years ago

I don't know where is the bug - in WiFi stack or somewhere else.

I have got broken firmware after OTA update and did some investigations. Looks like all data after some (random per re-flash, not per reboot/publish) offset returned as 0xFF

As an another corresponding bug - "clearing" OTA publish returns false when called after stream i/o but works if called directly after reboot.

all code based on sample ESP8266-OTA, latest arduino/pubsubclient for now. The hardware is ESP-07 with 4MB re-soldered flash

The sample code for checksum testing (note! printing from ESP cause stack error near 0x16F24 offset so disabled by '#if 0' for checksum-only testing):

// main.c 
// $>gcc main.c
// $>./a.out /tmp/build*.tmp/sketch_name.cpp.bin
#include <stdio.h>

void main(int argc, char *argv[]) {
    unsigned short x = 0;
    unsigned short x16 = 0;
    int l = 0;
    int c;
    FILE *f;
    printf("TEST CSUM\n");
    f = fopen(argv[1], "r");
    while((c=fgetc(f)) != EOF) {

        x += (unsigned char) c;
        x16 += (unsigned char) c;
        if (!l) {
            printf("0000:  ");
        }
        if (l && l%32==0) {
            printf(" : 0x%X\n%04X: ", x16, l);
            x16 = 0;
        }
        if (l && l%4==0) printf(" ");
        printf("%02X ", (unsigned char)c);
        l++;
    }
    fclose(f);
    printf("\nSum %d bytes of '%s': %u (0x%X)\n", l, argv[1], x, x);
}

An corresponding code in ESP:

Serial.print(" * Receive OTA: "); Serial.print(size); Serial.println(" bytes...");

    uint16_t csum = 0;
    uint16_t c16 = 0;
    for(int i=0;i<size;i++) {
      unsigned char c = (unsigned char)pub.payload_stream()->read();
   #if 0
      c16 += c;
        if (!i) Serial.print("0000:  ");
        if (i && i%32==0) {
          Serial.print(" : 0x");
          Serial.println(c16, HEX);
          if (i < 0x0010) Serial.print("000");
          else if (i < 0x0100) Serial.print("00");
              else if (i < 0x1000) Serial.print("0");
          Serial.print(i, HEX);
          Serial.print(": ");
          c16 = 0;
        }
        if (i && i%4==0) Serial.print(" ");
        if (c < 16) Serial.print("0");
        Serial.print(c,HEX);
        Serial.print(" ");
      delay(0);
 #endif
      csum += c;
    }
    pub.payload_stream()->stop();
    for(int i=0;i<5;i++) {
      if (mqtt.clear_ota()) break; // pubsubclient.publish(TOPIC, (byte*)"", 0, true) here
      mqtt.loop();
      delay(10);
    }
    for(int i=0;i<10;i++) {
      mqtt.loop();
      delay(10);
    }
    Serial.print(" > OTA CSUM: ");
    Serial.println(csum);

Latest log for binary:

Sum 348080 bytes of '/tmp/build3005941742736874158.tmp/sensor-v2.cpp.bin': 8989 (0x231D)

corresponding serial output:

* Receive OTA: 348080 bytes...
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > OTA CSUM: 37309
 * Receive OTA: 348080 bytes...
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > OTA CSUM: 18836
 * Receive OTA: 348080 bytes...
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > STOP_OTA: '/dev/esp-9e82d0/ota' ->0
 > OTA CSUM: 18836
...