Marko Repo <[EMAIL PROTECTED]> writes: > The problem is now that for some reason PPP fails to build up > connection more than once. Connection is built reliably during > lwip_init( ) every time. However, after I call pppClose( ) - > function for the first time I'm unable to reconnect anymore,
As you've noticed the PPP implementation has some problems in this respect. When pppClose is performed, the PPP thread dies (pppMain returns, i.e. the equivalent of calling cyg_thread_exit), but there is no clean-up after that. Unless you've bumped the SYS_THREADS define in sys_arch.c, there won't be enough space left in the memory pool to allocate thread stack and data for a new thread and the second pppOpen will block forever in cyg_mempool_var_alloc (via sys_thread_new). Since the sys_arch interface has no function for thread deletion, I've changed the PPP code so that the thread never terminates (see diff below). Also you're probably right that lwip_init and pppInit are not meant to be called more than once. You can remove the call to pppOpen from lwip_init, and instead call that from somewhere else in your application code. Best wishes, -- Daniel Néri <[EMAIL PROTECTED]> Sigicom AB, Stockholm, Sweden
--- /tmp/ppp.c Wed Aug 3 10:05:54 2005 +++ /tmp/ppp.c8130Dow Wed Aug 3 10:05:54 2005 @@ -133,6 +131,8 @@ * PPP interface control block. */ typedef struct PPPControl_s { + sys_thread_t thread; + sys_sem_t open_sem; char openFlag; /* True when in use. */ char oldFrame; /* Old framing character for fd. */ sio_fd_t fd; /* File device ID of port. */ @@ -180,10 +180,11 @@ /***********************************/ /*** LOCAL FUNCTION DECLARATIONS ***/ /***********************************/ -static void pppMain(void *pd); -static void pppDrop(PPPControl *pc); +static void pppDrop(PPPControl *); +static void pppMain(void *); static void pppInProc(int pd, u_char *s, int l); +static void ppp_thread(void *); /******************************/ /*** PUBLIC DATA STRUCTURES ***/ @@ -299,14 +300,18 @@ for (i = 0; i < NUM_PPP; i++) { pppControl[i].openFlag = 0; + pppControl[i].open_sem = sys_sem_new(0); + LWIP_ASSERT("pppControl[i].open_sem", pppControl[i].open_sem != SYS_SEM_NULL); - subnetMask = htonl(0xffffff00); + subnetMask = htonl(0xffffff00); /* * Initialize to the standard option set. */ for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j) (*protp->init)(i); + + pppControl[i].thread = sys_thread_new(ppp_thread, (void *)i, PPP_THREAD_PRIO); } #if LINK_STATS @@ -387,17 +390,15 @@ int pd; /* Find a free PPP session descriptor. Critical region? */ - for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + for (pd = 0; pd < NUM_PPP; pd++) { + if (!pppControl[pd].openFlag) + break; + } + if (pd >= NUM_PPP) pd = PPPERR_OPEN; - else - pppControl[pd].openFlag = !0; - - /* Launch a deamon thread. */ - if (pd >= 0) { - - pppControl[pd].openFlag = 1; - + else { + /* release daemon thread. */ lcp_init(pd); pc = &pppControl[pd]; pc->fd = fd; @@ -428,7 +429,8 @@ pc->linkStatusCB = linkStatusCB; pc->linkStatusCtx = linkStatusCtx; - sys_thread_new(pppMain, (void*)pd, PPP_THREAD_PRIO); + sys_sem_signal(pc->open_sem); + if(!linkStatusCB) { while(pd >= 0 && !pc->if_up) { sys_msleep(500); @@ -454,9 +456,9 @@ int st = 0; /* Disconnect */ - pc->kill_link = !0; + pc->kill_link = 1; pppMainWakeup(pd); - + if(!pc->linkStatusCB) { while(st >= 0 && lcp_phase[pd] != PHASE_DEAD) { sys_msleep(500); @@ -992,7 +994,6 @@ return ERR_OK; } - /* * sifup - Config the interface up and enable IP packets to pass. */ @@ -1196,6 +1197,29 @@ /**********************************/ /*** LOCAL FUNCTION DEFINITIONS ***/ /**********************************/ +static void +ppp_thread(void *arg) +{ + int pd = (int)arg; + PPPControl *pc = &pppControl[pd]; + + for (;;) { + // wait for open + sys_sem_wait(pc->open_sem); + + PPPDEBUG((LOG_INFO, "ppp_thread[%d]: open request\n", pd)); + + pppControl[pd].openFlag = 1; + + pppMain(arg); + + PPPDEBUG((LOG_INFO, "ppp_thread[%d]: closed\n", pd)); + + pppControl[pd].openFlag = 0; + } +} + + /* The main PPP process function. This implements the state machine according * to section 4 of RFC 1661: The Point-To-Point Protocol. */ static void pppMain(void *arg) @@ -1247,8 +1269,6 @@ PPPDEBUG((LOG_DEBUG, "pppMain: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); if(pc->linkStatusCB) pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); - - pc->openFlag = 0; } static struct pbuf *pppSingleBuf(struct pbuf *p)
_______________________________________________ lwip-users mailing list lwip-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/lwip-users