ESP32 OTA via bluetooth

I have an ESP32 and I can successfully perform an OTA (Over-the-Air) update by downloading a .bin firmware file from my server using WiFi.

I use the following function for that:

#include <WiFi.h>
#include <HTTPClient.h>
#include <Update.h> 

void OTA() { 
  HTTPClient http;
  http.begin("http://example.com/firmware.bin");

  int httpCode = http.GET();

  if (httpCode == HTTP_CODE_OK) {
    int contentLength = http.getSize();
    WiFiClient *stream = http.getStreamPtr();
    Update.begin(contentLength);
    size_t written = Update.writeStream(*stream);

    if (written == contentLength) {
      Serial.println("Firmware downloaded");

      if (Update.end()) {
        Serial.println("Firmware Installed");
        ESP.restart();
      } 
    } 
  } 

  http.end();
}

Now, I want to remove WiFi entirely from my project and instead send the firmware file via Bluetooth from an Android phone to the ESP32.

My Questions:

Is it possible to send the .bin file from an Android phone to the ESP32 using Bluetooth and install it same as it does via wifi?

Any guidance, code snippets, or references would be greatly appreciated!

Thanks in advance!

ESP32 is a name for a family of different boards. I'll not solve the matter but for more knowing ESP-helpers it is likely valuable to know.

my idea is something like this:

so if i call OTA function and then use "serial bluetooth terminal app" to send bin file



#include <BluetoothSerial.h>
BluetoothSerial ble_serial;  // Create Bluetooth Serial object
#include <Update.h>


void setup(){
  ble_serial.begin("ar_123");  // Initialize Bluetooth with a specific name
}

void loop(){
 if (SerialBT.available()) {
    String command = SerialBT.readStringUntil('\n');

    if (command == "OTA?") {
      Serial.println("OTA Command Received! Ready for firmware...");
      SerialBT.println("Send Firmware Now...");
      OTA();
    }
  }
}



void OTA() {
  ble_serial.println("Waiting for firmware file via Bluetooth...");

  // Wait for the first data packet
  while (!ble_serial.available()) {
    delay(100);
  }

  // Begin OTA update with unknown file size
  if (!Update.begin(UPDATE_SIZE_UNKNOWN)) {
    ble_serial.println("Failed to start OTA update.");
    return;
  }

  size_t written = 0;
  unsigned long lastDataTime = millis();

  while (true) {
    if (ble_serial.available()) {
      uint8_t data = ble_serial.read();  // Read one byte at a time
      Update.write(&data, 1);
      written++;
      lastDataTime = millis();  // Reset timeout timer
    }

    // Check for timeout (no data received for 5 seconds)
    if (millis() - lastDataTime > 5000) {
      ble_serial.println("Timeout: No data received.");
      Update.abort();
      return;
    }

    // Check if update is complete
    if (Update.isFinished()) {
      break;
    }
  }

  ble_serial.printf("Firmware received: %d bytes\n", written);

  if (Update.end()) {
    ble_serial.println("Firmware Installed! Restarting...");
    ESP.restart();
  } else {
    ble_serial.println("Firmware Update Failed!");
  }
}