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

📄 hdlc.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:

        /* Store the total size, removing the two bytes of the FCS. */
        bytes_left = (_ppp_rx_queue[_ppp_rx_queue_read]->size - PPP_FCS_SIZE_BYTE2);

        /* Determine offset if Address & Control compression is used. */
        if (buffer[0] == 0xff)
            acclen += PPP_MAX_ADDR_CONTROL_SIZE;

        /* Determine offset if Protocol Field compression is used. */
        if (buffer[acclen] == 0x21)
            pfclen += PPP_COMPRESS_HEADER;
        else
            pfclen += PPP_MAX_PROTOCOL_SIZE;

        hdrlen = sizeof(DLAYER) - (acclen + pfclen);
        paylen = NET_PARENT_BUFFER_SIZE - hdrlen;

        /* Allocate a buffer chain to copy this packet into. */
        buf_ptr = MEM_Buffer_Chain_Dequeue (&MEM_Buffer_Freelist,
                ((INT32)(bytes_left + hdrlen)));

        /* Make sure we got some buffers. */
        if (buf_ptr)
        {
            /* Set the total length in the parent buffer. */
            buf_ptr->mem_total_data_len = bytes_left;

            /* Set the data pointer. */
            buf_ptr->data_ptr = (buf_ptr->mem_parent_packet + hdrlen);

            /* Now break this packet into a buffer chain. */

            /* Will it all fit into one buffer? */
            if (bytes_left <= paylen)
            {
                /* Store the number of bytes held by this buffer, this includes the
                   protocol headers. */
                buf_ptr->data_len = buf_ptr->mem_total_data_len;

                /* Copy the data. */
                memcpy  (buf_ptr->data_ptr, buffer, (unsigned int)bytes_left);
            }
            else
            {
                /* Fill the parent buffer in the chain. This one is slightly smaller than
                   the rest in the chain. */
                memcpy (buf_ptr->data_ptr, buffer, (unsigned int)paylen);

                /* Take off the bytes just copied from the total bytes left. */
                bytes_left -= paylen;

                /* Store the number of bytes in this buffer. */
                buf_ptr->data_len = paylen;

                /* Bump it the number of bytes just copied. */
                buffer += paylen;

                /* Get a work buffer pointer to the buffer chain */
                work_buf = buf_ptr;

                /* Break the rest up into the multiple buffers in the chain. */
                do
                {
                    /* Move to the next buffer in the chain */
                    work_buf = work_buf->next_buffer;

                    /* If the bytes left will fit into one buffer then copy them over */
                    if (bytes_left <= NET_MAX_BUFFER_SIZE)
                    {
                        /* Copy the rest of the data. */
                        memcpy (work_buf->mem_packet, buffer, (unsigned int)bytes_left);

                        /* Set the data ptr */
                        work_buf->data_ptr = work_buf->mem_packet;

                        /* Store the number of bytes in this buffer. */
                        work_buf->data_len = bytes_left;

                        /* Update the data bytes left to copy. */
                        bytes_left = 0;

                    }
                    else
                    {
                        /* Copy all that will fit into a single buffer */
                        memcpy (work_buf->mem_packet, buffer, NET_MAX_BUFFER_SIZE);

                        /* Update the buffer pointer */
                        buffer += NET_MAX_BUFFER_SIZE;

                        /* Set the data ptr */
                        work_buf->data_ptr = work_buf->mem_packet;

                        /* Store the number of bytes in this buffer. */
                        work_buf->data_len = NET_MAX_BUFFER_SIZE;

                        /* Update the data bytes left to copy. */
                        bytes_left -= NET_MAX_BUFFER_SIZE;

                    }

                } while ( (bytes_left > 0) &&
                          (bytes_left <=
                          (_ppp_rx_queue[_ppp_rx_queue_read]->size - PPP_FCS_SIZE_BYTE2)) );

            } /* end if it will fit into one buffer */

            /* Remove Address and Control header if it exists. */
            if (acclen)
            {
                buf_ptr->data_ptr += acclen;
                buf_ptr->data_len -= acclen;
                buf_ptr->mem_total_data_len -= acclen;
            }

            /* Set the device that this packet was RX on. */
            buf_ptr->mem_buf_device = _ppp_rx_queue[_ppp_rx_queue_read]->device;

            /* Remove the temp buffer entry. */
            _ppp_rx_queue[_ppp_rx_queue_read] = NU_NULL;

            /* Move the packet onto the buffer list, where the upper
            layer protocols can find it. */
            MEM_Buffer_Enqueue (&MEM_Buffer_List, buf_ptr);

            /* Let the upper layer know a good packet is here. */
            NU_Set_Events(&Buffers_Available, (UNSIGNED)2, NU_OR);
        }
        else
        {
            NERRS_Log_Error (TCP_SEVERE, __FILE__, __LINE__);

            /* Bump the number of packets discarded. */
            ((LINK_LAYER *)_ppp_rx_queue[_ppp_rx_queue_read]->device->
                    link_layer)->silent_discards++;
        }
    }

    /* Bump the index and make sure the ring buffer loops. */
    _ppp_rx_queue_read++;
    _ppp_rx_queue_read %= (UINT8) HDLC_MAX_HOLDING_PACKETS_PTR;

}  /* end PPP_RX_HISR routine */



#ifndef PPP_POLLED_TX
/************************************************************************
* FUNCTION
*
*     PPP_TX_HISR_Entry
*
* DESCRIPTION
*
*     Entry function for transmit HISR. This function is responsible for
*     freeing the buffers used by the transmitted packet. It will also
*     begin transmission of the next packet if there is one ready on the
*     transmit queue.
*
* AUTHOR
*
*     Uriah Pollock
*
* INPUTS
*
*     none
*
* OUTPUTS
*
*     none
*
************************************************************************/
VOID HDLC_TX_HISR_Entry (VOID)
{
    DV_DEVICE_ENTRY *dev_ptr;
    INT old_val;

    /* Get a pointer to the device that activated this HISR. */
    dev_ptr = _ppp_tx_dev_ptr_queue[_ppp_tx_dev_ptr_queue_read];

    /* Make sure there was a device structure there. */
    if (dev_ptr)
    {
        /* Disable interrupts. */
        old_val = NU_Control_Interrupts (NU_DISABLE_INTERRUPTS);

        /* Clear this entry. */
        _ppp_tx_dev_ptr_queue[_ppp_tx_dev_ptr_queue_read] = NU_NULL;

        /* If there is a buffer on the TX queue then remove it. It was just
           transmitted. */
        if (dev_ptr->dev_transq.head != NU_NULL)
        {
            /* Give the buffers held by this packet back to the stack. Note
               that for PPP negotiation packets the deallocation list
               (dlist) for the packet is NU_NULL. This means that the
               packet will not be placed onto any list, which is the
               desired affect since PPP frees these packets itself. */
            if (dev_ptr->dev_transq.head->mem_dlist)
                DEV_Recover_TX_Buffers (dev_ptr);
            else
                MEM_Buffer_Dequeue(&dev_ptr -> dev_transq);

            /* Check to see if there is another packet that needs to be
               sent. */
            if (dev_ptr->dev_transq.head)
            {
                /* Restore the interrupts */
                NU_Control_Interrupts (old_val);

                /* Send the next packet in the tx queue. */
                dev_ptr->dev_start (dev_ptr, dev_ptr->dev_transq.head);
            }
        }

        /* Restore the interrupts */
        NU_Control_Interrupts (old_val);
    }

    /* Bump the read index. */
    _ppp_tx_dev_ptr_queue_read++;

    /* Check for wrap of the ring buffer. */
    _ppp_tx_dev_ptr_queue_read %= (UINT8) HDLC_MAX_TX_QUEUE_PTRS;


}
#endif


/************************************************************************
* FUNCTION
*
*     PPP_Compute_TX_FCS
*
* DESCRIPTION
*
*    This function will compute the frame check sequence for the frame
*    contained at the address pointed to by frame_ptr. The computation of
*    the FCS spans over multiple buffers in the chain containing the
*    packet.
*
* AUTHOR
*
*    Uriah Pollock
*
* INPUTS
*
*    UINT16             fcs             The initial FCS to start with
*    NET_BUFFER         *buf_ptr        Pointer to the buffer that
*                                        holds the packet to be sent.
*
* OUTPUTS
*
*    UINT16                             The computed FCS
*
************************************************************************/
UINT16 HDLC_Compute_TX_FCS (UINT16 fcs, NET_BUFFER *buf_ptr)
{
    NET_BUFFER          *tmp_buf_ptr = buf_ptr;
    INT32               len, bytes_done;
    UINT8       HUGE    *frame_ptr;

    bytes_done = 0;

    /* Get the length of the buffer and a pointer to the data. */
    len         = tmp_buf_ptr->data_len;
    frame_ptr   = tmp_buf_ptr->data_ptr;
    bytes_done += len;

    while (tmp_buf_ptr)
    {
        /* Compute the FCS over the bytes in this buffer. */
        while (len-- > 0)
            fcs = (UINT16) ((fcs >> 8) ^ fcstab[(fcs ^ *frame_ptr++) & 0xff]);

        tmp_buf_ptr = tmp_buf_ptr->next_buffer;

        if (tmp_buf_ptr)
        {
            /* Get the length of the buffer and a pointer to the data. */
            len         = tmp_buf_ptr->data_len;
            frame_ptr   = tmp_buf_ptr->data_ptr;
            bytes_done += len;
        }

    }

    return (fcs);
}

/************************************************************************
* FUNCTION
*
*     PPP_Compute_RX_FCS
*
* DESCRIPTION
*
*     This function will compute the frame check sequence for the frame
*     contained at the address pointed to by frame_ptr. The computaion
*     does not span buffers. It is done over a contiguous area of memory
*     only.
*
* AUTHOR
*
*     Uriah Pollock
*
* INPUTS
*
*     UINT16            fcs             The initial FCS to start with
*     PPP_TEMP_BUFFER   *buf_ptr        Pointer to the packet to
*                                        compute the FCS over.
*
* OUTPUTS
*
*     UINT16                            The computed FCS
*
************************************************************************/
UINT16 HDLC_Compute_RX_FCS (UINT16 fcs, PPP_TEMP_BUFFER *buf_ptr)
{
    UINT32 len;
    UINT8  HUGE *frame_ptr;

    /* Get the length of the buffer and a pointer to the data. */
    len         = buf_ptr->size;
    frame_ptr   = buf_ptr->buffer;

    /* Compute the FCS. */
    while (len--)
        fcs = (UINT16) ((fcs >> 8) ^ fcstab[(fcs ^ *frame_ptr++) & 0xff]);

    return (fcs);

}


















⌨️ 快捷键说明

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