HAL_UDP_rtthread.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (c) 2006-2018 RT-Thread Development Team. All rights reserved.
  3. * License-Identifier: Apache-2.0
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  6. * not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <sys/types.h>
  22. #include <sys/time.h>
  23. #include <sys/socket.h>
  24. #include <sys/select.h>
  25. #include <errno.h>
  26. #include <netdb.h>
  27. #include <unistd.h>
  28. #include "iot_import.h"
  29. #include <rtthread.h>
  30. #undef perror
  31. #define perror rt_kprintf
  32. void *HAL_UDP_create(char *host, unsigned short port)
  33. {
  34. #define NETWORK_ADDR_LEN (16)
  35. int rc = -1;
  36. long socket_id = -1;
  37. char port_ptr[6] = {0};
  38. struct addrinfo hints;
  39. char addr[NETWORK_ADDR_LEN] = {0};
  40. struct addrinfo *res, *ainfo;
  41. struct sockaddr_in *sa = NULL;
  42. if (NULL == host) {
  43. return (void *)(-1);
  44. }
  45. sprintf(port_ptr, "%u", port);
  46. memset((char *)&hints, 0x00, sizeof(hints));
  47. hints.ai_socktype = SOCK_DGRAM;
  48. hints.ai_family = AF_INET;
  49. hints.ai_protocol = IPPROTO_UDP;
  50. rc = getaddrinfo(host, port_ptr, &hints, &res);
  51. if (0 != rc) {
  52. perror("getaddrinfo error");
  53. return (void *)(-1);
  54. }
  55. for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) {
  56. if (AF_INET == ainfo->ai_family) {
  57. sa = (struct sockaddr_in *)ainfo->ai_addr;
  58. strncpy(addr, inet_ntoa(sa->sin_addr), NETWORK_ADDR_LEN);
  59. fprintf(stderr, "The host IP %s, port is %d\r\n", addr, ntohs(sa->sin_port));
  60. socket_id = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
  61. if (socket_id < 0) {
  62. perror("create socket error");
  63. continue;
  64. }
  65. if (0 == connect(socket_id, ainfo->ai_addr, ainfo->ai_addrlen)) {
  66. break;
  67. }
  68. close(socket_id);
  69. }
  70. }
  71. freeaddrinfo(res);
  72. return (void *)socket_id;
  73. #undef NETWORK_ADDR_LEN
  74. }
  75. void HAL_UDP_close(void *p_socket)
  76. {
  77. long socket_id = -1;
  78. socket_id = (long)p_socket;
  79. close(socket_id);
  80. }
  81. int HAL_UDP_write(void *p_socket,
  82. const unsigned char *p_data,
  83. unsigned int datalen)
  84. {
  85. int rc = -1;
  86. long socket_id = -1;
  87. socket_id = (long)p_socket;
  88. rc = send(socket_id, (char *)p_data, (int)datalen, 0);
  89. if (-1 == rc) {
  90. return -1;
  91. }
  92. return rc;
  93. }
  94. int HAL_UDP_read(void *p_socket,
  95. unsigned char *p_data,
  96. unsigned int datalen)
  97. {
  98. long socket_id = -1;
  99. int count = -1;
  100. if (NULL == p_data || NULL == p_socket) {
  101. return -1;
  102. }
  103. socket_id = (long)p_socket;
  104. count = (int)read(socket_id, p_data, datalen);
  105. return count;
  106. }
  107. int HAL_UDP_readTimeout(void *p_socket,
  108. unsigned char *p_data,
  109. unsigned int datalen,
  110. unsigned int timeout)
  111. {
  112. int ret;
  113. struct timeval tv;
  114. fd_set read_fds;
  115. long socket_id = -1;
  116. if (NULL == p_socket || NULL == p_data) {
  117. return -1;
  118. }
  119. socket_id = (long)p_socket;
  120. if (socket_id < 0) {
  121. return -1;
  122. }
  123. FD_ZERO(&read_fds);
  124. FD_SET(socket_id, &read_fds);
  125. tv.tv_sec = timeout / 1000;
  126. tv.tv_usec = (timeout % 1000) * 1000;
  127. ret = select(socket_id + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv);
  128. /* Zero fds ready means we timed out */
  129. if (ret == 0) {
  130. return -2; /* receive timeout */
  131. }
  132. if (ret < 0) {
  133. if (errno == EINTR) {
  134. return -3; /* want read */
  135. }
  136. return -4; /* receive failed */
  137. }
  138. /* This call will not block */
  139. return HAL_UDP_read(p_socket, p_data, datalen);
  140. }