STATIC mp_obj_t mod_getaddrinfo(size_t n_args, const mp_obj_t *args) { mp_obj_t host_in = args[0], port_in = args[1]; const char *host = mp_obj_str_get_str(host_in); mp_int_t family = 0; if (n_args > 2) { family = mp_obj_get_int(args[2]); } getaddrinfo_state_t state; // Just validate that it's int (void)mp_obj_get_int(port_in); state.port = port_in; state.result = mp_obj_new_list(0, NULL); k_sem_init(&state.sem, 0, UINT_MAX); for (int i = 2; i--;) { int type = (family != AF_INET6 ? DNS_QUERY_TYPE_A : DNS_QUERY_TYPE_AAAA); RAISE_ERRNO(dns_get_addr_info(host, type, NULL, dns_resolve_cb, &state, 3000)); k_sem_take(&state.sem, K_FOREVER); if (family != 0) { break; } family = AF_INET6; } // Raise error only if there's nothing to return, otherwise // it may be IPv4 vs IPv6 differences. mp_int_t len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(state.result)); if (state.status != 0 && len == 0) { mp_raise_OSError(state.status); } return state.result; }
STATIC mp_obj_t ffimod_var(mp_obj_t self_in, mp_obj_t vartype_in, mp_obj_t symname_in) { mp_obj_ffimod_t *self = MP_OBJ_TO_PTR(self_in); const char *rettype = mp_obj_str_get_str(vartype_in); const char *symname = mp_obj_str_get_str(symname_in); void *sym = dlsym(self->handle, symname); if (sym == NULL) { mp_raise_OSError(MP_ENOENT); } mp_obj_ffivar_t *o = m_new_obj(mp_obj_ffivar_t); o->base.type = &ffivar_type; o->var = sym; o->type = *rettype; return MP_OBJ_FROM_PTR(o); }
STATIC mp_obj_t mod_ffi_callback(mp_obj_t rettype_in, mp_obj_t func_in, mp_obj_t paramtypes_in) { const char *rettype = mp_obj_str_get_str(rettype_in); int nparams = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(paramtypes_in)); mp_obj_fficallback_t *o = m_new_obj_var(mp_obj_fficallback_t, ffi_type*, nparams); o->base.type = &fficallback_type; o->clo = ffi_closure_alloc(sizeof(ffi_closure), &o->func); o->rettype = *rettype; mp_obj_t iterable = mp_getiter(paramtypes_in); mp_obj_t item; int i = 0; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { o->params[i++] = get_ffi_type(item); } int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params); if (res != FFI_OK) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Error in ffi_prep_cif")); } res = ffi_prep_closure_loc(o->clo, &o->cif, call_py_func, func_in, o->func); if (res != FFI_OK) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ffi_prep_closure_loc")); } return o; }
mp_obj_t py_imlib_save_template(mp_obj_t image_obj, mp_obj_t rectangle_obj, mp_obj_t path_obj) { struct image t; struct image *image = NULL; struct rectangle r; mp_obj_t *array; const char *path = mp_obj_str_get_str(path_obj); array = mp_obj_get_array_fixed_n(rectangle_obj, 4); r.x = mp_obj_get_int(array[0]); r.y = mp_obj_get_int(array[1]); r.w = mp_obj_get_int(array[2]); r.h = mp_obj_get_int(array[3]); /* get C image pointer */ image = py_image_cobj(image_obj); t.w = r.w; t.h = r.h; t.data = malloc(sizeof(*t.data)*t.w*t.h); imlib_subimage(image, &t, r.x, r.y); int res = imlib_save_template(&t, path); free(t.data); if (res != FR_OK) { nlr_jump(mp_obj_new_exception_msg(qstr_from_str("Imlib"), ffs_strerror(res))); } return mp_const_true; }
STATIC mp_obj_t ffimod_var(mp_obj_t self_in, mp_obj_t vartype_in, mp_obj_t symname_in) { mp_obj_ffimod_t *self = self_in; const char *rettype = mp_obj_str_get_str(vartype_in); const char *symname = mp_obj_str_get_str(symname_in); void *sym = dlsym(self->handle, symname); if (sym == NULL) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno))); } mp_obj_ffivar_t *o = m_new_obj(mp_obj_ffivar_t); o->base.type = &ffivar_type; o->var = sym; o->type = *rettype; return o; }
STATIC mp_obj_t mod_os_getenv(mp_obj_t var_in) { const char *s = getenv(mp_obj_str_get_str(var_in)); if (s == NULL) { return mp_const_none; } return mp_obj_new_str(s, strlen(s), false); }
STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) { // TODO: "The buffer must contain exactly the amount of data required by the format (len(bytes) must equal calcsize(fmt))." const char *fmt = mp_obj_str_get_str(fmt_in); char fmt_type = get_fmt_type(&fmt); uint size = calcsize_items(fmt); mp_obj_tuple_t *res = mp_obj_new_tuple(size, NULL); mp_buffer_info_t bufinfo; mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); byte *p = bufinfo.buf; for (uint i = 0; i < size; i++) { machine_uint_t sz = 1; if (unichar_isdigit(*fmt)) { sz = get_fmt_num(&fmt); } if (sz > 1) { // TODO: size spec support only for string len assert(*fmt == 's'); } mp_obj_t item; if (*fmt == 's') { item = mp_obj_new_bytes(p, sz); p += sz; fmt++; } else { item = mp_binary_get_val(fmt_type, *fmt++, &p); } res->items[i] = item; } return res; }
STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) { const char *fmt = mp_obj_str_get_str(fmt_in); char fmt_type = get_fmt_type(&fmt); machine_uint_t size; for (size = 0; *fmt; fmt++) { uint align = 1; machine_uint_t cnt = 1; if (unichar_isdigit(*fmt)) { cnt = get_fmt_num(&fmt); } if (cnt > 1) { // TODO: count spec support only for string len assert(*fmt == 's'); } machine_uint_t sz; if (*fmt == 's') { sz = cnt; } else { sz = (machine_uint_t)mp_binary_get_size(fmt_type, *fmt, &align); } // TODO assert(sz != (machine_uint_t)-1); // Apply alignment size = (size + align - 1) & ~(align - 1); size += sz; } return MP_OBJ_NEW_SMALL_INT(size); }
/** * Perform the equivalent of a stat() system call on the given path. * * def stat(path) */ static mp_obj_t os_stat(mp_obj_t path_in) { const char *path_p; struct fs_stat_t stat; mp_obj_tuple_t *stat_p; int res; path_p = mp_obj_str_get_str(path_in); res = fs_stat(path_p, &stat); if (res != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Failed to stat '%s'", path_p)); } stat_p = mp_obj_new_tuple(10, NULL); stat_p->items[0] = MP_OBJ_NEW_SMALL_INT(0); /* st_mode */ stat_p->items[1] = MP_OBJ_NEW_SMALL_INT(0); /* st_ino */ stat_p->items[2] = MP_OBJ_NEW_SMALL_INT(0); /* st_dev */ stat_p->items[3] = MP_OBJ_NEW_SMALL_INT(0); /* st_nlink */ stat_p->items[4] = MP_OBJ_NEW_SMALL_INT(0); /* st_uid */ stat_p->items[5] = MP_OBJ_NEW_SMALL_INT(0); /* st_gid */ stat_p->items[6] = MP_OBJ_NEW_SMALL_INT(stat.size); /* st_size */ stat_p->items[7] = MP_OBJ_NEW_SMALL_INT(0); /* st_atime */ stat_p->items[8] = MP_OBJ_NEW_SMALL_INT(0); /* st_mtime */ stat_p->items[9] = MP_OBJ_NEW_SMALL_INT(0); /* st_ctime */ return (stat_p); }
/** * Return a list of all files and folders in given path. * * def listdir(path) */ static mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args_p) { struct fs_dir_t dir; struct fs_dir_entry_t entry; mp_obj_t entries; mp_obj_t name; const char *path_p; if (n_args == 0) { path_p = ""; } else { path_p = mp_obj_str_get_str(args_p[0]); } if (fs_dir_open(&dir, path_p, O_READ) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path_p)); } entries = mp_obj_new_list(0, NULL); while (fs_dir_read(&dir, &entry) == 1) { name = mp_obj_new_str(&entry.name[0], strlen(entry.name), false); mp_obj_list_append(entries, name); } fs_dir_close(&dir); return (entries); }
static mp_obj_t py_image_save(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { int res; image_t *image = py_image_cobj(args[0]); const char *path = mp_obj_str_get_str(args[1]); mp_map_elem_t *kw_subimage = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("subimage")), MP_MAP_LOOKUP); if (kw_subimage != NULL) { mp_obj_t *array; mp_obj_get_array_fixed_n(kw_subimage->value, 4, &array); rectangle_t r = { mp_obj_get_int(array[0]), mp_obj_get_int(array[1]), mp_obj_get_int(array[2]), mp_obj_get_int(array[3]), }; res = imlib_save_image(image, path, &r); } else { res = imlib_save_image(image, path, NULL); } if (res != FR_OK) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res))); } return mp_const_true; }
static mp_obj_t py_image_draw_circle(mp_obj_t image_obj, mp_obj_t c_obj, mp_obj_t r_obj) { int cx, cy, r; mp_obj_t *array; struct image *image; color_t c = {.r=0xFF, .g=0xFF, .b=0xFF}; /* get image pointer */ image = py_image_cobj(image_obj); /* center */ mp_obj_get_array_fixed_n(c_obj, 2, &array); cx = mp_obj_get_int(array[0]); cy = mp_obj_get_int(array[1]); /* radius */ r = mp_obj_get_int(r_obj); imlib_draw_circle(image, cx, cy, r, &c); return mp_const_none; } static mp_obj_t py_image_draw_string(uint n_args, const mp_obj_t *args) { int x = mp_obj_get_int(args[1]); int y = mp_obj_get_int(args[2]); image_t *image =py_image_cobj(args[0]); const char *str = mp_obj_str_get_str(args[3]); color_t c = {.r=0xFF, .g=0xFF, .b=0xFF}; // check x, y PY_ASSERT_TRUE_MSG(x>=0 && x<image->w, "Image index out of range"); PY_ASSERT_TRUE_MSG(y>=0 && y<image->h, "Image index out of range"); PY_ASSERT_TRUE_MSG(image->bpp <= 2, "This function is not supported on JPEG images"); if (n_args == 5) { // get color mp_obj_t *array; mp_obj_get_array_fixed_n(args[4], 3, &array); c.r = mp_obj_get_int(array[0]); c.g = mp_obj_get_int(array[1]); c.b = mp_obj_get_int(array[2]); } imlib_draw_string(image, x, y, str, &c); return mp_const_none; } static mp_obj_t py_image_erode(mp_obj_t image_obj, mp_obj_t ksize_obj) { image_t *image = NULL; image = py_image_cobj(image_obj); /* sanity checks */ PY_ASSERT_TRUE_MSG(image->bpp == 1, "This function is only supported on GRAYSCALE images"); imlib_erode(image, mp_obj_get_int(ksize_obj)); return mp_const_none; }
STATIC mp_obj_t mod_socket_getaddrinfo(uint n_args, const mp_obj_t *args) { // TODO: Implement all args assert(n_args == 2); assert(MP_OBJ_IS_STR(args[0])); const char *host = mp_obj_str_get_str(args[0]); const char *serv = NULL; // getaddrinfo accepts port in string notation, so however // it may seem stupid, we need to convert int to str if (MP_OBJ_IS_SMALL_INT(args[1])) { int port = (short)MP_OBJ_SMALL_INT_VALUE(args[1]); char buf[6]; sprintf(buf, "%d", port); serv = buf; } else { serv = mp_obj_str_get_str(args[1]); } struct addrinfo hints; struct addrinfo *addr; memset(&hints, 0, sizeof(hints)); int res = getaddrinfo(host, serv, NULL/*&hints*/, &addr); if (res != 0) { // CPython: socket.gaierror nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[addrinfo error %d]", res)); } assert(addr); mp_obj_t list = mp_obj_new_list(0, NULL); for (; addr; addr = addr->ai_next) { mp_obj_tuple_t *t = mp_obj_new_tuple(5, NULL); t->items[0] = MP_OBJ_NEW_SMALL_INT((machine_int_t)addr->ai_family); t->items[1] = MP_OBJ_NEW_SMALL_INT((machine_int_t)addr->ai_socktype); t->items[2] = MP_OBJ_NEW_SMALL_INT((machine_int_t)addr->ai_protocol); // "canonname will be a string representing the canonical name of the host // if AI_CANONNAME is part of the flags argument; else canonname will be empty." ?? if (addr->ai_canonname) { t->items[3] = MP_OBJ_NEW_QSTR(qstr_from_str(addr->ai_canonname)); } else { t->items[3] = mp_const_none; } t->items[4] = mp_obj_new_bytearray(addr->ai_addrlen, addr->ai_addr); mp_obj_list_append(list, t); } return list; }
static mp_obj_t mod_wlan_connect(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { int ssid_len =0; const char *ssid = NULL; const char *bssid = NULL; int key_len =0; int sec = WLAN_SEC_UNSEC; const char *key = NULL; mp_map_elem_t *kw_key, *kw_sec, *kw_bssid; ssid = mp_obj_str_get_str(args[0]); ssid_len = strlen(ssid); /* get KW args */ kw_key = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("key")), MP_MAP_LOOKUP); kw_sec = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("sec")), MP_MAP_LOOKUP); kw_bssid = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("bssid")), MP_MAP_LOOKUP); /* get key and sec */ if (kw_key && kw_sec) { key = mp_obj_str_get_str(kw_key->value); key_len = strlen(key); sec = mp_obj_get_int(kw_sec->value); if (!IS_WLAN_SEC(sec)) { nlr_raise(mp_obj_new_exception_msg( &mp_type_ValueError, "Invalid security mode")); return mp_const_false; } } /* get bssid */ if (kw_bssid != NULL) { bssid = mp_obj_str_get_str(kw_bssid->value); } /* connect to AP */ if (wlan_connect(sec, (char*) ssid, ssid_len, (uint8_t*)bssid, (uint8_t*)key, key_len) != 0) { return mp_const_false; } return mp_const_true; }
mp_obj_t pyb_ADC(mp_obj_t pin_name_obj) { pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t); o->base.type = &adc_type; o->pin_name = pin_name_obj; // work out the channel from the pin name const char *pin_name = mp_obj_str_get_str(pin_name_obj); GPIO_TypeDef *port; switch (pin_name[0]) { case 'A': case 'a': port = GPIOA; break; case 'B': case 'b': port = GPIOB; break; case 'C': case 'c': port = GPIOC; break; default: goto pin_error; } uint pin_num = 0; for (const char *s = pin_name + 1; *s; s++) { if (!('0' <= *s && *s <= '9')) { goto pin_error; } pin_num = 10 * pin_num + *s - '0'; } if (!(0 <= pin_num && pin_num <= 15)) { goto pin_error; } int i; for (i = 0; i < ADC_NUM_CHANNELS; i++) { if (adc_gpio[i].port == port && adc_gpio[i].pin == (1 << pin_num)) { o->channel = i; break; } } if (i == ADC_NUM_CHANNELS) { nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not have ADC capabilities", pin_name)); } // init ADC just for this channel adc_init_single(o->channel); o->is_enabled = true; return o; pin_error: nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %s does not exist", pin_name)); }
STATIC mp_obj_t mod_os_system(mp_obj_t cmd_in) { const char *cmd = mp_obj_str_get_str(cmd_in); int r = system(cmd); RAISE_ERRNO(r, errno); return MP_OBJ_NEW_SMALL_INT(r); }
STATIC mp_obj_t mod_os_unlink(mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); int r = unlink(path); RAISE_ERRNO(r, errno); return mp_const_none; }
STATIC mp_obj_t ffimod_addr(mp_obj_t self_in, mp_obj_t symname_in) { mp_obj_ffimod_t *self = MP_OBJ_TO_PTR(self_in); const char *symname = mp_obj_str_get_str(symname_in); void *sym = dlsym(self->handle, symname); if (sym == NULL) { mp_raise_OSError(MP_ENOENT); } return mp_obj_new_int((uintptr_t)sym); }
STATIC mp_obj_t mod_socket_inet_aton(mp_obj_t arg) { assert(MP_OBJ_IS_TYPE(arg, &mp_type_str)); const char *s = mp_obj_str_get_str(arg); struct in_addr addr; if (!inet_aton(s, &addr)) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EINVAL))); } return mp_obj_new_int(addr.s_addr); }
STATIC mp_obj_t ffimod_addr(mp_obj_t self_in, mp_obj_t symname_in) { mp_obj_ffimod_t *self = MP_OBJ_TO_PTR(self_in); const char *symname = mp_obj_str_get_str(symname_in); void *sym = dlsym(self->handle, symname); if (sym == NULL) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOENT))); } return mp_obj_new_int((uintptr_t)sym); }
STATIC void parse_inet_addr(socket_obj_t *socket, mp_obj_t addr_in, struct sockaddr *sockaddr) { // We employ the fact that port and address offsets are the same for IPv4 & IPv6 struct sockaddr_in *sockaddr_in = (struct sockaddr_in*)sockaddr; mp_obj_t *addr_items; mp_obj_get_array_fixed_n(addr_in, 2, &addr_items); sockaddr_in->sin_family = net_context_get_family((void*)socket->ctx); RAISE_ERRNO(net_addr_pton(sockaddr_in->sin_family, mp_obj_str_get_str(addr_items[0]), &sockaddr_in->sin_addr)); sockaddr_in->sin_port = htons(mp_obj_get_int(addr_items[1])); }
STATIC mp_obj_t mod_socket_gethostbyname(mp_obj_t arg) { const char *s = mp_obj_str_get_str(arg); struct hostent *h = gethostbyname(s); if (h == NULL) { // CPython: socket.herror mp_raise_OSError(h_errno); } assert(h->h_length == 4); return mp_obj_new_int(*(int*)*h->h_addr_list); }
static mp_obj_t mod_socket_inet_aton(mp_obj_t arg) { assert(MP_OBJ_IS_TYPE(arg, &str_type)); const char *s = mp_obj_str_get_str(arg); struct in_addr addr; if (!inet_aton(s, &addr)) { nlr_jump(mp_obj_new_exception_msg(MP_QSTR_OSError, "Invalid IP address")); } return mp_obj_new_int(addr.s_addr); }
// Version of mp_vfs_lookup_path that takes and returns uPy string objects. STATIC mp_vfs_mount_t *lookup_path(mp_obj_t path_in, mp_obj_t *path_out) { const char *path = mp_obj_str_get_str(path_in); const char *p_out; mp_vfs_mount_t *vfs = mp_vfs_lookup_path(path, &p_out); if (vfs != MP_VFS_NONE && vfs != MP_VFS_ROOT) { *path_out = mp_obj_new_str_of_type(mp_obj_get_type(path_in), (const byte*)p_out, strlen(p_out)); } return vfs; }
STATIC mp_obj_t mod_socket_inet_aton(mp_obj_t arg) { assert(MP_OBJ_IS_TYPE(arg, &mp_type_str)); const char *s = mp_obj_str_get_str(arg); struct in_addr addr; if (!inet_aton(s, &addr)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Invalid IP address")); } return mp_obj_new_int(addr.s_addr); }
STATIC mp_obj_t mod_socket_gethostbyname(mp_obj_t arg) { assert(MP_OBJ_IS_TYPE(arg, &mp_type_str)); const char *s = mp_obj_str_get_str(arg); struct hostent *h = gethostbyname(s); if (h == NULL) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno)); } assert(h->h_length == 4); return mp_obj_new_int(*(int*)*h->h_addr_list); }
STATIC mp_obj_t fdfile_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { mp_obj_fdfile_t *o = m_new_obj(mp_obj_fdfile_t); o->base.type = type_in; if (MP_OBJ_IS_SMALL_INT(args[0])) { o->fd = MP_OBJ_SMALL_INT_VALUE(args[0]); return o; } const char *fname = mp_obj_str_get_str(args[0]); const char *mode_s; if (n_args > 1) { mode_s = mp_obj_str_get_str(args[1]); } else { mode_s = "r"; } int mode = 0; while (*mode_s) { switch (*mode_s++) { // Note: these assume O_RDWR = O_RDONLY | O_WRONLY case 'r': mode |= O_RDONLY; break; case 'w': mode |= O_WRONLY | O_CREAT | O_TRUNC; break; case 'a': mode |= O_APPEND; break; case '+': mode |= O_RDWR; break; } } int fd = open(fname, mode, 0644); if (fd == -1) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "[Errno %d]", errno)); } return fdfile_new(fd); }
STATIC mp_obj_t mod_os_ilistdir(size_t n_args, const mp_obj_t *args) { const char *path = "."; if (n_args > 0) { path = mp_obj_str_get_str(args[0]); } mp_obj_listdir_t *o = m_new_obj(mp_obj_listdir_t); o->base.type = &mp_type_polymorph_iter; o->dir = opendir(path); o->iternext = listdir_next; return MP_OBJ_FROM_PTR(o); }
STATIC mp_obj_t mod_os_mkdir(mp_obj_t path_in) { // TODO: Accept mode param const char *path = mp_obj_str_get_str(path_in); #ifdef _WIN32 int r = mkdir(path); #else int r = mkdir(path, 0777); #endif RAISE_ERRNO(r, errno); return mp_const_none; }
STATIC mp_obj_t mod_socket_gethostbyname(mp_obj_t arg) { assert(MP_OBJ_IS_TYPE(arg, &mp_type_str)); const char *s = mp_obj_str_get_str(arg); struct hostent *h = gethostbyname(s); if (h == NULL) { // CPython: socket.herror nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(h_errno))); } assert(h->h_length == 4); return mp_obj_new_int(*(int*)*h->h_addr_list); }