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

📄 hdlc.c

📁 PPP协议C语言源程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/************************************************************************
*
*       Copyright (c) 1997-2001 by Accelerated Technology, Inc.
*
*  PROPRIETARY RIGHTS of Accelerated Technology are  involved in
*  the subject matter of this material.  All manufacturing,
*  reproduction, use, and sales rights pertaining to this subject
*  matter are  governed by the license agreement.  The recipient of
*     this software implicitly accepts the terms of the license.
*
*
*************************************************************************

*************************************************************************
* FILE NAME                                     VERSION
*
*     HDLC.C                                      2.4
*
* COMPONENT
*
*     HDLC - High-level Data Link Control Protocol.
*
* DESCRIPTION
*
*     This file contains routines that organize incoming serial
*     characters into Nucleus Net buffers and outgoing Net buffers
*     to serial characters for transmitting.
*
* DATA STRUCTURES
*
*     none
*
* FUNCTIONS
*
*     HDLC_Initialize
*     HDLC_RX_Packet
*     HDLC_TX_Packet
*     HDLC_TX_HISR_Entry
*     HDLC_RX_HISR_Entry
*     HDLC_Compute_TX_FCS
*     HDLC_Compute_RX_FCS
*
* DEPENDENCIES
*
*     nucleus.h
*     target.h
*     nu_ppp.h
*
*
************************************************************************/

#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "ppp/inc/nu_ppp.h"

/* Declarations for the interrupt service routines, tasks, and functions that
are required when interrupts are used. */
NU_HISR                 PPP_RX_HISR;

#ifndef PPP_POLLED_TX
NU_HISR                 PPP_TX_HISR;
#endif

DV_DEVICE_ENTRY         *_ppp_tx_dev_ptr_queue[HDLC_MAX_TX_QUEUE_PTRS];
UINT8                   _ppp_tx_dev_ptr_queue_read;
UINT8                   _ppp_tx_dev_ptr_queue_write;

PPP_TEMP_BUFFER         *_ppp_rx_queue[HDLC_MAX_HOLDING_PACKETS_PTR];
UINT8                   _ppp_rx_queue_read;
UINT8                   _ppp_rx_queue_write;

#ifdef DEBUG_PKT_TRACE
    CHAR debug_rx_buf[PKT_TRACE_SIZE];
    INT  debug_rx_index = 0;
    CHAR debug_tx_buf[PKT_TRACE_SIZE];
    INT  debug_tx_index = 0;
#endif

/* define the lookup table for the frame check sequence computation
   method, 16 bit version. */
   static UINT16 fcstab[256] = {
      0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
      0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
      0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
      0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
      0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
      0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
      0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
      0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
      0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
      0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
      0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
      0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
      0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
      0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
      0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
      0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
      0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
      0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
      0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
      0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
      0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
      0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
      0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
      0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
      0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
      0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
      0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
      0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
      0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
      0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
      0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
      0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
   };



/************************************************************************
* FUNCTION
*
*     HDLC_Initialize
*
* DESCRIPTION
*
*     This function initializes the HDLC layer of the protocol stack.
*     The UART and modem control routines are also initialized from
*     within this function.
*
* AUTHOR
*
*     Uriah Pollock
*
* INPUTS
*
*     DV_DEVICE_ENTRY   *device         Pointer to the device
*                                        structure for the device that
*                                        generated the RX interrupt.
*
* OUTPUTS
*
*     STATUS                            NU_SUCCESS is always returned
*
************************************************************************/
STATUS HDLC_Initialize(DV_DEVICE_ENTRY *dev_ptr)
{
    VOID            *pointer;
    PPP_LAYER       *ppp_layer_ptr;
    STATUS          status;
    NU_LCP_OPTIONS  lcpopts;
    static INT      ppp_open_count = 0;

    /* Only create the HISR once. The same one will be used for all PPP
       links. */
    if (ppp_open_count++ == 0)
    {
        /* Allocate a block of memory for the PPP RX HISR stack. */
        if (NU_Allocate_Memory (&System_Memory,
                            &pointer,
                            PPP_HISR_STACK_SIZE,
                            NU_NO_SUSPEND
                           ) != NU_SUCCESS)
        {
            NERRS_Log_Error (TCP_FATAL, __FILE__, __LINE__);
            return(-1);
        }

        /* Create the HISR. */
        if (NU_Create_HISR (&PPP_RX_HISR, "HDLC_RX",
                        HDLC_RX_HISR_Entry,
                        0, pointer, PPP_HISR_STACK_SIZE) != NU_SUCCESS)
        {
            NERRS_Log_Error (TCP_FATAL, __FILE__, __LINE__);
            return(-1);
        }

#ifndef PPP_POLLED_TX
        /* Allocate a block of memory for the PPP TX HISR stack. */
        if (NU_Allocate_Memory (&System_Memory,
                            &pointer,
                            PPP_HISR_STACK_SIZE,
                            NU_NO_SUSPEND
                           ) != NU_SUCCESS)
        {
            NERRS_Log_Error (TCP_FATAL, __FILE__, __LINE__);
            return(-1);
        }

        /* Create the HISR. */
        if (NU_Create_HISR (&PPP_TX_HISR, "HDLC_TX",
                        HDLC_TX_HISR_Entry,
                        0, pointer, PPP_HISR_STACK_SIZE) != NU_SUCCESS)
        {
            NERRS_Log_Error (TCP_FATAL, __FILE__, __LINE__);
            return(-1);
        }
#endif
    }


    /* init the globals */

#ifndef PPP_POLLED_TX
    _ppp_tx_dev_ptr_queue_read      = 0;
    _ppp_tx_dev_ptr_queue_write     = 0;
#endif

    _ppp_rx_queue_read   = 0;
    _ppp_rx_queue_write  = 0;

    /* Fill in the device */
    dev_ptr->dev_output     = PPP_Output;
    dev_ptr->dev_input      = PPP_Input;
    dev_ptr->dev_start      = HDLC_TX_Packet;
    dev_ptr->dev_receive    = HDLC_RX_Packet;

    /* Set the MTU if it hasn't been set yet, or it is set to
       a higher value. */
    if (dev_ptr->dev_mtu == 0 || dev_ptr->dev_mtu > HDLC_MTU)
        dev_ptr->dev_mtu = HDLC_MTU;

    /* Each link protocol adds a header size to a total for Net to use. */
    dev_ptr->dev_hdrlen     += PPP_MAX_ADDR_CONTROL_SIZE;

    /* Allocate memory for the PPP layer structure. This structure will
       be pointed to by the device structure for this device. */
    if (NU_Allocate_Memory (&System_Memory,
                            (VOID **)&ppp_layer_ptr,
                            sizeof (PPP_LAYER),
                            NU_NO_SUSPEND
                           ) != NU_SUCCESS)
    {
        NERRS_Log_Error (TCP_FATAL, __FILE__, __LINE__);
        return(-1);
    }

    /* Zero out the ppp layer information. */
    UTL_Zero (ppp_layer_ptr, sizeof (PPP_LAYER));

    /* Store the address of the ppp layer structure. */
    dev_ptr->dev_ppp_layer = ppp_layer_ptr;

    /* Assign the type of PPP hardware interface */
    ppp_layer_ptr->itype = PPP_ITYPE_UART | PPP_ITYPE_MODEM;

    /* Store the address of the device structure for the ppp layer. */
    ppp_layer_ptr->dev_ptr = dev_ptr;

    /* Init the connection status. */
    ppp_layer_ptr->connection_status = NU_PPP_DISCONNECTED;

    /* Store MDM layer information. */
    ppp_layer_ptr->init = MDM_Init;
    ppp_layer_ptr->passive = MDM_Wait_For_Client;
    ppp_layer_ptr->connect = MDM_Dial;
    ppp_layer_ptr->disconnect = MDM_Hangup;

    /* Initialize the MODEM module. */
    if(MDM_Init(dev_ptr) != NU_SUCCESS)
        return(-1);

    /* Initialize the UART. */
    if (URT_Init_Port(dev_ptr) != NU_SUCCESS)
        return (-1);

    /* Initialize upper PPP layer for this device. */
    status = PPP_Initialize(dev_ptr);
    if (status == NU_SUCCESS)
    {
        /* Set LCP and NCP link options for this link. */
        lcpopts.magic_number               = HDLC_DEFAULT_MAGIC_NUMBER;
        lcpopts.accm                       = HDLC_LOCAL_DEFAULT_ACCM;
        lcpopts.max_rx_unit                = (UINT16)dev_ptr->dev_mtu;
        lcpopts.authentication_protocol    = LCP_DEFAULT_AUTH_PROTOCOL;
        lcpopts.protocol_field_compression = HDLC_DEFAULT_PROTOCOL_COMPRESS;
        lcpopts.address_field_compression  = HDLC_DEFAULT_ADDRESS_COMPRESS;
        lcpopts.use_accm                   = HDLC_USE_ACCM;
        lcpopts.use_max_rx_unit            = HDLC_USE_MRU;
        lcpopts.Initial_max_rx_unit        = (UINT16)dev_ptr->dev_mtu;
        lcpopts.Initial_accm               = HDLC_LOCAL_DEFAULT_ACCM;
        lcpopts.Initial_magic_number       = HDLC_DEFAULT_MAGIC_NUMBER;

        status = PPP_Set_Link_Options (dev_ptr->dev_net_if_name, 
                                        &lcpopts, NU_NULL);
    }

    return status;
} /* HDLC_Initialize */



/************************************************************************
* FUNCTION
*
*     HDLC_RX_Packet
*
* DESCRIPTION
*
*     This function is called from the LISR whenever a
*     character receive interrupt occurs.  It reads the received character
*     from the UART and adds it to the buffer.  When a complete packet has
*     been received the HISR will be activated to notify the upper layer
*     software that a packet has arrived.
*
* AUTHOR
*
*     Uriah Pollock
*
* INPUTS
*
*     DV_DEVICE_ENTRY   *device         Pointer to the device
*                                        structure for the device that
*                                        generated the RX interrupt.
*
* OUTPUTS
*
*     STATUS                            NU_SUCCESS is always returned
*
************************************************************************/
STATUS HDLC_RX_Packet (DV_DEVICE_ENTRY *device)
{
    LINK_LAYER      *link_layer;
    UINT8           c;

    /* Get a pointer to the PPP link layer structure. */
    link_layer = (LINK_LAYER *)device->dev_ppp_layer;

    c = URT_Get_Char(&link_layer->uart);

    /* Was the previous character received an escape character. */
    /* The character following the escape needs to be replaced with
       its XOR value. */
    if (link_layer->esc_received)
    {
        switch(c)
        {
            case (PPP_HDLC_FRAME ^ PPP_HDLC_TRANSPARENCY):

                if (link_layer->received < PPP_MAX_RX_SIZE)
                {
                    link_layer->rx_ring[link_layer->rx_ring_write].buffer[link_layer->received++]
                                                = PPP_HDLC_FRAME;

#ifdef DEBUG_PKT_TRACE
                    if (debug_rx_index == PKT_TRACE_SIZE)
                        debug_rx_index = 0;

                    debug_rx_buf[debug_rx_index++] = PPP_HDLC_FRAME;
#endif
                }

                break;

            case (PPP_HDLC_CONTROL_ESCAPE ^ PPP_HDLC_TRANSPARENCY):

⌨️ 快捷键说明

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