def __init__(self, port=80, debug=False, application=None): self.application = application self.port = port self._server_sock = socket.socket(socknum=NO_SOCK_AVAIL) self._client_sock = socket.socket(socknum=NO_SOCK_AVAIL) self._debug = debug self._response_status = None self._response_headers = []
def client_available(self): """ returns a client socket connection if available. Otherwise, returns None :return: the client :rtype: Socket """ sock = None if self._server_sock.socknum != NO_SOCK_AVAIL: if self._client_sock.socknum != NO_SOCK_AVAIL: # check previous received client socket if self._debug > 2: print("checking if last client sock still valid") if self._client_sock.connected( ) and self._client_sock.available(): sock = self._client_sock if not sock: # check for new client sock if self._debug > 2: print("checking for new client sock") client_sock_num = _the_interface.socket_available( self._server_sock.socknum) sock = socket.socket(socknum=client_sock_num) else: print("Server has not been started, cannot check for clients!") if sock and sock.socknum != NO_SOCK_AVAIL: if self._debug > 2: print("client sock num is: ", sock.socknum) self._client_sock = sock return self._client_sock return None
def reconnect_socket(self): self.message_count = 0 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) try: self.sock.connect((self.host, self.port), esp.TCP_MODE) except RuntimeError as ex: print("[SocketManager reconnect] err", ex, "sleep and retry") time.sleep(1) self.reconnect_socket()
def sendMessage(self, recipient, subject, message): self.connectToWifi() try: s = socket.socket() s.connect(ADDR) s.send( bytes('%s\r\n%s\r\n%s\r\n' % (recipient, subject, message), 'utf8')) s.close() except RuntimeError as e: print("Could not send", recipient, subject, message, e)
def start(self): """ starts the server and begins listening for incoming connections. Call update_poll in the main loop for the application callable to be invoked on receiving an incoming request. """ self._server_sock = socket.socket() _the_interface.start_server(self.port, self._server_sock.socknum) if self._debug: ip = _the_interface.pretty_ip(_the_interface.ip_address) print("Server available at {0}:{1}".format(ip, self.port)) print("Sever status: ", _the_interface.get_server_state(self._server_sock.socknum))
def receiveMessage(self): self.connectToWifi() try: s = socket.socket() s.connect(ADDR) available = s.available() data = s.recv(available) s.close() self.time = time.monotonic() return data except RuntimeError as e: print(e) self.time = time.monotonic() return None
def connect(self, clean_session=True): if not self.sock: self.sock = socket.socket() addr = socket.getaddrinfo(self.server, self.port)[0][-1] self.sock.settimeout(10) self.sock.connect(addr, conntype=TCP_MODE) if self.ssl: import ussl self.sock = ussl.wrap_socket(self.sock, **self.ssl_params) premsg = bytearray(b"\x10\0\0") msg = bytearray(b"\x04MQTT\x04\x02\0\0") sz = 10 + 2 + len(self.client_id) msg[6] = clean_session << 1 if self.user is not None: sz += 2 + len(self.user) + 2 + len(self.pswd) msg[6] |= 0xC0 if self.keepalive: assert self.keepalive < 65536 msg[7] |= self.keepalive >> 8 msg[8] |= self.keepalive & 0x00FF if self.lw_topic: sz += 2 + len(self.lw_topic) + 2 + len(self.lw_msg) msg[6] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3 msg[6] |= self.lw_retain << 5 i = 1 while sz > 0x7f: premsg[i] = (sz & 0x7f) | 0x80 sz >>= 7 i += 1 premsg[i] = sz self.sock.write(premsg) #self.sock.write(i + 2) self.sock.write(msg) #print(hex(len(msg)), hexlify(msg, ":")) self._send_str(self.client_id) if self.lw_topic: self._send_str(self.lw_topic) self._send_str(self.lw_msg) if self.user is not None: self._send_str(self.user) self._send_str(self.pswd) resp = self.sock.read(4) assert resp[0] == 0x20 and resp[1] == 0x02 if resp[3] != 0: raise MQTTException(resp[3]) return resp[2] & 1
def check_client(self): """ if a client telnet is connected, check for input. if there is no client, check for new connections """ self.current_state = "No Network" if self.esp_mgr.ap: if self.client_socket: # client exists self.current_state = "Connected" if self.client_socket.connected(): if self.client_socket.available(): data = self.client_socket.recv() if data: self._add_to_buffer(data) else: self._close_client() if time.monotonic() > self.test_connection: data = bytes([0]) self.send_to_client(data) else: self._close_client() else: # check for new client self.current_state = "Listening port 23" # reset termious hack self.termious = None client_sock_num = self.esp_mgr.esp.socket_available(self.server_socket.socknum) if client_sock_num != adafruit_esp32spi_socket.NO_SOCKET_AVAIL: # new connection self.current_state = "Connected" self.test_connection = time.monotonic() + 5 self.client_socket = adafruit_esp32spi_socket.socket(socknum=client_sock_num) self.send_telnet_command([telnet_IAC, telnet_cmd_codes['WONT'], telnet_opt_codes['Echo']]) self.send_telnet_command([telnet_IAC, telnet_cmd_codes['WONT'], telnet_opt_codes['Suppress GA']]) return self.current_state
def request(method, url, data=None, json=None, headers=None, stream=False): """Perform an HTTP request to the given url which we will parse to determine whether to use SSL ('https://') or not. We can also send some provided 'data' or a json dictionary which we will stringify. 'headers' is optional HTTP headers sent along. 'stream' will determine if we buffer everything, or whether to only read only when requested """ global _the_interface # pylint: disable=global-statement, invalid-name if not headers: headers = {} try: proto, dummy, host, path = url.split("/", 3) # replace spaces in path path = path.replace(" ", "%20") except ValueError: proto, dummy, host = url.split("/", 2) path = "" if proto == "http:": port = 80 elif proto == "https:": port = 443 else: raise ValueError("Unsupported protocol: " + proto) if ":" in host: host, port = host.split(":", 1) port = int(port) addr_info = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM)[0] sock = socket.socket(addr_info[0], addr_info[1], addr_info[2]) resp = Response(sock) # our response sock.settimeout(1) # 1 second timeout try: if proto == "https:": conntype = _the_interface.TLS_MODE sock.connect((host, port), conntype) # for SSL we need to know the host name else: conntype = _the_interface.TCP_MODE sock.connect(addr_info[-1], conntype) sock.write(b"%s /%s HTTP/1.0\r\n" % (method, path)) if "Host" not in headers: sock.write(b"Host: %s\r\n" % host) if "User-Agent" not in headers: sock.write(b"User-Agent: Adafruit CircuitPython\r\n") # Iterate over keys to avoid tuple alloc for k in headers: sock.write(k.encode()) sock.write(b": ") sock.write(headers[k].encode()) sock.write(b"\r\n") if json is not None: assert data is None try: import json as json_module except ImportError: import ujson as json_module data = json_module.dumps(json) sock.write(b"Content-Type: application/json\r\n") if data: sock.write(b"Content-Length: %d\r\n" % len(data)) sock.write(b"\r\n") if data: sock.write(bytes(data, 'utf-8')) line = sock.readline() #print(line) line = line.split(None, 2) status = int(line[1]) reason = "" if len(line) > 2: reason = line[2].rstrip() while True: line = sock.readline() if not line or line == b"\r\n": break #print("**line: ", line) header_tuple = line.split(b': ', 1) if len(header_tuple) == 2: # sometimes there aren't two values? title, content = header_tuple if title and content: title = str(title.lower(), 'utf-8') content = str(content, 'utf-8') resp.headers[title] = content if line.startswith(b"Transfer-Encoding:"): if b"chunked" in line: raise ValueError("Unsupported " + line) elif line.startswith(b"Location:") and not 200 <= status <= 299: raise NotImplementedError("Redirects not yet supported") except OSError: sock.close() raise resp.status_code = status resp.reason = reason return resp
print("%s\t\tRSSI: %d" % (str(ap["ssid"], "utf-8"), ap["rssi"])) print() while not esp.is_connected: try: #esp.connect_AP(PJ_AP, PJ_PW) # AP mode esp.connect_AP(WLAN_AP_ID, WLAN_AP_PW) # Client mode except RuntimeError as e: print("Could not connect to AP, retrying: ", e) continue print("Connected to", str(esp.ssid, "utf-8")) #, "\tRSSI:", esp.rssi) print("PyPortal DHCP assignment", esp.pretty_ip(esp.ip_address)) print() time.sleep(1) try: cmd_socket = socket.socket() # or (socket.AF_INET, socket.SOCK_STREAM) except RuntimeError as e: print(e) # "Setup" ------------------------------------------------------------------------------# print("Initializing...") print() # Open a socket to the device open_socket() # See if we need to generate a SHA256 hash #auth_check() # Get the various params #get_status() # Close the socket close_socket()
# PyPortal or similar; edit pins as needed spi = board.SPI() esp32_cs = DigitalInOut(board.ESP_CS) esp32_ready = DigitalInOut(board.ESP_BUSY) esp32_reset = DigitalInOut(board.ESP_RESET) esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) # connect to wifi AP esp.connect(secrets) # test for connectivity to server print("Server ping:", esp.ping(HOST), "ms") # create the socket socket.set_interface(esp) socketaddr = socket.getaddrinfo(HOST, PORT)[0][4] s = socket.socket(type=socket.SOCK_DGRAM) s.settimeout(TIMEOUT) print("Sending") s.connect(socketaddr, conntype=esp.UDP_MODE) packet = bytearray(48) packet[0] = 0b00100011 # Not leap second, NTP version 4, Client mode s.send(packet) print("Receiving") packet = s.recv(48) seconds = struct.unpack_from("!I", packet, offset=len(packet) - 8)[0] print("Time:", time.localtime(seconds - NTP_TO_UNIX_EPOCH))
HOST = "wifitest.adafruit.com" PORT = 80 # PyPortal or similar; edit pins as needed spi = board.SPI() esp32_cs = DigitalInOut(board.ESP_CS) esp32_ready = DigitalInOut(board.ESP_BUSY) esp32_reset = DigitalInOut(board.ESP_RESET) esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) # connect to wifi AP esp.connect(secrets) # test for connectivity to server print("Server ping:", esp.ping(HOST), "ms") # create the socket socket.set_interface(esp) socketaddr = socket.getaddrinfo(HOST, PORT)[0][4] s = socket.socket() s.settimeout(TIMEOUT) print("Connecting") s.connect(socketaddr) print("Sending") s.send(b"GET /testwifi/index.html HTTP/1.0\r\n\r\n") print("Receiving") print(s.recv(1024))
def start_server(self): """ start the telnet server listening on port 23 """ if self.esp_mgr.ap: self.server_socket = adafruit_esp32spi_socket.socket() self.esp_mgr.esp.start_server(23, self.server_socket.socknum)