/** * @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); }
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); }
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); }
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 */
/*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 */
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); }