fbiego/ESP32_BLE_OTA_Arduino

esp32_ble_ota getting Incomplete while ota

ravisanapati opened this issue · 8 comments

Hi,
I am running the esp32_ble_ota code on my esp32 cam board, I have flashed the esp32_ble_ota arduino sketch on my esp32 cam board and then uploaded the bin file using the anrdoid app. In android its is showing file transfered 100%, but in serial monitor it is showing "Incomplete Available space: 603153 File Size: 16596862"
In arduino ide I have selected the following from tools tab Partition Scheme as Default 4MB with spiffs(1.2MBAPP/1.5MB SPIFFS), Board as ESP32 Dev Module.
even I have tried with esp32_nim_ble_ota code too ,but is connecting and immediately getting disconnecting.
I have attached serial monitor log for esp32_ble_ota, I am not able to find the problem

serial monitor log:

ets Jun 8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (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:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
Starting BLE OTA sketch
Characteristic defined! Now you can read it in your phone!
TX AA 00
TX F1 00 01
TX F1 00 02
TX F1 00 03
TX F1 00 04
TX F1 00 05
TX F1 00 06
TX F1 00 07
TX F1 00 08
TX F1 00 09
TX F1 00 0A
TX F1 00 0B
TX F1 00 0C
TX F1 00 0D
TX F1 00 0E
TX F1 00 0F
TX F1 00 10
TX F1 00 11
TX F1 00 12
TX F1 00 13
TX F1 00 14
TX F1 00 15
TX F1 00 16
TX F1 00 17
TX F1 00 18
TX F1 00 19
TX F1 00 1A
TX F1 00 1B
TX F1 00 1C
TX F1 00 1D
TX F1 00 1E
TX F1 00 1F
TX F1 00 20
TX F1 00 21
TX F1 00 22
TX F1 00 23
TX F1 00 24
TX F1 00 25
TX F1 00 26
TX F1 00 27
TX F1 00 28
TX F1 00 29
TX F1 00 2A
TX F1 00 2B
TX F1 00 2C
TX F1 00 2D
TX F1 00 2E
TX F2 00 2F
Incomplete
Available space: 603153
File Size: 16596862
Incomplete
Incomplete
Incomplete

The android app has not been updated, I'll try to do that soon

thank sfor reply, can you share any working anrdroid app for testing these ota sketches which is working

try using FFat, comment this line

#define USE_SPIFFS //comment to use FFat

alternatively, you can check out the python code to update from pc

Hi i have the same issue of [ravisanapati] but just by using the android app.
With the python code no issues at all.
Can you confirm that commenting line 39 will fix the issue with the android apk?

Thanks a lot

thank sfor reply, can you share any working anrdroid app for testing these ota sketches which is working

Did you find a solution to this problem?

thank sfor reply, can you share any working anrdroid app for testing these ota sketches which is working

Did you find a solution to this problem?

yes,

#include <Update.h>
#include "FS.h"
#include "FFat.h"
#include "SPIFFS.h"
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>

//#define BUILTINLED 33
//#define LED 4
#define FORMAT_SPIFFS_IF_FAILED true
#define FORMAT_FFAT_IF_FAILED true

#define USE_SPIFFS //comment to use FFat

#ifdef USE_SPIFFS
#define FLASH SPIFFS
#define FASTMODE false //SPIFFS write is slow // FC:F5:C4:00:32:52
#else
#define FLASH FFat
#define FASTMODE true //FFat is faster
#endif

#define NORMAL_MODE 0 // normal
#define UPDATE_MODE 1 // receiving firmware
#define OTA_MODE 2 // installing firmware

uint8_t updater[16384];
uint8_t updater2[16384];

#define SERVICE_UUID "fb1e4001-54ae-4a28-9f74-dfccb248601d"
#define CHARACTERISTIC_UUID_RX "fb1e4002-54ae-4a28-9f74-dfccb248601d"
#define CHARACTERISTIC_UUID_TX "fb1e4003-54ae-4a28-9f74-dfccb248601d"

static BLECharacteristic* pCharacteristicTX;
static BLECharacteristic* pCharacteristicRX;

static bool deviceConnected = false, sendMode = false;
static bool writeFile = false, request = false;
static int writeLen = 0, writeLen2 = 0;
static bool current = true;
static int parts = 0, next = 0, cur = 0, MTU = 0;
static int MODE = NORMAL_MODE;
unsigned long rParts, tParts;

static void rebootEspWithReason(String reason) {
Serial.println(reason);
delay(1000);
ESP.restart();
}

class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
Serial.println("Connected");
deviceConnected = true;

}
void onDisconnect(BLEServer* pServer) {
        Serial.println("disConnected");
  deviceConnected = false;
}

};

class MyCallbacks: public BLECharacteristicCallbacks {

//    void onStatus(BLECharacteristic* pCharacteristic, Status s, uint32_t code) {
//      Serial.print("Status ");
//      Serial.print(s);
//      Serial.print(" on characteristic ");
//      Serial.print(pCharacteristic->getUUID().toString().c_str());
//      Serial.print(" with code ");
//      Serial.println(code);
//    }

void onNotify(BLECharacteristic *pCharacteristic) {
  uint8_t* pData;
  std::string value = pCharacteristic->getValue();
  int len = value.length();
  pData = pCharacteristic->getData();
  if (pData != NULL) {
    //        Serial.print("Notify callback for characteristic ");
    //        Serial.print(pCharacteristic->getUUID().toString().c_str());
    //        Serial.print(" of data length ");
    //        Serial.println(len);
    Serial.print("TX  ");
    for (int i = 0; i < len; i++) {
      Serial.printf("%02X ", pData[i]);
    }
    Serial.println();
  }
}

void onWrite(BLECharacteristic *pCharacteristic) {
  uint8_t* pData;
  std::string value = pCharacteristic->getValue();
  int len = value.length();
  pData = pCharacteristic->getData();
  if (pData != NULL) {
    //        Serial.print("Write callback for characteristic ");
    //        Serial.print(pCharacteristic->getUUID().toString().c_str());
    //        Serial.print(" of data length ");
    //        Serial.println(len);
    //        Serial.print("RX  ");
    //        for (int i = 0; i < len; i++) {         // leave this commented
    //          Serial.printf("%02X ", pData[i]);
    //        }
    //        Serial.println();

    if (pData[0] == 0xFB) {
      int pos = pData[1];
      //Serial.println(" hi 2");
      for (int x = 0; x < len - 2; x++) {
        if (current) {
          updater[(pos * MTU) + x] = pData[x + 2];
        } else {
          updater2[(pos * MTU) + x] = pData[x + 2];
        }
      }

    } else if  (pData[0] == 0xFC) {
      if (current) {
        writeLen = (pData[1] * 256) + pData[2];
      } else {
        writeLen2 = (pData[1] * 256) + pData[2];
      }
      current = !current;
      cur = (pData[3] * 256) + pData[4];
      writeFile = true;
      if (cur < parts - 1) {
        request = !FASTMODE;
      }
    } else if (pData[0] == 0xFD) {
      sendMode = true;
      if (FLASH.exists("/update.bin")) {
        FLASH.remove("/update.bin");
      }
    }  else if  (pData[0] == 0xFF) {
      parts = (pData[1] * 256) + pData[2];
      MTU = (pData[3] * 256) + pData[4];
      MODE = UPDATE_MODE;

    } /*else if (pData[0] == 0xFE) {
      rParts = 0;
      tParts = (pData[1] * 256 * 256 * 256) + (pData[2] * 256 * 256) + (pData[3] * 256) + pData[4];

      Serial.print("Available space: ");
      Serial.println(FLASH.totalBytes() - FLASH.usedBytes());
      Serial.print("File Size: ");
      Serial.println(tParts);

    } */


  }

}

};

static void writeBinary(fs::FS &fs, const char * path, uint8_t *dat, int len) {

//Serial.printf("Write binary file %s\r\n", path);

File file = fs.open(path, FILE_APPEND);

if (!file) {
Serial.println("- failed to open file for writing");
return;
}
file.write(dat, len);
file.close();
writeFile = false;
rParts += len;
}

void sendOtaResult(String result) {
pCharacteristicTX->setValue(result.c_str());
pCharacteristicTX->notify();
delay(200);
}

void performUpdate(Stream &updateSource, size_t updateSize) {
char s1 = 0x0F;
String result = String(s1);
if (Update.begin(updateSize)) {
size_t written = Update.writeStream(updateSource);
if (written == updateSize) {
Serial.println("Written : " + String(written) + " successfully");
}
else {
Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
}
result += "Written : " + String(written) + "/" + String(updateSize) + " [" + String((written / updateSize) * 100) + "%] \n";
if (Update.end()) {
Serial.println("OTA done!");
result += "OTA Done: ";
if (Update.isFinished()) {
Serial.println("Update successfully completed. Rebooting...");
result += "Success!\n";
}
else {
Serial.println("Update not finished? Something went wrong!");
result += "Failed!\n";
}

}
else {
  Serial.println("Error Occurred. Error #: " + String(Update.getError()));
  result += "Error #: " + String(Update.getError());
}

}
else
{
Serial.println("Not enough space to begin OTA");
result += "Not enough space for OTA";
}
if (deviceConnected) {
sendOtaResult(result);
delay(5000);
}
}

void updateFromFS(fs::FS &fs) {
File updateBin = fs.open("/update.bin");
if (updateBin) {
if (updateBin.isDirectory()) {
Serial.println("Error, update.bin is not a file");
updateBin.close();
return;
}

size_t updateSize = updateBin.size();

if (updateSize > 0) {
  Serial.println("Trying to start update");
  performUpdate(updateBin, updateSize);
}
else {
  Serial.println("Error, file is empty");
}

updateBin.close();

// when finished remove the binary from spiffs to indicate end of the process
Serial.println("Removing update file");
fs.remove("/update.bin");

rebootEspWithReason("Rebooting to complete OTA update");

}
else {
Serial.println("Could not load update.bin from spiffs root");
}
}

void initBLE() {
BLEDevice::init("ESP32 OTA");
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());

BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristicTX = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY );
pCharacteristicRX = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_WRITE_NR);
pCharacteristicRX->setCallbacks(new MyCallbacks());
pCharacteristicTX->setCallbacks(new MyCallbacks());
pCharacteristicTX->addDescriptor(new BLE2902());
pCharacteristicTX->setNotifyProperty(true);
pService->start();

// BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println("Characteristic defined! Now you can read it in your phone!");
//Serial.println(BLEDevice);
}

void setup() {
Serial.begin(115200);
Serial.println("OLD version");
Serial.println("Starting BLE OTA sketch");
//pinMode(BUILTINLED, OUTPUT);
//pinMode(LED, OUTPUT);
//digitalWrite(LED, LOW);

#ifdef USE_SPIFFS
if (!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
Serial.println("SPIFFS Mount Failed");
return;
}
#else
if (!FFat.begin()) {
Serial.println("FFat Mount Failed");
if (FORMAT_FFAT_IF_FAILED) FFat.format();
return;
}
#endif

initBLE();

}

void loop() {

switch (MODE) {

case NORMAL_MODE:
  if (deviceConnected) {
    //digitalWrite(BUILTINLED, HIGH);
    if (sendMode) {
      uint8_t fMode[] = {0xAA, FASTMODE};
      pCharacteristicTX->setValue(fMode, 2);
      pCharacteristicTX->notify();
      delay(50);
      sendMode = false;
    }

    // your loop code here
  } else {
    //digitalWrite(BUILTINLED, LOW);
  }
  //digitalWrite(LED, LOW);
  //delay(70);
  //digitalWrite(LED, HIGH);
  // or here

  break;

case UPDATE_MODE:

  if (request) {
    uint8_t rq[] = {0xF1, (cur + 1) / 256, (cur + 1) % 256};
    pCharacteristicTX->setValue(rq, 3);
    pCharacteristicTX->notify();
    delay(50);
    request = false;
  }

  if (cur + 1 == parts) { // received complete file
    uint8_t com[] = {0xF2, (cur + 1) / 256, (cur + 1) % 256};
    pCharacteristicTX->setValue(com, 3);
    pCharacteristicTX->notify();
    delay(50);
    MODE = OTA_MODE;
  }

  if (writeFile) {
    //Serial.println("write file in update mode");
    if (!current) {
      writeBinary(FLASH, "/update.bin", updater, writeLen);
    } else {
      writeBinary(FLASH, "/update.bin", updater2, writeLen2);
    }
  } 

  break;

case OTA_MODE:

  /*if (writeFile) {
    if (!current) {
      writeBinary(FLASH, "/update.bin", updater, writeLen);
    } else {
      writeBinary(FLASH, "/update.bin", updater2, writeLen2);
    }
  } 
  Serial.println("in ota mode");  
  
  if (rParts == tParts) {
    //Serial.println("Complete");
    delay(1000);
    //updateFromFS(FLASH);
  } else {
    writeFile = true;
    Serial.println("complete");
    delay(3000);
    updateFromFS(FLASH);
  }  */
  writeFile = true;
  Serial.println("complete");
  delay(3000);
  updateFromFS(FLASH);
  break;

}

}

try this,its working for me

Thanks Mr [ravisanapati]..
Did you try to update the firmware by using the python script after your changes just to see it is still working?
Thanks a lot

Using python this won't work this works with the android app, the code in the repository..work with python.....there is only few lines change if use the commented lines in OTA_MODE(between /.../) Python code will work...if you want update with Android app comment those lines... calling updateFromFS(FLASH); function at different places is only the difference...for using it python and Android app