⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pppfsm.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * FILENAME: pppfsm.c
 *
 * Copyright  2000 By InterNiche Technologies Inc. All rights reserved
 *
 *  PPP Finite state machine logic for LCP, IPCP, etc.
 *
 * MODULE: PPP
 *
 * ROUTINES: ppp_inpkt(), ppp_fsm(), ppp_fsm_tmo(), 
 * ROUTINES: ppp_fsm_init(), ppp_sendctl(), ppp_allpktsend(), 
 * ROUTINES: ppp_lower_send(), ppp_lowerup(), ppp_lowerdown(), ppp_open(), 
 * ROUTINES: ppp_close(), ppp_hexdump()
 *
 * PORTABLE: yes
 */


#include "ipport.h"

#ifdef USE_PPP

#include "ppp_port.h"
#include "mppp.h"
#include "ip.h"

#include "minip.h"

#define PPPFSM_DEBUG        0
#if PPPFSM_DEBUG > 0
#include "ZPrint.h"

#endif

M_PPP ppp_list = NULL;      /* master list of PPP links */

extern   int   modem_hangup(LINEP);          /* in modem code */
extern   void  ppp_set_ipaddr(PACKET pkt);   /* in ifppp.c */

/* externally overridable PPP globals */
unsigned ppp_mru = PPP_MRU;
unsigned ppp_mtu = PPP_MTU;
int      ppp_maxnaks = 10;
int      ppp_retry_secs = 3;  /* seconds between retrys */

/* asyncmap is an LCP option for "escaping" bytes with values <32 which
 * might be used for line control (eg. XON/XOFF). A character is escaped if
 * it's bit is set, eg. a map of 0x00000010 means bytes with the value 4
 * will be escaped since the 4th bit is set (01 is the zero-th bit). This mask
 * is used by our LCP to negotiate to force the indicated chars to be
 * escaped.
 */
u_long   allow_asyncmap = 0;


/* PPP received "ECHO" callback routine */
void  (* mppp_echo_callback)(M_PPP mppp, u_char * inp, unsigned plen);


/* FSM table - corrosponds to RFC 1661, pages 11 & 12. Each entry
 * is an x/y coordinate for a particular state and event. The data
 * is a 16 bit value with the state we should transition to in the
 * low nibble and up to three actions to perform in the upper
 * three nibbles. FFFF means no event or no action.
 */

unshort fsm_table[160] =   /* 10 states times 16 events */
{
   /* state 0 (INITIAL) */
/* Up */       2,
/* Down */     0xFFFF,
/* Open */     (AC_TLS << 4) | 1,
/* Close, */   0,
/* TOP */      0xFFFF,
/* TOX */      0xFFFF,
/* RCROK */    0xFFFF,
/* RCRBAD, */  0xFFFF,
/* RCA */      0xFFFF,
/* RCN */      0xFFFF,
/* RTR */      0xFFFF,
/* RTA */      0xFFFF,
/* RUC */      0xFFFF,
/* RXJP */     0xFFFF,
/* RXJC */     0xFFFF,
/* RXR */      0xFFFF,

   /* state 1 (STARTING) */
/* Up */       (AC_IRC << 8) | (AC_SCR << 4) | 6,
/* Down */     0xFFFF,
/* Open */     1,
/* Close, */   (AC_TLF << 4) | 0,
/* TOP */      0xFFFF,
/* TOX */      0xFFFF,
/* RCROK */    0xFFFF,
/* RCRBAD, */  0xFFFF,
/* RCA */      0xFFFF,
/* RCN */      0xFFFF,
/* RTR */      0xFFFF,
/* RTA */      0xFFFF,
/* RUC */      0xFFFF,
/* RXJP */     0xFFFF,
/* RXJC */     0xFFFF,
/* RXR */      0xFFFF,

   /* state 2 (CLOSED) */
/* Up */       0xFFFF,
/* Down */     0,
/* Open */     (AC_IRC << 8) | (AC_SCR << 4) | 6,
/* Close, */   2,
/* TOP */      0xFFFF,
/* TOX */      0xFFFF,
/* RCROK */    (AC_STA << 4) | 2,
/* RCRBAD, */  (AC_STA << 4) | 2,
/* RCA */      (AC_STA << 4) | 2,
/* RCN */      (AC_STA << 4) | 2,
/* RTR */      (AC_STA << 4) | 2,
/* RTA */      2,
/* RUC */      (AC_SCJ << 4) | 2,
/* RXJP */     2,
/* RXJC */     (AC_TLF << 4) | 2,
/* RXR */      2,

   /* state 3 (STOPPED) */
/* Up */       0xFFFF,
/* Down */     (AC_TLF << 4) | 1,   /* RFC1661 says tls/1...typo??? */
/* Open */     3,
/* Close, */   2,
/* TOP */      0xFFFF,
/* TOX */      0xFFFF,
/* RCROK */    (AC_IRC << 12) | (AC_SCR << 8) | (AC_SCA << 4) | 8,
/* RCRBAD, */  (AC_IRC << 12) | (AC_SCR << 8) | (AC_SCN << 4) | 6,
/* RCA */      (AC_STA << 4) | 3,
/* RCN */      (AC_STA << 4) | 3,
/* RTR */      (AC_STA << 4) | 3,
/* RTA */      3,
/* RUC */      (AC_SCJ << 4) | 3,
/* RXJP */     3,
/* RXJC */     (AC_TLF << 4) | 3,
/* RXR */      3,

   /* state 4 (Closing) */
/* Up */       0xFFFF,
/* Down */     0,
/* Open */     5,
/* Close, */   4,
/* TOP */      (AC_STR << 4) | 4,
/* TOX */      (AC_TLF << 4) | 2,
/* RCROK */    4,
/* RCRBAD, */  4,
/* RCA */      4,
/* RCN */      4,
/* RTR */      (AC_STA << 4) | 4,
/* RTA */      (AC_TLF << 4) | 2,
/* RUC */      (AC_SCJ << 4) | 4,
/* RXJP */     4,
/* RXJC */     (AC_TLF << 4) | 2,
/* RXR */      4,

   /* state 5 (Stopping) */
/* Up */       0xFFFF,
/* Down */     1,
/* Open */     5,
/* Close, */   4,
/* TOP */      (AC_STR << 4) | 5,
/* TOX */      (AC_TLF << 4) | 3,
/* RCROK */    5,
/* RCRBAD, */  5,
/* RCA */      5,
/* RCN */      5,
/* RTR */      (AC_STA << 4) | 5,
/* RTA */      (AC_TLF << 4) | 3,
/* RUC */      (AC_SCJ << 4) | 5,
/* RXJP */     5,
/* RXJC */     (AC_TLF << 4) | 3,
/* RXR */      5,

   /* state 6 (REQ-SENT) */
/* Up */       0xFFFF,
/* Down */     1,
/* Open */     6,
/* Close, */   (AC_IRC << 8) | (AC_STR << 4) | 4,
/* TOP */      (AC_SCR << 4) | 6,
/* TOX */      (AC_TLF << 4) | 3,
/* RCROK */    (AC_SCA << 4) | 8,
/* RCRBAD, */  (AC_SCN << 4) | 6,
/* RCA */      (AC_IRC << 4) | 7,
/* RCN */      (AC_IRC << 8) | (AC_SCR << 4) | 6,
/* RTR */      (AC_STA << 4) | 6,
/* RTA */      6,
/* RUC */      (AC_SCJ << 4) | 6,
/* RXJP */     6,
/* RXJC */     (AC_TLF << 4) | 3,
/* RXR */      6,

   /* state 7 (ACK_RCVD) */
/* Up */       0xFFFF,
/* Down */     1,
/* Open */     7,
/* Close, */   (AC_IRC << 8) | (AC_STR << 4) | 4,
/* TOP */      (AC_SCR << 4) | 6,
/* TOX */      (AC_TLF << 4) | 3,
/* RCROK */    (AC_SCA << 8) | (AC_TLU << 4) | 9,
/* RCRBAD, */  (AC_SCN << 4) | 7,
/* RCA */      (AC_SCR << 4) | 6,
/* RCN */      (AC_SCR << 4) | 6,
/* RTR */      (AC_STA << 4) | 6,
/* RTA */      6,
/* RUC */      (AC_SCJ << 4) | 7,
/* RXJP */     6,
/* RXJC */     (AC_TLF << 4) | 3,
/* RXR */      7,

   /* state 8 ACK_SENT) */
/* Up */       0xFFFF,
/* Down */     1,
/* Open */     8,
/* Close, */   (AC_IRC << 8) | (AC_STR << 4) | 4,
/* TOP */      (AC_SCR << 4) | 8,
/* TOX */      (AC_TLF << 4) | 3,
/* RCROK */    (AC_SCA << 4) | 8,
/* RCRBAD, */  (AC_SCN << 4) | 6,
/* RCA */      (AC_IRC << 8) | (AC_TLU << 4) | 9,
/* RCN */      (AC_IRC << 8) | (AC_SCR << 4) | 8,
/* RTR */      (AC_STA << 4) | 6,
/* RTA */      8,
/* RUC */      (AC_SCJ << 4) | 8,
/* RXJP */     8,
/* RXJC */     (AC_TLF << 4) | 3,
/* RXR */      8,

   /* state 9 (OPENED) */
/* Up */       0xFFFF,
/* Down */     (AC_TLD << 4) | 1,
/* Open */     9,
/* Close, */   (AC_TLD << 12) | (AC_IRC << 8) | (AC_STR << 4) | 4,
/* TOP */      0xFFFF,
/* TOX */      0xFFFF,
/* RCROK */    (AC_TLD << 12) | (AC_SCR << 8) | (AC_SCA << 4) | 8,
/* RCRBAD, */  (AC_TLD << 12) | (AC_SCR << 8) | (AC_SCN << 4) | 6,
/* RCA */      (AC_TLD << 8) | (AC_SCR << 4) | 6,
/* RCN */      (AC_TLD << 8) | (AC_SCR << 4) | 6,
/* RTR */      (AC_TLD << 12) | (AC_ZRC << 8) | (AC_STA << 4)| 5,
/* RTA */      9,
/* RUC */      (AC_SCJ << 4) | 9,
/* RXJP */     9,
/* RXJC */     (AC_TLD << 12) | (AC_IRC << 8) | (AC_STR << 4) | 5,
/* RXR */      (AC_SER << 4) | 9,

};


prot_funcs prot_func_tabs[MAX_PPP_PROTS] = {
{
   lcp_resetci,      /* Reset our Configuration Information */
   lcp_addci,        /* Add our Configuration Information */
   lcp_ackci,        /* ACK our Configuration Information */
   lcp_nakci,        /* NAK our Configuration Information */
   lcp_rejci,        /* Reject our Configuration Information */
   lcp_reqci,        /* Request peer's Configuration Information */
   lcp_extcode,      /* Called to handle LCP-specific codes */
   lcp_up,           /* Called when fsm reaches OPENED state */
   lcp_down,         /* Called when fsm leaves OPENED state */
   lcp_starting,     /* Called when we want the lower layer up */
   lcp_finished,     /* Called when we want the lower layer down */
   "LCP"             /* String name of protocol */
},
{
   ipcp_resetci,     /* Reset our Configuration Information */
   ipcp_addci,       /* Add our Configuration Information */
   ipcp_ackci,       /* ACK our Configuration Information */
   ipcp_nakci,       /* NAK our Configuration Information */
   ipcp_rejci,       /* Reject our Configuration Information */
   ipcp_reqci,       /* Request peer's Configuration Information */
   NULL,             /* Called to handle protocol-specific codes */
   ipcp_up,          /* Called when fsm reaches OPENED state */
   ipcp_down,        /* Called when fsm leaves OPENED state */
   ipcp_started,     /* Called when we want the lower layer up */
   ipcp_finished,    /* Called when we want the lower layer down */
   "IPCP"            /* String name of protocol */
},
};


#ifndef NO_CONPRINTF
char *   fsmstate[]  = 
{
   "INITIAL",
   "STARTING",
   "CLOSED",
   "STOPPED",
   "CLOSING",
   "STOPPING",
   "REQSENT",
   "ACKRCVD",
   "ACKSENT",
   "OPENED",
};

char *   codes[]  = 
{
   "FOO",   /* code 0 not used */
   "CONFREQ",  /* code 1... */
   "CONFACK",  /* 2 */
   "CONFNAK",  /* 3 */
   "CONFREJ",  /* 4 */
   "TERMREQ",  /* 5 */
   "TERMACK",  /* 6 */
   "CODEREJ",  /* 7 */
   "PROTREJ",  /* 8 */
   "PECHOREQ", /* 9 */
   "PECHOREP", /* 10 */
   "DISCREQ",  /* 11 */
   "IDENTITY", /* 12 - was "KEEPALIVE" in old RFC */
};
char *   prots[]  =
{
   "LCP",
   "IPCP",
   "AUTH",
};
#endif   /* notdef NO_CONPRINTF */



/* FUNCTION: ppp_inpkt()
 * 
 * input routine for PPP packets. PPP header is pointed to by
 * pkt->nb_prot, length is pkt->nb_plen. This packet is already
 * unescaped and stripped of any HDLC-like stuffed bytes and
 * headers.
 *
 * PARAM1: M_PPP mppp
 * PARAM2: PACKET pkt
 *
 * RETURNS: void
 */

void
ppp_inpkt(M_PPP mppp, PACKET pkt)
{
   u_char * inp;        /* data from received packet */
   u_char   code;       /* FSM packet type */
   int      plen;       /* length of received packet */
   int      hlen;       /* length from PPP header */
   int      err;        /* error holder */
   int      event;      /* event for state machine lookup */
   unsigned pcode;      /* states[] index, 0 for LCP */
   int      reject;
   unshort  proto;      /* protocol of received pkt */
   prot_funcs * pfuncs; /* pointer to protocol function table */

   mppp->bytes_in += pkt->nb_plen;
   mppp->pkts_in++;

   /* see if we need to hexdump received PPP packet */
   //ConPrintf("ppp link %p rcvd:", mppp);
   ppp_hexdump((u_char*)pkt->nb_prot, pkt->nb_plen);

   /* set pointer and length of PPP packet data */
   plen = pkt->nb_plen - 2;   /* Strip 2 byte prot code  */
   inp = (u_char*)pkt->nb_prot + 2;

   /* Switch based on the received protocol. Get a protocol
    * table index for control protocols (LCP, IPCP), or
    * pass data to data protocol handlers (IP, VJ)
    */
   proto = ppp_getshort((u_char*)pkt->nb_prot);
   switch (proto)
   {
      case PPP_LCP:
         #if PPPFSM_DEBUG
         Printu("PPP_LCP\r\n");
	 #endif
         pcode = LCP_STATE;
         break;
      case PPP_IPCP:
         #if PPPFSM_DEBUG
         Printu("PPP_IPCP\r\n");
	 #endif
         pcode = IPCP_STATE;
         break;
#ifdef PPP_VJC				      
      case PPP_VJC_COMP:
         #if PPPFSM_DEBUG
          Printu("PPP_VJC_COMP\r\n");
	  #endif
         /* Make room for VJ routines in front of the received buffer. */
         {
            PACKET bigpkt;
            LOCK_NET_RESOURCE(FREEQ_RESID);
            bigpkt = pk_alloc(pkt->nb_plen + VJC_HDR_OFFSET);
            UNLOCK_NET_RESOURCE(FREEQ_RESID);
            if(!bigpkt)
            {
               //ConPrintf("(%p) pkalloc failed for VJ pkt len %d\n", 
                  //mppp, pkt->nb_plen);
               mppp->io_errors++;
               goto drop;
            }
            bigpkt->nb_prot += VJC_HDR_OFFSET;     /* prepend VJ space */
            bigpkt->nb_plen = pkt->nb_plen;
            MEMCPY((u_char*)bigpkt->nb_prot, (u_char*)pkt->nb_prot, pkt->nb_plen);
            bigpkt->net = pkt->net;
            LOCK_NET_RESOURCE(FREEQ_RESID);
            pk_free(pkt);
            UNLOCK_NET_RESOURCE(FREEQ_RESID);
            pkt = bigpkt;
            inp = (u_char*)pkt->nb_prot + 2;    /* reset input pointer */
            plen = pkt->nb_plen - 2;            /* Strip 2 byte prot code  */
         }
      case PPP_VJC_UNCOMP:
         #if PPPFSM_DEBUG
         Printu("PPP_VJC_UNCOMP\r\n");
	 #endif
         err = vj_uncompress_tcp(&inp, plen, proto, &mppp->sc_comp);
         if(err == 0) 
         {
        //    ConPrintf("(%p) vj_uncompress failed on type %x\n",
           //    mppp, proto);
            mppp->io_errors++;
            LOCK_NET_RESOURCE(FREEQ_RESID);
            pk_free(pkt);
            UNLOCK_NET_RESOURCE(FREEQ_RESID);
            return;
         }
         /* set NEW pointer and length of uncompressed packet. We adjust the 
          * pointer and length down by two bytes to compensate for the logic
          * in PPP_IKP case below.
          */
         pkt->nb_plen = err + 2;        /* returned new length */
         pkt->nb_prot = (char*)inp - 2;
         /* fall into PPP_IP code to deliver packet */
#endif   /* PPP_VJC */
      case PPP_IP:
         #if PPPFSM_DEBUG
         Printu("PPP_IP\r\n");
	 #endif
         mppp->ifp->mib.ifInOctets += pkt->nb_plen;
         pkt->type = htons(0x0800);
         pkt->nb_prot += 2;      /* bump past type to IP header */
         pkt->nb_plen -= 2;
#ifdef NPDEBUG
         if (*(pkt->nb_buff - ALIGN_TYPE) != 'M' ||
             *(pkt->nb_buff + pkt->nb_blen) != 'M')
         {
            dtrap("pppfsm 0\n");
            panic("pktdemux: corrupt pkt");
         }
#endif   /* NPDEBUG */
#ifdef USE_MODEM
         /* On modem lines check the IP addresses and ID of the last 
          * IP packet against those of the last IP packet we sent. If 
          * they all match it means a hung-up modem or looped-back UART. 
          */
         if(mppp->line.lower_type == LN_ATMODEM)
         {
/* (yaxon del) */
#if 0
            struct ip * pip = (struct ip *)(pkt->nb_prot);
            if((pip->ip_src == mppp->last_ip_src) &&
               (pip->ip_dest == mppp->last_ip_dest) &&
               (pip->ip_id == mppp->last_ip_id))
            {
             //  ConPrintf("ppp_inpkt: modem hung up\n");
               #if PPPFSM_DEBUG
               Printu("ppp_inpkt: modem hung up\r\n");
	       #endif
               modem_hangup(&mppp->line);    /* clean this up */
            }
#endif
         }
#endif /* PPP_CHARIO */
         LOCK_NET_RESOURCE(RXQ_RESID);
         putq(&rcvdq, (qp)pkt);
         UNLOCK_NET_RESOURCE(RXQ_RESID);
         SignalPktDemux();
         return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -