int PX4IO_Uploader::program(size_t fw_size) { uint8_t *file_buf; ssize_t count; int ret; size_t sent = 0; file_buf = new uint8_t[PROG_MULTI_MAX]; if (!file_buf) { log("Can't allocate program buffer"); return -ENOMEM; } ASSERT((fw_size & 3) == 0); ASSERT((PROG_MULTI_MAX & 3) == 0); log("programming %u bytes...", (unsigned)fw_size); ret = lseek(_fw_fd, 0, SEEK_SET); while (sent < fw_size) { /* get more bytes to program */ size_t n = fw_size - sent; if (n > PROG_MULTI_MAX) { n = PROG_MULTI_MAX; } count = read_with_retry(_fw_fd, file_buf, n); if (count != (ssize_t)n) { log("firmware read of %u bytes at %u failed -> %d errno %d", (unsigned)n, (unsigned)sent, (int)count, (int)errno); ret = -errno; break; } sent += count; send(PROTO_PROG_MULTI); send(count); send(file_buf, count); send(PROTO_EOC); ret = get_sync(1000); if (ret != OK) { break; } } delete [] file_buf; return ret; }
int PX4IO_Uploader::program(size_t fw_size) { uint8_t file_buf[PROG_MULTI_MAX]; ssize_t count; int ret; size_t sent = 0; log("programming %u bytes...", (unsigned)fw_size); ret = lseek(_fw_fd, 0, SEEK_SET); while (sent < fw_size) { /* get more bytes to program */ size_t n = fw_size - sent; if (n > sizeof(file_buf)) { n = sizeof(file_buf); } count = read_with_retry(_fw_fd, file_buf, n); if (count != (ssize_t)n) { log("firmware read of %u bytes at %u failed -> %d errno %d", (unsigned)n, (unsigned)sent, (int)count, (int)errno); } if (count == 0) return OK; sent += count; if (count < 0) return -errno; ASSERT((count % 4) == 0); send(PROTO_PROG_MULTI); send(count); send(&file_buf[0], count); send(PROTO_EOC); ret = get_sync(1000); if (ret != OK) return ret; } return OK; }
bool read_with_timeout(int fd, void* data, int len, struct timeval* timeout) { if(!timeout) { return read_with_retry(fd, data, len); } fd_set readfds; FD_ZERO(&readfds); FD_SET(fd, &readfds); int pos = 0; while(pos<len) { int ret; while(1) { ret = select(fd+1, &readfds, NULL, NULL, timeout); if(ret<0) { if(errno == EINTR || errno == EAGAIN) continue; return false; } if(ret>=0) break; } if(!FD_ISSET(fd, &readfds)) { // timeout return false; } ret = read(fd, data+pos, len-pos); if(ret<0) { if(errno == EINTR || errno == EAGAIN) continue; // read error return false; } if(ret==0) { // EOF return false; } pos += ret; } return true; }
int storage_file_read(struct storage_msg *msg, const void *r, size_t req_len) { int rc; const struct storage_file_read_req *req = r; if (req_len != sizeof(*req)) { ALOGE("%s: invalid request length (%zd != %zd)\n", __func__, req_len, sizeof(*req)); msg->result = STORAGE_ERR_NOT_VALID; goto err_response; } if (req->size > MAX_READ_SIZE) { ALOGW("%s: request is too large (%u > %d) - refusing\n", __func__, req->size, MAX_READ_SIZE); msg->result = STORAGE_ERR_NOT_VALID; goto err_response; } int fd = lookup_fd(req->handle, false); ssize_t read_res = read_with_retry(fd, read_rsp.hdr.data, req->size, (off_t)req->offset); if (read_res < 0) { rc = errno; ALOGW("%s: error reading file (fd=%d): %s\n", __func__, fd, strerror(errno)); msg->result = translate_errno(rc); goto err_response; } msg->result = STORAGE_NO_ERROR; return ipc_respond(msg, &read_rsp, read_res + sizeof(read_rsp.hdr)); err_response: return ipc_respond(msg, NULL, 0); }
int PX4IO_Uploader::verify_rev3(size_t fw_size_local) { int ret; uint8_t file_buf[4]; ssize_t count; uint32_t sum = 0; uint32_t bytes_read = 0; uint32_t crc = 0; uint32_t fw_size_remote; uint8_t fill_blank = 0xff; log("verify..."); lseek(_fw_fd, 0, SEEK_SET); ret = get_info(INFO_FLASH_SIZE, fw_size_remote); send(PROTO_EOC); if (ret != OK) { log("could not read firmware size"); return ret; } /* read through the firmware file again and calculate the checksum*/ while (bytes_read < fw_size_local) { size_t n = fw_size_local - bytes_read; if (n > sizeof(file_buf)) { n = sizeof(file_buf); } count = read_with_retry(_fw_fd, file_buf, n); if (count != (ssize_t)n) { log("firmware read of %u bytes at %u failed -> %d errno %d", (unsigned)n, (unsigned)bytes_read, (int)count, (int)errno); } /* set the rest to ff */ if (count == 0) { break; } /* stop if the file cannot be read */ if (count < 0) return -errno; /* calculate crc32 sum */ sum = crc32part((uint8_t *)&file_buf, sizeof(file_buf), sum); bytes_read += count; } /* fill the rest with 0xff */ while (bytes_read < fw_size_remote) { sum = crc32part(&fill_blank, sizeof(fill_blank), sum); bytes_read += sizeof(fill_blank); } /* request CRC from IO */ send(PROTO_GET_CRC); send(PROTO_EOC); ret = recv_bytes((uint8_t*)(&crc), sizeof(crc)); if (ret != OK) { log("did not receive CRC checksum"); return ret; } /* compare the CRC sum from the IO with the one calculated */ if (sum != crc) { log("CRC wrong: received: %d, expected: %d", crc, sum); return -EINVAL; } return OK; }
int PX4IO_Uploader::verify_rev2(size_t fw_size) { uint8_t file_buf[4]; ssize_t count; int ret; size_t sent = 0; log("verify..."); lseek(_fw_fd, 0, SEEK_SET); send(PROTO_CHIP_VERIFY); send(PROTO_EOC); ret = get_sync(); if (ret != OK) return ret; while (sent < fw_size) { /* get more bytes to verify */ size_t n = fw_size - sent; if (n > sizeof(file_buf)) { n = sizeof(file_buf); } count = read_with_retry(_fw_fd, file_buf, n); if (count != (ssize_t)n) { log("firmware read of %u bytes at %u failed -> %d errno %d", (unsigned)n, (unsigned)sent, (int)count, (int)errno); } if (count == 0) break; sent += count; if (count < 0) return -errno; ASSERT((count % 4) == 0); send(PROTO_READ_MULTI); send(count); send(PROTO_EOC); for (ssize_t i = 0; i < count; i++) { uint8_t c; ret = recv_byte_with_timeout(&c, 5000); if (ret != OK) { log("%d: got %d waiting for bytes", sent + i, ret); return ret; } if (c != file_buf[i]) { log("%d: got 0x%02x expected 0x%02x", sent + i, c, file_buf[i]); return -EINVAL; } } ret = get_sync(); if (ret != OK) { log("timeout waiting for post-verify sync"); return ret; } } return OK; }