mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-17 16:36:03 +08:00
1.新增esp-idf设备端sdk
This commit is contained in:
422
sdk/ESP-IDF/esp_fastbee_aliyun/esp-aliyun/wrappers/wrapper_udp.c
Normal file
422
sdk/ESP-IDF/esp_fastbee_aliyun/esp-aliyun/wrappers/wrapper_udp.c
Normal file
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* ESPRESSIF MIT License
|
||||
*
|
||||
* Copyright (c) 2019 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
|
||||
*
|
||||
* Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case,
|
||||
* it is free of charge, to any person obtaining a copy of this software and associated
|
||||
* documentation files (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
|
||||
* to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "infra_compat.h"
|
||||
#include "wrappers_defs.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "udp";
|
||||
|
||||
static int hal_net_errno(int fd)
|
||||
{
|
||||
int sock_errno = 0;
|
||||
u32_t optlen = sizeof(sock_errno);
|
||||
|
||||
getsockopt(fd, SOL_SOCKET, SO_ERROR, &sock_errno, &optlen);
|
||||
|
||||
return sock_errno;
|
||||
}
|
||||
|
||||
|
||||
int HAL_UDP_close_without_connect(intptr_t sockfd)
|
||||
{
|
||||
return close((int)sockfd);
|
||||
}
|
||||
|
||||
intptr_t 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 (-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) {
|
||||
ESP_LOGE(TAG, "getaddrinfo error");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) {
|
||||
if (AF_INET == ainfo->ai_family) {
|
||||
sa = (struct sockaddr_in *)ainfo->ai_addr;
|
||||
inet_ntop(AF_INET, &sa->sin_addr, 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) {
|
||||
ESP_LOGE(TAG, "create socket error");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 == connect(socket_id, ainfo->ai_addr, ainfo->ai_addrlen)) {
|
||||
break;
|
||||
}
|
||||
|
||||
close(socket_id);
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
|
||||
return socket_id;
|
||||
|
||||
#undef NETWORK_ADDR_LEN
|
||||
|
||||
}
|
||||
|
||||
intptr_t HAL_UDP_create_without_connect(const char *host, unsigned short port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int sockfd;
|
||||
int opt_val = 1;
|
||||
struct hostent *hp;
|
||||
struct in_addr in;
|
||||
uint32_t ip;
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if (sockfd < 0) {
|
||||
ESP_LOGE(TAG, "socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 == port) {
|
||||
return (intptr_t)sockfd;
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
if (0 != setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val))) {
|
||||
ESP_LOGE(TAG, "setsockopt");
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (0 != setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt_val, sizeof(opt_val))) {
|
||||
ESP_LOGE(TAG, "setsockopt");
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL == host) {
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
} else {
|
||||
if (inet_aton(host, &in)) {
|
||||
ip = *(uint32_t *)∈
|
||||
} else {
|
||||
hp = gethostbyname(host);
|
||||
|
||||
if (!hp) {
|
||||
ESP_LOGE(TAG, "can't resolute the host address \n");
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ip = *(uint32_t *)(hp->h_addr);
|
||||
}
|
||||
|
||||
addr.sin_addr.s_addr = ip;
|
||||
}
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
if (-1 == bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))) {
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "success to establish udp, fd=%d", sockfd);
|
||||
|
||||
return (intptr_t)sockfd;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int HAL_UDP_joinmulticast(intptr_t sockfd,
|
||||
char *p_group)
|
||||
{
|
||||
int err = -1;
|
||||
int socket_id = -1;
|
||||
|
||||
if (NULL == p_group) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*set loopback*/
|
||||
int loop = 0;
|
||||
socket_id = (int)sockfd;
|
||||
err = setsockopt(socket_id, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
|
||||
|
||||
if (err < 0) {
|
||||
ESP_LOGE(TAG, "setsockopt");
|
||||
return err;
|
||||
}
|
||||
|
||||
struct ip_mreq mreq;
|
||||
|
||||
mreq.imr_multiaddr.s_addr = inet_addr(p_group);
|
||||
|
||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY); /*default networt interface*/
|
||||
|
||||
/*join to the multicast group*/
|
||||
err = setsockopt(socket_id, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||
|
||||
if (err < 0) {
|
||||
ESP_LOGE(TAG, "setsockopt");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read data from the specific UDP connection by blocked
|
||||
*
|
||||
* @param [in] p_socket @n A descriptor identifying a UDP connection.
|
||||
* @param [in] p_data @n A pointer to a buffer to receive incoming data.
|
||||
* @param [out] datalen @n The length, in bytes, of the data pointed to by the 'p_data' parameter.
|
||||
* @return
|
||||
*
|
||||
* @retval < 0 : UDP connect error occur.
|
||||
* @retval = 0 : End of file.
|
||||
* @retval > 0 : The number of byte read.
|
||||
* @see None.
|
||||
*/
|
||||
int HAL_UDP_read(intptr_t p_socket,
|
||||
unsigned char *p_data,
|
||||
unsigned int datalen)
|
||||
{
|
||||
long socket_id = -1;
|
||||
int count = -1;
|
||||
|
||||
if (NULL == p_data || 0 == p_socket) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
socket_id = (long)p_socket;
|
||||
count = (int)read(socket_id, p_data, datalen);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
int HAL_UDP_readTimeout(intptr_t 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 (0 == 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 (hal_net_errno(socket_id) == EINTR) {
|
||||
return -3; /* want read */
|
||||
}
|
||||
|
||||
return -4; /* receive failed */
|
||||
}
|
||||
|
||||
/* This call will not block */
|
||||
return HAL_UDP_read(p_socket, p_data, datalen);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int HAL_UDP_recvfrom(intptr_t sockfd,
|
||||
NetworkAddr *p_remote,
|
||||
unsigned char *p_data,
|
||||
unsigned int datalen,
|
||||
unsigned int timeout_ms)
|
||||
{
|
||||
//printf("==========HAL_UDP_recvfromtimeout_ms :%d============\n",timeout_ms);
|
||||
int ret;
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
fd_set read_fds;
|
||||
struct timeval timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(sockfd, &read_fds);
|
||||
|
||||
ret = select(sockfd + 1, &read_fds, NULL, NULL, &timeout);
|
||||
|
||||
if (ret == 0) {
|
||||
return 0; /* receive timeout */
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (hal_net_errno(sockfd) == EINTR) {
|
||||
return -3; /* want read */
|
||||
}
|
||||
|
||||
return -4; /* receive failed */
|
||||
}
|
||||
|
||||
ret = recvfrom(sockfd, p_data, datalen, 0, (struct sockaddr *)&addr, &addr_len);
|
||||
|
||||
if (ret > 0) {
|
||||
if (NULL != p_remote) {
|
||||
p_remote->port = ntohs(addr.sin_port);
|
||||
|
||||
strcpy((char *)p_remote->addr, inet_ntoa(addr.sin_addr));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int HAL_UDP_sendto(intptr_t sockfd,
|
||||
const NetworkAddr *p_remote,
|
||||
const unsigned char *p_data,
|
||||
unsigned int datalen,
|
||||
unsigned int timeout_ms)
|
||||
{
|
||||
int ret;
|
||||
uint32_t ip;
|
||||
struct in_addr in;
|
||||
struct hostent *hp;
|
||||
struct sockaddr_in addr;
|
||||
fd_set write_fds;
|
||||
struct timeval timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
|
||||
|
||||
if (inet_aton((char *)p_remote->addr, &in)) {
|
||||
ip = *(uint32_t *)∈
|
||||
} else {
|
||||
hp = gethostbyname((char *)p_remote->addr);
|
||||
|
||||
if (!hp) {
|
||||
ESP_LOGE(TAG, "can't resolute the host address \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ip = *(uint32_t *)(hp->h_addr);
|
||||
}
|
||||
|
||||
FD_ZERO(&write_fds);
|
||||
FD_SET(sockfd, &write_fds);
|
||||
|
||||
ret = select(sockfd + 1, NULL, &write_fds, NULL, &timeout);
|
||||
|
||||
if (ret == 0) {
|
||||
return 0; /* write timeout */
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (hal_net_errno(sockfd) == EINTR) {
|
||||
return -3; /* want write */
|
||||
}
|
||||
|
||||
return -4; /* write failed */
|
||||
}
|
||||
|
||||
addr.sin_addr.s_addr = ip;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(p_remote->port);
|
||||
|
||||
ret = sendto(sockfd, p_data, datalen, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||
|
||||
if (ret < 0) {
|
||||
ESP_LOGE(TAG, "sendto");
|
||||
}
|
||||
|
||||
return (ret) > 0 ? ret : -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int HAL_UDP_write(intptr_t 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;
|
||||
}
|
||||
Reference in New Issue
Block a user