pimoroni-pico
pimoroni-pico copied to clipboard
Experimental: PINT module bindings.
P.I.N.T
Python Implementation of Network Transports.
The goal of this module/project/drive is to create a standard network driver which binds against a Python class in order to do the heavy lifting.
Why?
MicroPython is moving toward write-everything-in-Python. Following with network drivers allows us to experiment and prototype faster, makes networking less of a black box to end users, and lets folks - in theory - do custom network drivers for fun and profit, without having to delve into the sticky particulars of building modules and binding drivers.
It's my sincere hope that MicroPython will incorporate something like this in future, rendering PINT obsolete. But for now- a POC is a good start!
Quickstart for the reference implementation:
import network
import socket
class PINT_Socket:
"""An arbitrary structure for storing data about your sockets.
Does not have to be a class, you could just return an int with the
socket ID of your target device.
"""
def __init__(self):
pass
class PINT_NIC:
"""The actual NIC implementation.
Most of the heavy lifting is sockets based, you might want to implement
the socket_ methods on your socket class and simply delegate to them.
"""
def __init__(self) -> None:
pass
def __del__(self) -> None:
pass
def gethostbyname(self, name: str) -> tuple[int, int, int, int]:
return (127, 0, 0, 1)
def socket_socket(self) -> PINT_Socket:
return PINT_Socket()
def socket_close(self, socket: PINT_Socket) -> None:
pass
def socket_bind(self, socket: PINT_Socket, ip: tuple[int, int, int, int], port: int) -> bool:
return True
def socket_listen(self, socket: PINT_Socket, backlog: int) -> bool:
return True
def socket_accept(self, socket: PINT_Socket, socket2: PINT_Socket, ip: tuple[int, int, int, int], port: int) -> bool:
return True
def socket_connect(self, socket: PINT_Socket, ip: tuple[int, int, int, int], port) -> bool:
return True
def socket_send(self, socket: PINT_Socket, buf: bytearray) -> int:
return 0
def socket_recv(self, socket: PINT_Socket, buf: bytearray) -> int:
"""Buf is provided as a mutable bytearray, you must write into it."""
return 0
def socket_sendto(self, socket: PINT_Socket, buf: bytearray, ip, port) -> int:
return 0
def socket_recvfrom(self, socket: PINT_Socket, buf: bytearray, ip, port) -> int:
"""Buf is provided as a mutable bytearray, you must write into it."""
return 0
def socket_setsockopt(self, socket: PINT_Socket, level: int, opt: int, val: bytearray) -> bool:
return True
def socket_settimeout(self, socket: PINT_Socket, timeout_ms: int) -> bool:
return True
def socket_ioctl(self, socket: PINT_Socket, request: int, arg: int) -> bool:
return True
# Instance of our Python network driver
impl = PINT_NIC()
# Init PINT with our implementation
net = network.PINT(impl)
# Try some stuff
print(socket.getaddrinfo("google.com", 80)[0][-1])
test = socket.socket()
test.connect(("127.0.0.1", 80)) # this is where socket_socket is actually called
sent = test.write(b"Hello World")
result = test.read(10)
print(result)
TODO: Update the implementation stub above with my many, many findings from putting PINT to the test.