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

📄 p16_ppp.c

📁 16位单片机上的TCP/IP协议和WEB服务器
💻 C
📖 第 1 页 / 共 3 页
字号:
        {
            hostip.l = myip.l + 1;              // ..give host my IP addr + 1
            ipcp_event_handler(EVENT_RCR_ERR);  // (for want of anthing else)
            if (ipcp_action & SCN)
            {                                   // If OK to NAK, do so
                put_byte(IPCP_OPT_ADDR);
                put_byte(6);
                put_lword(&hostip);             // ..with new address as hint
                send_ppp(PPP_CFG_NAK, ppp_rxid, 1);
            }
        }
        else                                    // If options OK..
        {
            ipcp_event_handler(EVENT_RCR_OK);
            if (ipcp_action & SCA)              // ..and OK to send, do so
            {
                put_byte(IPCP_OPT_ADDR);
                put_byte(6);
                put_lword(&hostip);
                send_ppp(PPP_CFG_ACK, ppp_rxid, 1);
            }
        }
    }
    else if (ppp_code == PPP_CFG_NAK)           // If NAK received..
    {                                           // ..and IP address hint..
        if (match_byte(IPCP_OPT_ADDR) && match_byte(6))
            get_lword(&myip);                   // ..use it for my address
        ipcp_event_handler(EVENT_RCN);
    }                                           // Others to state machine..
    else if (ppp_code == PPP_TERM_REQ)          // ..terminate Request
        ipcp_event_handler(EVENT_RTR);
    else if (ppp_code == PPP_CFG_ACK)           // ..config ACK
        ipcp_event_handler(EVENT_RCA);
    else if (ppp_code == PPP_TERM_ACK)          // ..terminate ACK
        ipcp_event_handler(EVENT_RTA);
    do_ipcp_actions();
}

/* Handle an IPCP event */
void ipcp_event_handler(BYTE event)
{
    BYTE newstate, state;

    ppp_pcol = PPP_IPCP;
    state = newstate = ipcp_state & 0xf;        // Get new state & action
    if (state<=PPP_STOPPED || state==PPP_OPENED)
        ipcp_reqs = ipcp_terms = 0;
    if (state<=PPP_OPENED && event<=EVENT_RXJ_ERR)
    {
        newstate = lcp_states[event][state];
        ipcp_action = lcp_actions[event][state];
        if (ipcp_action & SCR)                  // Send config req?
        {
            if (ipcp_reqs >= MAX_REQS)          // Error if too many requests
            {
                newstate = lcp_states[EVENT_TO_ERR][state];
                ipcp_action = lcp_actions[EVENT_TO_ERR][state];
            }
            ipcp_reqs++;
        }
        if (ipcp_action & STR)                  // Send terminate req?
        {
            if (ipcp_terms >= MAX_TERMS)        // Error if too many requests
            {
                newstate = lcp_states[EVENT_TO_ERR][state];
                ipcp_action = lcp_actions[EVENT_TO_ERR][state];
            }
            ipcp_terms++;
        }
    }
#if DEBUG_IPCP
    serial_putch(newstate & 0xf);
#endif
    if (newstate != XXX)
    {
        ipcp_state = newstate;                  // Set new state
    }
}

/* Do the IPCP actions (all except config ACK/NAK) */
void do_ipcp_actions(void)
{
    ppp_pcol = PPP_IPCP;
    if (ipcp_action & SCR)                      // Send config request?
    {
        init_txbuff(0);
        setpos_txin(PPP_HEADLEN);
        put_byte(IPCP_OPT_ADDR);
        put_byte(6);
        put_lword(&myip);
        send_ppp(PPP_CFG_REQ, ++ppp_txid, 1);
    }                                           // Send terminate request?
    if (ipcp_action & STR)
        send_ppp(PPP_TERM_REQ, ppp_txid, 0);
    if (ipcp_action & STA)                      // Send terminate ACK?
        send_ppp(PPP_TERM_ACK, ppp_rxid, 0);
    if (ipcp_action & SCJ)                      // Send code reject?
        send_ppp(PPP_CODE_REJ, ppp_txid, 0);
    if (ipcp_action & IRC)                      // Init restart count?
        ipcp_rest = ipcp_action & STR ? MAX_TERMS : MAX_REQS;
    if (ipcp_action & ZRC)                      // Zero restart count?
        ipcp_rest = 0;
}

/* Rx handler for Password Authentication Protocol */
void pap_rx_handler(void)
{
    ppp_pcol = PPP_PAP;
    if (ppp_code == PPP_CFG_REQ)                // Config request?
    {                                           // (incoming authentication)
        if (match_data(serverid, strlen(serverid)))
        {
            send_ppp(PPP_CFG_ACK, ppp_rxid, 0); // ACK if ID and password OK
            pap_event_handler(EVENT_RCR_OK);
        }
        else
        {
            send_ppp(PPP_CFG_NAK, ppp_rxid, 0); // NAK if wrong
            pap_event_handler(EVENT_RCR_ERR);
        }
    }
    else if (ppp_code == PPP_CFG_ACK)           // Config ACK, client auth OK
        pap_event_handler(EVENT_RCA);
    else if (ppp_code == PPP_CFG_NAK)           // Config NAK, client auth fail
        pap_event_handler(EVENT_RCN);
}

/* Handle an PAP event */
void pap_event_handler(BYTE event)
{
    ppp_pcol = PPP_PAP;
    init_txbuff(0);                             // PAP layer up, or timeout?
    if (event == EVENT_UP || event==EVENT_TO_OK)
    {
        if (client_auth)                        // If client authentication..
        {
            setpos_txin(PPP_HEADLEN);           // ..send ID and password
            put_byte(strlen(clientname));
            put_ser(clientname);
            put_byte(strlen(clientpass));
            put_ser(clientpass);
            send_ppp(PPP_CFG_REQ, ppp_txid, 1);
        }
    }
    else if (event == EVENT_RCR_OK)             // Received config req
        server_auth_ok = 1;
    else if (event == EVENT_RCA)                // ..or config ACK
        client_auth_ok = 1;
    if ((!client_auth || client_auth_ok) && (!server_auth || server_auth_ok))
    {
        ipcp_event_handler(EVENT_UP);           // If authentication OK
        do_ipcp_actions();                      // ..start up IPCP
    }
}

/* Put a PPP header in the Tx buffer and transmit the frame */
void send_ppp(BYTE code, BYTE id, BYTE withdata)
{
    if (withdata)
        setpos_txin(0);
    else
        init_txbuff(0);
    put_byte(code);
    put_byte(id);
    if (withdata)
    {
        save_txbuff();
        put_word(net_txlen);
    }
    else
        put_word(4);
    save_txbuff();
    transmit();
}

/* Put out a byte using PPP escape codes, update the CRC */
void send_ppp_byte(BYTE b)
{
    poll_net();
    if (b==PPP_END || b==PPP_ESC || b<0x20)
    {
        serial_putch(PPP_ESC);
        poll_net();
        serial_putch(b ^ 0x20);
    }
    else
        serial_putch(b);
    poll_net();
    txcrc = ppp_crc16(txcrc, b);
}

/* Transmit the PPP frame */
void transmit(void)
{
    WORD n;
    BYTE hi, lo;

    txcrc = 0xffff;
    serial_putch(PPP_END);                  // Start flag
    send_ppp_byte(0xff);                    // HDLC address
    send_ppp_byte(3);                       // ..and control byte
    send_ppp_byte((BYTE)(ppp_pcol >> 8));   // PPP protocol word
    send_ppp_byte((BYTE)ppp_pcol);
#if NET_TXBUFFERS > 1                       // If more than 1 Tx buffer
    txbuff_lens[txbuffnum] = net_txlen;     // ..save Tx length
#endif
    for (n=0; n<net_txlen; n++)             // Transmit PPP data
#if NET_TXBUFFERS > 1
    {
        if (txbuffnum)
            send_ppp_byte(txbuff2[n]);
        else
            send_ppp_byte(txbuff[n]);
    }
#else
        send_ppp_byte(txbuff[n]);
#endif
    hi = ~ (BYTE)(txcrc >> 8);              // Append CRC
    lo = ~ (BYTE)txcrc;
    send_ppp_byte(lo);
    send_ppp_byte(hi);
    serial_putch(PPP_END);                  // End flag
}
#if NET_TXBUFFERS > 1
/* Retransmit the Ethernet frame */
void retransmit(BYTE buffnum)
{
    txbuffnum = buffnum;
    net_txlen = txbuff_lens[txbuffnum];
    transmit();
}
#endif

/* Poll the serial interface for Rx and Tx characters */
void poll_net(void)
{
    BYTE b, saver=1;
    static BYTE lastb=0, pluscount=0;
    static WORD crc;

    if (serial_kbhit())                     // Incoming serial byte?
    {
        b = serial_getch();
        if (lastb == PPP_ESC)               // Last char was Escape?
        {
            lastb = 0;
            b ^= 0x20;
        }
        else if (b == PPP_ESC)              // This char is Escape?
        {
            lastb = PPP_ESC;
            saver = 0;
        }
        else if (b == PPP_END)              // No escape; maybe End?
        {
            if (inframe)                    // If currently in a frame..
            {                               // Check CRC & save length
                if (crc==0xf0b8  && rxbuffin>2)
                    net_rxin = rxbuffin - 2;
                inframe = saver = 0;
            }
            else
                saver = 0;
            rxbuffin = 0;
        }
        if (!inframe)                       // If not in PPP frame..
        {
            if (b == PPP_START)             // ..check for start of frame
            {
                crc = 0xffff;
                rxbuffin = 0;
                inframe = 1;
            }
            else if (b=='\r' || b=='\n')    // ..or control char
            {
                mdm_rxin = rxbuffin;
                saver = rxbuffin = pluscount = 0;
            }                               // ..or 'CONNECT'
            else if (rxbuff[0]== 'C' && rxbuffin==5 && b=='T')
            {
                mdm_rxin = rxbuffin;
                saver = rxbuffin = pluscount = 0;
            }
            else if (b=='+')                // ..or '+++'
            {
                if (++pluscount >= 3)
                {
                    mdm_rxin = rxbuffin;
                    saver = rxbuffin = pluscount = 0;
                }
            }
            else
                pluscount = 0;
        }
        if (saver)                          // If saving the new byte
        {
            if (inframe)
                crc = ppp_crc16(crc, b);    // ..do CRC as well
            if (rxbuffin < RXBUFFLEN)
            {
                rxbuff[rxbuffin] = b;
                rxbuffin++;
            }
        }
    }
}

/* Return new PPP CRC value, given previous CRC value and new byte */
WORD ppp_crc16(WORD crc, BYTE b)
{
    BYTE i;

    for (i=0; i<8; i++)
    {
        if ((crc ^ b) & 1)
            crc = (crc >> 1) ^ 0x8408;
        else
            crc >>= 1;
        b >>= 1;
    }
    return(crc);
}

/* EOF */

⌨️ 快捷键说明

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