esp-idf/examples/protocols/http_request/main/http_request_example_main.c

149 wiersze
4.9 KiB
C

/* HTTP GET Example using plain POSIX sockets
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
#include "sdkconfig.h"
/* Constants that aren't configurable in menuconfig */
// Default example will work on all networks: IPv4 only, IPv6 only, and dual stack
#define WEB_SERVER "v4v6.ipv6-test.com"
// Alternative tests for IPv4 only and IPv6 only destinations
//#define WEB_SERVER "v4.ipv6-test.com"
//#define WEB_SERVER "v6.ipv6-test.com"
#define WEB_PORT "80"
// This will reflect the IP address the server sees, e.g. NAT64 will return the public IPv4
#define WEB_PATH "/api/myip.php"
static const char *TAG = "example";
static const char *REQUEST = "GET " WEB_PATH " HTTP/1.0\r\n"
"Host: "WEB_SERVER":"WEB_PORT"\r\n"
"User-Agent: esp-idf/1.0 esp32\r\n"
"\r\n";
static void http_get_task(void *pvParameters)
{
struct addrinfo *res;
void *addr;
int s, r;
char recv_buf[64];
while(1) {
ESP_LOGI(TAG, "DNS lookup %s (port %s)", WEB_SERVER, WEB_PORT);
int err = example_getaddrinfo(WEB_SERVER, WEB_PORT, &res);
if(err != 0 || res == NULL) {
ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p", err, res);
vTaskDelay(1000 / portTICK_PERIOD_MS);
continue;
}
/* Code to print the resolved IP. */
#if LWIP_IPV4 && LWIP_IPV6
if (res->ai_family == AF_INET6) {
addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
} else {
addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
}
#elif LWIP_IPV6
addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
#elif LWIP_IPV4
addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
#endif
char ipStr[128];
inet_ntop(res->ai_family, addr, ipStr, sizeof(ipStr));
ESP_LOGI(TAG, "DNS lookup succeeded. (%i) IP=%s", res->ai_family, ipStr);
s = socket(res->ai_family, res->ai_socktype, 0);
if(s < 0) {
ESP_LOGE(TAG, "... Failed to allocate socket.");
freeaddrinfo(res);
vTaskDelay(1000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGI(TAG, "... allocated socket");
if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
ESP_LOGE(TAG, "... socket connect failed errno=%d", errno);
close(s);
freeaddrinfo(res);
vTaskDelay(4000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGI(TAG, "... connected");
freeaddrinfo(res);
if (write(s, REQUEST, strlen(REQUEST)) < 0) {
ESP_LOGE(TAG, "... socket send failed");
close(s);
vTaskDelay(4000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGI(TAG, "... socket send success");
struct timeval receiving_timeout;
receiving_timeout.tv_sec = 5;
receiving_timeout.tv_usec = 0;
if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &receiving_timeout,
sizeof(receiving_timeout)) < 0) {
ESP_LOGE(TAG, "... failed to set socket receiving timeout");
close(s);
vTaskDelay(4000 / portTICK_PERIOD_MS);
continue;
}
ESP_LOGI(TAG, "... set socket receiving timeout success");
/* Read HTTP response */
do {
bzero(recv_buf, sizeof(recv_buf));
r = read(s, recv_buf, sizeof(recv_buf)-1);
for(int i = 0; i < r; i++) {
putchar(recv_buf[i]);
}
} while(r > 0);
putchar('\n');
ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d.", r, errno);
close(s);
for(int countdown = 10; countdown >= 0; countdown--) {
ESP_LOGI(TAG, "%d... ", countdown);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
ESP_LOGI(TAG, "Starting again!");
}
}
void app_main(void)
{
ESP_ERROR_CHECK( nvs_flash_init() );
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
* Read "Establishing Wi-Fi or Ethernet Connection" section in
* examples/protocols/README.md for more information about this function.
*/
ESP_ERROR_CHECK(example_connect());
xTaskCreate(&http_get_task, "http_get_task", 4096, NULL, 5, NULL);
}