Remove OSError(0) and old network modules

The newer modules are `socketpool` and `ssl`.

Fixes #3924, related to #2021, closes #1880, closes #2273, closes #2274
This commit is contained in:
Scott Shawcroft 2021-07-21 17:33:40 -07:00
parent 10645bf538
commit f84cb94819
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
30 changed files with 8 additions and 1858 deletions

View File

@ -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/

View File

@ -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
View File

@ -94,10 +94,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
@ -168,17 +164,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);

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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);
}

View File

@ -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) {

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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 \
@ -986,15 +966,11 @@ struct _supervisor_allocation_node;
BOARD_UART_ROOT_POINTER \
FLASH_ROOT_POINTERS \
MEMORYMONITOR_ROOT_POINTERS \
NETWORK_ROOT_POINTERS \
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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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,
};

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL));

View File

@ -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;
}

View File

@ -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);

View File

@ -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,
};

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();