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

Reply via email to