Example program for debugging failing event queue.

main.cpp

Committer:
sjalloq
Date:
2019-04-07
Revision:
0:c9670ffe21d4

File content as of revision 0:c9670ffe21d4:

/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

/*  
*/

#include "mbed.h"
#include "EthernetInterface.h"
#include "TCPSocket.h"
#include "SocketAddress.h"
#include <string.h>

#define PORT 7070
#define FLAG_SOCKET_ACCEPT  (1<<0)
#define FLAG_SOCKET_CLOSED  (1<<1)
#define FLAG_CLIENT_CONNECT (1<<2)

Serial Uart(USBTX,USBRX);
BusOut Leds(LED1,LED2,LED3,LED4);

EventQueue *queue = mbed_event_queue();
EventFlags evntFlags;
EthernetInterface eth;  
TCPSocket socket;
TCPSocket *client;


void set_leds(uint32_t leds) {
    Leds = leds & 0xF;
}

void client_sigio(TCPSocket *client, EventFlags *evnt) {
    
    static enum {
        RECEIVE,
        CLOSE
    } next_state = RECEIVE;
    
    static char buf[4];
    static char *buf_p = buf;
    static uint32_t remaining = 4;
    
    nsapi_size_or_error_t szerr;
    
    Uart.printf("client_sigio: state=%d\n\r", next_state);
    
    switch(next_state) {
        case CLOSE: {
            client->close();
            evnt->clear(FLAG_CLIENT_CONNECT);
            next_state = RECEIVE;
            break;
        }
        case RECEIVE: {
            szerr = client->recv(buf_p, remaining);
            Uart.printf("Received %0d bytes\n\r", szerr);
            if(szerr >= 0) {
                buf_p += szerr;
                remaining -= szerr;
                if(0 == remaining) {
                    // Send transaction
                    Uart.printf("Received transaction: buf[3]=0x%0x buf[2]=0x%0x buf[1]=0x%0x buf[0]=0x%0x ", 
                        buf[3], buf[2], buf[1], buf[0]);
                }
                break;
            } else {
                if(NSAPI_ERROR_WOULD_BLOCK == szerr) {
                    break;
                } else if(NSAPI_ERROR_NO_SOCKET == szerr) {
                    next_state = CLOSE;
                    // now fall through to default
                } else {
                    Uart.printf("client_sigio:  unhandled error on socket->recv(): %d\n\r", szerr);
                }
            }
        }
        default: {
            // something went wrong so reset the buffer
            buf_p = buf;
            remaining = 4;
        }
    }
}


void server_sigio(TCPSocket *server, TCPSocket *client, EventFlags *evnt) {
    
    static enum {
        LISTENING,
        ACCEPT,
        CLOSE
    } next_state = LISTENING;

    nsapi_error_t err;
    
    Uart.printf("server_sigio: state=%d\n\r", next_state);
    
    switch (next_state) {
        case LISTENING: {
            client = server->accept(&err);
            switch(err) {
                case NSAPI_ERROR_WOULD_BLOCK:
                // Continue to listen
                break;
                case NSAPI_ERROR_OK: {
                    // Accepted connection
                    evnt->set(FLAG_CLIENT_CONNECT);
                    Event<void()> client_handler = queue->event(client_sigio, client, evnt);
                    client->set_blocking(false);
                    client->sigio(client_handler);
                    Uart.printf("calling client_handler()\n\r");
                    client_handler.post();
                    next_state = ACCEPT;
                    Uart.printf("Just set state=%d\n\r", next_state);
                    break;
                }
                default:
                // Error in connection phase
                Uart.printf("server_sigio: err = %d\n\r", err);   
                //next_state = CLOSE;
                break;
            }
            break;
        }
        case ACCEPT: {
            //if (err == NSAPI_ERROR_WOULD_BLOCK)
            //  break;
            //next_state = CLOSE;
            Uart.printf("server_sigio: evntFlags=0x%0x\n\r", evnt->get());
            break;
        }
        case CLOSE: {
            Uart.printf("server_sigio: CLOSE state\n\r");
            //server->close();
            //flgs->set(FLAG_SOCKET_CLOSED);
            next_state = LISTENING;
            break;
        }
        default: {
            break;
        }
    }
}


// main() runs in its own thread in the OS
int main()
{
    nsapi_error_t err;
    nsapi_size_or_error_t szerr;

    Event<void()> server_handler = queue->event(server_sigio, &socket, client, &evntFlags);

    //Eventing evnt(&evntFlags);
    //Uart.attach(&evnt, &Eventing::print_event_flags);
    
    if(eth.connect() != NSAPI_ERROR_OK) {
        Uart.printf("Failed to connect to ethernet\n\r");
        while(1) ;
    } else {
        Uart.printf("Connected to ethernet, IP address = %s\n\r", eth.get_ip_address());
    }
    
    err = socket.open(&eth);
    if(err != NSAPI_ERROR_OK) {
        Uart.printf("Socket.open() failed with error: %d\n\r", err);
    }
    
    err = socket.bind(PORT);
    if(err != NSAPI_ERROR_OK) {
        Uart.printf("Socket.bind() failed with error: %d\n\r", err);
    }
    
    err = socket.listen();
    if(err != NSAPI_ERROR_OK) {
        Uart.printf("Socket.listen() failed with error: %d\n\r", err);
    }
    
    socket.set_blocking(false);
    socket.sigio(server_handler);
    server_handler.post();
    
    while(1) {      
        // All functionality handled within sigio() callbacks.
    }
}