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

📄 ppp.c

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

    } /* end while there are more ports to check and
         we have not already failed. */


    return (ret_status);

}

/************************************************************************
* FUNCTION
*
*     PPP_Still_Connected
*
* DESCRIPTION
*
*     Checks the state of the PPP link and returns TRUE if it is still
*     open. FALSE if it is not open.
*
* AUTHOR
*
*     Uriah Pollock
*
* INPUTS
*
*     CHAR              *link_name      Pointer to the PPP link name.
*
* OUTPUTS
*
*     STATUS                            Is the link open or not
*
************************************************************************/
STATUS PPP_Still_Connected (CHAR *link_name)
{
    DV_DEVICE_ENTRY *dev_ptr;
    LCP_LAYER       *lcp;
    STATUS          ret_status;

    /* Find the device that we want to hangup. */
    dev_ptr = DEV_Get_Dev_By_Name (link_name);

    /* Make sure a device was found and that it is a PPP device. */
    if ((dev_ptr) && (dev_ptr->dev_type == DVT_PPP))
    {

        /* Grab a pointer to the LCP layer stucture. */
        lcp = &((LINK_LAYER *)dev_ptr->link_layer)->lcp;

        if ((lcp->state == INITIAL) || (lcp->state == STARTING))
            ret_status = NU_FALSE;
        else
            ret_status = NU_TRUE;

    }
    else
        ret_status = NU_INVALID_LINK;

    return (ret_status);
}




/************************************************************************
* FUNCTION
*
*     PPP_Two_To_Power
*
* DESCRIPTION
*
*     Raises two to the power of the passed in variable. This function
*     is used instead of POW so that math and floating point libraries
*     do not have to be linked in.
*
* AUTHOR
*
*     Uriah Pollock
*
* INPUTS
*
*     UINT8             exponent        The exponent to raise two too
*
* OUTPUTS
*
*     UINT32                            The computed power
*
************************************************************************/
UINT32 PPP_Two_To_Power (UINT8 exponent)
{
    UINT32  answer;

#ifdef NU_NON_REENTRANT_CLIB
    INT     old_state;
#endif

    answer = PPP_ONE;

    /* Make sure the exponent is not zero */
    if (exponent != 0)
    {
        /* The bit shifting operation below has been seen to cause
           problems with non-reentrant C library's. To fix this
           turn interrupts off so that the PPP LISR does not
           interrupt the shift operation. */
#ifdef NU_NON_REENTRANT_CLIB
        old_state = NU_Control_Interrupts (NU_DISABLE_INTERRUPTS);
#endif

        answer <<= (UINT32) exponent;

#ifdef NU_NON_REENTRANT_CLIB
        NU_Control_Interrupts (old_state);
#endif
    }

    return (answer);
}





/************************************************************************
* FUNCTION
*
*     PPP_Output
*
* DESCRIPTION
*
*     Makes sure that the device is active and calls the transmit routine
*     for the device. Then deallocates the buffer to the appropriate list.
*
* AUTHOR
*
*     Uriah Pollock
*
* INPUTS
*
*     NET_BUFFER        *buf_ptr        Pointer to the packet buffer of
*                                        the packet to send.
*     DV_DEVICE_ENTRY   *device         Pointer to the device to send
*                                        the packet over.
*     SCK_SOCKADDR_IP   *dest           Not used by this routine. Only
*                                        included in order to comply
*                                        with NET 4.0.
*     RTAB_ROUTE        *ro             Not used by this routine. Only
*                                        included in order to comply
*                                        with NET 4.0.
*
* OUTPUTS
*
*     STATUS                            Was the packet sent?
*
************************************************************************/
STATUS PPP_Output (NET_BUFFER *buf_ptr, DV_DEVICE_ENTRY *device,
                SCK_SOCKADDR_IP *dest, RTAB_ROUTE *ro)
{
    STATUS  ret_status;

#ifndef PPP_POLLED_TX
    INT     old_val;
#endif

    /* Remove warnings. */
    UNUSED_PARAMETER(dest);
    UNUSED_PARAMETER(ro);

    /* Verify that the device is up and that this buffer is not an IP
       packet. If its not an IP packet then it is a PPP negotiation packet,
       in which case we do not care that the device is not up and running.
       That is what this packet is trying to accomplish. */
    if ( ((device->dev_flags & (DV_UP | DV_RUNNING)) != (DV_UP | DV_RUNNING) )
                && (buf_ptr->mem_flags & NET_IP))
        ret_status = NU_HOST_UNREACHABLE;

    else    /* send the packet */
    {

        /* Check if the packet to be sent is IP data.  If it is, update
           the last_activity_time variable which maintains the time
           of the last IP activity through the PPP link. */
        if (buf_ptr->mem_flags & NET_IP)
        {
           ((PPP_LAYER *)device->link_layer)->last_activity_time =
                NU_Retrieve_Clock();
        }

#ifndef PPP_POLLED_TX
        /* Disable interrupts. */
        old_val = NU_Control_Interrupts (NU_DISABLE_INTERRUPTS);

        /* Put this packet onto the TX queue. */
        MEM_Buffer_Enqueue (&device->dev_transq, buf_ptr);

        /* Bump up the counter. */
        device->dev_transq_length++;

        /* If the packet just added to the TX queue is the only one in the
           queue then send it. */
        if (device->dev_transq.head == buf_ptr)
        {
            /* Restore interrupt state */
            NU_Control_Interrupts (old_val);
#endif
            /* Send the packet */
            ret_status = device->dev_start (device, buf_ptr);

#ifndef PPP_POLLED_TX
        }
        else
        {
            /* Restore interrupt state */
            NU_Control_Interrupts (old_val);

            /* Set the status */
            ret_status = NU_SUCCESS;
        }
#endif

        /* Otherwise this packet will get sent by TX interrupts. */
    }

#ifdef PPP_POLLED_TX

    /* Add it to the buffer list for this buffer. If the dlist
       is NULL then this buffer is a PPP control packet. We
       do not free these buffers because they are retranmitted and
       freed up later by PPP. */
    if ((ret_status == NU_SUCCESS) && (buf_ptr->mem_dlist != NU_NULL))
        MEM_One_Buffer_Chain_Free (buf_ptr, buf_ptr->mem_dlist);

#endif

    return (ret_status);

}





/************************************************************************
* FUNCTION
*
*     PPP_Input
*
* DESCRIPTION
*
*     This function pulls the first packet off of the incoming packet
*     list and calls the correct protocol routine to handle the
*     encapsulated packet.
*
* AUTHOR
*
*     Uriah Pollock
*
* INPUTS
*
*     none
*
* OUTPUTS
*
*     STATUS                            NU_SUCCESS
*
************************************************************************/
STATUS PPP_Input (VOID)
{
    LCP_LAYER   *lcp_ptr;
    IPCP_LAYER  *ipcp_ptr;
    UINT8       *ppp_compress_protocol;
    UINT16      ppp_protocol;
    UINT32      *last_activity_time;

    /* Set up a pointer to the last_activity_time variable which maintains
       the time of the last IP activity through the PPP link. */
    last_activity_time = &(((PPP_LAYER *)MEM_Buffer_List.head->
        mem_buf_device->link_layer)->last_activity_time);

    /* Get a pointer to the head of the packet. */
    ppp_compress_protocol = (UINT8 *)MEM_Buffer_List.head->data_ptr;

    /* Now we must check to make sure it is a valid packet before
       it is passed on to get interpreted. The only compression checked
       for here is the PPP protocol. For the first check we will assume
       compression is turned on. */

    /* Assume the protocol field is compressed, this will be the
       case most of the time. */
    switch (*ppp_compress_protocol)
    {
        case PPP_IP_COMPRESS_PROTOCOL   :

            /* Get a pointer to the LCP and IPCP layers */
            lcp_ptr = &((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->lcp;
            ipcp_ptr = &((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->ipcp;

            /* Only allow IP packets if LCP and NCP are in the open state 
               and the device is up. */
            if ( (lcp_ptr->state == OPENED) && (ipcp_ptr->state == OPENED) &&
                (MEM_Buffer_List.head->mem_buf_device->dev_flags & DV_UP) )
            {                

                /* Update the last_activity_time variable which maintains the
                   time of the last IP activity through the PPP link. */
                *last_activity_time = NU_Retrieve_Clock();

                /* Point the data ptr to the beginning of the IP header. */
                MEM_Buffer_List.head->data_ptr += PPP_PROTOCOL_HEADER_1BYTE;
                MEM_Buffer_List.head->data_len -= PPP_PROTOCOL_HEADER_1BYTE;
                MEM_Buffer_List.head->mem_total_data_len -= PPP_PROTOCOL_HEADER_1BYTE;

                IP_Interpret ((IPLAYER *) MEM_Buffer_List.head->data_ptr,
                        MEM_Buffer_List.head->mem_buf_device, MEM_Buffer_List.head);
            }
            else
            {   
                /* Bump the number of silent discards and free the buffers */
                ((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->silent_discards++;
                MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);
            }
                

            break;

        default                         :

            /* Since it failed on the assumption try checking it one
               more time without protocol field compression. */

            /* Get the first byte. */
            ppp_protocol = MEM_Buffer_List.head->data_ptr[0];

            /* Shift it over to the MSB */
            ppp_protocol <<= 8;

            /* OR in the LSB byte */
            ppp_protocol = (ppp_protocol | MEM_Buffer_List.head->data_ptr[1]);

            /* Point the data ptr to the beginning of the IP header. */
            MEM_Buffer_List.head->data_ptr += PPP_PROTOCOL_HEADER_2BYTES;
            MEM_Buffer_List.head->data_len -= PPP_PROTOCOL_HEADER_2BYTES;
            MEM_Buffer_List.head->mem_total_data_len -= PPP_PROTOCOL_HEADER_2BYTES;

            switch (ppp_protocol)
            {
                case PPP_IP_PROTOCOL            :

                    /* Get a pointer to the LCP and IPCP layers */
                    lcp_ptr = &((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->lcp;
                    ipcp_ptr = &((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->ipcp;

                    /* Only allow IP packets if LCP and NCP are in the open state */
                    if ( (lcp_ptr->state == OPENED) && (ipcp_ptr->state == OPENED) &&
                        (MEM_Buffer_List.head->mem_buf_device->dev_flags & DV_UP) )
                    {                

                        /* Update the last_activity_time variable which maintains the
                           time of the last IP activity through the PPP link. */
                        *last_activity_time = NU_Retrieve_Clock();

                        IP_Interpret ((IPLAYER *) MEM_Buffer_List.head->data_ptr,
                                MEM_Buffer_List.head->mem_buf_device,
                                MEM_Buffer_List.head);
                    }
                    else
                    {   
                        /* Bump the number of silent discards and free the buffers */
                        ((PPP_LAYER *)MEM_Buffer_List.head->mem_buf_device->dev_ppp_layer)->silent_discards++;
                        MEM_Buffer_Chain_Free(&MEM_Buffer_List, &MEM_Buffer_Freelist);
                    }


                    break;

                case PPP_IP_CONTROL_PROTOCOL    :

                    PPP_NCP_IP_Interpret (MEM_Buffer_List.head);
                    break;

                case PPP_CHAP_PROTOCOL          :

                    PPP_CHAP_Interpret (MEM_Buffer_List.head);

⌨️ 快捷键说明

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