Skip to content

Commit 8f5da83

Browse files
committed
2 parents 06bd5c3 + 9114206 commit 8f5da83

File tree

2 files changed

+100
-56
lines changed

2 files changed

+100
-56
lines changed

libraries/MySensors/examples/Esp8266Gateway/Esp8266Gateway.ino

Lines changed: 93 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -123,24 +123,34 @@ MySensor gw(transport, hw
123123
);
124124

125125

126-
#define IP_PORT 5003 // The port you want to open
126+
#define IP_PORT 5003 // The port you want to open
127+
#define MAX_SRV_CLIENTS 5 // how many clients should be able to telnet to this ESP8266
127128

128129
// a R/W server on the port
129-
WiFiServer server(IP_PORT);
130-
// handle to open connection
131-
WiFiClient client;
132-
133-
char inputString[MAX_RECEIVE_LENGTH] = ""; // A string to hold incoming commands from serial/ethernet interface
134-
int inputPos = 0;
135-
bool sentReady = false;
136-
137-
void output(const char *fmt, ... ) {
138-
va_list args;
139-
va_start (args, fmt );
140-
vsnprintf_P(serialBuffer, MAX_SEND_LENGTH, fmt, args);
141-
va_end (args);
142-
Serial.print(serialBuffer);
143-
server.write(serialBuffer);
130+
static WiFiServer server(IP_PORT);
131+
static WiFiClient clients[MAX_SRV_CLIENTS];
132+
static bool clientsConnected[MAX_SRV_CLIENTS];
133+
static inputBuffer inputString[MAX_SRV_CLIENTS];
134+
135+
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
136+
137+
138+
void output(const char *fmt, ... )
139+
{
140+
char serialBuffer[MAX_SEND_LENGTH];
141+
va_list args;
142+
va_start (args, fmt );
143+
vsnprintf_P(serialBuffer, MAX_SEND_LENGTH, fmt, args);
144+
va_end (args);
145+
Serial.print(serialBuffer);
146+
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++)
147+
{
148+
if (clients[i] && clients[i].connected())
149+
{
150+
// Serial.print("Client "); Serial.print(i); Serial.println(" write");
151+
clients[i].write((uint8_t*)serialBuffer, strlen(serialBuffer));
152+
}
153+
}
144154
}
145155

146156
void setup()
@@ -153,7 +163,8 @@ void setup()
153163
Serial.print("Connecting to "); Serial.println(ssid);
154164

155165
(void)WiFi.begin(ssid, pass);
156-
while (WiFi.status() != WL_CONNECTED) {
166+
while (WiFi.status() != WL_CONNECTED)
167+
{
157168
delay(500);
158169
Serial.print(".");
159170
}
@@ -168,6 +179,7 @@ void setup()
168179

169180
// start listening for clients
170181
server.begin();
182+
server.setNoDelay(true);
171183
}
172184

173185

@@ -176,47 +188,74 @@ void loop() {
176188

177189
checkButtonTriggeredInclusion();
178190
checkInclusionFinished();
179-
180-
//check if there are any new clients
181-
if (server.hasClient())
191+
192+
// Go over list of clients and stop any that are no longer connected.
193+
// If the server has a new client connection it will be assigned to a free slot.
194+
bool allSlotsOccupied = true;
195+
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++)
182196
{
183-
if (client)
197+
if (!clients[i].connected())
184198
{
185-
client.stop();
199+
if (clientsConnected[i])
200+
{
201+
Serial.print("Client "); Serial.print(i); Serial.println(" disconnected");
202+
clients[i].stop();
203+
}
204+
//check if there are any new clients
205+
if (server.hasClient())
206+
{
207+
clients[i] = server.available();
208+
inputString[i].idx = 0;
209+
Serial.print("Client "); Serial.print(i); Serial.println(" connected");
210+
output(PSTR("0;0;%d;0;%d;Gateway startup complete.\n"), C_INTERNAL, I_GATEWAY_READY);
211+
}
186212
}
187-
client = server.available();
188-
output(PSTR("0;0;%d;0;%d;Gateway startup complete.\n"), C_INTERNAL, I_GATEWAY_READY);
189-
}
190-
191-
if (client) {
192-
if (!client.connected()) {
193-
client.stop();
194-
} else if (client.available()) {
195-
// read the bytes incoming from the client
196-
char inChar = client.read();
197-
if (inputPos<MAX_RECEIVE_LENGTH-1) {
198-
// if newline then command is complete
199-
if (inChar == '\n') {
200-
Serial.println("Finished");
201-
// a command was issued by the client
202-
// we will now try to send it to the actuator
203-
inputString[inputPos] = 0;
204-
205-
// echo the string to the serial port
206-
Serial.print(inputString);
207-
208-
parseAndSend(gw, inputString);
209-
210-
// clear the string:
211-
inputPos = 0;
212-
} else {
213-
// add it to the inputString:
214-
inputString[inputPos] = inChar;
215-
inputPos++;
216-
}
213+
bool connected = clients[i].connected();
214+
clientsConnected[i] = connected;
215+
allSlotsOccupied &= connected;
216+
}
217+
if (allSlotsOccupied && server.hasClient())
218+
{
219+
//no free/disconnected spot so reject
220+
Serial.println("No free slot available");
221+
WiFiClient c = server.available();
222+
c.stop();
223+
}
224+
225+
// Loop over clients connect and read available data
226+
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++)
227+
{
228+
while(clients[i].connected() && clients[i].available())
229+
{
230+
char inChar = clients[i].read();
231+
if ( inputString[i].idx < MAX_RECEIVE_LENGTH - 1 )
232+
{
233+
// if newline then command is complete
234+
if (inChar == '\n')
235+
{
236+
// a command was issued by the client
237+
// we will now try to send it to the actuator
238+
inputString[i].string[inputString[i].idx] = 0;
239+
240+
// echo the string to the serial port
241+
Serial.print("Client "); Serial.print(i); Serial.print(": "); Serial.println(inputString[i].string);
242+
243+
parseAndSend(gw, inputString[i].string);
244+
245+
// clear the string:
246+
inputString[i].idx = 0;
247+
// Finished with this client's message. Next loop() we'll see if there's more to read.
248+
break;
249+
} else {
250+
// add it to the inputString:
251+
inputString[i].string[inputString[i].idx++] = inChar;
252+
}
217253
} else {
218-
// Incoming message too long. Throw away
219-
inputPos = 0;
254+
// Incoming message too long. Throw away
255+
Serial.print("Client "); Serial.print(i); Serial.println(": Message too long");
256+
inputString[i].idx = 0;
257+
// Finished with this client's message. Next loop() we'll see if there's more to read.
258+
break;
220259
}
221260
}
222261
}

libraries/MySensors/examples/Esp8266Gateway/GatewayUtil.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,19 @@
33

44
#ifdef ARDUINO
55

6-
76
static uint8_t inclusionTime = 1; // Number of minutes inclusion mode is enabled
87
static uint8_t pinInclusion = 3; // Input pin that should trigger inclusion mode
98

109
#define MAX_RECEIVE_LENGTH 100 // Max buffersize needed for messages coming from controller
1110
#define MAX_SEND_LENGTH 120 // Max buffersize needed for messages destined for controller
1211

12+
13+
typedef struct
14+
{
15+
char string[MAX_RECEIVE_LENGTH];
16+
uint8_t idx;
17+
} inputBuffer;
18+
1319
static volatile boolean buttonTriggeredInclusion;
1420
static boolean inclusionMode; // Keeps track on inclusion mode
1521
bool inclusionButtonSupported = false;
@@ -20,7 +26,6 @@ MyParserSerial parser;
2026
void setInclusionMode(boolean newMode);
2127

2228
char convBuf[MAX_PAYLOAD*2+1];
23-
char serialBuffer[MAX_SEND_LENGTH]; // Buffer for building string when sending data to vera
2429
unsigned long inclusionStartTime;
2530

2631

0 commit comments

Comments
 (0)