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

📄 udp.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* Drop the packet by placing it back on the buffer_freelist. */
        MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
        status = -1;
    }

    return (status);

} /* UDP_Append */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       UDP_Read                                                         
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Get the data from the UDP buffer and transfer it into your buffer.
*       Returns the number of bytes transferred or -1 of none available.  
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *sockptr                                                         
*       *buffer                                                          
*       *from                                                            
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       NU_NO_DATA_TRANSFER                                              
*       bytes_copied                                                     
*                                                                       
*************************************************************************/
INT32 UDP_Read (struct sock_struct *sockptr, char *buffer, struct addr_struct *from)
{
    UDPLAYER    HUGE    *pkt_ptr;
    IPLAYER             *ip_pkt_ptr;
    INT32               bytes_copied;
    NET_BUFFER          *buf_ptr;
    UINT8       HUGE    *ch_ptr;

    /* Check to see if there are any packets waiting. */
    if (sockptr->s_recvlist.head == NU_NULL)
        return (NU_NO_DATA_TRANSFER);

    /* Set up a pointer to the packet stored in first buffer in the list */
    ch_ptr = sockptr->s_recvlist.head->data_ptr;
    ch_ptr -= sizeof (UDPLAYER);

    pkt_ptr = (UDPLAYER *) ch_ptr;
    ip_pkt_ptr = (IPLAYER *) (ch_ptr - sizeof (IPLAYER));

    /* Move the data into the caller's buffer, copy it from the buffer chain. */

    /* Get a pointer to the data */
    buf_ptr = sockptr->s_recvlist.head;

    /* Do the parent buffer first */
    NU_BLOCK_COPY(buffer, buf_ptr->data_ptr, (unsigned int)buf_ptr->data_len);

    /* Update the bytes copied. */
    bytes_copied = buf_ptr->data_len;

    /* Loop through the chain if needed and copy all buffers. */
    while (buf_ptr->next_buffer != NU_NULL)
    {
        /* Move to the next buffer in the chain */
        buf_ptr = buf_ptr->next_buffer;

        /* Copy the data */
        NU_BLOCK_COPY(((CHAR HUGE *)buffer) + bytes_copied, buf_ptr->data_ptr, (unsigned int)buf_ptr->data_len);

        /* Update the bytes copied. */
        bytes_copied += buf_ptr->data_len;

     } /* end while there are buffers in the chain */

    /*  Get his IP number.  */
    *(UINT32 *)from->id.is_ip_addrs  = LONGSWAP(GET32(ip_pkt_ptr, IP_SRC_OFFSET));

    /*  Get his port number. */
    from->port = GET16(pkt_ptr, UDP_SRC_OFFSET);

    /*  Update the socket descriptor with foreign address
        information.  */
    *(UINT32 *)sockptr->s_foreign_addr.ip_num.is_ip_addrs = GET32(ip_pkt_ptr, IP_SRC_OFFSET);
    sockptr->s_foreign_addr.port_num = from->port;

    /* Check the IP_RECVIFADDR option */
    if (sockptr->s_options & IP_RECVIFADDR_OP)
        sockptr->s_recv_if = sockptr->s_recvlist.head->mem_buf_device;

    /* Place this buffer back onto the free list. */
    MEM_Buffer_Chain_Free (&sockptr->s_recvlist, &MEM_Buffer_Freelist);

    /* Update the number of buffered datagrams. */
    sockptr->s_recvpackets--;

    return (bytes_copied);

} /* UDP_Read */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       UDP_Send                                                         
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Send some data out in a udp packet.                                  
*                                                                       
*       Returns 0 on ok send, non-zero for an error                          
*                                                                       
*   INPUTS                                                                
*
*       *uptr                                                            
*       *buffer                                                          
*       nbytes                                                           
*       sock_options                                                     
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       stat                                                             
*       NU_NO_BUFFERS                                                    
*       -1                                                               
*       nbytes                                                           
*                                                                       
*************************************************************************/
INT32 UDP_Send (UDP_PORT *uptr, CHAR *buffer, INT32 nbytes)
{
    UDPLAYER            *udp_pkt;
    NET_BUFFER          *buf_ptr, *work_buf;
    STATUS              stat;
    INT32               bytes_left;
    UINT8               *work_ptr;
    struct sock_struct  *sock_ptr = SCK_Sockets[uptr->up_socketd];
    UINT16              checksum;

    /* Before we do anything else make sure a route to the host is up. */
    if ( (stat = UDP_Cache_Route (uptr, uptr->up_faddr)) != NU_SUCCESS)
        return stat;

    /* Extract the local IP address to use from the route. */
    uptr->up_laddr = uptr->up_route.rt_route->rt_device->dev_addr.dev_ip_addr;

    /* Allocate a buffer, or chain of buffers, to place the packet in. The size is 
       increased by the various protocols header sizes to make room for them.*/
    buf_ptr = MEM_Buffer_Chain_Dequeue(&MEM_Buffer_Freelist, 
                                       nbytes + NET_MAX_UDP_HEADER_SIZE);
    
    if(buf_ptr == NU_NULL)
    {
        return (NU_NO_BUFFERS);
    }

    /* Compute the data size with the UDP header. */
    buf_ptr->mem_total_data_len = (nbytes + sizeof (UDPLAYER));

    /* Set the deallocation list pointer. */
    buf_ptr->mem_dlist = &MEM_Buffer_Freelist;

    /* Set the data pointer to the correct location. */
    buf_ptr->data_ptr = (buf_ptr->mem_parent_packet + 
            (NET_MAX_UDP_HEADER_SIZE - sizeof (UDPLAYER)));

    /* Set the UDP header pointer to that it can be filled in. */
    udp_pkt = (UDPLAYER *)buf_ptr->data_ptr;

    /* Initialize the local and foreign port numbers. */
    PUT16(udp_pkt, UDP_SRC_OFFSET, uptr->up_lport);
    PUT16(udp_pkt, UDP_DEST_OFFSET, uptr->up_fport);
    
    /*  Get the length of the buffer.  */
    PUT16(udp_pkt, UDP_LENGTH_OFFSET, (INT16)buf_ptr->mem_total_data_len);

    /*  Move the data into the output buffer. This will depend on the size of
        the data. The data may need to be copied into the multiple buffers
        in the buffer chain. */

    /* Get the total number of bytes that must be copied. */
    bytes_left = nbytes;

    /* Will it all fit into one buffer? */
    if (bytes_left <= (NET_PARENT_BUFFER_SIZE - NET_MAX_UDP_HEADER_SIZE))
    {
        /* 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 after the UDP header. */
        NU_BLOCK_COPY  (buf_ptr->data_ptr + sizeof (UDPLAYER), buffer, (unsigned int)nbytes);
    }
    else
    {

        /* Fill the parent buffer in the chain. This one is slightly smaller than
           the rest in the chain. */
        NU_BLOCK_COPY (buf_ptr->data_ptr + sizeof (UDPLAYER), buffer, NET_PARENT_BUFFER_SIZE - 
            NET_MAX_UDP_HEADER_SIZE);

        /* Take off the bytes just copied from the total bytes left. */
        bytes_left -= (NET_PARENT_BUFFER_SIZE - NET_MAX_UDP_HEADER_SIZE);

        /* Store the number of bytes in this buffer. */
        buf_ptr->data_len = ((NET_PARENT_BUFFER_SIZE - NET_MAX_UDP_HEADER_SIZE)
            + sizeof (UDPLAYER));

        /* Get a work pointer and bump it the number of bytes just copied. */
        work_ptr = (UINT8 *)(buffer + (NET_PARENT_BUFFER_SIZE - NET_MAX_UDP_HEADER_SIZE));

        /* 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. */
                NU_BLOCK_COPY (work_buf->mem_packet, work_ptr, (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;
            }
            else
            {
                /* Copy all that will fit into a single buffer */
                NU_BLOCK_COPY (work_buf->mem_packet, work_ptr, NET_MAX_BUFFER_SIZE);

                /* Update the buffer pointer */
                work_ptr += 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);

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

    /* Clear the checksum field before calcualting the real checksum. */
    PUT16(udp_pkt, UDP_CHECK_OFFSET, 0);

    /*  Calculate the checksum. */
    checksum = UTL_Checksum(buf_ptr, uptr->up_laddr, uptr->up_faddr, IP_UDP_PROT);
    
    /* If a checksum of zero is computed it should be replaced with 0xffff. */
    if (checksum == 0)
        checksum = 0xFFFF;

    PUT16(udp_pkt, UDP_CHECK_OFFSET, checksum);

    /* Send this packet. */
    stat = IP_Send( buf_ptr, &uptr->up_route, 
                    uptr->up_route.rt_ip_dest.sck_addr, uptr->up_laddr, 
                    IP_ALLOWBROADCAST, IP_TIME_TO_LIVE, IP_UDP_PROT, 
                    IP_TYPE_OF_SERVICE, sock_ptr->s_moptions);

    if (stat == NU_SUCCESS)
    {
        /* Increment the number of UDP datagrams transmitted. */
        SNMP_udpoutDatagrams_Inc;

    }
    else
    {
        /* The packet was not sent.  Deallocate the buffer.  If the packet was
           transmitted it will be deallocated later by the apropriate MAC layer
           TX routine. */
        MEM_One_Buffer_Chain_Free (buf_ptr, &MEM_Buffer_Freelist);

⌨️ 快捷键说明

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