Skip to content

Accept method #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions adafruit_wiznet5k/adafruit_wiznet5k.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# SPDX-FileCopyrightText: 2018 Paul Stoffregen
# SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries
# SPDX-FileCopyrightText: 2021 Patrick Van Oosterwijck
# SPDX-FileCopyrightText: 2021 Adam Cummick
#
# SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -328,10 +329,13 @@ def link_status(self):
return data[0] & 0x01
return 0

@property
def remote_port(self):
def remote_port(self, socket_num):
"""Returns the port of the host who sent the current incoming packet."""
return self.remote_port
if socket_num >= self.max_sockets:
return self._pbuff
for octet in range(0, 2):
self._pbuff[octet] = self._read_socket(socket_num, REG_SNDPORT + octet)[0]
return int((self._pbuff[0] << 8) | self._pbuff[0])

@property
def ifconfig(self):
Expand Down Expand Up @@ -598,6 +602,22 @@ def socket_listen(self, socket_num, port):
if status[0] == SNSR_SOCK_CLOSED:
raise RuntimeError("Listening socket closed.")

def socket_accept(self, socket_num):
"""Gets the dest IP and port from an incoming connection.
Returns the next socket number so listening can continue
:parm int socket_num: socket number
"""
dest_ip = self.remote_ip(socket_num)
dest_port = self.remote_port(socket_num)
next_socknum = self.get_socket()
if self._debug:
print(
"* Dest is ({}, {}), Next listen socknum is #{}".format(
dest_ip, dest_port, next_socknum
)
)
return next_socknum, (dest_ip, dest_port)

def socket_open(self, socket_num, conn_mode=SNMR_TCP):
"""Opens a TCP or UDP socket. By default, we use
'conn_mode'=SNMR_TCP but we may also use SNMR_UDP.
Expand Down
63 changes: 59 additions & 4 deletions adafruit_wiznet5k/adafruit_wiznet5k_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

A socket compatible interface with the Wiznet5k module.

* Author(s): ladyada, Brent Rubell, Patrick Van Oosterwijck
* Author(s): ladyada, Brent Rubell, Patrick Van Oosterwijck, Adam Cummick

"""
import gc
Expand Down Expand Up @@ -108,11 +108,31 @@ def __init__(
if self._socknum == SOCKET_INVALID:
raise RuntimeError("Failed to allocate socket.")

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self.disconnect()
stamp = time.monotonic()
while self.status == adafruit_wiznet5k.SNSR_SOCK_FIN_WAIT:
if time.monotonic() - stamp > 1000:
raise RuntimeError("Failed to disconnect socket")
self.close()
stamp = time.monotonic()
while self.status != adafruit_wiznet5k.SNSR_SOCK_CLOSED:
if time.monotonic() - stamp > 1000:
raise RuntimeError("Failed to close socket")

@property
def socknum(self):
"""Returns the socket object's socket number."""
return self._socknum

@property
def status(self):
"""Returns the status of the socket"""
return _the_interface.socket_status(self.socknum)[0]

@property
def connected(self):
"""Returns whether or not we are connected to the socket."""
Expand Down Expand Up @@ -147,10 +167,16 @@ def inet_aton(self, ip_string):
return self._buffer

def bind(self, address):
"""Bind the socket to the listen port, we ignore the host.
:param tuple address: local socket as a (host, port) tuple, host is ignored.
"""Bind the socket to the listen port, if host is specified the interface
will be reconfigured to that IP.
:param tuple address: local socket as a (host, port) tuple.
"""
_, self._listen_port = address
if address[0] is not None:
ip_address = _the_interface.unpretty_ip(address[0])
current_ip, subnet_mask, gw_addr, dns = _the_interface.ifconfig
if ip_address != current_ip:
_the_interface.ifconfig = (ip_address, subnet_mask, gw_addr, dns)
self._listen_port = address[1]

def listen(self, backlog=None):
"""Listen on the port specified by bind.
Expand All @@ -160,6 +186,35 @@ def listen(self, backlog=None):
_the_interface.socket_listen(self.socknum, self._listen_port)
self._buffer = b""

def accept(self):
"""Accept a connection. The socket must be bound to an address and listening for
connections. The return value is a pair (conn, address) where conn is a new
socket object usable to send and receive data on the connection, and address is
the address bound to the socket on the other end of the connection.
"""
stamp = time.monotonic()
while self.status not in (
adafruit_wiznet5k.SNSR_SOCK_SYNRECV,
adafruit_wiznet5k.SNSR_SOCK_ESTABLISHED,
):
if self._timeout > 0 and time.monotonic() - stamp > self._timeout:
return None
if self.status == adafruit_wiznet5k.SNSR_SOCK_CLOSED:
self.close()
self.listen()

new_listen_socknum, addr = _the_interface.socket_accept(self.socknum)
current_socknum = self.socknum
# Create a new socket object and swap socket nums so we can continue listening
client_sock = socket()
client_sock._socknum = current_socknum # pylint: disable=protected-access
self._socknum = new_listen_socknum # pylint: disable=protected-access
self.bind((None, self._listen_port))
self.listen()
while self.status != adafruit_wiznet5k.SNSR_SOCK_LISTEN:
raise RuntimeError("Failed to open new listening socket")
return client_sock, addr

def connect(self, address, conntype=None):
"""Connect to a remote socket at address. (The format of address depends
on the address family — see above.)
Expand Down
36 changes: 36 additions & 0 deletions examples/wiznet5k_simpleserver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-FileCopyrightText: 2021 Adam Cummick
#
# SPDX-License-Identifier: MIT

import board
import busio
import digitalio
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket

print("Wiznet5k SimpleServer Test")

# For Adafruit Ethernet FeatherWing
cs = digitalio.DigitalInOut(board.D10)
# For Particle Ethernet FeatherWing
# cs = digitalio.DigitalInOut(board.D5)
spi_bus = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)

# Initialize ethernet interface
eth = WIZNET5K(spi_bus, cs, is_dhcp=False)

# Initialize a socket for our server
socket.set_interface(eth)
server = socket.socket() # Allocate socket for the server
server_ip = "192.168.10.1" # IP address of server
server_port = 50007 # Port to listen on
server.bind((server_ip, server_port)) # Bind to IP and Port
server.listen() # Begin listening for incoming clients

while True:
conn, addr = server.accept() # Wait for a connection from a client.
with conn:
data = conn.recv()
print(data)
conn.send(data) # Echo message back to client