Skip to content

Commit 6514ff6

Browse files
committed
extmod/modwebrepl: Initial implementation of "get file" operation.
1 parent 25d0f7d commit 6514ff6

1 file changed

Lines changed: 49 additions & 15 deletions

File tree

extmod/modwebrepl.c

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct webrepl_file {
5454
char fname[64];
5555
} __attribute__((packed));
5656

57+
enum { PUT_FILE = 1, GET_FILE, LIST_DIR };
58+
5759
typedef struct _mp_obj_webrepl_t {
5860
mp_obj_base_t base;
5961
mp_obj_t sock;
@@ -96,6 +98,52 @@ STATIC mp_obj_t webrepl_make_new(const mp_obj_type_t *type, size_t n_args, size_
9698
return o;
9799
}
98100

101+
STATIC void handle_op(mp_obj_webrepl_t *self) {
102+
mp_obj_t open_args[2] = {
103+
mp_obj_new_str(self->hdr.fname, strlen(self->hdr.fname), false),
104+
MP_OBJ_NEW_QSTR(MP_QSTR_rb)
105+
};
106+
107+
if (self->hdr.type == PUT_FILE) {
108+
open_args[1] = MP_OBJ_NEW_QSTR(MP_QSTR_wb);
109+
}
110+
111+
self->cur_file = mp_builtin_open(2, open_args, (mp_map_t*)&mp_const_empty_map);
112+
const mp_stream_p_t *file_stream =
113+
mp_get_stream_raise(self->cur_file, MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
114+
115+
#if 0
116+
struct mp_stream_seek_t seek = { .offset = self->hdr.offset, .whence = 0 };
117+
int err;
118+
mp_uint_t res = file_stream->ioctl(self->cur_file, MP_STREAM_SEEK, (uintptr_t)&seek, &err);
119+
assert(res != MP_STREAM_ERROR);
120+
#endif
121+
122+
write_webrepl_resp(self->sock, 0);
123+
124+
if (self->hdr.type == PUT_FILE) {
125+
self->data_to_recv = self->hdr.size;
126+
} else if (self->hdr.type == GET_FILE) {
127+
byte readbuf[256];
128+
int err;
129+
// TODO: It's not ideal that we block connection while sending file
130+
// and don't process any input.
131+
while (1) {
132+
mp_uint_t out_sz = file_stream->read(self->cur_file, readbuf, sizeof(readbuf), &err);
133+
assert(out_sz != MP_STREAM_ERROR);
134+
write_webrepl(self->sock, &out_sz, 2);
135+
if (out_sz == 0) {
136+
break;
137+
}
138+
DEBUG_printf("webrepl: Sending %d bytes of file\n", out_sz);
139+
write_webrepl(self->sock, readbuf, out_sz);
140+
}
141+
142+
write_webrepl_resp(self->sock, 0);
143+
self->hdr_to_recv = sizeof(struct webrepl_file);
144+
}
145+
}
146+
99147
STATIC mp_uint_t webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
100148
// We know that os.dupterm always calls with size = 1
101149
assert(size == 1);
@@ -130,21 +178,7 @@ STATIC mp_uint_t webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *
130178

131179
DEBUG_printf("webrepl: op: %d, file: %s, chunk @%x, sz=%d\n", self->hdr.type, self->hdr.fname, (uint32_t)self->hdr.offset, self->hdr.size);
132180

133-
// Process header
134-
mp_obj_t open_args[2] = {
135-
mp_obj_new_str(self->hdr.fname, strlen(self->hdr.fname), false),
136-
MP_OBJ_NEW_QSTR(MP_QSTR_wb)
137-
};
138-
139-
self->cur_file = mp_builtin_open(2, open_args, (mp_map_t*)&mp_const_empty_map);
140-
const mp_stream_p_t *file_stream = mp_get_stream_raise(self->cur_file, MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
141-
struct mp_stream_seek_t seek = { .offset = self->hdr.offset, .whence = 0 };
142-
int err;
143-
mp_uint_t res = file_stream->ioctl(self->cur_file, MP_STREAM_SEEK, (uintptr_t)&seek, &err);
144-
assert(res != MP_STREAM_ERROR);
145-
146-
write_webrepl_resp(self->sock, 0);
147-
self->data_to_recv = self->hdr.size;
181+
handle_op(self);
148182

149183
*errcode = EAGAIN;
150184
return MP_STREAM_ERROR;

0 commit comments

Comments
 (0)