📄 hdlc.c
字号:
if (link_layer->received < PPP_MAX_RX_SIZE)
{
link_layer->rx_ring[link_layer->rx_ring_write].buffer[link_layer->received++]
= PPP_HDLC_CONTROL_ESCAPE;
#ifdef DEBUG_PKT_TRACE
if (debug_rx_index == PKT_TRACE_SIZE)
debug_rx_index = 0;
debug_rx_buf[debug_rx_index++] = PPP_HDLC_CONTROL_ESCAPE;
#endif
}
break;
default:
if (link_layer->received < PPP_MAX_RX_SIZE)
{
link_layer->rx_ring[link_layer->rx_ring_write].buffer[link_layer->received++]
= ( c ^PPP_HDLC_TRANSPARENCY);
#ifdef DEBUG_PKT_TRACE
if (debug_rx_index == PKT_TRACE_SIZE)
debug_rx_index = 0;
debug_rx_buf[debug_rx_index++] = (c ^ PPP_HDLC_TRANSPARENCY);
#endif
}
break;
}
/* Reset the escape received flag. */
link_layer->esc_received = NU_FALSE;
}
/* This is either just another character or its the end of the
frame. */
else
{
switch (c)
{
/* If it's an END character, then we're done with the packet. */
case PPP_HDLC_FRAME:
/* A minor optimization: If there is no data in the packet,
ignore it. This is meant to avoid bothering IP with all the
empty packets generated by the duplicate END characters which
are in Serial Line IP.
*/
if(link_layer->received)
{
/* Store the length of this packet and a pointer to it for
the HISR */
/* Store the device for this interrupt. */
link_layer->rx_ring[link_layer->rx_ring_write].device = device;
/* Update the length of current buffer. */
link_layer->rx_ring[link_layer->rx_ring_write].size = link_layer->received;
/* Add this packet to the HISR's packet pointer list. Make
sure there is room first. We must also check for looping
of the write pointer. */
if ((_ppp_rx_queue_write + 1) >= HDLC_MAX_HOLDING_PACKETS_PTR)
{
/* This is the case if it does wrap. */
if (_ppp_rx_queue_read != 0)
{
_ppp_rx_queue[_ppp_rx_queue_write] =
&link_layer->rx_ring[link_layer->rx_ring_write++];
/* Wrap the HISR write pointer. */
_ppp_rx_queue_write = 0;
/* Activate the HISR. The HISR will inform the upper layer
protocols that a packet has arrived. */
NU_Activate_HISR (&PPP_RX_HISR);
}
else
NERRS_Log_Error (TCP_SEVERE, __FILE__, __LINE__);
}
else
{
/* This is the case if it doesn't wrap */
if ((_ppp_rx_queue_write + 1) != _ppp_rx_queue_read)
{
_ppp_rx_queue[_ppp_rx_queue_write++] =
&link_layer->rx_ring[link_layer->rx_ring_write++];
/* Activate the HISR. The HISR will inform the upper layer
protocols that a packet has arrived. */
NU_Activate_HISR (&PPP_RX_HISR);
}
else
NERRS_Log_Error (TCP_SEVERE, __FILE__, __LINE__);
}
/* Make sure the LISR index wraps around if needed. */
link_layer->rx_ring_write %= (UINT8) HDLC_MAX_HOLDING_PACKETS;
/* Reset the number of bytes received. */
link_layer->received = 0;
}
break;
case PPP_HDLC_CONTROL_ESCAPE:
/* Set the escape received flag. */
link_layer->esc_received = NU_TRUE;
break;
default:
if (link_layer->received < PPP_MAX_RX_SIZE)
{
/* Store the char if we are under our MTU and if the char
is not one that is supposed to be control escaped. */
if (c < PPP_MAX_ACCM)
{
if (!(PPP_Two_To_Power(c) & (((LINK_LAYER *)device->link_layer)
->lcp.local_options.accm)))
{
#ifdef DEBUG_PKT_TRACE
if (debug_rx_index == PKT_TRACE_SIZE)
debug_rx_index = 0;
debug_rx_buf [debug_rx_index++] = c;
#endif
link_layer->rx_ring[link_layer->rx_ring_write].buffer[link_layer->received++] = c;
}
}
else
{
link_layer->rx_ring[link_layer->rx_ring_write].buffer[link_layer->received++] = c;
}
}
break;
}
}
return (NU_SUCCESS);
} /* end PPP_Receive */
/************************************************************************
* FUNCTION
*
* PPP_TX_Packet
*
* DESCRIPTION
*
* This function will send the PPP packet. This includes adding the
* correct PPP header and computing the Frame Check Sequence over the
* packet.
*
* AUTHOR
*
* Uriah Pollock
*
* INPUTS
*
* DEV_DEVICE_ENTRY *device Pointer to device structure for
* the device to send the packet
* over.
* NET_BUFFER *buf_ptr Pointer to the buffer that
* holds the packet to be sent.
*
* OUTPUTS
*
* STATUS NU_SUCCESS is always returned
*
************************************************************************/
STATUS HDLC_TX_Packet (DV_DEVICE_ENTRY *device, NET_BUFFER *buf_ptr)
{
NET_BUFFER *tmp_buf_ptr = buf_ptr;
URT_LAYER *uart;
LCP_LAYER *lcp;
IPCP_LAYER *ipcp;
UINT16 frame_check, pkt_type;
UINT8 HUGE *ppp_header_ptr;
INT16 length;
UINT8 more_to_send = NU_TRUE;
/* Get the uart stucture for this device. */
uart = &((LINK_LAYER *)device->link_layer)->uart;
/* Get the LCP stucture for this device. */
lcp = &((LINK_LAYER *)device->link_layer)->lcp;
/* Get the IPCP stucture for this device. */
ipcp = &((LINK_LAYER *)device->link_layer)->ipcp;
/* Get the type of packet we are encapsulating. */
if (buf_ptr->mem_flags & NET_IP)
pkt_type = PPP_IP_PROTOCOL;
else
if (buf_ptr->mem_flags & NET_LCP)
pkt_type = PPP_LINK_CONTROL_PROTOCOL;
else
if (buf_ptr->mem_flags & NET_IPCP)
pkt_type = PPP_IP_CONTROL_PROTOCOL;
else
if (buf_ptr->mem_flags & NET_PAP)
pkt_type = PPP_PAP_PROTOCOL;
else
if (buf_ptr->mem_flags & NET_CHAP)
pkt_type = PPP_CHAP_PROTOCOL;
else
return NU_PPP_INVALID_PROTOCOL;
/* Add the PPP protocol header. */
if ((lcp->state == OPENED) && (ipcp->state == OPENED)
&& (buf_ptr->mem_flags & NET_IP) &&
(lcp->foreign_options.protocol_field_compression == NU_TRUE))
{
/* Make room for the PPP header and adjust the lengths */
buf_ptr->data_ptr -= PPP_COMPRESS_HEADER;
buf_ptr->data_len += PPP_COMPRESS_HEADER;
buf_ptr->mem_total_data_len += PPP_COMPRESS_HEADER;
/* Add the packet type in MSB LSB order. */
buf_ptr->data_ptr[0] = (UINT8)pkt_type;
}
else
{
/* Since we are not in the opened state we must be sending
configure pkts, none of these are compressed. */
buf_ptr->data_ptr -= PPP_MAX_PROTOCOL_SIZE;
buf_ptr->data_len += PPP_MAX_PROTOCOL_SIZE;
buf_ptr->mem_total_data_len += PPP_MAX_PROTOCOL_SIZE;
/* Add the packet type in MSB LSB order. */
PUT16 (buf_ptr->data_ptr, 0, pkt_type);
}
/* Add the PPP address and control field header. */
if (!((lcp->state == OPENED) && (ipcp->state == OPENED)
&& (buf_ptr->mem_flags & NET_IP) &&
(lcp->foreign_options.address_field_compression == NU_TRUE)))
{
/* Make room for the HDLC header and adjust the lengths */
buf_ptr->data_ptr -= PPP_MAX_PROTOCOL_SIZE;
buf_ptr->data_len += PPP_MAX_PROTOCOL_SIZE;
buf_ptr->mem_total_data_len += PPP_MAX_PROTOCOL_SIZE;
/* Add the HDLC header info. */
buf_ptr->data_ptr[0] = PPP_HDLC_ADDRESS;
buf_ptr->data_ptr[1] = PPP_HDLC_CONTROL;
}
/* Now compute the FCS. */
frame_check = HDLC_Compute_TX_FCS (PPP_INIT_FCS16, buf_ptr);
frame_check ^= 0xffff; /* get the complement */
#ifdef PPP_POLLED_TX
/* Send a FLAG character to flush out any characters the remote host might
have received because of line noise and to mark the begining of this
PPP HDLC frame. */
URT_Put_Char (PPP_HDLC_FRAME, uart);
#endif
/* Loop through all the buffers in the chain and send out each byte. */
while (more_to_send)
{
/* Get the length so that we can loop through the packet and send out
each byte. */
length = (UINT16) tmp_buf_ptr->data_len;
/* Get a pointer to the data. */
ppp_header_ptr = tmp_buf_ptr->data_ptr;
/* Now loop through the encapsulated packet and send it out */
while(length-- > 0)
{
switch((CHAR)*ppp_header_ptr)
{
/* If it's the same code as a FRAME character, then send the special
two character code so that the receiver does not think we sent
a FRAME.
*/
case PPP_HDLC_FRAME:
#ifdef DEBUG_PKT_TRACE
if (debug_tx_index == PKT_TRACE_SIZE)
debug_tx_index = 0;
debug_tx_buf [debug_tx_index++] = (PPP_HDLC_FRAME);
#endif
#ifdef PPP_POLLED_TX
URT_Put_Char(PPP_HDLC_CONTROL_ESCAPE, uart);
URT_Put_Char(PPP_HDLC_FRAME ^ PPP_HDLC_TRANSPARENCY, uart);
#else
/* Store the byte. */
uart->tx_buffer[uart->tx_buffer_write++] = PPP_HDLC_CONTROL_ESCAPE;
/* Check for wrapping of the write pointer. */
uart->tx_buffer_write %= (UINT16) URT_TX_BUFFER_SIZE;
/* Store the byte. */
uart->tx_buffer[uart->tx_buffer_write++] = (PPP_HDLC_FRAME ^ PPP_HDLC_TRANSPARENCY);
/* Check for wrapping of the write pointer. */
uart->tx_buffer_write %= (UINT16) URT_TX_BUFFER_SIZE;
#endif
break;
/* If it's the same code as an ESC character, then send the special
two character code so that the receiver does not think we sent
an ESC.
*/
case PPP_HDLC_CONTROL_ESCAPE:
#ifdef DEBUG_PKT_TRACE
if (debug_tx_index == PKT_TRACE_SIZE)
debug_tx_index = 0;
debug_tx_buf [debug_tx_index++] = PPP_HDLC_CONTROL_ESCAPE;
#endif
#ifdef PPP_POLLED_TX
URT_Put_Char(PPP_HDLC_CONTROL_ESCAPE, uart);
URT_Put_Char(PPP_HDLC_CONTROL_ESCAPE ^ PPP_HDLC_TRANSPARENCY, uart);
#else
/* Store the byte. */
uart->tx_buffer[uart->tx_buffer_write++] = PPP_HDLC_CONTROL_ESCAPE;
/* Check for wrapping of the write pointer. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -