mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
fix server sockets; use patched lwip
This commit is contained in:
parent
c115a78988
commit
1f562156ca
2
Makefile
2
Makefile
@ -1337,7 +1337,7 @@ ifeq ($(FAMILY),ESP8266)
|
||||
DEFINES += -DUSE_OPTIMIZE_PRINTF
|
||||
DEFINES += -D__ETS__ -DICACHE_FLASH -DXTENSA -DUSE_US_TIMER
|
||||
ESP8266=1
|
||||
LIBS += -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip_536 -lwpa -lmain -lpwm -lcrypto
|
||||
LIBS += -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain -lpwm -lcrypto
|
||||
CFLAGS+= -fno-builtin \
|
||||
-Wno-maybe-uninitialized -Wno-old-style-declaration -Wno-conversion -Wno-unused-variable \
|
||||
-Wno-unused-parameter -Wno-ignored-qualifiers -Wno-discarded-qualifiers -Wno-float-conversion \
|
||||
|
||||
@ -31,7 +31,7 @@ typedef long long int64_t;
|
||||
#include "esp8266_board_utils.h"
|
||||
#include "pktbuf.h"
|
||||
|
||||
#define espconn_abort espconn_disconnect
|
||||
//#define espconn_abort espconn_disconnect
|
||||
|
||||
// Set NET_DBG to 0 to disable debug printf's, to 1 for important printf's
|
||||
#define NET_DBG 1
|
||||
@ -417,12 +417,14 @@ static void releaseEspconn(
|
||||
struct socketData *pSocketData
|
||||
) {
|
||||
if (pSocketData->pEspconn == NULL) return;
|
||||
if (pSocketData->creationType == SOCKET_CREATED_INBOUND) return; // we did not allocate it
|
||||
DBG("%s: freeing espconn %p/%p for socket %d\n", DBG_LIB,
|
||||
pSocketData->pEspconn, pSocketData->pEspconn->proto.tcp, pSocketData->socketId);
|
||||
os_free(pSocketData->pEspconn->proto.tcp);
|
||||
pSocketData->pEspconn->proto.tcp = NULL;
|
||||
os_free(pSocketData->pEspconn);
|
||||
// if the socket is an inbound connection then espconn will free the struct, else we do it now
|
||||
if (pSocketData->creationType != SOCKET_CREATED_INBOUND) {
|
||||
DBG("%s: freeing espconn %p/%p for socket %d\n", DBG_LIB,
|
||||
pSocketData->pEspconn, pSocketData->pEspconn->proto.tcp, pSocketData->socketId);
|
||||
os_free(pSocketData->pEspconn->proto.tcp);
|
||||
pSocketData->pEspconn->proto.tcp = NULL;
|
||||
os_free(pSocketData->pEspconn);
|
||||
}
|
||||
pSocketData->pEspconn = NULL;
|
||||
}
|
||||
|
||||
@ -808,7 +810,7 @@ int net_ESP8266_BOARD_recv(
|
||||
// if we now have exactly one buffer enqueued we need to re-enable the flood
|
||||
if (pSocketData->rxBufQ != NULL && pSocketData->rxBufQ->next == NULL)
|
||||
espconn_recv_unhold(pSocketData->pEspconn);
|
||||
DBG("%s: recv %d on socket %d\n", DBG_LIB, retLen, sckt);
|
||||
DBG("%s: socket %d JS recv %d\n", DBG_LIB, sckt, retLen);
|
||||
return retLen;
|
||||
}
|
||||
|
||||
@ -823,7 +825,7 @@ int net_ESP8266_BOARD_recv(
|
||||
uint16_t newLen = rxBuf->filled - len;
|
||||
os_memmove(rxBuf->data, rxBuf->data + len, newLen);
|
||||
rxBuf->filled = newLen;
|
||||
DBG("%s: recv %d on socket %d\n", DBG_LIB, len, sckt);
|
||||
DBG("%s: socket %d JS recv %d\n", DBG_LIB, sckt, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -892,7 +894,7 @@ int net_ESP8266_BOARD_send(
|
||||
}
|
||||
|
||||
pSocketData->state = SOCKET_STATE_TRANSMITTING;
|
||||
DBG("%s: socket %d sending %d\n", DBG_LIB, sckt, len);
|
||||
DBG("%s: socket %d JS send %d\n", DBG_LIB, sckt, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -1086,6 +1088,8 @@ static int connectSocket(
|
||||
releaseSocket(pSocketData);
|
||||
return rc;
|
||||
}
|
||||
DBG("%s: listening socket %d on port %d\n", DBG_LIB,
|
||||
pSocketData->socketId, pEspconn->proto.tcp->local_port);
|
||||
}
|
||||
|
||||
return newSocket;
|
||||
|
||||
19
libs/network/esp8266/tests/projects/http-test-simple.js
Normal file
19
libs/network/esp8266/tests/projects/http-test-simple.js
Normal file
@ -0,0 +1,19 @@
|
||||
// Espruino esp8266 Socket tester - Copyright 2015 by Thorsten von Eicken
|
||||
// HTTP client test from tests/test_http_*.js
|
||||
|
||||
test_host = "h.voneicken.com";
|
||||
test_port = 4567;
|
||||
|
||||
var result = 0;
|
||||
var http = require("http");
|
||||
|
||||
http.get("http://"+test_host+":"+test_port+"/ping", function(res) {
|
||||
console.log("Got response: " + JSON.stringify(res));
|
||||
res.on('data', function(data) {
|
||||
console.log(">" + data +"<");
|
||||
result = data=="pong\nEND";
|
||||
if (result) console.log("*** TEST SUCCESSFUL");
|
||||
});
|
||||
});//.on('error', function(e) {
|
||||
// console.log("Got error: " + e.message);
|
||||
//});*/
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
// Test error handling
|
||||
|
||||
test_host = "h.voneicken.com"; // <======= confirgure for your local server running the test_http.rb sinatra server
|
||||
test_host = "h.voneicken.com"; // <======= configure for your local server running the test_http.rb sinatra server
|
||||
test_port = 4567;
|
||||
|
||||
var test_ip = 0; // will be resolved
|
||||
|
||||
@ -45,9 +45,12 @@
|
||||
|
||||
// Define the size of buffers/chunks that are transmitted or received
|
||||
#ifdef ESP8266
|
||||
#define CHUNK 536
|
||||
#define CHUNK (536/2)
|
||||
extern int os_printf_plus(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
#define os_printf os_printf_plus
|
||||
#else
|
||||
#define CHUNK 64
|
||||
#define os_printf(X) do { } while(0)
|
||||
#endif
|
||||
|
||||
|
||||
@ -291,12 +294,16 @@ bool socketServerConnectionsIdle(JsNetwork *net) {
|
||||
|
||||
int sckt = (int)jsvGetIntegerAndUnLock(jsvObjectGetChild(connection,HTTP_NAME_SOCKET,0))-1; // so -1 if undefined
|
||||
bool closeConnectionNow = jsvGetBoolAndUnLock(jsvObjectGetChild(connection, HTTP_NAME_CLOSENOW, false));
|
||||
int error = 0;
|
||||
|
||||
if (!closeConnectionNow) {
|
||||
int num = netRecv(net, sckt, buf,sizeof(buf));
|
||||
if (num != 0) os_printf("netRecv on socket %d returned %d\n", sckt, num);
|
||||
if (num<0) {
|
||||
// we probably disconnected so just get rid of this
|
||||
closeConnectionNow = true;
|
||||
os_printf("Error from netRecv: %d\n", num);
|
||||
error = num;
|
||||
} else {
|
||||
// add it to our request string
|
||||
if (num>0) {
|
||||
@ -334,15 +341,23 @@ bool socketServerConnectionsIdle(JsNetwork *net) {
|
||||
JsVar *sendData = jsvObjectGetChild(socket,HTTP_NAME_SEND_DATA,0);
|
||||
if (sendData) {
|
||||
int sent = socketSendData(net, socket, sckt, &sendData);
|
||||
// FIXME? checking for errors is a bit iffy. With the esp8266 network that returns
|
||||
// varied error codes we'd want to skip SOCKET_ERR_CLOSED and let the recv side deal
|
||||
// with normal closing so we don't miss the tail of what's received, but other drivers
|
||||
// return -1 (which is the same value) for all errors. So we rely on the check ~12 lines
|
||||
// down if(num>0)closeConnectionNow=false instead.
|
||||
if (sent < 0) {
|
||||
closeConnectionNow = true;
|
||||
//error = sent;
|
||||
os_printf("Error from netSend: %d\n", sent);
|
||||
error = sent;
|
||||
}
|
||||
jsvObjectSetChild(socket, HTTP_NAME_SEND_DATA, sendData); // socketSendData prob updated sendData
|
||||
}
|
||||
// only close if we want to close, have no data to send, and aren't receiving data
|
||||
if (jsvGetBoolAndUnLock(jsvObjectGetChild(socket,HTTP_NAME_CLOSE,0)) && !sendData && num<=0)
|
||||
closeConnectionNow = true;
|
||||
else if (num > 0)
|
||||
closeConnectionNow = false; // guarantee that anything received is processed
|
||||
jsvUnLock(sendData);
|
||||
}
|
||||
if (closeConnectionNow) {
|
||||
@ -354,9 +369,25 @@ bool socketServerConnectionsIdle(JsNetwork *net) {
|
||||
jswrap_stream_pushData(connection, receiveData, true);
|
||||
}
|
||||
jsvUnLock(receiveData);
|
||||
|
||||
// fire the error listeners
|
||||
bool hadError = error < 0 && error != SOCKET_ERR_CLOSED;
|
||||
JsVar *params[1];
|
||||
if (hadError) {
|
||||
params[0] = jsvNewWithFlags(JSV_OBJECT);
|
||||
jsvObjectSetChildAndUnLock(params[0], "code", jsvNewFromInteger(error));
|
||||
jsvObjectSetChildAndUnLock(params[0], "message",
|
||||
jsvNewFromString(socketErrorString(error)));
|
||||
jsiQueueObjectCallbacks(connection, HTTP_NAME_ON_ERROR, params, 1);
|
||||
jsiQueueObjectCallbacks(socket, HTTP_NAME_ON_ERROR, params, 1);
|
||||
jsvUnLock(params[0]);
|
||||
}
|
||||
|
||||
// fire the close listeners
|
||||
jsiQueueObjectCallbacks(connection, HTTP_NAME_ON_CLOSE, &connection, 1);
|
||||
jsiQueueObjectCallbacks(socket, HTTP_NAME_ON_CLOSE, &socket, 1);
|
||||
params[0] = jsvNewFromBool(hadError);
|
||||
jsiQueueObjectCallbacks(connection, HTTP_NAME_ON_CLOSE, params, 1);
|
||||
jsiQueueObjectCallbacks(socket, HTTP_NAME_ON_CLOSE, params, 1);
|
||||
jsvUnLock(params[0]);
|
||||
|
||||
_socketConnectionKill(net, connection);
|
||||
JsVar *connectionName = jsvObjectIteratorGetKey(&it);
|
||||
@ -476,8 +507,10 @@ bool socketClientConnectionsIdle(JsNetwork *net) {
|
||||
if (receiveData) { // could be out of memory
|
||||
jsvAppendStringBuf(receiveData, buf, (size_t)num);
|
||||
if ((socketType&ST_TYPE_MASK)==ST_HTTP && !hadHeaders) {
|
||||
// for HTTP see whether we now have full response headers
|
||||
JsVar *resVar = jsvObjectGetChild(connection,HTTP_NAME_RESPONSE_VAR,0);
|
||||
if (httpParseHeaders(&receiveData, resVar, false)) {
|
||||
os_printf("Got http response headers\n");
|
||||
hadHeaders = true;
|
||||
jsvObjectSetChildAndUnLock(connection, HTTP_NAME_HAD_HEADERS, jsvNewFromBool(hadHeaders));
|
||||
jsiQueueObjectCallbacks(connection, HTTP_NAME_ON_CONNECT, &resVar, 1);
|
||||
@ -494,6 +527,7 @@ bool socketClientConnectionsIdle(JsNetwork *net) {
|
||||
}
|
||||
|
||||
if (closeConnectionNow) {
|
||||
os_printf("Closing socket %d due to error %d\n", sckt, error);
|
||||
socketClientPushReceiveData(connection, socket, &receiveData);
|
||||
if (!receiveData) {
|
||||
if ((socketType&ST_TYPE_MASK) != ST_HTTP)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user