int transfer_file(char* filename) { int fd_read = cfs_open(filename, CFS_READ); if (fd_read == -1) { log_error("cfs_open(%s) failed\n", filename); return -1; } cfs_offset_t pos = -1; if ((pos = cfs_seek(fd_read, 0, CFS_SEEK_END)) == -1) { log_error("cfs_seek(%s) to file end failed", filename); cfs_close(fd_read); return -1; } if ((pos = cfs_seek(fd_read, 0, CFS_SEEK_SET)) == -1) { log_error("cfs_seek(%s) to file begin failed", filename); cfs_close(fd_read); return -1; } init_file_reader(&_f_reader); strcpy(_f_reader.file_name, filename); _f_reader.send_fd = begin_send_file(filename); _f_reader.read_fd = fd_read; _f_reader.file_size = (uint16_t)pos; send_file_block(_f_reader.send_fd); return 0; }
void elfloader_arch_write_rom(int fd, unsigned short textoff, unsigned int size, char *mem) { #if ELFLOADER_CONF_TEXT_IN_ROM uint32_t ptr; int nbytes; cfs_seek(fd, textoff, CFS_SEEK_SET); cfs_seek(fd, textoff, CFS_SEEK_SET); /* Read data from file into RAM. */ nbytes = cfs_read(fd, (unsigned char *)datamemory, READSIZE); PRINTF("Bytes read: %d\n", nbytes); flash_erase_memory_page((uint32_t)mem); for(ptr = 0; ptr < size; ptr += 2) { uint16_t data; data = datamemory[ptr + 1]; data = data << 8; data |= datamemory[ptr]; /* Write data to flash. */ //PRINTF("Writing %x to %x\n", data, (uint32_t)mem + ptr); flash_write_memory_half_word((uint32_t) mem + ptr, data); } for(ptr = 0; ptr < size; ptr += 2) { uint16_t* data = (uint16_t*)(mem + ptr); /* Write data to flash. */ //PRINTF("Reading %x to %p\n", *data, data); } #else /* ELFLOADER_CONF_TEXT_IN_ROM */ PRINTF("Using serial flash\n"); cfs_seek(fd, textoff, CFS_SEEK_SET); cfs_read(fd, (unsigned char *)mem, size); #endif /* ELFLOADER_CONF_TEXT_IN_ROM */ }
db_result_t storage_read(db_storage_id_t fd, void *buffer, unsigned long offset, unsigned length) { char *ptr; int r; /* Extend the file if necessary, so that previously unwritten bytes will be read in as zeroes. */ if(cfs_seek(fd, offset + length, CFS_SEEK_SET) == (cfs_offset_t)-1) { return DB_STORAGE_ERROR; } if(cfs_seek(fd, offset, CFS_SEEK_SET) == (cfs_offset_t)-1) { return DB_STORAGE_ERROR; } ptr = buffer; while(length > 0) { r = cfs_read(fd, ptr, length); if(r <= 0) { return DB_STORAGE_ERROR; } ptr += r; length -= r; } return DB_OK; }
static int sendDelugeGroup(void* inst, ContainerRoot* model) { // so, we receive a new model to distribute DelugeGroup* instance = (DelugeGroup*) inst; PRINTF("Sending with DELUGE %p %p\n", instance->lastReceivedModel, model); /* we don't want to resend the model as if we were the creators if we just received */ if (instance->lastReceivedModel == model){ return 0; } PRINTF("Sending the model through deluge\n"); // TODO serialize model to a file // TODO calculate number of pages in the file int fd = cfs_open(instance->fileNameWithModel, CFS_READ); cfs_offset_t offset = cfs_seek(fd, 0, CFS_SEEK_END); uint16_t nPages = offset / S_PAGE; cfs_close(fd); if (offset % S_PAGE != 0) { uint16_t mod = offset % S_PAGE; PRINTF("INFO: +++++++++++++++++++++++++ %d\n", mod); mod = S_PAGE - mod; char* buf = (char*)malloc(mod); memset(buf, ' ', mod); fd = cfs_open(instance->fileNameWithModel, CFS_WRITE | CFS_APPEND); cfs_seek(fd, 0, CFS_SEEK_END); cfs_write(fd, buf, mod); cfs_close(fd); free(buf); nPages++; } // set my local announcement to the new version instance->info.version = instance->info.version + 1; instance->info.nr_pages = nPages; // FIXME distribute announcement to other motes #if 0 announcement_bump(&instance->a); #endif // activate deluge if (deluge_disseminate(instance->fileNameWithModel, 1, NULL)) { PRINTF("ERROR: some problem dissemineting\n"); } else { PRINTF("INFO: dissemineting new version of the file with version %d\n", newVersion); } return 0; }
/*---------------------------------------------------------------------*/ static u16_t send_udpdata(struct codeprop_udphdr *uh) { u16_t len; uh->type = HTONS(TYPE_DATA); uh->addr = htons(s.addr); uh->id = htons(s.id); if(s.len - s.addr > UDPDATASIZE) { len = UDPDATASIZE; } else { len = s.len - s.addr; } cfs_seek(fd, s.addr, CFS_SEEK_SET); cfs_read(fd, &uh->data[0], len); /* eeprom_read(EEPROMFS_ADDR_CODEPROP + s.addr, &uh->data[0], len);*/ uh->len = htons(s.len); PRINTF(("codeprop: sending packet from address 0x%04x\n", s.addr)); uip_udp_send(len + UDPHEADERSIZE); return len; }
/*---------------------------------------------------------------------------*/ static void write_chunk(struct rudolph2_conn *c, int offset, int flag, uint8_t *data, int datalen) { int fd; #if CONTIKI_TARGET_NETSIM { char buf[100]; sprintf(buf, "%d%%", (100 * (offset + datalen)) / FILESIZE); ether_set_text(buf); } #endif /* CONTIKI_TARGET_NETSIM */ if(flag == RUDOLPH2_FLAG_NEWFILE) { printf("+++ rudolph2 new file incoming at %lu\n", clock_time()); leds_on(LEDS_RED); fd = cfs_open("codeprop.out", CFS_WRITE); } else { fd = cfs_open("codeprop.out", CFS_WRITE + CFS_APPEND); } if(datalen > 0) { int ret; cfs_seek(fd, offset, CFS_SEEK_SET); ret = cfs_write(fd, data, datalen); printf("+++ rudolph2 offset %d, length %d\n", offset, datalen); } cfs_close(fd); if(flag == RUDOLPH2_FLAG_LASTCHUNK) { int i; printf("+++ rudolph2 entire file received at %d, %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]); leds_off(LEDS_RED); leds_on(LEDS_YELLOW); fd = cfs_open("hej", CFS_READ); for(i = 0; i < FILESIZE; ++i) { unsigned char buf; int r = cfs_read(fd, &buf, 1); if (r != 1) { printf("%d.%d: error: read failed at %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], i); break; } else if(buf != (unsigned char)i) { printf("%d.%d: error: diff at %d, %d != %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], i, (unsigned char)i, buf); break; } } #if CONTIKI_TARGET_NETSIM ether_send_done(); #endif cfs_close(fd); } }
/* Flush tmpdata to CFS */ static int queuebuf_flush_tmpdata(void) { int fileid, fd, ret; cfs_offset_t offset; if(tmpdata_qbuf) { queuebuf_remove_from_file(tmpdata_qbuf->swap_id); tmpdata_qbuf->swap_id = get_new_swap_id(); if(tmpdata_qbuf->swap_id == -1) { return -1; } fileid = tmpdata_qbuf->swap_id / NQBUF_PER_FILE; offset = (tmpdata_qbuf->swap_id % NQBUF_PER_FILE) * sizeof(struct queuebuf_data); fd = qbuf_files[fileid].fd; ret = cfs_seek(fd, offset, CFS_SEEK_SET); if(ret == -1) { PRINTF("queuebuf_flush_tmpdata: cfs seek error\n"); return -1; } ret = cfs_write(fd, &tmpdata, sizeof(struct queuebuf_data)); if(ret == -1) { PRINTF("queuebuf_flush_tmpdata: cfs write error\n"); return -1; } } return 0; }
/* If the queuebuf is in CFS, load it to tmpdata */ static struct queuebuf_data * queuebuf_load_to_ram(struct queuebuf *b) { int fileid, fd, ret; cfs_offset_t offset; if(b->location == IN_RAM) { /* the qbuf is loacted in RAM */ return b->ram_ptr; } else { /* the qbuf is located in CFS */ if(tmpdata_qbuf && tmpdata_qbuf->swap_id == b->swap_id) { /* the qbuf is already in tmpdata */ return &tmpdata; } else { /* the qbuf needs to be loaded from CFS */ tmpdata_qbuf = b; /* read the qbuf from CFS */ fileid = b->swap_id / NQBUF_PER_FILE; offset = (b->swap_id % NQBUF_PER_FILE) * sizeof(struct queuebuf_data); fd = qbuf_files[fileid].fd; ret = cfs_seek(fd, offset, CFS_SEEK_SET); if(ret == -1) { PRINTF("queuebuf_load_to_ram: cfs seek error\n"); } ret = cfs_read(fd, &tmpdata, sizeof(struct queuebuf_data)); if(ret == -1) { PRINTF("queuebuf_load_to_ram: cfs read error\n"); } return &tmpdata; } } }
/** File read callback. * Responds to a SBP_MSG_FILEIO_READ_REQUEST message. * * Reads a certain length (up to 255 bytes) from a given offset. Returns the * data in a SBP_MSG_FILEIO_READ_RESPONSE message where the message length field * indicates how many bytes were succesfully read. */ static void read_cb(u16 sender_id, u8 len, u8 msg[], void* context) { (void)context; if (sender_id != SBP_SENDER_ID) { log_error("Invalid sender!\n"); return; } if ((len < 9) || (msg[len-1] != '\0')) { log_error("Invalid fileio read message!\n"); return; } u32 offset = ((u32)msg[3] << 24) | ((u32)msg[2] << 16) | (msg[1] << 8) | msg[0]; u8 readlen = MIN(msg[4], SBP_FRAMING_MAX_PAYLOAD_SIZE - len); u8 buf[256]; memcpy(buf, msg, len); int f = cfs_open((char*)&msg[5], CFS_READ); cfs_seek(f, offset, CFS_SEEK_SET); len += cfs_read(f, buf + len, readlen); cfs_close(f); sbp_send_msg(SBP_MSG_FILEIO_READ_RESPONSE, len, buf); }
off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence) { if (fd < 0) { /* invalid file descriptor */ r->_errno = EBADF; return -1; } if (fd >= MAX_OPEN_DEVICES) { int ret; /* CFS file */ fd -= MAX_OPEN_DEVICES; /* Remap to CFS FD number */ /* CFS_SEEK_* macros used by the CFS whence parameter is assumed to * correspond with POSIX constants */ /* this is not really reentrant */ ret = cfs_seek(fd, offset, whence); if (ret < 0) { r->_errno = EBADF; } return ret; } if (devoptab_list[fd] == NULL) { /* nothing mapped on that FD */ r->_errno = EBADF; return -1; } if (devoptab_list[fd]->lseek_r == NULL) { /* Function not implemented */ r->_errno = ENOSYS; return -1; } /* Call method from device operations table */ return devoptab_list[fd]->lseek_r(r, fd, offset, whence); }
static void send_file_block(int para) { uint8_t buf[200]; cfs_seek(_f_reader.read_fd, _f_reader.read_cursor, CFS_SEEK_SET); _f_reader.sent_bytes = cfs_read(_f_reader.read_fd, buf, sizeof(buf)); send_file_data(para, buf, _f_reader.sent_bytes, send_file_callback, para); log_info("send_file_block(%d), %d, %d\n", para, _f_reader.sent_bytes, _f_reader.read_cursor); }
int main() { init(); printf("\n\nFirmware info - git: " GIT_VERSION ", built: " __DATE__ " " __TIME__ "\n"); printf("--- COFFEE TEST ---\n"); char buf[80] = "Hello, world\n"; int ret = cfs_coffee_format(); if (ret < 0) while(1); int fd = cfs_open("test", CFS_READ | CFS_WRITE); if(fd >= 0) { ret = cfs_write(fd, buf, strlen(buf)); if (ret < 0) while(1); ret = cfs_write(fd, "JELLO\n", 7); if (ret < 0) while(1); ret = cfs_seek(fd, 0, CFS_SEEK_SET); if (ret < 0) while(1); ret = cfs_read(fd, buf, sizeof(buf)); if (ret < 0) while(1); printf("Read message: %s\n", buf); ret = cfs_seek(fd, 0, CFS_SEEK_SET); if (ret < 0) while(1); ret = cfs_write(fd, "JELLO", 5); if (ret < 0) while(1); ret = cfs_seek(fd, 0, CFS_SEEK_SET); if (ret < 0) while(1); ret = cfs_read(fd, buf, sizeof(buf)); if (ret < 0) while(1); printf("Read message: %s\n", buf); cfs_close(fd); if (ret < 0) while(1); } while (1); return 0; }
static int send_data(int fd, int block){ int len; tftp_header *h = (tftp_header *)uip_appdata; h->op = uip_htons(TFTP_DATA); h->block_nr = uip_htons(block); cfs_seek(fd, (block-1)*config.blksize, CFS_SEEK_SET); len = cfs_read(fd, h->data, config.blksize); if(len>=0) send_packet(h, 4+len); PRINTF("> block %d (len %d)\n", block, len); return len; }
static int write_page(struct deluge_object *obj, unsigned pagenum, unsigned char *data) { cfs_offset_t offset; offset = pagenum * S_PAGE; if(cfs_seek(obj->cfs_fd, offset, CFS_SEEK_SET) != offset) { return -1; } return cfs_write(obj->cfs_fd, (char *)data, S_PAGE); }
static int read_page(struct deluge_object *obj, unsigned pagenum, unsigned char *buf) { cfs_offset_t offset; offset = pagenum * S_PAGE; if(cfs_seek(obj->cfs_fd, offset, CFS_SEEK_SET) != offset) { return -1; } return cfs_read(obj->cfs_fd, (char *)buf, S_PAGE); }
PROCESS_THREAD(test_cfs_process, ev, data) { static struct etimer et; static int fd; static uint16_t counter; static char buf[30]; PROCESS_BEGIN(); printf("Starting CFS test process\n"); while(1) { etimer_set(&et, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); /* Write to filesystem */ sprintf(buf, "filedata%04ifiledata%04i", counter, counter); fd = cfs_open("filename", CFS_READ | CFS_WRITE); cfs_seek(fd, 0, CFS_SEEK_SET); cfs_write(fd, buf, 24); cfs_close(fd); printf("Wrote to filesystem: '%s'\n", buf); counter++; etimer_set(&et, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); /* Read from filesystem */ fd = cfs_open("file1", CFS_READ | CFS_WRITE); cfs_seek(fd, 4, CFS_SEEK_SET); cfs_read(fd, buf, 12); cfs_close(fd); buf[12] = '\0'; printf("Read from filesystem: '%s'\n", buf); } PROCESS_END(); }
db_result_t storage_put_row(relation_t *rel, storage_row_t row) { cfs_offset_t end; unsigned remaining; int r; unsigned char *last_byte; #if DB_FEATURE_INTEGRITY int missing_bytes; char buf[rel->row_length]; #endif end = cfs_seek(rel->tuple_storage, 0, CFS_SEEK_END); if(end == (cfs_offset_t)-1) { return DB_STORAGE_ERROR; } #if DB_FEATURE_INTEGRITY missing_bytes = end % rel->row_length; if(missing_bytes > 0) { memset(buf, 0xff, sizeof(buf)); r = cfs_write(rel->tuple_storage, buf, sizeof(buf)); if(r != missing_bytes) { return DB_STORAGE_ERROR; } } #endif /* Ensure that last written byte is separated from 0, to make file lengths correct in Coffee. */ last_byte = row + rel->row_length - 1; *last_byte ^= ROW_XOR; remaining = rel->row_length; do { r = cfs_write(rel->tuple_storage, row, remaining); if(r < 0) { PRINTF("DB: Failed to store %u bytes\n", remaining); *last_byte ^= ROW_XOR; return DB_STORAGE_ERROR; } row += r; remaining -= r; } while(remaining > 0); PRINTF("DB: Stored a of %d bytes\n", rel->row_length); *last_byte ^= ROW_XOR; return DB_OK; }
static int read_chunk(struct rudolph0_conn *c, int offset, uint8_t *to, int maxsize) { int ret; int fd; fd = cfs_open(filename, CFS_READ); cfs_seek(fd, offset, CFS_SEEK_SET); ret = cfs_read(fd, to, maxsize); /* printf("read_chunk %d bytes at %d, %d\n", ret, offset, (unsigned char)to[0]);*/ cfs_close(fd); return ret; }
static cfs_offset_t file_size(const char *file) { int fd; cfs_offset_t size; fd = cfs_open(file, CFS_READ); if(fd < 0) { return (cfs_offset_t)-1; } size = cfs_seek(fd, 0, CFS_SEEK_END); cfs_close(fd); return size; }
/*---------------------------------------------------------------------------*/ static int read_chunk(struct rucb_conn *c, int offset, char *to, int maxsize) { int ret; if(fd < 0) { /* No file, send EOF */ leds_off(LEDS_GREEN); return 0; } cfs_seek(fd, offset, CFS_SEEK_SET); ret = cfs_read(fd, to, maxsize); if(ret < maxsize) { cfs_close(fd); fd = -1; } return ret; }
static int read_chunk(struct rudolph2_conn *c, int offset, uint8_t *to, int maxsize) { int fd; int ret; fd = cfs_open("hej", CFS_READ); cfs_seek(fd, offset, CFS_SEEK_SET); ret = cfs_read(fd, to, maxsize); /* printf("%d.%d: read_chunk %d bytes at %d, %d\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], ret, offset, (unsigned char)to[0]);*/ cfs_close(fd); return ret; }
/*---------------------------------------------------------------------------*/ static void seek_read(int fd, unsigned int offset, char *buf, int len) { cfs_seek(fd, offset, CFS_SEEK_SET); cfs_read(fd, buf, len); #if DEBUG { int i; PRINTF("seek_read: Read len %d from offset %d\n", len, offset); for(i = 0; i < len; ++i ) { PRINTF("%02x ", buf[i]); } printf("\n"); } #endif /* DEBUG */ }
char* getFromConfig(char* value){ int fd; fd = cfs_open("/config.xml",CFS_READ); memset(answer,0,100); int i = 0,j=0,k=0; uint8_t check = 1; if (fd!=-1){ char config[128]; int read; read = cfs_read(fd, config, 128); cfs_close(fd); while (config[i]!='\0'){ if (config[i]=='<'){ i++; for (j=0;j<strlen(value);j++){ if (config[i]!=value[j]){ check = 0; break; } i++; } if (check && config[i]=='>'){ i++; j=0; while (config[i]!='<' && j<100){ answer[j++]=config[i++]; } break; } } if (config[i]=='>'){ //if (config[i+1]=='\0') break; k+=i; cfs_open("/config.xml",CFS_READ); cfs_seek(fd,++k,CFS_SEEK_SET); memset(config,0,128); cfs_read(fd,config,128); cfs_close(fd); check = 1; i=-1; } i++; } return answer; } else return "-"; }
db_result_t storage_get_row_amount(relation_t *rel, tuple_id_t *amount) { cfs_offset_t offset; if(rel->row_length == 0) { *amount = 0; } else { offset = cfs_seek(rel->tuple_storage, 0, CFS_SEEK_END); if(offset == (cfs_offset_t)-1) { return DB_STORAGE_ERROR; } *amount = (tuple_id_t)(offset / rel->row_length); } return DB_OK; }
static int read_chunk(struct rudolph0_conn *c, int offset, uint8_t *to, int maxsize) { int fd; int ret; leds_toggle(LEDS_GREEN); fd = cfs_open("codeprop.out", CFS_READ); cfs_seek(fd, offset, CFS_SEEK_SET); ret = cfs_read(fd, to, maxsize); /* printf("read_chunk %d bytes at %d, %d\n", ret, offset, (unsigned char)to[0]);*/ if(ret < maxsize) { leds_off(LEDS_GREEN); } cfs_close(fd); return ret; }
static void almanac_callback(u16 sender_id, u8 len, u8 msg[], void* context) { (void)sender_id; (void)len; (void) context; almanac_t *new_almanac = (almanac_t*)msg; log_info("Received alamanc for PRN %02d\n", new_almanac->prn); memcpy(&almanac[new_almanac->prn-1], new_almanac, sizeof(almanac_t)); int fd = cfs_open("almanac", CFS_WRITE); if (fd != -1) { cfs_seek(fd, (new_almanac->prn-1)*sizeof(almanac_t), CFS_SEEK_SET); if (cfs_write(fd, new_almanac, sizeof(almanac_t)) != sizeof(almanac_t)) { log_error("Error writing to almanac file\n"); } else { log_info("Saved almanac to flash\n"); } cfs_close(fd); } else { log_error("Error opening almanac file\n"); } }
/*---------------------------------------------------------------------------*/ static void handle_get_command(void) { int fd = 0; fd = cfs_open("cp", CFS_READ); if(fd < 0) { printf("ERROR: No file access (get)\n"); } else { PRINTF_COMMAND("GET:START\n"); char data[8]; int offset=0, size=0, read=8; unsigned short crc = 0; cfs_seek(fd, offset, CFS_SEEK_SET); while (read == 8) { int i; /*if(offset != cfs_seek(fd, offset, CFS_SEEK_SET)) { printf("bad seek, breaking\n"); break; }*/ read = cfs_read(fd, data, 8); size += read; printf("%04i: ", offset); /*REMOVE*/ for (i=0; i < read; i++) { crc = crc16_add((uint8_t) data[i], crc); printf("%02x", (uint8_t) (0xff&data[i])); } printf("\n"); offset += 8; } PRINTF_COMMAND("GET:DONE CRC=%u\n", crc); cfs_close(fd); } }
/* Write to file callback. * Responds to a SBP_MSG_FILEIO_WRITE_REQUEST message. * * Writes a certain length (up to 255 bytes) at a given offset. Returns a copy * of the original SBP_MSG_FILEIO_WRITE_RESPONSE message to check integrity of * the write. */ static void write_cb(u16 sender_id, u8 len, u8 msg[], void* context) { (void)context; if (sender_id != SBP_SENDER_ID) { log_error("Invalid sender!\n"); return; } if (len < 6) { log_error("Invalid fileio write message!\n"); return; } u32 offset = ((u32)msg[3] << 24) | ((u32)msg[2] << 16) | (msg[1] << 8) | msg[0]; u8 headerlen = 4 + strlen((char*)&msg[4]) + 1; int f = cfs_open((char*)&msg[4], CFS_WRITE); cfs_seek(f, offset, CFS_SEEK_SET); cfs_write(f, msg + headerlen, len - headerlen); cfs_close(f); sbp_send_msg(SBP_MSG_FILEIO_WRITE_RESPONSE, headerlen, msg); }
db_result_t storage_write(db_storage_id_t fd, void *buffer, unsigned long offset, unsigned length) { char *ptr; int r; if(cfs_seek(fd, offset, CFS_SEEK_SET) == (cfs_offset_t)-1) { return DB_STORAGE_ERROR; } ptr = buffer; while(length > 0) { r = cfs_write(fd, ptr, length); if(r <= 0) { return DB_STORAGE_ERROR; } ptr += r; length -= r; } return DB_OK; }
/*---------------------------------------------------------------------*/ static void write_chunk(struct rudolph0_conn *c, int offset, int flag, uint8_t *data, int datalen) { int fd; leds_toggle(LEDS_YELLOW); if(flag == RUDOLPH0_FLAG_NEWFILE) { printf("+++ rudolph0 new file incoming at %u\n", clock_time()); fd = cfs_open("codeprop.out", CFS_WRITE); if(elfloader_autostart_processes != NULL) { PRINTF("Stopping old programs.\n"); autostart_exit(elfloader_autostart_processes); elfloader_autostart_processes = NULL; } } else { fd = cfs_open("codeprop.out", CFS_WRITE + CFS_APPEND); } if(datalen > 0) { int ret; cfs_seek(fd, offset, CFS_SEEK_SET); ret = cfs_write(fd, data, datalen); /* printf("write_chunk wrote %d bytes at %d, %d\n", ret, offset, (unsigned char)data[0]);*/ } cfs_close(fd); if(flag == RUDOLPH0_FLAG_LASTCHUNK) { printf("+++ rudolph0 entire file received at %u\n", clock_time()); start_program(); leds_off(LEDS_YELLOW); } }