8 years, 2 months ago.  This question has been closed. Reason: Opinion based - no single answer

wiz550io blocks the while loop

Managed to transfer data to/from PC and Nucleo F401RE using wiz550io!! See below my code. But the while loops is always waiting for a connection from PC. Is there any way around such that I can run my other (non Ethernet related) code in the while loop while exchanging data with the PC.

It will be ideal to have an Interrupt service routine for receiving and sending data?

int main (void)
{
    SPI spi2(PC_12, PC_11, PC_10); // mosi, miso, sclk
    EthernetInterface eth(&spi2, PC_6, PB_8);
    wait(1); // 1 second for stable state

    // late binding
    TCPSocketServer svr;
    TCPSocketConnection client;

    ledTick.attach(&ledTickfunc,2);

    // as your env. change to real IP address and so on.
    int     ret = eth.init(MY_IP, MY_NETMASK, MY_GATEWAY);
    if (!ret) {
        serial.printf("Initialized, MAC: %s\n\r", eth.getMACAddress());
        serial.printf("Connected, IP: %s, MASK: %s, GW: %s\n\r",
                      eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
    } else {
        serial.printf("Error eth.init() - ret = %d\n\r", ret);
        return -1;
    }

    //setup tcp socket
    if(svr.bind(PORT)< 0) {
        serial.printf("tcp server bind failed.\n\r");
        return -1;
    } else {
        serial.printf("tcp server bind successed.\n\r");
        serverIsListened = true;
    }

    if(svr.listen(1) < 0) {
        serial.printf("tcp server listen failed.\n\r");
        return -1;
    } else {
        serial.printf("tcp server is listening...\n\r");
    }

    char buffer[256] = {};
    //blocking mode(never timeout)
    client.set_blocking(true,0); // Timeout after (1.5)s
    while (serverIsListened) {

        if(svr.accept(client)<0) {
            serial.printf("failed to accept connection.\n\r");
        }else if(svr.accept(client)== 5){ // there is no connection
        }else {
            serial.printf("connection success!\n\rIP: %s\n\r",client.get_address());
            clientIsConnected = true;
                       
            while(clientIsConnected) { 
                switch(client.receive(buffer, 255)) {
                    case 0:
                        //serial.printf("recieved buffer is empty.\n\r");
                        clientIsConnected = false;
                        client.close();
                        break;
                    case -1:
                        //serial.printf("failed to read data from client.\n\r");
                        clientIsConnected = false;
                        client.close();
                        break;
                    default:
                        //serial.printf("Recieved Data: %d\n\r\n\r%.*s\n\r",strlen(buffer),strlen(buffer),buffer);
                        //if(buffer[0] == 'G' && buffer[1] == 'E' && buffer[2] == 'T' ) {
                            //serial.printf("GET request incomming.\n\r");
                            //wait(1);
                            float cnv;
                            cnv = atof(buffer);
                            cnv = -cnv/10.0f;
                            //serial.printf("data in %f.\n\r",cnv);
                            for(int i =0; i < 255; i++) buffer[i] = '\0';
                            sprintf(buffer,"%f\r\n",cnv);
                            client.send(buffer,strlen(buffer));
                            clientIsConnected = false;
                            //serial.printf("echo back done.\n\r");
                        //}
                        for(int i =0; i < 255; i++) buffer[i] = '\0';
                        clientIsConnected = false;   // ***
                        client.close(); // ***
                        break;
                } // switch(client.receive(buffer, 255))
                client.close(); // ***               
            } // while(clientIsConnected)
            //serial.printf("close connection here.\n\rtcp server is listening...\n\r");
        } //if(svr.accept(client)<0)
        clientIsConnected = false;   // ***
        client.close();
    } //while (serverIsListened)
}

A very bad hack is to modify the TCPSocketServer.cpp file as follows. Indeed the data is missed few times

int TCPSocketServer::accept(TCPSocketConnection& connection)
{
    if (_sock_fd < 0) {
        return -1;
    }
    Timer t;
    t.reset();
    t.start();
    //*** while(1) {

    if (t.read_ms() > _timeout && _blocking == false) {
        return -1;
    }
    if (eth->sreg<uint8_t>(_sock_fd, Sn_SR) == WIZnet_Chip::SOCK_ESTABLISHED) {
        //*** break;
        //*** }
        //*** }
        uint32_t ip = eth->sreg<uint32_t>(_sock_fd, Sn_DIPR);
        char host[16];
        snprintf(host, sizeof(host), "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip&0xff);
        uint16_t port = eth->sreg<uint16_t>(_sock_fd, Sn_DPORT);

        // change this server socket to connection socket.
        connection._sock_fd = _sock_fd;
        connection._is_connected = true;
        connection.set_address(host, port);

        // and then, for the next connection, server socket should be assigned new one.
        _sock_fd = -1; // want to assign new available _sock_fd.
        if(bind(listen_port) < 0) {
            // modified by Patrick Pollet
            error("No more socket for listening, bind error");
            return -1;
        } else {
            //return -1;
            if(listen(1) < 0) {
                // modified by Patrick Pollet
                error("No more socket for listening, listen error");
                return -1;
            }
        }
        return 0;
    }
    return 5; // i.e. no connection yet 
}
posted by Baljit Riar 18 Feb 2016