Merge pull request #5036 from tannewt/esp_oserror0
Remove OSError(0) and old network modules
This commit is contained in:
commit
e790ff7327
|
@ -157,5 +157,3 @@ shared-bindings/vectorio/__init__.rst shared-bindings/vectorio/
|
|||
shared-bindings/watchdog/WatchDogMode.rst shared-bindings/watchdog/#watchdog.WatchDogMode
|
||||
shared-bindings/watchdog/WatchDogTimer.rst shared-bindings/watchdog/#watchdog.WatchDogTimer
|
||||
shared-bindings/watchdog/__init__.rst shared-bindings/watchdog/
|
||||
shared-bindings/wiznet/WIZNET5K.rst shared-bindings/wiznet/#wiznet.WIZNET5K
|
||||
shared-bindings/wiznet/__init__.rst shared-bindings/wiznet/
|
||||
|
|
|
@ -61,7 +61,6 @@ aliases_brand_names = {
|
|||
additional_modules = {
|
||||
"fontio": "CIRCUITPY_DISPLAYIO",
|
||||
"terminalio": "CIRCUITPY_DISPLAYIO",
|
||||
# "socket": "CIRCUITPY_NETWORK",
|
||||
"adafruit_bus_device": "CIRCUITPY_BUSDEVICE",
|
||||
"adafruit_pixelbuf": "CIRCUITPY_PIXELBUF"
|
||||
}
|
||||
|
|
12
main.c
12
main.c
|
@ -95,10 +95,6 @@
|
|||
#include "shared-module/memorymonitor/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_NETWORK
|
||||
#include "shared-module/network/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
#include "shared-module/usb_hid/__init__.h"
|
||||
#endif
|
||||
|
@ -169,17 +165,9 @@ STATIC void start_mp(supervisor_allocation* heap) {
|
|||
// Reset alarm module only after we retrieved the wakeup alarm.
|
||||
alarm_reset();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_NETWORK
|
||||
network_module_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC void stop_mp(void) {
|
||||
#if CIRCUITPY_NETWORK
|
||||
network_module_deinit();
|
||||
#endif
|
||||
|
||||
#if MICROPY_VFS
|
||||
mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);
|
||||
|
||||
|
|
|
@ -326,32 +326,6 @@ ifeq ($(CIRCUITPY_SDIOIO),1)
|
|||
SRC_C += ports/atmel-samd/sd_mmc/sd_mmc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CIRCUITPY_NETWORK),1)
|
||||
CFLAGS += -DMICROPY_PY_NETWORK=1
|
||||
|
||||
SRC_MOD += lib/netutils/netutils.c
|
||||
|
||||
ifneq ($(MICROPY_PY_WIZNET5K),0)
|
||||
WIZNET5K_DIR=drivers/wiznet5k
|
||||
INC += -I$(TOP)/$(WIZNET5K_DIR)
|
||||
CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=$(MICROPY_PY_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_WIZNET5K)
|
||||
SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\
|
||||
ethernet/w$(MICROPY_PY_WIZNET5K)/w$(MICROPY_PY_WIZNET5K).c \
|
||||
ethernet/wizchip_conf.c \
|
||||
ethernet/socket.c \
|
||||
internet/dns/dns.c \
|
||||
internet/dhcp/dhcp.c \
|
||||
)
|
||||
|
||||
endif # MICROPY_PY_WIZNET5K
|
||||
endif # CIRCUITPY_NETWORK
|
||||
|
||||
ifeq ($(CIRCUITPY_NETWORK),1)
|
||||
ifneq ($(MICROPY_PY_WIZNET5K),0)
|
||||
SRC_SHARED_MODULE += wiznet/__init__.c wiznet/wiznet5k.c
|
||||
endif
|
||||
endif
|
||||
|
||||
# The smallest SAMD51 packages don't have I2S. Everything else does.
|
||||
ifeq ($(CIRCUITPY_AUDIOBUSIO),1)
|
||||
SRC_C += peripherals/samd/i2s.c peripherals/samd/$(PERIPHERALS_CHIP_FAMILY)/i2s.c
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "supervisor/usb.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "shared-module/network/__init__.h"
|
||||
#include "supervisor/shared/stack.h"
|
||||
#include "supervisor/port.h"
|
||||
|
||||
|
|
|
@ -97,7 +97,6 @@ CIRCUITPY_TOUCHIO_USE_NATIVE = 0
|
|||
|
||||
# The ?='s allow overriding in mpconfigboard.mk.
|
||||
|
||||
CIRCUITPY_NETWORK ?= 0
|
||||
CIRCUITPY_PS2IO ?= 1
|
||||
CIRCUITPY_SAMD ?= 1
|
||||
CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FULL_BUILD)
|
||||
|
@ -116,7 +115,6 @@ CIRCUITPY_TOUCHIO_USE_NATIVE = 0
|
|||
|
||||
# The ?='s allow overriding in mpconfigboard.mk.
|
||||
|
||||
CIRCUITPY_NETWORK ?= 0
|
||||
CIRCUITPY_PS2IO ?= 1
|
||||
CIRCUITPY_SAMD ?= 1
|
||||
CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FULL_BUILD)
|
||||
|
|
|
@ -144,7 +144,7 @@ void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self) {
|
|||
}
|
||||
}
|
||||
|
||||
bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self,
|
||||
void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self,
|
||||
const char *host, size_t hostlen, uint32_t port) {
|
||||
const struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
|
@ -184,7 +184,7 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self,
|
|||
|
||||
if (result >= 0) {
|
||||
self->connected = true;
|
||||
return true;
|
||||
return;
|
||||
} else {
|
||||
mp_raise_OSError(errno);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self) {
|
|||
self->tls = NULL;
|
||||
}
|
||||
|
||||
bool common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self,
|
||||
void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self,
|
||||
const char *host, size_t hostlen, uint32_t port) {
|
||||
esp_tls_cfg_t *tls_config = NULL;
|
||||
tls_config = &self->ssl_context->ssl_config;
|
||||
|
@ -84,8 +84,6 @@ bool common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self,
|
|||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
|
||||
}
|
||||
|
||||
return self->sock->connected;
|
||||
}
|
||||
|
||||
bool common_hal_ssl_sslsocket_get_closed(ssl_sslsocket_obj_t *self) {
|
||||
|
|
|
@ -162,33 +162,6 @@ SRC_C += \
|
|||
reset.c \
|
||||
supervisor/flexspi_nor_flash_ops.c
|
||||
|
||||
|
||||
ifeq ($(CIRCUITPY_NETWORK),1)
|
||||
CFLAGS += -DMICROPY_PY_NETWORK=1
|
||||
|
||||
SRC_MOD += lib/netutils/netutils.c
|
||||
|
||||
ifneq ($(MICROPY_PY_WIZNET5K),0)
|
||||
WIZNET5K_DIR=drivers/wiznet5k
|
||||
INC += -I$(TOP)/$(WIZNET5K_DIR)
|
||||
CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=$(MICROPY_PY_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_WIZNET5K)
|
||||
SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\
|
||||
ethernet/w$(MICROPY_PY_WIZNET5K)/w$(MICROPY_PY_WIZNET5K).c \
|
||||
ethernet/wizchip_conf.c \
|
||||
ethernet/socket.c \
|
||||
internet/dns/dns.c \
|
||||
internet/dhcp/dhcp.c \
|
||||
)
|
||||
|
||||
endif # MICROPY_PY_WIZNET5K
|
||||
endif # CIRCUITPY_NETWORK
|
||||
|
||||
ifeq ($(CIRCUITPY_NETWORK),1)
|
||||
ifneq ($(MICROPY_PY_WIZNET5K),0)
|
||||
SRC_SHARED_MODULE += wiznet/__init__.c wiznet/wiznet5k.c
|
||||
endif
|
||||
endif
|
||||
|
||||
# TODO
|
||||
#ifeq ($(CIRCUITPY_AUDIOBUSIO),1)
|
||||
#SRC_C += peripherals/samd/i2s.c peripherals/samd/$(CHIP_FAMILY)/i2s.c
|
||||
|
|
|
@ -182,32 +182,6 @@ SRC_C += \
|
|||
endif
|
||||
endif # CIRCUITPY_USB
|
||||
|
||||
ifeq ($(CIRCUITPY_NETWORK),1)
|
||||
CFLAGS += -DMICROPY_PY_NETWORK=1
|
||||
|
||||
SRC_MOD += lib/netutils/netutils.c
|
||||
|
||||
ifneq ($(MICROPY_PY_WIZNET5K),0)
|
||||
WIZNET5K_DIR=drivers/wiznet5k
|
||||
INC += -I$(TOP)/$(WIZNET5K_DIR)
|
||||
CFLAGS_MOD += -DMICROPY_PY_WIZNET5K=$(MICROPY_PY_WIZNET5K) -D_WIZCHIP_=$(MICROPY_PY_WIZNET5K)
|
||||
SRC_MOD += $(addprefix $(WIZNET5K_DIR)/,\
|
||||
ethernet/w$(MICROPY_PY_WIZNET5K)/w$(MICROPY_PY_WIZNET5K).c \
|
||||
ethernet/wizchip_conf.c \
|
||||
ethernet/socket.c \
|
||||
internet/dns/dns.c \
|
||||
internet/dhcp/dhcp.c \
|
||||
)
|
||||
|
||||
endif # MICROPY_PY_WIZNET5K
|
||||
endif # CIRCUITPY_NETWORK
|
||||
|
||||
ifeq ($(CIRCUITPY_NETWORK),1)
|
||||
ifneq ($(MICROPY_PY_WIZNET5K),0)
|
||||
SRC_SHARED_MODULE += wiznet/__init__.c wiznet/wiznet5k.c
|
||||
endif
|
||||
endif
|
||||
|
||||
SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
|
||||
$(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
|
||||
$(addprefix common-hal/, $(SRC_COMMON_HAL))
|
||||
|
|
|
@ -214,9 +214,6 @@ endif
|
|||
ifeq ($(CIRCUITPY_NEOPIXEL_WRITE),1)
|
||||
SRC_PATTERNS += neopixel_write/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_NETWORK),1)
|
||||
SRC_PATTERNS += network/% socket/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_NVM),1)
|
||||
SRC_PATTERNS += nvm/%
|
||||
endif
|
||||
|
|
|
@ -578,23 +578,6 @@ extern const struct _mp_obj_module_t neopixel_write_module;
|
|||
#define NEOPIXEL_WRITE_MODULE
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_NETWORK
|
||||
extern const struct _mp_obj_module_t network_module;
|
||||
extern const struct _mp_obj_module_t socket_module;
|
||||
#define NETWORK_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&network_module },
|
||||
#define SOCKET_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&socket_module },
|
||||
#define NETWORK_ROOT_POINTERS mp_obj_list_t mod_network_nic_list;
|
||||
#if MICROPY_PY_WIZNET5K
|
||||
extern const struct _mp_obj_module_t wiznet_module;
|
||||
#define WIZNET_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_wiznet), (mp_obj_t)&wiznet_module },
|
||||
#endif
|
||||
#else
|
||||
#define NETWORK_MODULE
|
||||
#define SOCKET_MODULE
|
||||
#define WIZNET_MODULE
|
||||
#define NETWORK_ROOT_POINTERS
|
||||
#endif
|
||||
|
||||
// This is not a top-level module; it's microcontroller.nvm.
|
||||
#if CIRCUITPY_NVM
|
||||
extern const struct _mp_obj_module_t nvm_module;
|
||||
|
@ -918,9 +901,6 @@ extern const struct _mp_obj_module_t msgpack_module;
|
|||
MICROCONTROLLER_MODULE \
|
||||
MSGPACK_MODULE \
|
||||
NEOPIXEL_WRITE_MODULE \
|
||||
NETWORK_MODULE \
|
||||
SOCKET_MODULE \
|
||||
WIZNET_MODULE \
|
||||
PEW_MODULE \
|
||||
PIXELBUF_MODULE \
|
||||
PS2IO_MODULE \
|
||||
|
@ -977,24 +957,20 @@ extern const struct _mp_obj_module_t msgpack_module;
|
|||
struct _supervisor_allocation_node;
|
||||
|
||||
#define CIRCUITPY_COMMON_ROOT_POINTERS \
|
||||
const char *readline_hist[8]; \
|
||||
vstr_t *repl_line; \
|
||||
mp_obj_t rtc_time_source; \
|
||||
GAMEPAD_ROOT_POINTERS \
|
||||
KEYPAD_ROOT_POINTERS \
|
||||
mp_obj_t pew_singleton; \
|
||||
BOARD_UART_ROOT_POINTER \
|
||||
FLASH_ROOT_POINTERS \
|
||||
KEYPAD_ROOT_POINTERS \
|
||||
GAMEPAD_ROOT_POINTERS \
|
||||
BOARD_UART_ROOT_POINTER \
|
||||
MEMORYMONITOR_ROOT_POINTERS \
|
||||
NETWORK_ROOT_POINTERS \
|
||||
vstr_t *repl_line; \
|
||||
mp_obj_t pew_singleton; \
|
||||
mp_obj_t rtc_time_source; \
|
||||
const char *readline_hist[8]; \
|
||||
struct _supervisor_allocation_node *first_embedded_allocation; \
|
||||
|
||||
void supervisor_run_background_tasks_if_tick(void);
|
||||
#define RUN_BACKGROUND_TASKS (supervisor_run_background_tasks_if_tick())
|
||||
|
||||
// TODO: Used in wiznet5k driver, but may not be needed in the long run.
|
||||
#define MICROPY_THREAD_YIELD()
|
||||
|
||||
#define MICROPY_VM_HOOK_LOOP RUN_BACKGROUND_TASKS;
|
||||
#define MICROPY_VM_HOOK_RETURN RUN_BACKGROUND_TASKS;
|
||||
|
||||
|
|
|
@ -217,10 +217,6 @@ CFLAGS += -DCIRCUITPY_MSGPACK=$(CIRCUITPY_MSGPACK)
|
|||
CIRCUITPY_NEOPIXEL_WRITE ?= 1
|
||||
CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE)
|
||||
|
||||
# Enabled on SAMD51. Won't fit on SAMD21 builds. Not tested on nRF or STM32F4 builds.
|
||||
CIRCUITPY_NETWORK ?= 0
|
||||
CFLAGS += -DCIRCUITPY_NETWORK=$(CIRCUITPY_NETWORK)
|
||||
|
||||
CIRCUITPY_NVM ?= 1
|
||||
CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM)
|
||||
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/objlist.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "lib/netutils/netutils.h"
|
||||
|
||||
#include "shared-bindings/network/__init__.h"
|
||||
|
||||
#if CIRCUITPY_NETWORK
|
||||
|
||||
//| """Network Interface Management
|
||||
//|
|
||||
//| .. warning:: This module is disabled in 6.x and will removed in 7.x. Please use networking
|
||||
//| libraries instead.
|
||||
//|
|
||||
//| This module provides a registry of configured NICs.
|
||||
//| It is used by the 'socket' module to look up a suitable
|
||||
//| NIC when a socket is created."""
|
||||
//|
|
||||
//| def route() -> List[object]:
|
||||
//| """Returns a list of all configured NICs."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t network_route(void) {
|
||||
return MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_route), MP_ROM_PTR(&network_route_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table);
|
||||
|
||||
const mp_obj_module_t network_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&mp_module_network_globals,
|
||||
};
|
||||
|
||||
#endif // CIRCUITPY_NETWORK
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H
|
||||
|
||||
// nothing
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_NETWORK___INIT___H
|
|
@ -1,613 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
||||
* 2018 Nick Moore for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "lib/netutils/netutils.h"
|
||||
|
||||
#include "shared-module/network/__init__.h"
|
||||
|
||||
//| """TCP, UDP and RAW socket support
|
||||
//|
|
||||
//| .. warning:: This module is disabled in 6.x and will removed in 7.x. Please use networking
|
||||
//| libraries instead. (Native networking will provide a socket compatible class.)
|
||||
//|
|
||||
//| Create TCP, UDP and RAW sockets for communicating over the Internet."""
|
||||
//|
|
||||
|
||||
STATIC const mp_obj_type_t socket_type;
|
||||
|
||||
//| class socket:
|
||||
//|
|
||||
//| AF_INET: int
|
||||
//| AF_INET6: int
|
||||
//| SOCK_STREAM: int
|
||||
//| SOCK_DGRAM: int
|
||||
//| SOCK_RAW: int
|
||||
//| IPPROTO_TCP: int
|
||||
//|
|
||||
//| def __init__(self, family: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP) -> None:
|
||||
//| """Create a new socket
|
||||
//|
|
||||
//| :param int family: AF_INET or AF_INET6
|
||||
//| :param int type: SOCK_STREAM, SOCK_DGRAM or SOCK_RAW
|
||||
//| :param int proto: IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW (ignored)"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
mp_arg_check_num(n_args, kw_args, 0, 4, false);
|
||||
|
||||
// create socket object (not bound to any NIC yet)
|
||||
mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t);
|
||||
s->base.type = &socket_type;
|
||||
s->nic = MP_OBJ_NULL;
|
||||
s->nic_type = NULL;
|
||||
s->u_param.domain = MOD_NETWORK_AF_INET;
|
||||
s->u_param.type = MOD_NETWORK_SOCK_STREAM;
|
||||
s->u_param.fileno = -1;
|
||||
if (n_args >= 1) {
|
||||
s->u_param.domain = mp_obj_get_int(args[0]);
|
||||
if (n_args >= 2) {
|
||||
s->u_param.type = mp_obj_get_int(args[1]);
|
||||
if (n_args >= 4) {
|
||||
s->u_param.fileno = mp_obj_get_int(args[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MP_OBJ_FROM_PTR(s);
|
||||
}
|
||||
|
||||
STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) {
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// select NIC based on IP
|
||||
self->nic = network_module_find_nic(ip);
|
||||
self->nic_type = (mod_network_nic_type_t *)mp_obj_get_type(self->nic);
|
||||
|
||||
// call the NIC to open the socket
|
||||
int _errno;
|
||||
if (self->nic_type->socket(self, &_errno) != 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//| def bind(self, address: Tuple[str, int]) -> None:
|
||||
//| """Bind a socket to an address
|
||||
//|
|
||||
//| :param address: tuple of (remote_address, remote_port)
|
||||
//| :type address: tuple(str, int)"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
// get address
|
||||
uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG);
|
||||
|
||||
// check if we need to select a NIC
|
||||
socket_select_nic(self, ip);
|
||||
|
||||
// call the NIC to bind the socket
|
||||
int _errno;
|
||||
if (self->nic_type->bind(self, ip, port, &_errno) != 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind);
|
||||
|
||||
//| def listen(self, backlog: int) -> None:
|
||||
//| """Set socket to listen for incoming connections
|
||||
//|
|
||||
//| :param int backlog: length of backlog queue for waiting connetions"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
// TODO I think we can listen even if not bound...
|
||||
mp_raise_OSError(MP_ENOTCONN);
|
||||
}
|
||||
|
||||
int _errno;
|
||||
if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen);
|
||||
|
||||
//| def accept(self) -> Tuple[socket, str]:
|
||||
//| """Accept a connection on a listening socket of type SOCK_STREAM,
|
||||
//| creating a new socket of type SOCK_STREAM.
|
||||
//| Returns a tuple of (new_socket, remote_address)"""
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
// create new socket object
|
||||
// starts with empty NIC so that finaliser doesn't run close() method if accept() fails
|
||||
mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t);
|
||||
socket2->base.type = &socket_type;
|
||||
socket2->nic = MP_OBJ_NULL;
|
||||
socket2->nic_type = NULL;
|
||||
|
||||
// accept incoming connection
|
||||
uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
||||
mp_uint_t port;
|
||||
int _errno;
|
||||
if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
|
||||
// new socket has valid state, so set the NIC to the same as parent
|
||||
socket2->nic = self->nic;
|
||||
socket2->nic_type = self->nic_type;
|
||||
|
||||
// make the return value
|
||||
mp_obj_tuple_t *client = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
|
||||
client->items[0] = MP_OBJ_FROM_PTR(socket2);
|
||||
client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);
|
||||
|
||||
return MP_OBJ_FROM_PTR(client);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
|
||||
|
||||
//| def connect(self, address: Tuple[str, int]) -> None:
|
||||
//| """Connect a socket to a remote address
|
||||
//|
|
||||
//| :param address: tuple of (remote_address, remote_port)
|
||||
//| :type address: tuple(str, int)"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
// get address
|
||||
uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG);
|
||||
|
||||
// check if we need to select a NIC
|
||||
socket_select_nic(self, ip);
|
||||
|
||||
// call the NIC to connect the socket
|
||||
int _errno;
|
||||
if (self->nic_type->connect(self, ip, port, &_errno) != 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
|
||||
|
||||
//| def send(self, bytes: ReadableBuffer) -> int:
|
||||
//| """Send some bytes to the connected remote address.
|
||||
//| Suits sockets of type SOCK_STREAM
|
||||
//|
|
||||
//| :param ~_typing.ReadableBuffer bytes: some bytes to send"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
mp_raise_OSError(MP_EPIPE);
|
||||
}
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
||||
int _errno;
|
||||
mp_int_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno);
|
||||
if (ret == -1) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
return mp_obj_new_int_from_uint(ret);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send);
|
||||
|
||||
|
||||
// helper function for socket_recv and socket_recv_into to handle common operations of both
|
||||
STATIC mp_int_t _socket_recv_into(mod_network_socket_obj_t *sock, byte *buf, mp_int_t len) {
|
||||
int _errno;
|
||||
mp_int_t ret = sock->nic_type->recv(sock, buf, len, &_errno);
|
||||
if (ret == -1) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//| def recv_into(self, buffer: WriteableBuffer, bufsize: int) -> int:
|
||||
//| """Reads some bytes from the connected remote address, writing
|
||||
//| into the provided buffer. If bufsize <= len(buffer) is given,
|
||||
//| a maximum of bufsize bytes will be read into the buffer. If no
|
||||
//| valid value is given for bufsize, the default is the length of
|
||||
//| the given buffer.
|
||||
//|
|
||||
//| Suits sockets of type SOCK_STREAM
|
||||
//| Returns an int of number of bytes read.
|
||||
//|
|
||||
//| :param ~_typing.WriteableBuffer buffer: buffer to receive into
|
||||
//| :param int bufsize: optionally, a maximum number of bytes to read."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_recv_into(size_t n_args, const mp_obj_t *args) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
mp_raise_OSError(MP_ENOTCONN);
|
||||
}
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
|
||||
mp_int_t len = bufinfo.len;
|
||||
if (n_args == 3) {
|
||||
mp_int_t given_len = mp_obj_get_int(args[2]);
|
||||
if (given_len < len) {
|
||||
len = given_len;
|
||||
}
|
||||
}
|
||||
|
||||
mp_int_t ret = _socket_recv_into(self, (byte *)bufinfo.buf, len);
|
||||
return mp_obj_new_int_from_uint(ret);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_recv_into_obj, 2, 3, socket_recv_into);
|
||||
|
||||
//| def recv(self, bufsize: int) -> bytes:
|
||||
//| """Reads some bytes from the connected remote address.
|
||||
//| Suits sockets of type SOCK_STREAM
|
||||
//| Returns a bytes() of length <= bufsize
|
||||
//|
|
||||
//| :param int bufsize: maximum number of bytes to receive"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
mp_raise_OSError(MP_ENOTCONN);
|
||||
}
|
||||
mp_int_t len = mp_obj_get_int(len_in);
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, len);
|
||||
mp_int_t ret = _socket_recv_into(self, (byte *)vstr.buf, len);
|
||||
if (ret == 0) {
|
||||
return mp_const_empty_bytes;
|
||||
}
|
||||
vstr.len = ret;
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv);
|
||||
|
||||
//| def sendto(self, bytes: ReadableBuffer, address: Tuple[str, int]) -> int:
|
||||
//| """Send some bytes to a specific address.
|
||||
//| Suits sockets of type SOCK_DGRAM
|
||||
//|
|
||||
//| :param ~_typing.ReadableBuffer bytes: some bytes to send
|
||||
//| :param address: tuple of (remote_address, remote_port)
|
||||
//| :type address: tuple(str, int)"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
// get the data
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ);
|
||||
|
||||
// get address
|
||||
uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG);
|
||||
|
||||
// check if we need to select a NIC
|
||||
socket_select_nic(self, ip);
|
||||
|
||||
// call the NIC to sendto
|
||||
int _errno;
|
||||
mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno);
|
||||
if (ret == -1) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
|
||||
return mp_obj_new_int(ret);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto);
|
||||
|
||||
//| def recvfrom(self, bufsize: int) -> Tuple[bytes, Tuple[str, int]]:
|
||||
//| """Reads some bytes from the connected remote address.
|
||||
//| Suits sockets of type SOCK_STREAM
|
||||
//|
|
||||
//| Returns a tuple containing
|
||||
//| * a bytes() of length <= bufsize
|
||||
//| * a remote_address, which is a tuple of ip address and port number
|
||||
//|
|
||||
//| :param int bufsize: maximum number of bytes to receive"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
mp_raise_OSError(MP_ENOTCONN);
|
||||
}
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, mp_obj_get_int(len_in));
|
||||
byte ip[4];
|
||||
mp_uint_t port;
|
||||
int _errno;
|
||||
mp_int_t ret = self->nic_type->recvfrom(self, (byte *)vstr.buf, vstr.len, ip, &port, &_errno);
|
||||
if (ret == -1) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
mp_obj_t tuple[2];
|
||||
if (ret == 0) {
|
||||
tuple[0] = mp_const_empty_bytes;
|
||||
} else {
|
||||
vstr.len = ret;
|
||||
tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);
|
||||
return mp_obj_new_tuple(2, tuple);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom);
|
||||
|
||||
//| def setsockopt(self, level: int, optname: int, value: int) -> None:
|
||||
//| """Sets socket options"""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
|
||||
mp_int_t level = mp_obj_get_int(args[1]);
|
||||
mp_int_t opt = mp_obj_get_int(args[2]);
|
||||
|
||||
const void *optval;
|
||||
mp_uint_t optlen;
|
||||
mp_int_t val;
|
||||
if (mp_obj_is_integer(args[3])) {
|
||||
val = mp_obj_get_int_truncated(args[3]);
|
||||
optval = &val;
|
||||
optlen = sizeof(val);
|
||||
} else {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ);
|
||||
optval = bufinfo.buf;
|
||||
optlen = bufinfo.len;
|
||||
}
|
||||
|
||||
int _errno;
|
||||
if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt);
|
||||
|
||||
//| def settimeout(self, value: int) -> None:
|
||||
//| """Set the timeout value for this socket.
|
||||
//|
|
||||
//| :param int value: timeout in seconds. 0 means non-blocking. None means block indefinitely."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
mp_raise_OSError(MP_ENOTCONN);
|
||||
}
|
||||
mp_uint_t timeout;
|
||||
if (timeout_in == mp_const_none) {
|
||||
timeout = -1;
|
||||
} else {
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
timeout = 1000 * mp_obj_get_float(timeout_in);
|
||||
#else
|
||||
timeout = 1000 * mp_obj_get_int(timeout_in);
|
||||
#endif
|
||||
}
|
||||
int _errno;
|
||||
if (self->nic_type->settimeout(self, timeout, &_errno) != 0) {
|
||||
mp_raise_OSError(_errno);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_settimeout_obj, socket_settimeout);
|
||||
|
||||
//| def setblocking(self, flag: bool) -> Optional[int]:
|
||||
//| """Set the blocking behaviour of this socket.
|
||||
//|
|
||||
//| :param bool flag: False means non-blocking, True means block indefinitely."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
// method socket.setblocking(flag)
|
||||
STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) {
|
||||
if (mp_obj_is_true(blocking)) {
|
||||
return socket_settimeout(self_in, mp_const_none);
|
||||
} else {
|
||||
return socket_settimeout(self_in, MP_OBJ_NEW_SMALL_INT(0));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
|
||||
|
||||
STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socket_bind_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socket_listen_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socket_accept_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socket_connect_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socket_send_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&socket_recv_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socket_sendto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_recvfrom), MP_ROM_PTR(&socket_recvfrom_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socket_recv_into_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
|
||||
|
||||
mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||
mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (request == MP_STREAM_CLOSE) {
|
||||
if (self->nic != MP_OBJ_NULL) {
|
||||
self->nic_type->close(self);
|
||||
self->nic = MP_OBJ_NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return self->nic_type->ioctl(self, request, arg, errcode);
|
||||
}
|
||||
|
||||
STATIC const mp_stream_p_t socket_stream_p = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
|
||||
.ioctl = socket_ioctl,
|
||||
.is_text = false,
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t socket_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_socket,
|
||||
.make_new = socket_make_new,
|
||||
.protocol = &socket_stream_p,
|
||||
.locals_dict = (mp_obj_dict_t *)&socket_locals_dict,
|
||||
};
|
||||
|
||||
//| def getaddrinfo(host: str, port: int) -> Tuple[int, int, int, str, str]:
|
||||
//| """Gets the address information for a hostname and port
|
||||
//|
|
||||
//| Returns the appropriate family, socket type, socket protocol and
|
||||
//| address information to call socket.socket() and socket.connect() with,
|
||||
//| as a tuple."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t socket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
|
||||
size_t hlen;
|
||||
const char *host = mp_obj_str_get_data(host_in, &hlen);
|
||||
mp_int_t port = mp_obj_get_int(port_in);
|
||||
uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
||||
bool have_ip = false;
|
||||
|
||||
if (hlen > 0) {
|
||||
// check if host is already in IP form
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG);
|
||||
have_ip = true;
|
||||
nlr_pop();
|
||||
} else {
|
||||
// swallow exception: host was not in IP form so need to do DNS lookup
|
||||
}
|
||||
}
|
||||
|
||||
if (!have_ip) {
|
||||
// find a NIC that can do a name lookup
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
||||
mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
|
||||
mod_network_nic_type_t *nic_type = (mod_network_nic_type_t *)mp_obj_get_type(nic);
|
||||
if (nic_type->gethostbyname != NULL) {
|
||||
int ret = nic_type->gethostbyname(nic, host, hlen, out_ip);
|
||||
if (ret != 0) {
|
||||
mp_raise_OSError(ret);
|
||||
}
|
||||
have_ip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!have_ip) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC")));
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL));
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_AF_INET);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM);
|
||||
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
|
||||
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
|
||||
tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG);
|
||||
return mp_obj_new_list(1, (mp_obj_t *)&tuple);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_getaddrinfo_obj, socket_getaddrinfo);
|
||||
|
||||
STATIC const mp_rom_map_elem_t socket_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usocket) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socket_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&socket_getaddrinfo_obj) },
|
||||
|
||||
// class constants
|
||||
{ MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(MOD_NETWORK_AF_INET) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(MOD_NETWORK_AF_INET6) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(MOD_NETWORK_SOCK_STREAM) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(MOD_NETWORK_SOCK_DGRAM) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(MOD_NETWORK_SOCK_RAW) },
|
||||
|
||||
/*
|
||||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_IP), MP_ROM_INT(MOD_NETWORK_IPPROTO_IP) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_ICMP), MP_ROM_INT(MOD_NETWORK_IPPROTO_ICMP) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV4), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV4) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_TCP), MP_ROM_INT(MOD_NETWORK_IPPROTO_TCP) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_UDP), MP_ROM_INT(MOD_NETWORK_IPPROTO_UDP) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_IPV6), MP_ROM_INT(MOD_NETWORK_IPPROTO_IPV6) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IPPROTO_RAW), MP_ROM_INT(MOD_NETWORK_IPPROTO_RAW) },
|
||||
*/
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(socket_globals, socket_globals_table);
|
||||
|
||||
const mp_obj_module_t socket_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&socket_globals,
|
||||
};
|
|
@ -140,10 +140,7 @@ STATIC mp_obj_t socketpool_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
|||
mp_raise_ValueError(translate("port must be >= 0"));
|
||||
}
|
||||
|
||||
bool ok = common_hal_socketpool_socket_connect(self, host, hostlen, (uint32_t)port);
|
||||
if (!ok) {
|
||||
mp_raise_OSError(0);
|
||||
}
|
||||
common_hal_socketpool_socket_connect(self, host, hostlen, (uint32_t)port);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
@ -289,9 +286,6 @@ STATIC mp_obj_t socketpool_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_
|
|||
}
|
||||
|
||||
mp_int_t ret = common_hal_socketpool_socket_sendto(self, host, hostlen, (uint32_t)port, bufinfo.buf, bufinfo.len);
|
||||
if (!ret) {
|
||||
mp_raise_OSError(0);
|
||||
}
|
||||
|
||||
return mp_obj_new_int_from_uint(ret);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ extern const mp_obj_type_t socketpool_socket_type;
|
|||
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port);
|
||||
bool common_hal_socketpool_socket_bind(socketpool_socket_obj_t *self, const char *host, size_t hostlen, uint32_t port);
|
||||
void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self);
|
||||
bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self, const char *host, size_t hostlen, uint32_t port);
|
||||
void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self, const char *host, size_t hostlen, uint32_t port);
|
||||
bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t *self);
|
||||
bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *self);
|
||||
mp_uint_t common_hal_socketpool_socket_get_timeout(socketpool_socket_obj_t *self);
|
||||
|
|
|
@ -123,7 +123,7 @@ STATIC mp_obj_t socketpool_socketpool_getaddrinfo(size_t n_args, const mp_obj_t
|
|||
}
|
||||
|
||||
if (ip_str == mp_const_none) {
|
||||
mp_raise_OSError(0);
|
||||
mp_raise_OSError(-2); // socket.EAI_NONAME from CPython
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL));
|
||||
|
|
|
@ -139,10 +139,7 @@ STATIC mp_obj_t ssl_sslsocket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
|||
mp_raise_ValueError(translate("port must be >= 0"));
|
||||
}
|
||||
|
||||
bool ok = common_hal_ssl_sslsocket_connect(self, host, hostlen, (uint32_t)port);
|
||||
if (!ok) {
|
||||
mp_raise_OSError(0);
|
||||
}
|
||||
common_hal_ssl_sslsocket_connect(self, host, hostlen, (uint32_t)port);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ extern const mp_obj_type_t ssl_sslsocket_type;
|
|||
ssl_sslsocket_obj_t *common_hal_ssl_sslsocket_accept(ssl_sslsocket_obj_t *self, uint8_t *ip, uint32_t *port);
|
||||
bool common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port);
|
||||
void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self);
|
||||
bool common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port);
|
||||
void common_hal_ssl_sslsocket_connect(ssl_sslsocket_obj_t *self, const char *host, size_t hostlen, uint32_t port);
|
||||
bool common_hal_ssl_sslsocket_get_closed(ssl_sslsocket_obj_t *self);
|
||||
bool common_hal_ssl_sslsocket_get_connected(ssl_sslsocket_obj_t *self);
|
||||
bool common_hal_ssl_sslsocket_listen(ssl_sslsocket_obj_t *self, int backlog);
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/objlist.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
|
||||
#include "shared-module/network/__init__.h"
|
||||
|
||||
//| """Support for WizNet hardware, including the WizNet 5500 Ethernet adaptor.
|
||||
//|
|
||||
//|
|
||||
//| .. warning:: This module is disabled in 6.x and will removed in 7.x. Please use networking
|
||||
//| libraries instead.
|
||||
//| """
|
||||
//|
|
||||
|
||||
extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k;
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_wiznet_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wiznet) },
|
||||
#ifdef MICROPY_PY_WIZNET5K
|
||||
{ MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) },
|
||||
#endif // MICROPY_PY_WIZNET5K
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_wiznet_globals, mp_module_wiznet_globals_table);
|
||||
|
||||
const mp_obj_module_t wiznet_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&mp_module_wiznet_globals,
|
||||
};
|
|
@ -1,212 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/objlist.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/netutils/netutils.h"
|
||||
|
||||
#if MICROPY_PY_WIZNET5K
|
||||
|
||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||
#include "shared-bindings/digitalio/DriveMode.h"
|
||||
#include "shared-bindings/busio/SPI.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
|
||||
#include "shared-module/network/__init__.h"
|
||||
#include "shared-module/wiznet/wiznet5k.h"
|
||||
|
||||
//| class WIZNET5K:
|
||||
//| """Wrapper for Wiznet 5500 Ethernet interface"""
|
||||
//|
|
||||
//| def __init__(self, spi: busio.SPI, cs: microcontroller.Pin, rst: microcontroller.Pin, dhcp: bool = True) -> None:
|
||||
//| """Create a new WIZNET5500 interface using the specified pins
|
||||
//|
|
||||
//| :param ~busio.SPI spi: spi bus to use
|
||||
//| :param ~microcontroller.Pin cs: pin to use for Chip Select
|
||||
//| :param ~microcontroller.Pin rst: pin to use for Reset (optional)
|
||||
//| :param bool dhcp: boolean flag, whether to start DHCP automatically (optional, keyword only, default True)
|
||||
//|
|
||||
//| * The reset pin is optional: if supplied it is used to reset the
|
||||
//| wiznet board before initialization.
|
||||
//| * The SPI bus will be initialized appropriately by this library.
|
||||
//| * At present, the WIZNET5K object is a singleton, so only one WizNet
|
||||
//| interface is supported at a time."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_spi, ARG_cs, ARG_rst, ARG_dhcp };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_spi, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_cs, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_rst, MP_ARG_OBJ, { .u_obj = mp_const_none } },
|
||||
{ MP_QSTR_dhcp, MP_ARG_KW_ONLY | MP_ARG_BOOL, { .u_bool = true } },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
// TODO check type of ARG_spi?
|
||||
const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj);
|
||||
const mcu_pin_obj_t *rst = validate_obj_is_free_pin_or_none(args[ARG_rst].u_obj);
|
||||
|
||||
mp_obj_t ret = wiznet5k_create(args[ARG_spi].u_obj, cs, rst);
|
||||
if (args[ARG_dhcp].u_bool) {
|
||||
wiznet5k_start_dhcp();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//| connected: bool
|
||||
//| """(boolean, readonly) is this device physically connected?"""
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) {
|
||||
(void)self_in;
|
||||
return mp_obj_new_bool(wizphy_getphylink() == PHY_LINK_ON);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_connected_get_value_obj, wiznet5k_connected_get_value);
|
||||
|
||||
const mp_obj_property_t wiznet5k_connected_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&wiznet5k_connected_get_value_obj,
|
||||
MP_ROM_NONE,
|
||||
MP_ROM_NONE},
|
||||
};
|
||||
|
||||
//| dhcp: bool
|
||||
//| """(boolean, readwrite) is DHCP active on this device?
|
||||
//|
|
||||
//| * set to True to activate DHCP, False to turn it off"""
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t wiznet5k_dhcp_get_value(mp_obj_t self_in) {
|
||||
(void)self_in;
|
||||
return mp_obj_new_bool(wiznet5k_check_dhcp());
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_dhcp_get_value_obj, wiznet5k_dhcp_get_value);
|
||||
|
||||
STATIC mp_obj_t wiznet5k_dhcp_set_value(mp_obj_t self_in, mp_obj_t value) {
|
||||
(void)self_in;
|
||||
if (mp_obj_is_true(value)) {
|
||||
int ret = wiznet5k_start_dhcp();
|
||||
if (ret) {
|
||||
mp_raise_OSError(ret);
|
||||
}
|
||||
} else {
|
||||
int ret = wiznet5k_stop_dhcp();
|
||||
if (ret) {
|
||||
mp_raise_OSError(ret);
|
||||
}
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(wiznet5k_dhcp_set_value_obj, wiznet5k_dhcp_set_value);
|
||||
|
||||
const mp_obj_property_t wiznet5k_dhcp_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&wiznet5k_dhcp_get_value_obj,
|
||||
(mp_obj_t)&wiznet5k_dhcp_set_value_obj,
|
||||
MP_ROM_NONE},
|
||||
};
|
||||
|
||||
//| def ifconfig(self, params: Optional[Tuple[str, str, str, str]] = None) -> Optional[Tuple[str, str, str, str]]:
|
||||
//| """Called without parameters, returns a tuple of
|
||||
//| (ip_address, subnet_mask, gateway_address, dns_server)
|
||||
//|
|
||||
//| Or can be called with the same tuple to set those parameters.
|
||||
//| Setting ifconfig parameters turns DHCP off, if it was on."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) {
|
||||
wiz_NetInfo netinfo;
|
||||
ctlnetwork(CN_GET_NETINFO, &netinfo);
|
||||
if (n_args == 1) {
|
||||
// get
|
||||
mp_obj_t tuple[4] = {
|
||||
netutils_format_ipv4_addr(netinfo.ip, NETUTILS_BIG),
|
||||
netutils_format_ipv4_addr(netinfo.sn, NETUTILS_BIG),
|
||||
netutils_format_ipv4_addr(netinfo.gw, NETUTILS_BIG),
|
||||
netutils_format_ipv4_addr(netinfo.dns, NETUTILS_BIG),
|
||||
};
|
||||
return mp_obj_new_tuple(4, tuple);
|
||||
} else {
|
||||
// set
|
||||
wiznet5k_stop_dhcp();
|
||||
mp_obj_t *items;
|
||||
mp_obj_get_array_fixed_n(args[1], 4, &items);
|
||||
netutils_parse_ipv4_addr(items[0], netinfo.ip, NETUTILS_BIG);
|
||||
netutils_parse_ipv4_addr(items[1], netinfo.sn, NETUTILS_BIG);
|
||||
netutils_parse_ipv4_addr(items[2], netinfo.gw, NETUTILS_BIG);
|
||||
netutils_parse_ipv4_addr(items[3], netinfo.dns, NETUTILS_BIG);
|
||||
ctlnetwork(CN_SET_NETINFO, &netinfo);
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wiznet5k_ifconfig_obj, 1, 2, wiznet5k_ifconfig);
|
||||
|
||||
STATIC const mp_rom_map_elem_t wiznet5k_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wiznet5k_ifconfig_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&wiznet5k_connected_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_dhcp), MP_ROM_PTR(&wiznet5k_dhcp_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(wiznet5k_locals_dict, wiznet5k_locals_dict_table);
|
||||
|
||||
const mod_network_nic_type_t mod_network_nic_type_wiznet5k = {
|
||||
.base = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_WIZNET5K,
|
||||
.make_new = wiznet5k_make_new,
|
||||
.locals_dict = (mp_obj_dict_t *)&wiznet5k_locals_dict,
|
||||
},
|
||||
.gethostbyname = wiznet5k_gethostbyname,
|
||||
.socket = wiznet5k_socket_socket,
|
||||
.close = wiznet5k_socket_close,
|
||||
.bind = wiznet5k_socket_bind,
|
||||
.listen = wiznet5k_socket_listen,
|
||||
.accept = wiznet5k_socket_accept,
|
||||
.connect = wiznet5k_socket_connect,
|
||||
.send = wiznet5k_socket_send,
|
||||
.recv = wiznet5k_socket_recv,
|
||||
.sendto = wiznet5k_socket_sendto,
|
||||
.recvfrom = wiznet5k_socket_recvfrom,
|
||||
.setsockopt = wiznet5k_socket_setsockopt,
|
||||
.settimeout = wiznet5k_socket_settimeout,
|
||||
.ioctl = wiznet5k_socket_ioctl,
|
||||
.timer_tick = wiznet5k_socket_timer_tick,
|
||||
.deinit = wiznet5k_socket_deinit,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_WIZNET5K
|
|
@ -1,113 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Nick Moore
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/objlist.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/mperrno.h"
|
||||
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
#include "shared-bindings/random/__init__.h"
|
||||
|
||||
#include "shared-module/network/__init__.h"
|
||||
|
||||
// mod_network_nic_list needs to be declared in mpconfigport.h
|
||||
|
||||
|
||||
void network_module_init(void) {
|
||||
mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0);
|
||||
}
|
||||
|
||||
void network_module_deinit(void) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
||||
mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
|
||||
mod_network_nic_type_t *nic_type = (mod_network_nic_type_t *)mp_obj_get_type(nic);
|
||||
if (nic_type->deinit != NULL) {
|
||||
nic_type->deinit(nic);
|
||||
}
|
||||
}
|
||||
mp_obj_list_set_len(&MP_STATE_PORT(mod_network_nic_list), 0);
|
||||
}
|
||||
|
||||
void network_module_background(void) {
|
||||
static uint32_t next_tick = 0;
|
||||
uint32_t this_tick = supervisor_ticks_ms32();
|
||||
if (this_tick < next_tick) {
|
||||
return;
|
||||
}
|
||||
next_tick = this_tick + 1000;
|
||||
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
||||
mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
|
||||
mod_network_nic_type_t *nic_type = (mod_network_nic_type_t *)mp_obj_get_type(nic);
|
||||
if (nic_type->timer_tick != NULL) {
|
||||
nic_type->timer_tick(nic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void network_module_register_nic(mp_obj_t nic) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
||||
if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) {
|
||||
// nic already registered
|
||||
return;
|
||||
}
|
||||
}
|
||||
// nic not registered so add to list
|
||||
mp_obj_list_append(MP_OBJ_FROM_PTR(&MP_STATE_PORT(mod_network_nic_list)), nic);
|
||||
}
|
||||
|
||||
mp_obj_t network_module_find_nic(const uint8_t *ip) {
|
||||
// find a NIC that is suited to given IP address
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
||||
mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
|
||||
// TODO check IP suitability here
|
||||
// mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
|
||||
return nic;
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("no available NIC")));
|
||||
}
|
||||
|
||||
void network_module_create_random_mac_address(uint8_t *mac) {
|
||||
uint32_t rb1 = shared_modules_random_getrandbits(24);
|
||||
uint32_t rb2 = shared_modules_random_getrandbits(24);
|
||||
// first octet has multicast bit (0) cleared and local bit (1) set
|
||||
// everything else is just set randomly
|
||||
mac[0] = ((uint8_t)(rb1 >> 16) & 0xfe) | 0x02;
|
||||
mac[1] = (uint8_t)(rb1 >> 8);
|
||||
mac[2] = (uint8_t)(rb1);
|
||||
mac[3] = (uint8_t)(rb2 >> 16);
|
||||
mac[4] = (uint8_t)(rb2 >> 8);
|
||||
mac[5] = (uint8_t)(rb2);
|
||||
}
|
||||
|
||||
uint16_t network_module_create_random_source_tcp_port(void) {
|
||||
return 0xc000 | shared_modules_random_getrandbits(14);
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2018 Nick Moore
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H
|
||||
|
||||
void network_module_create_random_mac_address(uint8_t *mac);
|
||||
uint16_t network_module_create_random_source_tcp_port(void);
|
||||
|
||||
#define MOD_NETWORK_IPADDR_BUF_SIZE (4)
|
||||
|
||||
#define MOD_NETWORK_AF_INET (2)
|
||||
#define MOD_NETWORK_AF_INET6 (10)
|
||||
|
||||
#define MOD_NETWORK_SOCK_STREAM (1)
|
||||
#define MOD_NETWORK_SOCK_DGRAM (2)
|
||||
#define MOD_NETWORK_SOCK_RAW (3)
|
||||
|
||||
struct _mod_network_socket_obj_t;
|
||||
|
||||
typedef struct _mod_network_nic_type_t {
|
||||
mp_obj_type_t base;
|
||||
|
||||
// API for non-socket operations
|
||||
int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out);
|
||||
|
||||
// API for socket operations; return -1 on error
|
||||
int (*socket)(struct _mod_network_socket_obj_t *socket, int *_errno);
|
||||
void (*close)(struct _mod_network_socket_obj_t *socket);
|
||||
int (*bind)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno);
|
||||
int (*listen)(struct _mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno);
|
||||
int (*accept)(struct _mod_network_socket_obj_t *socket, struct _mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno);
|
||||
int (*connect)(struct _mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno);
|
||||
mp_uint_t (*send)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno);
|
||||
mp_uint_t (*recv)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno);
|
||||
mp_uint_t (*sendto)(struct _mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno);
|
||||
mp_uint_t (*recvfrom)(struct _mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno);
|
||||
int (*setsockopt)(struct _mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno);
|
||||
int (*settimeout)(struct _mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno);
|
||||
int (*ioctl)(struct _mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno);
|
||||
void (*timer_tick)(struct _mod_network_socket_obj_t *socket);
|
||||
void (*deinit)(struct _mod_network_socket_obj_t *socket);
|
||||
} mod_network_nic_type_t;
|
||||
|
||||
typedef struct _mod_network_socket_obj_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t nic;
|
||||
mod_network_nic_type_t *nic_type;
|
||||
union {
|
||||
struct {
|
||||
uint8_t domain;
|
||||
uint8_t type;
|
||||
int8_t fileno;
|
||||
} u_param;
|
||||
mp_uint_t u_state;
|
||||
};
|
||||
} mod_network_socket_obj_t;
|
||||
|
||||
extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k;
|
||||
extern const mod_network_nic_type_t mod_network_nic_type_cc3k;
|
||||
|
||||
void network_module_init(void);
|
||||
void network_module_deinit(void);
|
||||
void network_module_background(void);
|
||||
void network_module_register_nic(mp_obj_t nic);
|
||||
mp_obj_t network_module_find_nic(const uint8_t *ip);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_MODULE_NETWORK___INIT___H
|
|
@ -1,442 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/objlist.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/netutils/netutils.h"
|
||||
|
||||
#if MICROPY_PY_WIZNET5K
|
||||
|
||||
#include "shared-module/network/__init__.h"
|
||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||
#include "shared-bindings/digitalio/DriveMode.h"
|
||||
#include "shared-bindings/busio/SPI.h"
|
||||
|
||||
#include "shared-module/network/__init__.h"
|
||||
|
||||
#include "ethernet/wizchip_conf.h"
|
||||
#include "ethernet/socket.h"
|
||||
#include "internet/dns/dns.h"
|
||||
#include "internet/dhcp/dhcp.h"
|
||||
|
||||
#include "shared-module/wiznet/wiznet5k.h"
|
||||
|
||||
STATIC wiznet5k_obj_t wiznet5k_obj;
|
||||
|
||||
STATIC void wiz_cris_enter(void) {
|
||||
wiznet5k_obj.cris_state = MICROPY_BEGIN_ATOMIC_SECTION();
|
||||
}
|
||||
|
||||
STATIC void wiz_cris_exit(void) {
|
||||
MICROPY_END_ATOMIC_SECTION(wiznet5k_obj.cris_state);
|
||||
}
|
||||
|
||||
STATIC void wiz_cs_select(void) {
|
||||
common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 0);
|
||||
}
|
||||
|
||||
STATIC void wiz_cs_deselect(void) {
|
||||
common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.cs, 1);
|
||||
}
|
||||
|
||||
STATIC void wiz_spi_read(uint8_t *buf, uint32_t len) {
|
||||
(void)common_hal_busio_spi_read(wiznet5k_obj.spi, buf, len, 0);
|
||||
}
|
||||
|
||||
STATIC void wiz_spi_write(const uint8_t *buf, uint32_t len) {
|
||||
(void)common_hal_busio_spi_write(wiznet5k_obj.spi, buf, len);
|
||||
}
|
||||
|
||||
int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip) {
|
||||
uint8_t dns_ip[MOD_NETWORK_IPADDR_BUF_SIZE] = {8, 8, 8, 8};
|
||||
uint8_t *buf = m_new(uint8_t, MAX_DNS_BUF_SIZE);
|
||||
DNS_init(0, buf);
|
||||
mp_int_t ret = DNS_run(dns_ip, (uint8_t *)name, out_ip);
|
||||
m_del(uint8_t, buf, MAX_DNS_BUF_SIZE);
|
||||
if (ret == 1) {
|
||||
// success
|
||||
return 0;
|
||||
} else {
|
||||
// failure
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
int get_available_socket(wiznet5k_obj_t *wiz) {
|
||||
for (uint8_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) {
|
||||
if ((wiz->socket_used & (1 << sn)) == 0) {
|
||||
wiz->socket_used |= (1 << sn);
|
||||
return sn;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) {
|
||||
if (socket->u_param.domain != MOD_NETWORK_AF_INET) {
|
||||
*_errno = MP_EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (socket->u_param.type) {
|
||||
case MOD_NETWORK_SOCK_STREAM:
|
||||
socket->u_param.type = Sn_MR_TCP;
|
||||
break;
|
||||
case MOD_NETWORK_SOCK_DGRAM:
|
||||
socket->u_param.type = Sn_MR_UDP;
|
||||
break;
|
||||
default:
|
||||
*_errno = MP_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (socket->u_param.fileno == -1) {
|
||||
// get first unused socket number
|
||||
socket->u_param.fileno = get_available_socket(&wiznet5k_obj);
|
||||
if (socket->u_param.fileno == -1) {
|
||||
// too many open sockets
|
||||
*_errno = MP_EMFILE;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// WIZNET does not have a concept of pure "open socket". You need to know
|
||||
// if it's a server or client at the time of creation of the socket.
|
||||
// So, we defer the open until we know what kind of socket we want.
|
||||
|
||||
// use "domain" to indicate that this socket has not yet been opened
|
||||
socket->u_param.domain = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void wiznet5k_socket_close(mod_network_socket_obj_t *socket) {
|
||||
uint8_t sn = (uint8_t)socket->u_param.fileno;
|
||||
if (sn < _WIZCHIP_SOCK_NUM_) {
|
||||
wiznet5k_obj.socket_used &= ~(1 << sn);
|
||||
WIZCHIP_EXPORT(close)(sn);
|
||||
}
|
||||
}
|
||||
|
||||
int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) {
|
||||
// open the socket in server mode (if port != 0)
|
||||
mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->u_param.fileno, socket->u_param.type, port, 0);
|
||||
if (ret < 0) {
|
||||
wiznet5k_socket_close(socket);
|
||||
*_errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// indicate that this socket has been opened
|
||||
socket->u_param.domain = 1;
|
||||
|
||||
// success
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) {
|
||||
mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->u_param.fileno);
|
||||
if (ret < 0) {
|
||||
wiznet5k_socket_close(socket);
|
||||
*_errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) {
|
||||
for (;;) {
|
||||
int sr = getSn_SR((uint8_t)socket->u_param.fileno);
|
||||
if (sr == SOCK_ESTABLISHED) {
|
||||
socket2->u_param = socket->u_param;
|
||||
getSn_DIPR((uint8_t)socket2->u_param.fileno, ip);
|
||||
*port = getSn_PORT(socket2->u_param.fileno);
|
||||
|
||||
// WIZnet turns the listening socket into the client socket, so we
|
||||
// need to re-bind and re-listen on another socket for the server.
|
||||
// TODO handle errors, especially no-more-sockets error
|
||||
socket->u_param.domain = MOD_NETWORK_AF_INET;
|
||||
socket->u_param.fileno = -1;
|
||||
int _errno2;
|
||||
if (wiznet5k_socket_socket(socket, &_errno2) != 0) {
|
||||
// printf("(bad resocket %d)\n", _errno2);
|
||||
} else if (wiznet5k_socket_bind(socket, NULL, *port, &_errno2) != 0) {
|
||||
// printf("(bad rebind %d)\n", _errno2);
|
||||
} else if (wiznet5k_socket_listen(socket, 0, &_errno2) != 0) {
|
||||
// printf("(bad relisten %d)\n", _errno2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (sr == SOCK_CLOSED || sr == SOCK_CLOSE_WAIT) {
|
||||
wiznet5k_socket_close(socket);
|
||||
*_errno = MP_ENOTCONN; // ??
|
||||
return -1;
|
||||
}
|
||||
mp_hal_delay_ms(1);
|
||||
}
|
||||
}
|
||||
|
||||
int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) {
|
||||
uint16_t src_port = network_module_create_random_source_tcp_port();
|
||||
// make sure same outgoing port number can't be in use by two different sockets.
|
||||
src_port = (src_port & ~(_WIZCHIP_SOCK_NUM_ - 1)) | socket->u_param.fileno;
|
||||
|
||||
// use "bind" function to open the socket in client mode
|
||||
if (wiznet5k_socket_bind(socket, NULL, src_port, _errno) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// now connect
|
||||
MP_THREAD_GIL_EXIT();
|
||||
mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->u_param.fileno, ip, port);
|
||||
MP_THREAD_GIL_ENTER();
|
||||
|
||||
if (ret < 0) {
|
||||
wiznet5k_socket_close(socket);
|
||||
*_errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// success
|
||||
return 0;
|
||||
}
|
||||
|
||||
mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) {
|
||||
MP_THREAD_GIL_EXIT();
|
||||
mp_int_t ret = WIZCHIP_EXPORT(send)(socket->u_param.fileno, (byte *)buf, len);
|
||||
MP_THREAD_GIL_ENTER();
|
||||
|
||||
// TODO convert Wiz errno's to POSIX ones
|
||||
if (ret < 0) {
|
||||
wiznet5k_socket_close(socket);
|
||||
*_errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) {
|
||||
MP_THREAD_GIL_EXIT();
|
||||
mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->u_param.fileno, buf, len);
|
||||
MP_THREAD_GIL_ENTER();
|
||||
|
||||
// TODO convert Wiz errno's to POSIX ones
|
||||
if (ret < 0) {
|
||||
wiznet5k_socket_close(socket);
|
||||
*_errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) {
|
||||
if (socket->u_param.domain == 0) {
|
||||
// socket not opened; use "bind" function to open the socket in client mode
|
||||
if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
MP_THREAD_GIL_EXIT();
|
||||
mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->u_param.fileno, (byte *)buf, len, ip, port);
|
||||
MP_THREAD_GIL_ENTER();
|
||||
|
||||
if (ret < 0) {
|
||||
wiznet5k_socket_close(socket);
|
||||
*_errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
|
||||
uint16_t port2;
|
||||
MP_THREAD_GIL_EXIT();
|
||||
mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->u_param.fileno, buf, len, ip, &port2);
|
||||
MP_THREAD_GIL_ENTER();
|
||||
*port = port2;
|
||||
if (ret < 0) {
|
||||
wiznet5k_socket_close(socket);
|
||||
*_errno = -ret;
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) {
|
||||
// TODO
|
||||
*_errno = MP_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno) {
|
||||
// TODO
|
||||
*_errno = MP_EINVAL;
|
||||
return -1;
|
||||
|
||||
/*
|
||||
if (timeout_ms == 0) {
|
||||
// set non-blocking mode
|
||||
uint8_t arg = SOCK_IO_NONBLOCK;
|
||||
WIZCHIP_EXPORT(ctlsocket)(socket->u_param.fileno, CS_SET_IOMODE, &arg);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) {
|
||||
if (request == MP_STREAM_POLL) {
|
||||
int ret = 0;
|
||||
if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) {
|
||||
ret |= MP_STREAM_POLL_RD;
|
||||
}
|
||||
if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) {
|
||||
ret |= MP_STREAM_POLL_WR;
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
*_errno = MP_EINVAL;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket) {
|
||||
if (wiznet5k_obj.dhcp_socket >= 0) {
|
||||
DHCP_time_handler();
|
||||
DHCP_run();
|
||||
}
|
||||
}
|
||||
|
||||
int wiznet5k_start_dhcp(void) {
|
||||
// XXX this should throw an error if DHCP fails
|
||||
static DHCP_INIT_BUFFER_TYPE dhcp_buf[DHCP_INIT_BUFFER_SIZE];
|
||||
|
||||
if (wiznet5k_obj.dhcp_socket < 0) {
|
||||
// Set up the socket to listen on UDP 68 before calling DHCP_init
|
||||
wiznet5k_obj.dhcp_socket = get_available_socket(&wiznet5k_obj);
|
||||
if (wiznet5k_obj.dhcp_socket < 0) {
|
||||
return MP_EMFILE;
|
||||
}
|
||||
|
||||
WIZCHIP_EXPORT(socket)(wiznet5k_obj.dhcp_socket, MOD_NETWORK_SOCK_DGRAM, DHCP_CLIENT_PORT, 0);
|
||||
DHCP_init(wiznet5k_obj.dhcp_socket, dhcp_buf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wiznet5k_stop_dhcp(void) {
|
||||
if (wiznet5k_obj.dhcp_socket >= 0) {
|
||||
DHCP_stop();
|
||||
WIZCHIP_EXPORT(close)(wiznet5k_obj.dhcp_socket);
|
||||
wiznet5k_obj.socket_used &= ~(1 << wiznet5k_obj.dhcp_socket);
|
||||
wiznet5k_obj.dhcp_socket = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool wiznet5k_check_dhcp(void) {
|
||||
return wiznet5k_obj.dhcp_socket >= 0;
|
||||
}
|
||||
|
||||
void wiznet5k_reset(void) {
|
||||
if (wiznet5k_obj.rst.pin) {
|
||||
// hardware reset if using RST pin
|
||||
common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 0);
|
||||
mp_hal_delay_us(10); // datasheet says 2us
|
||||
common_hal_digitalio_digitalinout_set_value(&wiznet5k_obj.rst, 1);
|
||||
mp_hal_delay_ms(150); // datasheet says 150ms
|
||||
} else {
|
||||
// otherwise, software reset
|
||||
wizchip_sw_reset();
|
||||
}
|
||||
}
|
||||
|
||||
void wiznet5k_socket_deinit(mod_network_socket_obj_t *socket) {
|
||||
wiznet5k_reset();
|
||||
}
|
||||
|
||||
/// Create and return a WIZNET5K object.
|
||||
mp_obj_t wiznet5k_create(busio_spi_obj_t *spi_in, const mcu_pin_obj_t *cs_in, const mcu_pin_obj_t *rst_in) {
|
||||
|
||||
// init the wiznet5k object
|
||||
wiznet5k_obj.base.type = (mp_obj_type_t *)&mod_network_nic_type_wiznet5k;
|
||||
wiznet5k_obj.cris_state = 0;
|
||||
wiznet5k_obj.spi = spi_in;
|
||||
wiznet5k_obj.socket_used = 0;
|
||||
wiznet5k_obj.dhcp_socket = -1;
|
||||
|
||||
/*!< SPI configuration */
|
||||
// XXX probably should check if the provided SPI is already configured, and
|
||||
// if so skip configuration?
|
||||
|
||||
common_hal_busio_spi_configure(wiznet5k_obj.spi,
|
||||
10000000, // BAUDRATE 10MHz
|
||||
1, // HIGH POLARITY
|
||||
1, // SECOND PHASE TRANSITION
|
||||
8 // 8 BITS
|
||||
);
|
||||
|
||||
common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.cs, cs_in);
|
||||
common_hal_digitalio_digitalinout_switch_to_output(&wiznet5k_obj.cs, 1, DRIVE_MODE_PUSH_PULL);
|
||||
|
||||
if (rst_in) {
|
||||
common_hal_digitalio_digitalinout_construct(&wiznet5k_obj.rst, rst_in);
|
||||
}
|
||||
wiznet5k_reset();
|
||||
|
||||
reg_wizchip_cris_cbfunc(wiz_cris_enter, wiz_cris_exit);
|
||||
reg_wizchip_cs_cbfunc(wiz_cs_select, wiz_cs_deselect);
|
||||
reg_wizchip_spi_cbfunc(wiz_spi_read, wiz_spi_write);
|
||||
|
||||
// 2k buffer for each socket
|
||||
uint8_t sn_size[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
|
||||
ctlwizchip(CW_INIT_WIZCHIP, sn_size);
|
||||
|
||||
wiz_NetInfo netinfo = {
|
||||
.dhcp = NETINFO_DHCP,
|
||||
};
|
||||
network_module_create_random_mac_address(netinfo.mac);
|
||||
ctlnetwork(CN_SET_NETINFO, (void *)&netinfo);
|
||||
|
||||
// seems we need a small delay after init
|
||||
mp_hal_delay_ms(250);
|
||||
|
||||
// register with network module
|
||||
network_module_register_nic(&wiznet5k_obj);
|
||||
|
||||
// return wiznet5k object
|
||||
return &wiznet5k_obj;
|
||||
}
|
||||
|
||||
#endif // MICROPY_PY_WIZNET5K
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H
|
||||
#define MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H
|
||||
|
||||
#include "ethernet/wizchip_conf.h"
|
||||
#include "ethernet/socket.h"
|
||||
#include "internet/dns/dns.h"
|
||||
#include "internet/dhcp/dhcp.h"
|
||||
|
||||
typedef struct _wiznet5k_obj_t {
|
||||
mp_obj_base_t base;
|
||||
mp_uint_t cris_state;
|
||||
busio_spi_obj_t *spi;
|
||||
digitalio_digitalinout_obj_t cs;
|
||||
digitalio_digitalinout_obj_t rst;
|
||||
uint8_t socket_used;
|
||||
int8_t dhcp_socket; // -1 for DHCP not in use
|
||||
} wiznet5k_obj_t;
|
||||
|
||||
int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *out_ip);
|
||||
int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno);
|
||||
void wiznet5k_socket_close(mod_network_socket_obj_t *socket);
|
||||
int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno);
|
||||
int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno);
|
||||
int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno);
|
||||
int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno);
|
||||
mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno);
|
||||
mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno);
|
||||
mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno);
|
||||
mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno);
|
||||
int wiznet5k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno);
|
||||
int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno);
|
||||
int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno);
|
||||
void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket);
|
||||
void wiznet5k_socket_deinit(mod_network_socket_obj_t *socket);
|
||||
mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in);
|
||||
mp_obj_t wiznet5k_create(busio_spi_obj_t *spi_in, const mcu_pin_obj_t *cs_in, const mcu_pin_obj_t *rst_in);
|
||||
|
||||
int wiznet5k_start_dhcp(void);
|
||||
int wiznet5k_stop_dhcp(void);
|
||||
bool wiznet5k_check_dhcp(void);
|
||||
|
||||
extern const mod_network_nic_type_t mod_network_nic_type_wiznet5k;
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_MODULE_WIZNET_WIZNET5K_H
|
|
@ -52,10 +52,6 @@
|
|||
#include "shared-module/keypad/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_NETWORK
|
||||
#include "shared-module/network/__init__.h"
|
||||
#endif
|
||||
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
#if CIRCUITPY_WATCHDOG
|
||||
|
@ -80,9 +76,6 @@ void supervisor_background_tasks(void *unused) {
|
|||
displayio_background();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_NETWORK
|
||||
network_module_background();
|
||||
#endif
|
||||
filesystem_background();
|
||||
|
||||
port_background_task();
|
||||
|
|
Loading…
Reference in New Issue