Skip to content
Snippets Groups Projects
Commit bc365c4a authored by David Wehr's avatar David Wehr
Browse files

Added ESP8266 WiFi bridge code

parent e06d32b5
No related branches found
No related tags found
No related merge requests found
//
// Created by dawehr on 10/24/2016.
//
#include "circ_buffer.h"
#define circ_buf_min(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; })
unsigned char buffer[CIRC_BUFFER_SIZE];
size_t buf_start = 0;
size_t buf_end = 0;
size_t size = 0;
struct data_chunk getChunk() {
size_t chunk_end = buf_end;
if (buf_end < buf_start) {
chunk_end = CIRC_BUFFER_SIZE;
}
size_t ret_size = chunk_end - buf_start;
struct data_chunk c = {
ret_size,
&buffer[buf_start]
};
return c;
}
void markConsumed( size_t n_consumed) {
size_t chunk_end = buf_start + n_consumed;
buf_start = chunk_end;
size -= n_consumed;
if (buf_start == CIRC_BUFFER_SIZE) {
buf_start = 0;
}
}
size_t putChunk(struct data_chunk c) {
// The amount that will be placed into the buffer
size_t will_place = circ_buf_min(CIRC_BUFFER_SIZE - size, c.length);
// Actual amount placed so far
size_t placed = 0;
while (placed < will_place) {
// Available room without wrapping
size_t to_copy;
if (buf_end >= buf_start) {
// If buffer is not wrapped, we can copy until the end of the buffer
to_copy = circ_buf_min(will_place, CIRC_BUFFER_SIZE - buf_end);
} else {
// Otherwise, remaining space in buffer is contiguous
to_copy = will_place - placed;
}
memcpy(buffer + buf_end, c.data + placed, to_copy);
// Update buffer endpoint
buf_end += to_copy;
if (buf_end > CIRC_BUFFER_SIZE) {
printf("Error: buf_end: %d\n", buf_end);
}
// If we copied to the end
if (buf_end == CIRC_BUFFER_SIZE) {
buf_end = 0;
}
placed += to_copy;
}
size += placed;
return placed;
}
size_t get_buffer_size() {
return size;
}
//
// Created by dawehr on 10/24/2016.
//
#ifndef CIRC_BUFFER_H
#define CIRC_BUFFER_H
#define CIRC_BUFFER_SIZE 1024
#include <unistd.h>
#include <stdio.h>
#include <string.h>
struct data_chunk {
size_t length;
unsigned char* data;
};
/*
* Returns the largest contiguous chunk from the buffer
* Does not move the buffer forward. You must call markConsumed to
* mark the area as free.
*/
struct data_chunk getChunk();
/*
* Marks the n_consumed bytes as used, and that
* area of the buffer can be used for new data now
*/
void markConsumed(size_t n_consumed);
/*
* Places data into the circular buffer. Returns the number of bytes stored.
* Will store the entire chunk, unless there is not enough remaining size in the buffer
*/
size_t putChunk(struct data_chunk);
/*
* Returns the remaining size in the buffer
*/
size_t get_buffer_size();
#endif //CIRC_BUFFER_H
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(115200);
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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment