extern "C" { #include "user_interface.h" #include "circ_buffer.h" } #include <ESP8266WiFi.h> #include <algorithm> char ssid[] = "uCart_AP"; // Network name of hosted network char pass[] = "password"; IPAddress client_ip; unsigned int tcp_port = 8080; // Server object for listening for requests WiFiServer server(tcp_port); // Reusable client object to communicate with the connected client WiFiClient client; // Maximum number of bytes to read at a time const int BUF_SIZE = 1024; byte tcp_in_buffer[BUF_SIZE]; byte serial_in_buf[BUF_SIZE]; const int SEND_BUF_SIZE = 1024; void setup() { // Set baud rate for UART Serial.begin(921600); Serial.setTimeout(2000); WiFiEventHandler client_disconnected_handler = WiFi.onSoftAPModeStationDisconnected( [](const WiFiEventSoftAPModeStationDisconnected& event) { //Serial.println("disconnected"); }); // Configure chip to be access point WiFi.mode(WIFI_AP); // Wait for Access point to be created while (!WiFi.softAP(ssid)) { delay(500); // Wait half a second before re-trying } waitForStation(); // Begin TCP on a particular port server.begin(); //server.setNoDelay(true); } void waitForStation() { // Wait for a client to connect struct station_info* connected_stns = NULL; while (connected_stns = wifi_softap_get_station_info(), !connected_stns) { delay(500); } client_ip = IPAddress(IP2STR(&connected_stns->ip)); wifi_softap_free_station_info(); } void loop() { // Assume only one client will connect at a time. If a new request has arrived, // that means the old client has expired, and the new one should be used WiFiClient new_client = server.available(); if (new_client) { // Read and forward any unread data tcpToSerial(); // Close existing client client.stop(); // Make new client the active one client = new_client; // Disable Nagle algorithm to decrease latency //client.setNoDelay(true); } if (client.connected() && client.available()) { // Send any unsent data //sendTCPBacklog(); tcpToSerial(); } // Try reading Serial data int to_read = std::min(Serial.available(), BUF_SIZE); if (to_read) { Serial.readBytes(serial_in_buf, to_read); sendTCP(serial_in_buf, to_read); to_read = std::min(Serial.available(), BUF_SIZE); } } void tcpToSerial() { if (client.available()) { // Don't read more than Serial can write at once, to prevent blocking size_t n_to_read = std::min(std::min(client.available(), BUF_SIZE), Serial.availableForWrite()); if (n_to_read) { client.read(tcp_in_buffer, n_to_read); } sendSerial(tcp_in_buffer, n_to_read); } } void sendTCP(byte data[], size_t n_bytes) { size_t to_write = n_bytes; while (client.connected() && to_write) { //sendTCPBacklog(); size_t written = client.write((const uint8_t*) data, to_write); to_write = to_write - written; if (written != n_bytes) { size_t remaining = n_bytes = written; //putChunk({remaining, data + written}); } } //else { //putChunk({n_bytes, data}); //} } void sendTCPBacklog() { struct data_chunk needs_sent = getChunk(); if (needs_sent.length) { size_t written = client.write((const uint8_t*) needs_sent.data, needs_sent.length); markConsumed(written); } } //void sendUDP(byte data[], int n_bytes) { // udp.beginPacket(address, localPort); // udp.write(data, n_bytes); // udp.endPacket(); //} void sendSerial(byte data[], int n_bytes) { int to_write = n_bytes; while (to_write) { int written = Serial.write(data, to_write); to_write -= written; } }