コード例 #1
0
ファイル: fnet_telnet.c プロジェクト: jhgorse/fnet
/************************************************************************
* NAME: fnet_telnet_putchar
*
* DESCRIPTION: 
************************************************************************/
static void fnet_telnet_putchar(long id, int character)
{
    struct fnet_telnet_session_if *session = (struct fnet_telnet_session_if *)id;
    
    if(session->state != FNET_TELNET_STATE_CLOSING)
    {
        tx_buffer_write(session, (char)character);         

        if(tx_buffer_free_space(session) < 1) /* Buffer is full => flush. */
        {
            fnet_telnet_send(session);
        }
    }
}
コード例 #2
0
ファイル: fnet_telnet.c プロジェクト: butok/FNET
/************************************************************************
* DESCRIPTION:
************************************************************************/
static void fnet_telnet_putchar(fnet_index_t id, fnet_char_t character)
{
    struct fnet_telnet_session_if *session = (struct fnet_telnet_session_if *)id;

    if(session->state != FNET_TELNET_STATE_CLOSING)
    {
        tx_buffer_write(session, (fnet_uint8_t)character);

        if(tx_buffer_free_space(session) < 1u) /* Buffer is full => flush. */
        {
            fnet_telnet_send(session);
        }
    }
}
コード例 #3
0
ファイル: fnet_telnet.c プロジェクト: jhgorse/fnet
/************************************************************************
* NAME: fnet_telnet_state_machine
*
* DESCRIPTION: Telnet server state machine.
************************************************************************/
static void fnet_telnet_state_machine( void *telnet_if_p )
{
    struct sockaddr                 foreign_addr;
    int                             res;
    struct fnet_telnet_if           *telnet = (struct fnet_telnet_if *)telnet_if_p;
    char                            rx_data[1];
    int                             len;
    int                             i;
    struct fnet_telnet_session_if   *session;
    
    for(i=0; i<FNET_CFG_TELNET_SESSION_MAX; i++) 
    { 
        session = &telnet->session[i];
        telnet->session_active = session;
        
        do
        {
            switch(session->state)
            {
                /*---- LISTENING ------------------------------------------------*/
                case FNET_TELNET_STATE_LISTENING:
                     len = sizeof(foreign_addr);
                    session->socket_foreign = accept(telnet->socket_listen, (struct sockaddr *) &foreign_addr, &len);
                    
                    if(session->socket_foreign != SOCKET_INVALID)
                    {
                        #if FNET_CFG_DEBUG_TELNET
                        {
                            char ip_str[FNET_IP_ADDR_STR_SIZE];
                            fnet_inet_ntop(foreign_addr.sa_family, foreign_addr.sa_data, ip_str, sizeof(ip_str)); 
                            FNET_DEBUG_TELNET("\nTELNET: New connection: %s; Port: %d.", ip_str, fnet_ntohs(foreign_addr.sa_port));
                        }
                        #endif

                        /* Init Shell. */
                        session->shell_descriptor = fnet_shell_init(&session->shell_params); 
        
                        if(session->shell_descriptor == FNET_ERR)
                        {
                            session->shell_descriptor = 0;
                            
                            FNET_DEBUG_TELNET("TELNET: Shell Service registration error.");
                            session->state = FNET_TELNET_STATE_CLOSING;   /*=> CLOSING */
                        }
                        else
                        {    
                            listen(telnet->socket_listen, --telnet->backlog); /* Ignor other connections.*/
                            
                            /* Reset TX timeout. */
                            session->state = FNET_TELNET_STATE_RECEIVING; /* => WAITING data */
                        }
                    }
                    break;
                /*---- NORMAL -----------------------------------------------*/
                case FNET_TELNET_STATE_RECEIVING:
                    if(rx_buffer_free_space(session)>0) 
                    {                
                        res = recv(session->socket_foreign, rx_data, 1, 0);
                        if(res == 1)
                        {
                            if(rx_data[0] == FNET_TELNET_CMD_IAC )
                            {
                                session->state = FNET_TELNET_STATE_IAC; /*=> Handle IAC */
                            }
                            else
                            {
                                rx_buffer_write (session, rx_data[0]);
                            }
                        }
                        else if (res == SOCKET_ERROR)
                        {              
                            session->state = FNET_TELNET_STATE_CLOSING; /*=> CLOSING */
                        }
                    }                
                    break;
                /*---- IAC -----------------------------------------------*/    
                case FNET_TELNET_STATE_IAC:
                    FNET_DEBUG_TELNET("TELNET: STATE_IAC");
                    
                    if((res = recv(session->socket_foreign, rx_data, 1, 0) )!= SOCKET_ERROR)
                    {
                        if(res)
                        {
                            switch(rx_data[0])
                            {
                                case FNET_TELNET_CMD_WILL:
                                    session->state = FNET_TELNET_STATE_DONT;
                                    break;
                                case FNET_TELNET_CMD_DO:
                                    session->state = FNET_TELNET_STATE_WONT;
                                    break;                        
                                case FNET_TELNET_CMD_WONT:
                                case FNET_TELNET_CMD_DONT:
                                    session->state = FNET_TELNET_STATE_SKIP ;
                                    break;   
                                case FNET_TELNET_CMD_IAC:
                                    /*
                                    the IAC need be doubled to be sent as data, and
                                    the other 255 codes may be passed transparently.
                                    */
                                    rx_buffer_write (session, rx_data[0]);
                                default:
                                    session->state = FNET_TELNET_STATE_RECEIVING; /*=> Ignore commands */ 
                            }
                        }
                    }
                    else
                    {              
                        session->state = FNET_TELNET_STATE_CLOSING; /*=> CLOSING */
                    }
                    break;
                /*---- DONT & WONT -----------------------------------------------*/     
                case FNET_TELNET_STATE_DONT:
                case FNET_TELNET_STATE_WONT:
                    {
                        char command;
                        
                        if(session->state == FNET_TELNET_STATE_DONT)
                        {
                            FNET_DEBUG_TELNET("TELNET: STATE_DONT");
                            command = FNET_TELNET_CMD_DONT;
                        }
                        else
                        {
                            FNET_DEBUG_TELNET("TELNET: STATE_WONT");
                            command =  FNET_TELNET_CMD_WONT;
                        }
                         
                        if(tx_buffer_free_space(session) >= 3)
        	            {
                            res = recv(session->socket_foreign, rx_data, 1, 0);
                            
                            if(res == 1)
                            {
                                /* Send command. */
                                fnet_telnet_send_cmd(session, command, rx_data[0]);
                                session->state = FNET_TELNET_STATE_RECEIVING; 
                            }
                            else if (res == SOCKET_ERROR)
                            {              
                                session->state = FNET_TELNET_STATE_CLOSING; /*=> CLOSING */
                            }
                        }
                    }
                    break;
                /*---- SKIP -----------------------------------------------*/                    
                case FNET_TELNET_STATE_SKIP:
                    FNET_DEBUG_TELNET("TELNET: STATE_SKIP");
                     
                    res = recv(session->socket_foreign, rx_data, 1, 0);
                    if(res == 1)
                    {
                        session->state = FNET_TELNET_STATE_RECEIVING; 
                    }
                    else if (res == SOCKET_ERROR)
                    {              
                        session->state = FNET_TELNET_STATE_CLOSING; /*=> CLOSING */
                    }

                    break;
                /*---- CLOSING --------------------------------------------*/
                case FNET_TELNET_STATE_CLOSING:
                    FNET_DEBUG_TELNET("TELNET: STATE_CLOSING");
                    
                    if(session->shell_descriptor)
                    {
                        fnet_shell_release(session->shell_descriptor);
                        session->shell_descriptor = 0;
                    }
                    
                    session->rx_buffer_head = session->rx_buffer;
                    session->rx_buffer_tail = session->rx_buffer; 
                  
                    closesocket(session->socket_foreign);
                    session->socket_foreign = SOCKET_INVALID;
                    
                    listen(telnet->socket_listen, ++telnet->backlog); /* Allow connection.*/
                    
                    session->state = FNET_TELNET_STATE_LISTENING; /*=> LISTENING */
                    break;
                default:
                    break;

            }

        }
        while(session->state == FNET_TELNET_STATE_CLOSING);
    }
}