/* * Copyright (c) 2006-2018 RT-Thread Development Team. All rights reserved. * License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include #include #include #include #include #include "iot_import.h" #include #undef perror #define perror rt_kprintf void *HAL_UDP_create(char *host, unsigned short port) { #define NETWORK_ADDR_LEN (16) int rc = -1; long socket_id = -1; char port_ptr[6] = {0}; struct addrinfo hints; char addr[NETWORK_ADDR_LEN] = {0}; struct addrinfo *res, *ainfo; struct sockaddr_in *sa = NULL; if (NULL == host) { return (void *)(-1); } sprintf(port_ptr, "%u", port); memset((char *)&hints, 0x00, sizeof(hints)); hints.ai_socktype = SOCK_DGRAM; hints.ai_family = AF_INET; hints.ai_protocol = IPPROTO_UDP; rc = getaddrinfo(host, port_ptr, &hints, &res); if (0 != rc) { perror("getaddrinfo error"); return (void *)(-1); } for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) { if (AF_INET == ainfo->ai_family) { sa = (struct sockaddr_in *)ainfo->ai_addr; strncpy(addr, inet_ntoa(sa->sin_addr), NETWORK_ADDR_LEN); fprintf(stderr, "The host IP %s, port is %d\r\n", addr, ntohs(sa->sin_port)); socket_id = socket(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol); if (socket_id < 0) { perror("create socket error"); continue; } if (0 == connect(socket_id, ainfo->ai_addr, ainfo->ai_addrlen)) { break; } close(socket_id); } } freeaddrinfo(res); return (void *)socket_id; #undef NETWORK_ADDR_LEN } void HAL_UDP_close(void *p_socket) { long socket_id = -1; socket_id = (long)p_socket; close(socket_id); } int HAL_UDP_write(void *p_socket, const unsigned char *p_data, unsigned int datalen) { int rc = -1; long socket_id = -1; socket_id = (long)p_socket; rc = send(socket_id, (char *)p_data, (int)datalen, 0); if (-1 == rc) { return -1; } return rc; } int HAL_UDP_read(void *p_socket, unsigned char *p_data, unsigned int datalen) { long socket_id = -1; int count = -1; if (NULL == p_data || NULL == p_socket) { return -1; } socket_id = (long)p_socket; count = (int)read(socket_id, p_data, datalen); return count; } int HAL_UDP_readTimeout(void *p_socket, unsigned char *p_data, unsigned int datalen, unsigned int timeout) { int ret; struct timeval tv; fd_set read_fds; long socket_id = -1; if (NULL == p_socket || NULL == p_data) { return -1; } socket_id = (long)p_socket; if (socket_id < 0) { return -1; } FD_ZERO(&read_fds); FD_SET(socket_id, &read_fds); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; ret = select(socket_id + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv); /* Zero fds ready means we timed out */ if (ret == 0) { return -2; /* receive timeout */ } if (ret < 0) { if (errno == EINTR) { return -3; /* want read */ } return -4; /* receive failed */ } /* This call will not block */ return HAL_UDP_read(p_socket, p_data, datalen); }