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 ); }
_______________________________________________ lwip-users mailing list lwip-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/lwip-users