Hi,
I've been trying to work out this issue, but my research is coming up fairly blank (that is to say, I'm not able to understand any of the potential answers I find enough to know if they are, indeed, answers)...
I am trying to communicate from a PC, to a remote ESP8266 (packaged in a wemos d1 mini).
I've butchered the ESP8266 Telnet to Serial example to add the key element of parsing the TCP data. This all works as expected. I do however, want to make the communication more 'secure' in the sense that I only actually want to allow a specific client IP to be able to trigger the ESP8266's actions.
I want to limit it to a single IP (or for testing a couple based on an array of IPs).
For the life of me however, I can't seem to find any documentation that allows you to obtain the remote client's IP. Unless I fundamentally misunderstand IP protocols, this information (ie. the IP address, and even the MAC address for that matter) needs to be known by the server (how can it ACK if it doesn't know what IP to ACK in the first place?).
I know of the UDP remote IP function (WiFiUDPRemoteIP) but I don't want to use UDP, I would like the client to know that server has received the data, and that its been actioned. I might end up having to use UDP in a bi-directional way (receive packet, find remote IP, send acknowledgement UDP back to aforementioned remote IP) but that's just a 'TCP like' implementation....
I feel like I'm missing something obvious.... Or I do fundamentally misunderstand TCP / UDP (which isn't outside the realms of possibility).
Here's the Code (not that its much different at this stage than the example):
/*
WiFiTelnetToSerial - Example Transparent UART to Telnet Server for esp8266
*/
#include <ESP8266WiFi.h>
//how many clients should be able to telnet to this ESP8266
#define MAX_SRV_CLIENTS 1
const char* ssid = "***************";
const char* password = "******************";
const IPAddress ip(/*IP OF ESP8266*/);
const IPAddress gateway(/*GATEWAY OF ESP8266*/);
const IPAddress subnet(/*SUBNET MASK OF ESP8266*/);
WiFiServer server(23);
WiFiClient serverClients[MAX_SRV_CLIENTS];
void setup() {
pinMode(16, OUTPUT);
digitalWrite(16, LOW);
Serial.begin(115200);
WiFi.begin(ssid, password);
WiFi.config(ip, gateway, subnet);
Serial.print("\nConnecting to "); Serial.println(ssid);
uint8_t i = 0;
while (WiFi.status() != WL_CONNECTED && i++ < 20) {
delay(500);
Serial.print(".");
}
if (i == 21) {
Serial.print("Could not connect to"); Serial.println(ssid);
while (1) {
delay(500);
}
}
//start UART and the server
Serial.begin(115200);
server.begin();
server.setNoDelay(true);
Serial.print("\nReady! Use 'telnet ");
Serial.print(WiFi.localIP());
Serial.println(" 23' to connect");
}
void loop() {
char c;
String data;
uint8_t i;
//check if there are any new clients
if (server.hasClient()) {
for (i = 0; i < MAX_SRV_CLIENTS; i++) {
//find free/disconnected spot
if (!serverClients[i] || !serverClients[i].connected()) {
if (serverClients[i]) {
serverClients[i].stop();
}
serverClients[i] = server.available();
Serial.print("New client: "); Serial.print(i); Serial.print("\n");
break;
}
}
//no free/disconnected spot so reject
if (i == MAX_SRV_CLIENTS) {
WiFiClient serverClient = server.available();
serverClient.stop();
Serial.println("Connection rejected \n");
}
}
//check clients for data
for (i = 0; i < MAX_SRV_CLIENTS; i++) {
if (serverClients[i] && serverClients[i].connected()) {
if (serverClients[i].available()) {
//get data from the telnet client and push it to the UART
while (serverClients[i].available()) {
c = serverClients[i].read();
data += c;
}
Serial.print(data);Serial.print("\n");
if (data == "ON"){
//do something interesting....
Serial.print("ON RECEIVED\n");
digitalWrite(16, HIGH);
delay(1000);
digitalWrite(16, LOW);
} else {
//don't do anything interesting....
Serial.print("UNKOWN COMMAND RECEIVED\n");
}
}
}
}
}
Anyone's help and support would be hugely, hugely appreciated!
Thanks,
Owen.