lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] Assert "tcp_slowtmr" in tcp.c reached


From: Marco Jakobs
Subject: Re: [lwip-users] Assert "tcp_slowtmr" in tcp.c reached
Date: Tue, 02 Feb 2010 16:29:53 +0100
User-agent: Thunderbird 2.0.0.23 (Windows/20090812)


Kieran Mansley schrieb:
Could you send it to the list so that others who are interested can see
the code too?
Sure ... i was not sure if attachments are welcome here.

The RTOS task "AppIP" is responsible for initialization of the LwIP and PPP handling. There is also a bunch of test code in it. The important areas are:

LwIP Init: Line 138
PPP start connection: Line 244
PPP close connection: Line 277

Marco


/***************************************************************************
 * AppIP - Takes care of PPP and ethernet connections.
 * Copyright (c) 2009 © Funk-Electronics Picorgros GmbH
 *
 * TODO:
 *  - The main task is passed a pointer to the network interfaces. We
 *    have a race condition if the PPP link would went down in a few
 *    microseconds before the main task has been scheduled. In this
 *    case the main task would have an pointer to a no longer existing
 *    network interface.
 *
 * $Id: AppIP.c 731 2009-12-18 20:42:41Z jakobs $
 ***************************************************************************/

/* ----------------------- System includes --------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include <stdarg.h>
#include <stdio.h>

#include "lwip/init.h"
#include "lwip/api.h"
#include "lwip/tcpip.h"
#include "lwip/ip.h"
#include "ppp.h"
#include "nat.h"
/* ----------------------- Project includes -------------------------------*/
#include "AppIP.h"
#include "Libraries\lwIP\port\EMAC\SAM7_EMAC.h"
#include "confreg_ext.h"
#include "tmo_ext.h"
/* ----------------------- Defines ----------------------------------------*/

#define APPIP_DEBUG                     ( 0 )

#if APPIP_DEBUG == 1
#define APPIP_TRACE(x)                  do { vSysDiag x; } while(0)
#else
#define APPIP_TRACE(x)
#endif

//#define PPP_USER                        "test"
//#define PPP_PASS                        "test"

#define MODEM_GPRS                      ( 0 )
#define MODEM_TETRA                     ( 1 )
#define MODEM_NULL                      ( 2 )
#define MODEM                           ( MODEM_NULL )
#if MODEM == MODEM_GPRS
#define PPP_DUMMY_STRING                "at\r\n"
#define PPP_HANGUP_STRING               "ath0\r\n"
#define PPP_INIT_STRING_0               "ate0\r\n"
#define PPP_INIT_STRING_1               "at+cpin=4711\r\n"
#define PPP_INIT_STRING_2               
"at+cgdcont=1,\"IP\",\"internet.eplus.de\"\r\n"
#define PPP_DIAL_STRING                 "atdt*99***1#\r\n"
#elif MODEM == MODEM_TETRA
#define PPP_DUMMY_STRING                "at\r\n"
#define PPP_HANGUP_STRING               "ath0\r\n"
#define PPP_INIT_STRING_0               "ate0\r\n"
#define PPP_DIAL_STRING                 "atd*99#\r\n"
#elif MODEM == MODEM_NULL
#else
#error "no modem set!"
#endif
#define PPP_DIAL_CONNECT_WAITMAX        10000
#define PPP_DIAL_CONNECT_OKAY           "\r\nCONNECT\r\n"

/* ----------------------- Type Definitions -------------------------------*/
typedef enum
{
    STATE_INIT,
    STATE_IDLE,
    STATE_MODEM_INIT,
    STATE_MODEM_DIAL,
    STATE_MODEM_WAIT_CONNECT,
    STATE_PPP_INIT,
    STATE_PPP_ISOPEN,
    STATE_PPP_CLOSE_WAIT_SHUTDOWN,
    STATE_PPP_CLOSE
} eAppIPState_t;

typedef enum
{
    PPP_MSG_PPP_LINKREADY,
    PPP_MSG_PPP_LINKDEAD,
    PPP_MSG_PPP_CLOSE_FINALIZED
} ePPPMsg_t;

/* ----------------------- Global variables -------------------------------*/

extern volatile unsigned char eth_link_status;                          // 
Merker für Linkstatus aus SAM7_emac.c

/* ----------------------- Static variables -------------------------------*/
static xAppIP_CFG_t xCurCFG;
static eAppIPState_t eState;
static int      ppp_con_fd;
static struct netif xEMAC_if;
static struct netif *pxPPP_if;

/* ----------------------- Static functions -------------------------------*/
static void     vAppDumpInMessage( const xAppIP_MsgIn_t * pxInMsg );
static void     vModemSend( sio_fd_t xFd, const char *pszCommand );
static void     vModemRead( sio_fd_t xFd, char *pszBuffer, int iBufferMax );
static void     vPPPStatusCB( void *ctx, int errCode, void *arg );
static const char *vPPPStatusStrError( int errCode );
void            ppp_trace( int level, const char *format, ... );

/* ----------------------- Prototypes -------------------------------------*/
extern err_t    ethernetif_init( struct netif *netif );

/* ----------------------- Start implementation ---------------------------*/
void
vAppIP( void *pvIPCFG )
{
    xAppIP_MsgIn_t  xMsgIn;
    portBASE_TYPE   pdResult;
    char            arucRcvBuffer[32];
    u32_t           uiBufferCurPos;
    portTickType    xTickWaitStart, xTickDelta;
    ePPPMsg_t       eMsg;
    int             err;
    xAppIP_MsgOut_t xMsgOut;

                char f,ppp_user[21],ppp_pass[21];

                // Username und Password kopieren
                ppp_user[20]=0;
                ppp_pass[20]=0;
                for (f=0;f<10;f++)
                {
                        ppp_user[f*2]=kreg[350+f]>>8;
                        ppp_user[f*2+1]=kreg[350+f]&0xff;
                        ppp_pass[f*2]=kreg[360+f]>>8;
                        ppp_pass[f*2+1]=kreg[360+f]&0xff;
                }

    /* Initialize IP stack */
    tcpip_init( NULL, NULL );
    pppInit(  );
    pppSetAuth( PPPAUTHTYPE_PAP, &ppp_user[0], &ppp_pass[0] );

    PORT_ASSERT( NULL != pvIPCFG );
    memcpy( &xCurCFG, pvIPCFG, sizeof( xAppIP_CFG_t ) );

    eState = STATE_INIT;
    for( ;; )
    {
        switch ( eState )
        {
        case STATE_INIT:
            netif_add( &xEMAC_if, &( xCurCFG.xETHCfg.xETHIP ), &( 
xCurCFG.xETHCfg.xETHNetmask ),
                       &( xCurCFG.xETHCfg.xETHGateway ), NULL, ethernetif_init, 
tcpip_input );
            netif_set_default( &xEMAC_if );
            netif_set_up( &xEMAC_if );

            xMsgOut.eMsgType = MSGOUT_ETHERNET_ISOPEN;
            xMsgOut.x.xMSGEthernetOpen.nif = &xEMAC_if;
            pdResult = xQueueSend( xCurCFG.xMsgQueueOut, &xMsgOut, sizeof( 
xMsgOut ) );
            PORT_ASSERT( pdTRUE == pdResult );
            eState = STATE_IDLE;
            break;

        case STATE_IDLE:
                                                pdResult = xQueueReceive( 
xCurCFG.xMsgQueueIn, &xMsgIn, portMAX_DELAY );
            if( pdTRUE == pdResult )
            {
                                                                
//vSysDiag("MsgQueueIn receive State Idle\r\n");
                vAppDumpInMessage( &xMsgIn );
                switch ( xMsgIn.eMsgType )
                {
                case MSGIN_DO_OPEN_PPPLINK:
                    APPIP_TRACE( ( "vAppIP(STATE_IDLE): opening new PPP 
link...\r\n" ) );
                    eState = STATE_MODEM_INIT;
                    break;
                default:
                    APPIP_TRACE( ( "vAppIP(STATE_IDLE): received unknown 
message. ignoring it.\r\n" ) );
                    break;
                }
            }
            break;

        case STATE_MODEM_INIT:
            eState = STATE_MODEM_DIAL;
            break;

        case STATE_MODEM_DIAL:
#if MODEM == MODEM_NULL
#elif MODEM == MODEM_GPRS
            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_DUMMY_STRING );
            vTaskDelay( 1000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_DUMMY_STRING, arucRcvBuffer ) );

            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_HANGUP_STRING );
            vTaskDelay( 1000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_HANGUP_STRING, arucRcvBuffer ) );

            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_INIT_STRING_0 );
            vTaskDelay( 1000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_INIT_STRING_0, arucRcvBuffer ) );

            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_INIT_STRING_1 );
            vTaskDelay( 5000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_INIT_STRING_1, arucRcvBuffer ) );

            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_INIT_STRING_2 );
            vTaskDelay( 1000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_INIT_STRING_2, arucRcvBuffer ) );

            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_DIAL_STRING );
            vTaskDelay( 1000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_DIAL_STRING, arucRcvBuffer ) );
#elif MODEM == MODEM_TETRA
            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_DUMMY_STRING );
            vTaskDelay( 1000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_DUMMY_STRING, arucRcvBuffer ) );

            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_HANGUP_STRING );
            vTaskDelay( 1000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_HANGUP_STRING, arucRcvBuffer ) );

            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_INIT_STRING_0 );
            vTaskDelay( 1000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_INIT_STRING_0, arucRcvBuffer ) );

            vModemSend( xCurCFG.xMODEMCfg.xMODEMfd, PPP_DIAL_STRING );
            vTaskDelay( 1000 );
            vModemRead( xCurCFG.xMODEMCfg.xMODEMfd, arucRcvBuffer, sizeof( 
arucRcvBuffer ) );
            APPIP_TRACE( ( "vAppIP(STATE_MODEM_DIAL): sent='%s', 
received='%s'\r\n", PPP_DIAL_STRING, arucRcvBuffer ) );
#endif
            eState = STATE_PPP_INIT;
            break;

        case STATE_PPP_INIT:
            ppp_con_fd = -1;
            ppp_con_fd = pppOverSerialOpen( xCurCFG.xMODEMCfg.xMODEMfd, 
vPPPStatusCB, NULL );
            APPIP_TRACE( ( "vAppIP(STATE_PPP_INIT): opening ppp connection\r\n" 
) );
            eState = STATE_PPP_ISOPEN;
            break;

        case STATE_PPP_ISOPEN:
            pdResult = xQueueReceive( xCurCFG.xMsgQueueIn, &xMsgIn, 1000 );
            if( pdTRUE == pdResult )
            {
                //vSysDiag("MsgQueueIn receive State PPP_ISOPEN\r\n");
                                                                switch ( 
xMsgIn.eMsgType )
                {
                case MSGIN_INTERNAL:
                    eMsg = xMsgIn.x.xMSGInternal.iMsg;
                    switch ( eMsg )
                    {
                    case PPP_MSG_PPP_LINKREADY:
                        xMsgOut.eMsgType = MSGOUT_PPPLINK_ISOPEN;
                        xMsgOut.x.xMSGEthernetOpen.nif = pxPPP_if;
                        pdResult = xQueueSend( xCurCFG.xMsgQueueOut, &xMsgOut, 
sizeof( xMsgOut ) );
                        PORT_ASSERT( pdTRUE == pdResult );
                        break;
                    case PPP_MSG_PPP_LINKDEAD:
                        eState = STATE_PPP_CLOSE;
                        break;
                    default:
                        APPIP_TRACE( ( "vAppIP(STATE_PPP_ISOPEN): received 
unknown internal message %d. ignoring it.\r\n",
                                       ( int )eMsg ) );
                        break;
                    }
                    break;

                case MSGIN_DO_SHUTDOWN_PPPLINK:
                    err = pppClose( ppp_con_fd );
                    PORT_ASSERT( 0 == err );
                    eState = STATE_PPP_CLOSE_WAIT_SHUTDOWN;
                    break;

                default:
                    APPIP_TRACE( ( "vAppIP(STATE_PPP_ISOPEN): received unknown 
message %d. ignoring it.\r\n",
                                   ( int )xMsgIn.eMsgType ) );
                    break;
                }
            }
            else
            {
                APPIP_TRACE( ( "vAppIP(STATE_PPP_ISOPEN): no events 
pending\r\n" ) );
            }
            break;



        case STATE_PPP_CLOSE_WAIT_SHUTDOWN:
            APPIP_TRACE( ( "vAppIP(STATE_PPP_CLOSE_WAIT_SHUTDOWN): PPP link 
waiting for shutdown...\r\n" ) );
            pdResult = xQueueReceive( xCurCFG.xMsgQueueIn, &xMsgIn, 1000 );
            if( pdTRUE == pdResult )
            {
                                                                
//vSysDiag("MsgQueueIn receive State PPP_CLOSE_WAIT_SHUTDOWN\r\n");
                switch ( xMsgIn.eMsgType )
                {
                case MSGIN_INTERNAL:
                    eMsg = xMsgIn.x.xMSGInternal.iMsg;
                    switch ( eMsg )
                    {
                    case PPP_MSG_PPP_LINKDEAD:
                        eState = STATE_PPP_CLOSE;
                        break;
                    default:
                        APPIP_TRACE( ( "vAppIP(STATE_PPP_CLOSE_WAIT_SHUTDOWN): 
received unknown internal message %d. ignoring it.\r\n", ( int )eMsg ) );
                        break;
                    }
                    break;
                default:
                    APPIP_TRACE( ( "vAppIP(STATE_PPP_CLOSE_WAIT_SHUTDOWN): 
received unknown message %d. ignoring it.\r\n",
                                   ( int )xMsgIn.eMsgType ) );
                    break;
                }
            }
            break;

        case STATE_PPP_CLOSE:
            xMsgOut.eMsgType = MSGOUT_PPPLINK_ISDEAD;
            xMsgOut.x.xMSGEthernetOpen.nif = pxPPP_if;
            pdResult = xQueueSend( xCurCFG.xMsgQueueOut, &xMsgOut, sizeof( 
xMsgOut ) );
            PORT_ASSERT( pdTRUE == pdResult );
            APPIP_TRACE( ( "vAppIP(STATE_PPP_CLOSE): Switching to state idle 
after close...\r\n" ) );
            eState = STATE_IDLE;
            break;

        default:
            PORT_ASSERT( 0 );
            break;
        }
    }
}


// Reports Link status (1=Link online, 0=Link offline)
unsigned char get_eth_link(void)
{
        if (eth_link_status==1) return (1); else return (0);
}



static void
vAppDumpInMessage( const xAppIP_MsgIn_t * pxInMsg )
{
    APPIP_TRACE( ( "msg type: %d\r\n", ( int )pxInMsg->eMsgType ) );
}

static void
vModemSend( sio_fd_t xFd, const char *pszCommand )
{
    sio_write( xFd, ( char * )pszCommand, strlen( pszCommand ) );
}

static void
vModemRead( sio_fd_t xFd, char *pszBuffer, int iBufferMax )
{
    int             iBytesLeft = iBufferMax - 1;        /* One space for 
terminating character. */
    char           *pszBufferCur = pszBuffer;
    u32_t           uiBytesReadCur;
    portTickType    xTickWaitStart, xTickDelta, xAllowedTickDelta = 5000;

    xTickWaitStart = xTaskGetTickCount(  );

    do
    {
        uiBytesReadCur = sio_read( xFd, pszBufferCur, iBytesLeft );
        if( uiBytesReadCur > 0 )
        {
            xAllowedTickDelta = 10;
            pszBufferCur += uiBytesReadCur;
            iBytesLeft -= uiBytesReadCur;
            xTickWaitStart = xTaskGetTickCount(  );
        }
        else
        {
            /* Always take care when tick counter might overflow. */
            xTickDelta = xTaskGetTickCount(  ) - xTickWaitStart;
        }
    }
    while( ( xTickDelta < xAllowedTickDelta ) && ( iBytesLeft > 0 ) );
    *pszBufferCur = '\0';
}

static const char *
vPPPStatusStrError( int errCode )
{
    const char     *retval;

    switch ( errCode )
    {
    case PPPERR_NONE:
        retval = "none";
        break;
    case PPPERR_PARAM:
        retval = "param";
        break;
    case PPPERR_OPEN:
        retval = "open";
        break;
    case PPPERR_DEVICE:
        retval = "device";
        break;
    case PPPERR_ALLOC:
        retval = "alloc";
        break;
    case PPPERR_USER:
        retval = "user";
        break;
    case PPPERR_CONNECT:
        retval = "connect";
        break;
    case PPPERR_AUTHFAIL:
        retval = "authfail";
        break;
    case PPPERR_PROTOCOL:
        retval = "protocol";
        break;
    case PPPERR_IFUP:
        retval = "ifup";
        break;
    default:
        retval = "unknown";
        break;
    }
    return retval;
}

static void
vPPPStatusCB( void *ctx, int errCode, void *arg )
{
    xAppIP_MsgIn_t  eMsg;
    portBASE_TYPE   pdStatus;
    ip_nat_entry_t  new_nat_entry;

    ( void )ctx;
    APPIP_TRACE( ( "vPPPStatusCB: error code = %s\r\n", vPPPStatusStrError( 
errCode ) ) );
    switch ( errCode )
    {
    case PPPERR_NONE:
        APPIP_TRACE( ( "vPPPStatusCB: PPP link reported connection 
established.\r\n" ) );
        break;
    case PPPERR_IFUP:
        APPIP_TRACE( ( "vPPPStatusCB: PPP link reported network interface is 
up.\r\n" ) );
        pxPPP_if = ( struct netif * )arg;

        new_nat_entry.out_if = ( struct netif * )pxPPP_if;
        new_nat_entry.in_if = ( struct netif * )&xEMAC_if;
//        IP4_ADDR( &new_nat_entry.source_net, 92, 168, 0, 100 );             
// NAT nur von diesem Rechner ...
//        IP4_ADDR( &new_nat_entry.source_netmask, 255, 255, 255, 255 );
//        IP4_ADDR( &new_nat_entry.dest_net, 192, 168, 0, 0 );                
// ... in dieses Netzwerk
//        IP4_ADDR( &new_nat_entry.dest_netmask, 255, 255, 255, 0 );
        IP4_ADDR( &new_nat_entry.source_net, kreg[460]>>8, kreg[460], 
kreg[461]>>8, kreg[461] );                // hier wird alles genattet
        IP4_ADDR( &new_nat_entry.source_netmask, kreg[462]>>8, kreg[462], 
kreg[463]>>8, kreg[463] );
        IP4_ADDR( &new_nat_entry.dest_net, kreg[464]>>8, kreg[464], 
kreg[465]>>8, kreg[465] );
        IP4_ADDR( &new_nat_entry.dest_netmask, kreg[466]>>8, kreg[466], 
kreg[467]>>8, kreg[467] );
                                vSysDiag("NAT initialized 
%hu.%hu.%hu.%hu/%hu.%hu.%hu.%hu to %hu.%hu.%hu.%hu/%hu.%hu.%hu.%hu\r\n",\
                                                                        
kreg[460]>>8,kreg[460]&0xff,kreg[461]>>8,kreg[461]&0xff,\
                                                                        
kreg[462]>>8,kreg[462]&0xff,kreg[463]>>8,kreg[463]&0xff,\
                                                                        
kreg[464]>>8,kreg[464]&0xff,kreg[465]>>8,kreg[465]&0xff,\
                                                                        
kreg[466]>>8,kreg[466]&0xff,kreg[467]>>8,kreg[467]&0xff);
        ip_nat_init( &new_nat_entry );

        eMsg.eMsgType = MSGIN_INTERNAL;
        eMsg.x.xMSGInternal.iMsg = PPP_MSG_PPP_LINKREADY;
                                //vSysDiag("MsgQueueIn send PPPERR_IFUP\r\n");
                                pdStatus = xQueueSend( xCurCFG.xMsgQueueIn, 
&eMsg, sizeof( eMsg ) );
        PORT_ASSERT( pdTRUE == pdStatus );
        break;
    case PPPERR_PROTOCOL:
    case PPPERR_CONNECT:
    case PPPERR_USER:
        break;
    case PPPERR_SHUTDOWN:
        ip_nat_remove_all(  );
        pxPPP_if = NULL;
        eMsg.eMsgType = MSGIN_INTERNAL;
        eMsg.x.xMSGInternal.iMsg = PPP_MSG_PPP_LINKDEAD;
        APPIP_TRACE( ( "vPPPStatusCB: PPP link is now dead.\r\n" ) );
                                //vSysDiag("MsgQueueIn send 
PPPERR_SHUTDOWN\r\n");
                                pdStatus = xQueueSend( xCurCFG.xMsgQueueIn, 
&eMsg, sizeof( eMsg ) );
        PORT_ASSERT( pdTRUE == pdStatus );
        break;
    default:
        APPIP_TRACE( ( "vPPPStatusCB: unhandled error code!\r\n" ) );
        PORT_ASSERT( 0 );
        break;
    }
}


void
ppp_trace( int level, const char *format, ... )
{
    va_list         ap;
    static char     szDebugBuffer[160];

    ( void )level;
    va_start( ap, format );
    vsnprintf( szDebugBuffer, sizeof( szDebugBuffer ), format, ap );
    vSysDiag( "%s", szDebugBuffer );
    va_end( ap );
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]