Exemplo n.º 1
0
/**
 * @brief Receive data from a datagram socket.
 * 
 * Provides RTCS with the buffer in which to place data that is incoming on the datagram
 * socket. Supports IPv6 and IPv4 family. 
 * If a remote endpoint has been specified with connect(), only datagrams from that source
 * will be received.
 * When the flags parameter is RTCS_MSG_PEEK, the same datagram is received the next time recv() or
 * recvfrom() is called.
 * If addrlen is NULL, the socket address is not written to sourceaddr. If sourceaddr is NULL and the value of
 * addrlen is not NULL, the result is unspecified.
 * If the function returns RTCS_ERROR, the application can call RTCS_geterror() to determine the reason
 * for the error.
 * This function blocks (unles nonblocking option has been set for the socket) until data is available 
 * or an error or a timeout occurs.
 *
 * 
 * @param sock [IN] socket handle.
 * @param buffer [IN] pointer to a buffer for received data.
 * @param buflen [IN] size of the buffer in bytes.
 * @param flags [IN] flags to underlying protocols. One of the following:
 *              RTCS_MSG_PEEK - receives a datagram bug does not consume it.
 *              Zero - ignore.
 * @param sourceaddr [IN/OUT] 
 * @param addrlen [IN/OUT] 
 * @return number of bytes received (success)
 *         RTCS_ERROR (failure).
 * @see SOCK_DGRAM_bind
 * @see RTCS_geterror
 * @see SOCK_DGRAM_sendto
 * @code 
 * uint32_t handle;
 * sockaddr_in remote_sin;
 * uint32_t count;
 * char my_buffer[500];
 * uint16_t remote_len = sizeof(remote_sin);
 * ...
 * count = recvfrom(handle, my_buffer, sizeof(my_buffer), 0, (struct sockaddr *) &remote_sin, &remote_len);
 * if (count == RTCS_ERROR)
 * {
 *   printf(“\nrecvfrom() failed with error %lx”,
 *   RTCS_geterror(handle));
 * } else {
 * printf(“\nReceived %ld bytes of data.”, count);
 * }
 * @endcode
 */
static int32_t  SOCK_DGRAM_recvfrom
   (
      uint32_t              sock,
         /* [IN] socket handle */
      void                *buffer,
         /* [IN] buffer for received data */
      uint32_t              buflen,
         /* [IN] length of the buffer, in bytes */
      uint32_t              flags,
         /* [IN] flags to underlying protocols */
               
      struct sockaddr  *sourceaddr,
         /* [OUT] address from which data was received */
      uint16_t         *addrlen
         /* [IN/OUT] length of the address, in bytes */
   )
{
    UDP_PARM          parms = {0};
    uint32_t          error;
    struct sockaddr   addr_from = {0};
    SOCKET_STRUCT_PTR sock_struct_ptr = (SOCKET_STRUCT_PTR)sock;

    RTCS_ENTER(RECVFROM, sock);

    if(sock_struct_ptr->STATE == SOCKSTATE_DGRAM_GROUND) 
    {
      RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_BOUND);
      RTCS_EXIT2(RECVFROM, RTCSERR_SOCK_NOT_BOUND, RTCS_ERROR);
    }

    parms.ucb      = sock_struct_ptr->UCB_PTR;
    parms.udpptr   = buffer;
    parms.udpword  = buflen;
    parms.udpflags = flags;
    if(addrlen)
    {
      /* if addrlen pointer is NULL, nothing is to be written to sourceaddr. parms.saddr_ptr is NULL by default. 
       * if addrlen is a non NULL pointer, UDP code will indicate the remote peer address via *saddr_ptr
       */      
      parms.saddr_ptr = &addr_from;
    }
     
    error = RTCSCMD_issue(parms, UDP_receive);
      
    if(error) 
    {
      RTCS_setsockerror(sock, error);
      RTCS_EXIT2(RECVFROM, error, RTCS_ERROR);
    }
    
    /* write the address from which data was received */
    SOCKADDR_return_addr(sock_struct_ptr, sourceaddr, &addr_from, addrlen);     
    RTCS_EXIT2(RECVFROM, RTCS_OK, parms.udpword);
} 
Exemplo n.º 2
0
static int32_t  SOCK_DGRAM_recv
   (
      uint32_t        sock,
         /* [IN] socket handle */
      void          *buffer,
         /* [IN] buffer for received data */
      uint32_t        buflen,
         /* [IN] length of the buffer, in bytes */
      uint32_t        flags
         /* [IN] flags to underlying protocols */
   )
{
    int32_t   len;

    RTCS_ENTER(RECV, sock);
    len = SOCK_DGRAM_recvfrom(sock, buffer, buflen, flags, NULL, NULL);
    RTCS_EXIT2(RECV, (len < 0) ? RTCS_ERROR : RTCS_OK, len);
}
Exemplo n.º 3
0
static int32_t  SOCK_DGRAM_send
   (
      uint32_t        sock,
         /* [IN] socket handle */
      void          *buffer,
         /* [IN] data to transmit */
      uint32_t        buflen,
         /* [IN] length of the buffer, in bytes */
      uint32_t        flags
         /* [IN] flags to underlying protocols */
   )
{
    int32_t len= -1 ; // it will generate error if AF != AF_INET or AF_INET6

    RTCS_ENTER(SEND, sock);
     
    len = SOCK_DGRAM_sendto(sock, buffer, buflen, flags, NULL, 0);
 
    RTCS_EXIT2(SEND, (len < 0) ? RTCS_ERROR : RTCS_OK, len);
}
Exemplo n.º 4
0
int32_t  SOCK_DGRAM_sendto
   (
      uint32_t              sock,
         /* [IN] socket handle */
      void                *send_buffer,
         /* [IN] data to transmit */
      uint32_t              buflen,
         /* [IN] length of the buffer, in bytes */
      uint32_t              flags,
         /* [IN] flags to underlying protocols */
      sockaddr     *destaddr,
         /* [IN] address to which to send data */
      uint16_t              addrlen
         /* [IN] length of the address, in bytes */
   )
{ /* Body */
   UDP_PARM    parms = {0};
   uint32_t    error = 0;
   sockaddr    addr = {0};
   uint16_t    len = sizeof(addr);

   RTCS_ENTER(SENDTO, sock);

#if RTCSCFG_CHECK_ADDRSIZE
   
    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) 
            {
        #endif

                if(destaddr && addrlen < sizeof(sockaddr_in)) 
                {
                    RTCS_setsockerror(sock, RTCSERR_SOCK_SHORT_ADDRESS);
                    RTCS_EXIT2(SENDTO, RTCSERR_SOCK_SHORT_ADDRESS, RTCS_ERROR);
                } /* Endif */

        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) 
            {
        #endif
                if(destaddr && addrlen < sizeof(sockaddr_in6)) 
                {
                    RTCS_setsockerror(sock, RTCSERR_SOCK_SHORT_ADDRESS);
                    RTCS_EXIT2(SENDTO, RTCSERR_SOCK_SHORT_ADDRESS, RTCS_ERROR);
                } /* Endif */

        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif

#endif


   if(!destaddr) 
   {
      error = SOCK_DGRAM_getpeername(sock, &addr, &len);
      if(error) 
      {
         RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_CONNECTED);
         RTCS_EXIT2(SENDTO, RTCSERR_SOCK_NOT_CONNECTED, RTCS_ERROR);
      } /* Endif */
   } 
   else 
   {

      _mem_copy(destaddr, &addr, sizeof(addr));

   } /* Endif */


    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) 
            {
        #endif
                if(((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) 
                {
                    sockaddr_in localaddr = {0};
                    localaddr.sin_family      = AF_INET;
                    localaddr.sin_port        = 0;
                    localaddr.sin_addr.s_addr = INADDR_ANY;
                    error = SOCK_DGRAM_bind(sock,(sockaddr *)&localaddr, sizeof(localaddr));
                    if(error) 
                    {
                        RTCS_setsockerror(sock, error);
                        RTCS_EXIT2(SENDTO, error, RTCS_ERROR);
                    } /* Endif */
                } /* Endif */
                parms.ipaddress = ((sockaddr_in *)&addr)->sin_addr.s_addr;
                parms.udpport   = ((sockaddr_in *)&addr)->sin_port;

        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) 
            {
        #endif
                if(((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) 
                {
                    struct sockaddr_in6 localaddr = {0};
                    localaddr.sin6_family      = AF_INET6;
                    localaddr.sin6_port        = 0;
                    IN6_ADDR_COPY((in6_addr*)(&(in6addr_any)),&(localaddr.sin6_addr));
                    error = SOCK_DGRAM_bind(sock, (sockaddr *)&localaddr, sizeof(localaddr));
                    if (error) 
                    {
                        RTCS_setsockerror(sock, error);
                        RTCS_EXIT2(SENDTO, error, RTCS_ERROR);
                    } /* Endif */
                } /* Endif */

                IN6_ADDR_COPY(&(((sockaddr_in6 *)&addr)->sin6_addr),&(parms.ipv6address));
                parms.udpport   = ((sockaddr_in6 *)&addr)->sin6_port;
                parms.if_scope_id =((sockaddr_in6 *)&addr)->sin6_scope_id; 
   
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
   
   parms.ucb       = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
   parms.udpptr    = send_buffer;
   parms.udpword   = buflen;
   parms.udpflags  = flags;

   error = RTCSCMD_issue(parms, UDP_send);

   if(error) 
   {
      RTCS_setsockerror(sock, error);
      RTCS_EXIT2(SENDTO, error, RTCS_ERROR);
   } /* Endif */

   RTCS_EXIT2(SENDTO, RTCS_OK, buflen);

} /* Endbody */
Exemplo n.º 5
0
/*FUNCTION*-------------------------------------------------------------
*
* Function Name   : SOCK_DGRAM_recvfrom
* Returned Value  : number of bytes received or RTCS_ERROR
* Comments  :  Receive data from a socket for IPv6 and IPv4 family.
*
*END*-----------------------------------------------------------------*/
int32_t  SOCK_DGRAM_recvfrom
   (
      uint32_t              sock,
         /* [IN] socket handle */
      void                *buffer,
         /* [IN] buffer for received data */
      uint32_t              buflen,
         /* [IN] length of the buffer, in bytes */
      uint32_t              flags,
         /* [IN] flags to underlying protocols */
      
         /*sockaddr_in6     *sourceaddr,*/
      struct sockaddr  *sourceaddr,
         /* [OUT] address from which data was received */
      uint16_t         *addrlen
         /* [IN/OUT] length of the address, in bytes */
   )
{ /* Body */
   UDP_PARM    parms = {0};
   uint32_t     error;

   RTCS_ENTER(RECVFROM, sock);

#if RTCSCFG_CHECK_ERRORS
   if (((SOCKET_STRUCT_PTR)sock)->STATE == SOCKSTATE_DGRAM_GROUND) {
      RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_BOUND);
      RTCS_EXIT2(RECVFROM, RTCSERR_SOCK_NOT_BOUND, RTCS_ERROR);
   } /* Endif */
#endif

    parms.ucb      = ((SOCKET_STRUCT_PTR)sock)->UCB_PTR;
    parms.udpptr   = buffer;
    parms.udpword  = buflen;
    parms.udpflags = flags;

    #if RTCSCFG_ENABLE_IP4
        #if RTCSCFG_ENABLE_IP6
            if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET) 
            {
        #endif

                error = RTCSCMD_issue(parms, UDP_receive);
                if (error) 
                {
                    RTCS_setsockerror(sock, error);
                    RTCS_EXIT2(RECVFROM, error, RTCS_ERROR);
                } /* Endif */
                if (!addrlen) 
                {
                #if RTCSCFG_CHECK_ADDRSIZE
                } 
                else if (*addrlen < sizeof(sockaddr_in)) 
                {
                    sockaddr_in fullname;
                    fullname.sin_family      = AF_INET;
                    fullname.sin_port        = parms.udpport;
                    fullname.sin_addr.s_addr = parms.ipaddress;
                    _mem_copy(&fullname, sourceaddr, *addrlen);
                    *addrlen = sizeof(sockaddr_in);
                #endif
                } 
                else 
                {
                    ((sockaddr_in *)sourceaddr)->sin_family      = AF_INET;
                    ((sockaddr_in *)sourceaddr)->sin_port        = parms.udpport;
                    ((sockaddr_in *)sourceaddr)->sin_addr.s_addr = parms.ipaddress;
                    *addrlen = sizeof(sockaddr_in);
                } /* Endif */
        #if RTCSCFG_ENABLE_IP6
            }
        #endif
    #endif

    #if RTCSCFG_ENABLE_IP6
        #if RTCSCFG_ENABLE_IP4
            else if (((SOCKET_STRUCT_PTR)sock)->AF == AF_INET6) 
            {
        #endif
                error = RTCSCMD_issue(parms, UDP_receive6);
                if (error) 
                {
                    RTCS_setsockerror(sock, error);
                    RTCS_EXIT2(RECVFROM, error, RTCS_ERROR);
                } /* Endif */
                /* copy addr structure to output */ 
                if(!addrlen)//if parameter of addrlen is not NULL
                {
                #if RTCSCFG_CHECK_ADDRSIZE
                } 
                else if (*addrlen < sizeof(struct sockaddr_in6)) 
                {
                    struct sockaddr_in6 fullname;
                    fullname.sin6_family      = AF_INET6;
                    fullname.sin6_port        = parms.udpport;
                    fullname.sin6_scope_id    = parms.if_scope_id;
                    IN6_ADDR_COPY(&(parms.ipv6address),&(fullname.sin6_addr));
                    /*do safe mem copy to avoid overflow*/
                    _mem_copy(&fullname, sourceaddr, *addrlen);
                    /*return real value of size of addr structure*/
                    *addrlen = sizeof(struct sockaddr_in6);
                #endif
                } 
                else 
                {   
                    ((sockaddr_in6 *)sourceaddr)->sin6_family      = AF_INET6;
                    ((sockaddr_in6 *)sourceaddr)->sin6_port        = parms.udpport;
                    ((sockaddr_in6 *)sourceaddr)->sin6_scope_id    = parms.if_scope_id;
                    IN6_ADDR_COPY(&(parms.ipv6address),&(((sockaddr_in6 *)sourceaddr)->sin6_addr));
                    *addrlen = sizeof(struct sockaddr_in6);
                }
        #if RTCSCFG_ENABLE_IP4
            }
        #endif 
    #endif
   
   RTCS_EXIT2(RECVFROM, RTCS_OK, parms.udpword);

} /* Endbody */
Exemplo n.º 6
0
static int32_t  SOCK_DGRAM_sendto
   (
      uint32_t              sock,
         /* [IN] socket handle */
      void                *send_buffer,
         /* [IN] data to transmit */
      uint32_t              buflen,
         /* [IN] length of the buffer, in bytes */
      uint32_t              flags,
         /* [IN] flags to underlying protocols */
      sockaddr     *destaddr,
         /* [IN] address to which to send data */
      uint16_t              addrlen
         /* [IN] length of the address, in bytes */
   )
{
    UDP_PARM    parms = {0};
    uint32_t    error = RTCS_OK;
    sockaddr    addr = {0};
    uint16_t    len = sizeof(addr);
    SOCKET_STRUCT_PTR sock_struct_ptr = (SOCKET_STRUCT_PTR)sock;

    RTCS_ENTER(SENDTO, sock);
    
    if(!destaddr) /* called from SOCK_DGRAM_send() */
    {
      error = SOCK_DGRAM_getpeername(sock, &addr, &len);
      if(error) 
      {
        RTCS_setsockerror(sock, RTCSERR_SOCK_NOT_CONNECTED);
        RTCS_EXIT2(SENDTO, RTCSERR_SOCK_NOT_CONNECTED, RTCS_ERROR);
      }
      destaddr = &addr;
    } 
    parms.saddr_ptr = destaddr;
     
    if(sock_struct_ptr->STATE == SOCKSTATE_DGRAM_GROUND) 
    {
      sockaddr localaddr = {0};
      localaddr.sa_family = sock_struct_ptr->AF;
      error = SOCK_DGRAM_bind(sock,(sockaddr *)&localaddr, sizeof(localaddr));
      if(error) 
      {
        RTCS_setsockerror(sock, error);
        RTCS_EXIT2(SENDTO, error, RTCS_ERROR);
      }
    }
     
    parms.ucb       = sock_struct_ptr->UCB_PTR;
    parms.udpptr    = send_buffer;
    parms.udpword   = buflen;
    parms.udpflags  = flags;

    error = RTCSCMD_issue(parms, UDP_send);

    if(error) 
    {
      RTCS_setsockerror(sock, error);
      RTCS_EXIT2(SENDTO, error, RTCS_ERROR);
    }

    RTCS_EXIT2(SENDTO, RTCS_OK, buflen);
}