--- /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)