boolean OTAUpdateClass::copyFile(const char* src, const char* dst) {
    char buffer[DIGEST_SIZE_BUFFER];

    LFlash.begin();
    LFile fsrc = LFlash.open(src, FILE_READ);
    if(!fsrc) {
        DEBUG_UPDATE("OTAUpdate::copyFile - error opening src %s\r\n", src);
        return false;
    }
    LFile fdst = LFlash.open(dst, FILE_WRITE);
    if(!fsrc) {
        fsrc.close();
        DEBUG_UPDATE("OTAUpdate::copyFile - error opening dst %s\r\n", dst);
        return false;
    }

    fdst.seek(0);
    int size = fsrc.size();
    int done = 0;
    while(done < size) {
        int read = fsrc.read(buffer, DIGEST_SIZE_BUFFER);
        fdst.write(buffer, read);
        done += read;
    }
    fsrc.close();
    fdst.close();

    return true;
}
boolean OTAUpdateClass::begin(const char* host, const char* port, const char* path) {
    DEBUG_UPDATE("OTAUpdate::begin - %s %s\r\n", host, path);

    // initialize our memory structures
    this->initialized = false;
    memset(this->firmware_name, 0, OTA_MAX_PATH_LEN);
    memset(this->firmware_digest, 0, DIGEST_SIZE_CHAR);
    memset(this->host, 0, OTA_MAX_PATH_LEN);
    memset(this->path, 0, OTA_MAX_PATH_LEN);
    memset(this->port, 0, OTA_MAX_PATH_LEN);
    strncpy(this->host, host, OTA_MAX_PATH_LEN-1);
    strncpy(this->path, path, OTA_MAX_PATH_LEN-1);
    strncpy(this->port, port, OTA_MAX_PATH_LEN-1);

    // read the firmware information
    LFlash.begin();
    LFile cfg = LFlash.open("autostart.txt", FILE_READ);
    if (!cfg) {
        DEBUG_UPDATE("OTAUpdateClass::begin - could not read autostart.txt\r\n");
        return false;
    }

    DEBUG_UPDATE("OTAUpdateClass::begin - reading autostart.txt\r\n");
    while (cfg.available()) {
        String line = "";
        char c = '\n';
        // read the setting part of the line
        while (cfg.available()) {
            c = cfg.read();
            line += c;
            if(c == '\n') {
                break;
            }
        }

        // look for = in the config line
        line.trim();
        int idx = line.indexOf("=");

        if(idx >= 0) {
            String setting = line.substring(0, idx);
            String value = line.substring(idx+1);

            setting.trim();
            value.trim();

            DEBUG_UPDATE("autostart.txt: %s=%s\r\n", setting.c_str(), value.c_str());
            if(setting == "App") {
                value.toCharArray(firmware_name, OTA_MAX_PATH_LEN);
                this->initialized = true;
                break;
            }
        }
    }
    cfg.close();

    if(this->initialized) {
        // we found the app name... calculate the md5 sum
        md5sum(this->firmware_name, this->firmware_digest);
        DEBUG_UPDATE("OTAUpdate::begin - %s [%s]\r\n", this->firmware_name, this->firmware_digest);
    } else {
        DEBUG_UPDATE("OTAUpdate::begin - could not find firmware name\r\n");
        return false;
    }

    return true;
}