
// Declare a task stack for the StdIO Swap task
#define STDIOSWAP_STK_SIZE  (USER_TASK_STK_SIZE)
DWORD StdioSwapStack[STDIOSWAP_STK_SIZE] __attribute__( ( aligned( 4 ) ) );

#define STDIO_SWAP_PRIO 46
#define MY_MAIN_PRIO    47

int fd_Stdio;

char * Print_TCP_Error(int error)
{
    static char mbuf[20];
    switch(error)
    {
        case TCP_ERR_TIMEOUT:
            return("timeout");
        case TCP_ERR_NOCON:
            return("no connection");
        case TCP_ERR_CLOSING:
            return("socket closed");
        case TCP_ERR_NOSUCH_SOCKET:
            return("no such socket");
        case TCP_ERR_NONE_AVAIL:
            return("no socket available");
        case TCP_ERR_CON_RESET:
            return("connection reset");
        case TCP_ERR_CON_ABORT:
            return("connection abort");
        default:
            siprintf(mbuf, "unknown error %d", error);
            return(mbuf);
    }
}

int Shutdown(void)
{

    puts("\n\nAutoUpdate Attempt Accepted - Preparing to Shut Down\n\n");


    if ( fd_Stdio > 0 )
    {
        SetHaveError(fd_Stdio);
    }


    while ( ( fd_Stdio > 0 )  )
    {
        OSTimeDly(1);
    }

    puts("\n\nAutoUpdate Attempt Accepted - Finished Shut Down\n\n");


    return 1;
}


#define STDIO_COM_PORT  0
void Stdio_OpenSerial(void)
{
    int fd = SimpleOpenSerial(STDIO_COM_PORT,115200);
    ReplaceStdio( 0, fd );
    ReplaceStdio( 1, fd );
    ReplaceStdio( 2, fd );
}

void Stdio_CloseSerial(void)
{
    SerialClose(STDIO_COM_PORT);
}

void Stdio_FlushSerial(void)
{
    while( !(UartData[STDIO_COM_PORT].m_UartState & UART_TX_EMPTY) )
    {
        OSTimeDly(1);
    }
}

void StdioSwapTask( void *pd )
{
    int fd_Listen = listen( INADDR_ANY, STDIO_PORT, 1 );
    if ( fd_Listen > 0 )
    {
        while(1)
        {
            IPADDR  client_addr;
            WORD    client_port;
            fd_Stdio = accept(fd_Listen, &client_addr, &client_port, 0);

            if ( fd_Stdio > 0 )
            {
                iprintf("STDIO connected to: ");
                ShowIP( client_addr );
                iprintf(":%d\n", client_port);
                stdio_ip = client_addr;

                Stdio_FlushSerial();

                Stdio_CloseSerial();

                ReplaceStdio(0,fd_Stdio);
                ReplaceStdio(1,fd_Stdio);
                ReplaceStdio(2,fd_Stdio);

                puts(AppName);

                while ( fd_Stdio )
                {

                    fd_set read_fds;
                    fd_set error_fds;
                    FD_ZERO( &read_fds );
                    FD_ZERO( &error_fds );
                    FD_SET( fd_Listen, &read_fds );
                    FD_SET( fd_Stdio, &error_fds );

                    if (select( FD_SETSIZE, &read_fds, (fd_set *)NULL, &error_fds, 0 ))
                    {
                        close(fd_Stdio);
                        fd_Stdio = 0;
                        Stdio_OpenSerial();
                        puts("STDIO connected to serial");
                    }
                }
            }
            else
            {
                iprintf( "STDIO accept error: %s\n", Print_TCP_Error(fd_Stdio));
            }
        }
    }
    else
    {
        iprintf( "STDIO listen error: %s\n", Print_TCP_Error(fd_Listen));
    }
}

void UserMain(void * pd)
{

//  code to switch com0 over from polled to interrupt driven

    Stdio_CloseSerial();
    Stdio_OpenSerial();

    InitializeStack();
    if (EthernetIP == 0) GetDHCPAddress();
    OSChangePrio(MY_MAIN_PRIO);
    EnableAutoUpdate();
    EnableSmartTraps();
    EnableTaskMonitor();

#ifdef _DEBUG
    InitializeNetworkGDB_and_Wait();
#endif

    iprintf("APPLICATION STARTED: %s\n",AppName);


    update_shutdown_func = Shutdown;	// Shutdown cannot be called until after InitNVData

    if (OSTaskCreatewName( StdioSwapTask, NULL, &StdioSwapStack[STDIOSWAP_STK_SIZE], StdioSwapStack, STDIOSWAP_PRIO, "STDIO" ) != OS_NO_ERR)
    {
        puts("Error Creating StdioSwapTask");
    }

    while ( 1 )
    {
    // ... fill in your stuff

    }
}

