diff options
Diffstat (limited to 'extmod')
-rw-r--r-- | extmod/modbtree.c | 56 | ||||
-rw-r--r-- | extmod/modussl_axtls.c (renamed from extmod/modussl.c) | 48 | ||||
-rw-r--r-- | extmod/modwebrepl.c | 84 | ||||
-rw-r--r-- | extmod/modwebsocket.c | 27 | ||||
-rw-r--r-- | extmod/vfs_fat.c | 9 |
5 files changed, 134 insertions, 90 deletions
diff --git a/extmod/modbtree.c b/extmod/modbtree.c index 0a0c5271c0..f21e7e4421 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -31,6 +31,8 @@ #include "py/nlr.h" #include "py/runtime.h" +#include "py/runtime0.h" +#include "py/stream.h" #if MICROPY_PY_BTREE @@ -291,6 +293,24 @@ STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } } +STATIC mp_obj_t btree_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { + mp_obj_btree_t *self = MP_OBJ_TO_PTR(lhs_in); + switch (op) { + case MP_BINARY_OP_IN: { + mp_uint_t v; + DBT key, val; + key.data = (void*)mp_obj_str_get_data(rhs_in, &v); + key.size = v; + int res = __bt_get(self->db, &key, &val, 0); + CHECK_ERROR(res); + return mp_obj_new_bool(res != RET_SPECIAL); + } + default: + // op not supported + return MP_OBJ_NULL; + } +} + STATIC const mp_rom_map_elem_t btree_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&btree_close_obj) }, { MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&btree_get_obj) }, @@ -310,27 +330,47 @@ STATIC const mp_obj_type_t btree_type = { .print = btree_print, .getiter = btree_getiter, .iternext = btree_iternext, + .binary_op = btree_binary_op, .subscr = btree_subscr, .locals_dict = (void*)&btree_locals_dict, }; +STATIC FILEVTABLE btree_stream_fvtable = { + mp_stream_posix_read, + mp_stream_posix_write, + mp_stream_posix_lseek, + mp_stream_posix_fsync +}; + STATIC mp_obj_t mod_btree_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { static const mp_arg_t allowed_args[] = { - { MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_flags, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_cachesize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_pagesize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_minkeypage, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, }; - const char *fname = NULL; - if (pos_args[0] != mp_const_none) { - fname = mp_obj_str_get_str(pos_args[0]); - } + // Make sure we got a stream object + mp_get_stream_raise(pos_args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); struct { - mp_arg_val_t server_side; + mp_arg_val_t flags; + mp_arg_val_t cachesize; + mp_arg_val_t pagesize; + mp_arg_val_t minkeypage; } args; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t*)&args); - - DB *db = __bt_open(fname, /*flags*/O_CREAT | O_RDWR, /*mode*/0770, /*openinfo*/NULL, /*dflags*/0); + BTREEINFO openinfo = {0}; + openinfo.flags = args.flags.u_int; + openinfo.cachesize = args.cachesize.u_int; + openinfo.psize = args.pagesize.u_int; + openinfo.minkeypage = args.minkeypage.u_int; + + DB *db = __bt_open(pos_args[0], &btree_stream_fvtable, &openinfo, /*dflags*/0); + if (db == NULL) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno))); + } return MP_OBJ_FROM_PTR(btree_new(db)); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_btree_open_obj, 1, mod_btree_open); diff --git a/extmod/modussl.c b/extmod/modussl_axtls.c index 4a3e297e1e..ce86263c2c 100644 --- a/extmod/modussl.c +++ b/extmod/modussl_axtls.c @@ -32,7 +32,7 @@ #include "py/runtime.h" #include "py/stream.h" -#if MICROPY_PY_USSL +#if MICROPY_PY_USSL && MICROPY_SSL_AXTLS #include "ssl.h" @@ -122,14 +122,21 @@ STATIC mp_uint_t socket_write(mp_obj_t o_in, const void *buf, mp_uint_t size, in return r; } +STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t flag_in) { + // Currently supports only blocking mode + (void)self_in; + if (!mp_obj_is_true(flag_in)) { + mp_not_implemented(""); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking); + STATIC mp_obj_t socket_close(mp_obj_t self_in) { mp_obj_ssl_socket_t *self = MP_OBJ_TO_PTR(self_in); ssl_free(self->ssl_sock); ssl_ctx_free(self->ssl_ctx); - - mp_obj_t dest[2]; - mp_load_method(self->sock, MP_QSTR_close, dest); - return mp_call_method_n_kw(0, 0, dest); + return mp_stream_close(self->sock); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close); @@ -139,6 +146,7 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&socket_close_obj) }, }; @@ -192,34 +200,4 @@ const mp_obj_module_t mp_module_ussl = { .globals = (mp_obj_dict_t*)&mp_module_ssl_globals, }; - -// These functions might be split to stream_posix.c. They are referenced by -// axtls os_port.h . -ssize_t mp_stream_posix_write(void *sock_obj, const void *buf, size_t len); -ssize_t mp_stream_posix_read(void *sock_obj, void *buf, size_t len); - -int mp_stream_errno; - -ssize_t mp_stream_posix_write(void *sock_obj, const void *buf, size_t len) { - struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)sock_obj; - const mp_stream_p_t *stream_p = o->type->protocol; - mp_uint_t out_sz = stream_p->write(o, buf, len, &mp_stream_errno); - if (out_sz == MP_STREAM_ERROR) { - return -1; - } else { - return out_sz; - } -} - -ssize_t mp_stream_posix_read(void *sock_obj, void *buf, size_t len) { - struct _mp_obj_base_t *o = (struct _mp_obj_base_t *)sock_obj; - const mp_stream_p_t *stream_p = o->type->protocol; - mp_uint_t out_sz = stream_p->read(o, buf, len, &mp_stream_errno); - if (out_sz == MP_STREAM_ERROR) { - return -1; - } else { - return out_sz; - } -} - #endif // MICROPY_PY_USSL diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c index 4f7b924e07..4e3780fa4d 100644 --- a/extmod/modwebrepl.c +++ b/extmod/modwebrepl.c @@ -38,6 +38,7 @@ #include "py/mphal.h" #endif #include "extmod/modwebsocket.h" +#include "genhdr/mpversion.h" #if MICROPY_PY_WEBREPL @@ -57,7 +58,7 @@ struct webrepl_file { char fname[64]; } __attribute__((packed)); -enum { PUT_FILE = 1, GET_FILE, LIST_DIR }; +enum { PUT_FILE = 1, GET_FILE, GET_VER }; enum { STATE_PASSWD, STATE_NORMAL }; typedef struct _mp_obj_webrepl_t { @@ -77,12 +78,6 @@ STATIC char denied_prompt[] = "\r\nAccess denied\r\n"; STATIC char webrepl_passwd[10]; -static inline void close_meth(mp_obj_t stream) { - mp_obj_t dest[2]; - mp_load_method(stream, MP_QSTR_close, dest); - mp_call_method_n_kw(0, 0, dest); -} - STATIC void write_webrepl(mp_obj_t websock, const void *buf, size_t len) { const mp_stream_p_t *sock_stream = mp_get_stream_raise(websock, MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); int err; @@ -117,7 +112,37 @@ STATIC mp_obj_t webrepl_make_new(const mp_obj_type_t *type, size_t n_args, size_ return o; } +STATIC int write_file_chunk(mp_obj_webrepl_t *self) { + 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); + 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) { + + // 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), false), MP_OBJ_NEW_QSTR(MP_QSTR_rb) @@ -128,8 +153,6 @@ STATIC void handle_op(mp_obj_webrepl_t *self) { } 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 }; @@ -143,24 +166,7 @@ STATIC void handle_op(mp_obj_webrepl_t *self) { 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); + self->data_to_recv = 1; } } @@ -248,17 +254,27 @@ STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int buf_sz += sz; } - DEBUG_printf("webrepl: Writing %lu bytes to file\n", buf_sz); - int err; - mp_uint_t res = mp_stream_write_exactly(self->cur_file, filebuf, buf_sz, &err); - if (err != 0 || res != buf_sz) { - assert(0); + if (self->hdr.type == PUT_FILE) { + DEBUG_printf("webrepl: Writing %lu bytes to file\n", buf_sz); + int err; + mp_uint_t res = mp_stream_write_exactly(self->cur_file, filebuf, buf_sz, &err); + if (err != 0 || res != buf_sz) { + assert(0); + } + } else if (self->hdr.type == GET_FILE) { + assert(buf_sz == 1); + assert(self->data_to_recv == 0); + assert(filebuf[0] == 0); + mp_uint_t out_sz = write_file_chunk(self); + if (out_sz != 0) { + self->data_to_recv = 1; + } } if (self->data_to_recv == 0) { - close_meth(self->cur_file); + mp_stream_close(self->cur_file); self->hdr_to_recv = sizeof(struct webrepl_file); - DEBUG_printf("webrepl: Finished writing file\n"); + DEBUG_printf("webrepl: Finished file operation %d\n", self->hdr.type); write_webrepl_resp(self->sock, 0); } diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c index 6354633af4..f46dac1773 100644 --- a/extmod/modwebsocket.c +++ b/extmod/modwebsocket.c @@ -73,11 +73,11 @@ STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, siz if (n_args > 1 && args[1] == mp_const_true) { o->opts |= BLOCKING_WRITE; } - return o; + return MP_OBJ_FROM_PTR(o); } STATIC mp_uint_t websocket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) { - mp_obj_websocket_t *self = self_in; + mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in); const mp_stream_p_t *stream_p = mp_get_stream_raise(self->sock, MP_STREAM_OP_READ); while (1) { if (self->to_recv != 0) { @@ -219,7 +219,7 @@ no_payload: } STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) { - mp_obj_websocket_t *self = self_in; + mp_obj_websocket_t *self = MP_OBJ_TO_PTR(self_in); assert(size < 0x10000); byte header[4] = {0x80 | (self->opts & FRAME_OPCODE_MASK)}; int hdr_sz; @@ -280,12 +280,13 @@ STATIC mp_obj_t websocket_close(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(websocket_close_obj, websocket_close); -STATIC const mp_map_elem_t websocket_locals_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), (mp_obj_t)&mp_stream_readinto_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&mp_stream_ioctl_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&websocket_close_obj }, +STATIC const mp_rom_map_elem_t websocket_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&mp_stream_ioctl_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&websocket_close_obj) }, }; STATIC MP_DEFINE_CONST_DICT(websocket_locals_dict, websocket_locals_dict_table); @@ -300,12 +301,12 @@ STATIC const mp_obj_type_t websocket_type = { .name = MP_QSTR_websocket, .make_new = websocket_make_new, .protocol = &websocket_stream_p, - .locals_dict = (mp_obj_t)&websocket_locals_dict, + .locals_dict = (void*)&websocket_locals_dict, }; -STATIC const mp_map_elem_t websocket_module_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_websocket) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_websocket), (mp_obj_t)&websocket_type }, +STATIC const mp_rom_map_elem_t websocket_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_websocket) }, + { MP_ROM_QSTR(MP_QSTR_websocket), MP_ROM_PTR(&websocket_type) }, }; STATIC MP_DEFINE_CONST_DICT(websocket_module_globals, websocket_module_globals_table); diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index df5cbb0d62..a691ee062c 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -90,6 +90,14 @@ STATIC mp_obj_t fat_vfs_remove(mp_obj_t vfs_in, mp_obj_t path_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_remove_obj, fat_vfs_remove); +STATIC mp_obj_t fat_vfs_rmdir(mp_obj_t vfs_in, mp_obj_t path_in) { + // TODO: Currently just redirects to fat_vfs_remove(), which are + // backed by the same underlying FatFs function. Should at least + // check that path is actually a dir. + return fat_vfs_remove(vfs_in, path_in); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_rmdir_obj, fat_vfs_rmdir); + STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_out) { (void)vfs_in; const char *old_path = mp_obj_str_get_str(path_in); @@ -247,6 +255,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&fat_vfs_open_obj) }, { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&fat_vfs_listdir_obj) }, { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&fat_vfs_mkdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&fat_vfs_rmdir_obj) }, { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&fat_vfs_chdir_obj) }, { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&fat_vfs_getcwd_obj) }, { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&fat_vfs_remove_obj) }, |