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 3 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
61 changes: 57 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,30 @@ 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()
while self.status == adafruit_wiznet5k.SNSR_SOCK_FIN_WAIT:
pass
self.close()

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

@socknum.setter
def socknum(self, socknum):
"""Sets the socket object's socket number."""
self._socknum = 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 +166,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 +185,34 @@ def listen(self, backlog=None):
_the_interface.socket_listen(self.socknum, self._listen_port)
self._buffer = b""

def accept(self):
"""Mimic python socket accept for compatibility. The socket where the
connection originated is returned while a new socket is allocated and begins
listening.
"""
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
self.socknum = new_listen_socknum
self.bind((None, self._listen_port))
self.listen()
while self.status != adafruit_wiznet5k.SNSR_SOCK_LISTEN:
print("Waiting for socket to listen")
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