📄 hdlc.c
字号:
/************************************************************************
*
* 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 + -