STATIC void handle_op(mp_obj_webrepl_t *self) { // Handle operations not requiring opened file switch (self->hdr.type) { case GET_VER: { static char ver[] = {MICROPY_VERSION_MAJOR, MICROPY_VERSION_MINOR, MICROPY_VERSION_MICRO}; write_webrepl(self->sock, ver, sizeof(ver)); self->hdr_to_recv = sizeof(struct webrepl_file); return; } } // Handle operations requiring opened file mp_obj_t open_args[2] = { mp_obj_new_str(self->hdr.fname, strlen(self->hdr.fname)), MP_OBJ_NEW_QSTR(MP_QSTR_rb) }; if (self->hdr.type == PUT_FILE) { open_args[1] = MP_OBJ_NEW_QSTR(MP_QSTR_wb); } self->cur_file = mp_builtin_open(2, open_args, (mp_map_t*)&mp_const_empty_map); #if 0 struct mp_stream_seek_t seek = { .offset = self->hdr.offset, .whence = 0 }; int err; mp_uint_t res = file_stream->ioctl(self->cur_file, MP_STREAM_SEEK, (uintptr_t)&seek, &err); assert(res != MP_STREAM_ERROR); #endif write_webrepl_resp(self->sock, 0); if (self->hdr.type == PUT_FILE) { self->data_to_recv = self->hdr.size; check_file_op_finished(self); } else if (self->hdr.type == GET_FILE) { self->data_to_recv = 1; } } STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode); STATIC mp_uint_t webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) { mp_uint_t out_sz; do { out_sz = _webrepl_read(self_in, buf, size, errcode); } while (out_sz == -2); return out_sz; }
STATIC int write_file_chunk(mp_obj_webrepl_t *self) { const mp_stream_p_t *file_stream = mp_get_stream(self->cur_file); byte readbuf[2 + 256]; int err; mp_uint_t out_sz = file_stream->read(self->cur_file, readbuf + 2, sizeof(readbuf) - 2, &err); if (out_sz == MP_STREAM_ERROR) { return out_sz; } readbuf[0] = out_sz; readbuf[1] = out_sz >> 8; DEBUG_printf("webrepl: Sending %d bytes of file\n", out_sz); write_webrepl(self->sock, readbuf, 2 + out_sz); return out_sz; }
STATIC void handle_op(mp_obj_webrepl_t *self) { mp_obj_t open_args[2] = { mp_obj_new_str(self->hdr.fname, strlen(self->hdr.fname), false), MP_OBJ_NEW_QSTR(MP_QSTR_rb) }; if (self->hdr.type == PUT_FILE) { open_args[1] = MP_OBJ_NEW_QSTR(MP_QSTR_wb); } self->cur_file = mp_builtin_open(2, open_args, (mp_map_t*)&mp_const_empty_map); const mp_stream_p_t *file_stream = mp_get_stream_raise(self->cur_file, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); #if 0 struct mp_stream_seek_t seek = { .offset = self->hdr.offset, .whence = 0 }; int err; mp_uint_t res = file_stream->ioctl(self->cur_file, MP_STREAM_SEEK, (uintptr_t)&seek, &err); assert(res != MP_STREAM_ERROR); #endif write_webrepl_resp(self->sock, 0); if (self->hdr.type == PUT_FILE) { self->data_to_recv = self->hdr.size; } else if (self->hdr.type == GET_FILE) { byte readbuf[2 + 256]; int err; // TODO: It's not ideal that we block connection while sending file // and don't process any input. while (1) { mp_uint_t out_sz = file_stream->read(self->cur_file, readbuf + 2, sizeof(readbuf) - 2, &err); assert(out_sz != MP_STREAM_ERROR); readbuf[0] = out_sz; readbuf[1] = out_sz >> 8; DEBUG_printf("webrepl: Sending %d bytes of file\n", out_sz); write_webrepl(self->sock, readbuf, 2 + out_sz); if (out_sz == 0) { break; } } write_webrepl_resp(self->sock, 0); self->hdr_to_recv = sizeof(struct webrepl_file); } }
STATIC void write_webrepl_resp(mp_obj_t websock, uint16_t code) { char buf[4] = {'W', 'B', code & 0xff, code >> 8}; write_webrepl(websock, buf, sizeof(buf)); }