mbed official WiflyInterface (interface for Roving Networks Wifly modules)

Dependents:   Wifly_HelloWorld Websocket_Wifly_HelloWorld RPC_Wifly_HelloWorld HTTPClient_Wifly_HelloWorld ... more

Issue: TCPSocketServer accept method can consume all memory

The accept( ) method searches the input stream for "*OPEN*", but appears to accept everything into an ever growing string allocation until *OPEN* is found.

This becomes a concern because I have found in practice that if the Wifly module gets out of phase with the input stream, then a block of "data" comes directly into the accept method. The size of that data is determined by what you have on the other end of the network.

At this point, when *OPEN* is found, the original version throws away not just the received stream up to that point, but anything after the *OPEN* which could be valid data, so it should not flush that. I have tested and use the proposed mods in my derived WiflyInterface.

I added a few side-bar comments below -

TCPSocketServer.cpp - mbed WiflyInterface (official version 8)

int TCPSocketServer::accept(TCPSocketConnection& connection) {
    int nb_available = 0, pos = 0;
    char c;
    string str;
    bool o_find = false;
    while (1) {
        while(!wifi->readable());
        nb_available = wifi->readable();
        for (int i = 0; i < nb_available; i++) {
            c = wifi->getc();
            if (c == '*') {
                o_find = true;
            }
            if (o_find && c != '\r' && c != '\n') {
                str += c;                            // C++ str concatenation is unbounded?
                pos = str.find("*OPEN*");            // only when *OPEN* is found do we return
                if (pos != string::npos) {
                    wifi->flush();                   // this flush may remove valid input data
                    return 0;                        // the C++ str goes out of scope and is removed
                }
            }
        }
    }

Suggested revision avoids C++ string concatenation. When *OPEN* is found, this also does not flush the wifi input, since it may have valid input in the buffer.

TCPSocketServer.cpp - proposed

int TCPSocketServer::accept(TCPSocketConnection& connection)
{
    int nb_available = 0;
    char c;
    const char OPEN[] = "*OPEN*";   // seeking this to accept

    while (1) {
        while(!wifi->readable());
        nb_available = wifi->readable();
        for (int i = 0; i < nb_available; i++) {
            c = wifi->getc();
            if (c != OPEN[acceptIndex])
                acceptIndex = 0;
            if (c == OPEN[acceptIndex]) {
                acceptIndex++;
                if (acceptIndex == strlen(OPEN)) {
                    acceptIndex = 0;    // for next pass
                    return 0;
                }
            }
        }
    }
}