| 1002 | #endif |
| 1003 | |
| 1004 | int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen) |
| 1005 | { |
| 1006 | struct at_socket *sock = RT_NULL; |
| 1007 | int timeout, result = 0; |
| 1008 | size_t recv_len = 0; |
| 1009 | |
| 1010 | if (mem == RT_NULL || len == 0) |
| 1011 | { |
| 1012 | /* if the requested number of bytes to receive from a stream socket was 0. */ |
| 1013 | rt_set_errno(EFAULT); |
| 1014 | return -1; |
| 1015 | } |
| 1016 | |
| 1017 | sock = at_get_socket(socket); |
| 1018 | if (sock == RT_NULL) |
| 1019 | { |
| 1020 | rt_set_errno(ENXIO); |
| 1021 | return -1; |
| 1022 | } |
| 1023 | |
| 1024 | /* if the socket type is UDP, need to connect socket first */ |
| 1025 | if (sock->type == AT_SOCKET_UDP) |
| 1026 | { |
| 1027 | if (from == RT_NULL || fromlen == 0) |
| 1028 | { |
| 1029 | rt_set_errno(EFAULT); |
| 1030 | return -1; |
| 1031 | } |
| 1032 | |
| 1033 | if(sock->state == AT_SOCKET_CONNECT && rt_memcmp(&sock->last_udp_adr, from, sizeof(struct sockaddr)) != 0) |
| 1034 | { |
| 1035 | if (sock->ops->at_closesocket(sock) != 0) |
| 1036 | { |
| 1037 | free_socket(sock); |
| 1038 | rt_set_errno(EIO); |
| 1039 | goto __exit; |
| 1040 | } |
| 1041 | sock->state = AT_SOCKET_OPEN; |
| 1042 | } |
| 1043 | |
| 1044 | if (sock->state == AT_SOCKET_OPEN) |
| 1045 | { |
| 1046 | ip_addr_t remote_addr; |
| 1047 | uint16_t remote_port = 0; |
| 1048 | char ipstr[16] = { 0 }; |
| 1049 | |
| 1050 | socketaddr_to_ipaddr_port(from, &remote_addr, &remote_port); |
| 1051 | ipaddr_to_ipstr(from, ipstr); |
| 1052 | |
| 1053 | if (sock->ops->at_connect(sock, ipstr, remote_port, sock->type, RT_TRUE) < 0) |
| 1054 | { |
| 1055 | at_do_event_changes(sock, AT_EVENT_ERROR, RT_TRUE); |
| 1056 | rt_set_errno(EIO); |
| 1057 | /* socket shutdown */ |
| 1058 | goto __exit; |
| 1059 | } |
| 1060 | |
| 1061 | rt_memcpy(&sock->last_udp_adr, from, sizeof(struct sockaddr)); |
no test coverage detected