默认的 TLS
功能是打开的, 这里可以使用 , 由于TLS证书有时间的要求,如果错误的系统时间可能会导致TLS报错。
#include "esp_crt_bundle.h"
#include "esp_err.h"
#include "esp_event.h"
#include "esp_http_client.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_tls.h"
#include "esp_wifi.h"
#include "esp_wifi_default.h"
#include "esp_wifi_types_generic.h"
#include "freertos/FreeRTOS.h"
#include "freertos/idf_additions.h"
#include "freertos/task.h"
#include "lwip/sockets.h"
#include "mbedtls/platform_util.h"
#include "nvs_flash.h"
#include <assert.h>
#include <lwip/netdb.h>
#include <stdio.h>
static const char *TAG = "HTTPS";
bool isConnected = false;
static EventGroupHandle_t s_wifi_event_group;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static int s_retry_num = 0;
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data) {
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT &&
event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retry_num < 5) {
esp_wifi_connect();
s_retry_num += 1;
ESP_LOGI("STA", "retry connect to the AP");
} else {
// 超时
xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
}
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
wifi_event_sta_connected_t *event =
(wifi_event_sta_connected_t *)event_data;
ESP_LOGI("STA", "connected: %s", event->ssid);
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
// 拿到 IP, 应该可以冲浪了
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
}
void wifiInit() {
// 初始化 netif 和事件轮训
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
// 默认配置设置wifi
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// 注册事件回调
ESP_ERROR_CHECK(esp_event_handler_instance_register(
WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, NULL));
ESP_ERROR_CHECK(esp_event_handler_instance_register(
IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, NULL));
// 初始化 sta 和 netif, 个人感觉是为netif接入sta
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
// sta 配置, 你要连接哪个wifi
wifi_config_t wifi_config = {
.sta =
{
.ssid = "Man_2.4GHz",
.password = "liang114514",
},
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
// 开始干活
ESP_ERROR_CHECK(esp_wifi_start());
}
esp_err_t _http_event_handler(esp_http_client_event_t *evt) {
switch (evt->event_id) {
case HTTP_EVENT_ON_DATA:
// 可能会多次接受数据, 进阶是将接受到数据输入缓冲区
ESP_LOGI(TAG, "HTTP data received: %s", (char *)evt->data);
break;
case HTTP_EVENT_ERROR:
break;
case HTTP_EVENT_ON_FINISH:
break;
case HTTP_EVENT_DISCONNECTED:
// 断开连接通常是HTTP接受到所有的报文, 可以发出信号通知接收到完整的报文
break;
default:
break;
}
return ESP_OK;
}
void https_get_task(void *pvParameters) {
// 配置 HTTPS 请求
esp_http_client_config_t config = {
.url = "<https://wttr.in/Beijing?format=%t+%c+%h>",
.event_handler = _http_event_handler,
.method = HTTP_METHOD_GET,
.crt_bundle_attach = esp_crt_bundle_attach, // 使用 x509 证书包, tls 认证
};
// 初始化 HTTP 客户端
esp_http_client_handle_t client = esp_http_client_init(&config);
if (client == NULL) {
ESP_LOGE(TAG, "Failed to initialize HTTP client");
vTaskDelete(NULL);
return;
}
// 发送请求
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
} else {
ESP_LOGE(TAG, "HTTPS request failed: %s", esp_err_to_name(err));
}
// 清理
esp_http_client_cleanup(client);
vTaskDelete(NULL);
}
void app_main() {
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
s_wifi_event_group = xEventGroupCreate();
wifiInit();
// 无限等待, 返回
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE, pdFALSE, portMAX_DELAY);
// esp_tls_t *tls = esp_tls_init();
// if (!tls) {
// ESP_LOGE(TAG, "Failed to allocate esp_tls handle!");
// return;
// }
xTaskCreate(&https_get_task, "https_get_task", 8192, NULL, 5, NULL);
}
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "nvs_flash.h"
#include "lwip/err.h"
#include "lwip/sys.h"
#include "esp_http_client.h"
#define EXAMPLE_WIFI_SSID "your_ssid"
#define EXAMPLE_WIFI_PASS "your_password"
#define MAX_HTTP_RECV_BUFFER 1024
#define TAG "HTTP_CLIENT"
static void wifi_init(void);
static void http_post_task(void *pvParameters);
// HTTP 事件处理回调函数
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
static char *output_buffer; // 用于存储完整的 HTTP 响应
static int output_len = 0; // 响应数据的长度
switch(evt->event_id) {
case HTTP_EVENT_ON_DATA:
// 接收到数据时,动态分配内存并追加数据
if (!output_buffer) {
output_buffer = (char *)malloc(evt->data_len);
memcpy(output_buffer, evt->data, evt->data_len);
output_len = evt->data_len;
} else {
output_buffer = (char *)realloc(output_buffer, output_len + evt->data_len);
memcpy(output_buffer + output_len, evt->data, evt->data_len);
output_len += evt->data_len;
}
break;
case HTTP_EVENT_ON_FINISH:
// 请求完成,打印完整的响应报文
ESP_LOGI(TAG, "HTTP Response received, length=%d", output_len);
ESP_LOGI(TAG, "Response:\\n%.*s", output_len, output_buffer);
// 释放内存
free(output_buffer);
output_buffer = NULL;
output_len = 0;
break;
case HTTP_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "HTTP Disconnected");
// 释放内存
if (output_buffer) {
free(output_buffer);
output_buffer = NULL;
output_len = 0;
}
break;
case HTTP_EVENT_ERROR:
ESP_LOGE(TAG, "HTTP Error");
break;
default:
break;
}
return ESP_OK;
}
static void http_post_task(void *pvParameters)
{
// JSON 数据示例
char post_data[] = "{\\"key\\":\\"value\\",\\"id\\":123}";
// 配置 HTTP 客户端
esp_http_client_config_t config = {
.url = "<http://example.com/api>", // 替换为目标 POST URL
.method = HTTP_METHOD_POST,
.event_handler = _http_event_handler,
.timeout_ms = 10000, // 设置超时时间
};
// 初始化 HTTP 客户端
esp_http_client_handle_t client = esp_http_client_init(&config);
// 设置请求头
esp_http_client_set_header(client, "Content-Type", "application/json");
// 设置 POST 数据
esp_http_client_set_post_field(client, post_data, strlen(post_data));
// 发送 HTTP POST 请求
esp_err_t err = esp_http_client_perform(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d",
esp_http_client_get_status_code(client),
esp_http_client_get_content_length(client));
} else {
ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
}
// 清理客户端
esp_http_client_cleanup(client);
vTaskDelete(NULL);
}
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
esp_wifi_connect();
ESP_LOGI(TAG, "Retry to connect to the AP");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&event->ip_info.ip));
// WiFi 连接成功后启动 HTTP POST 任务
xTaskCreate(&http_post_task, "http_post_task", 4096, NULL, 5, NULL);
}
}
static void wifi_init(void)
{
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id);
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, &instance_got_ip);
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
esp_wifi_start();
}
void app_main(void)
{
// 初始化 NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// 初始化 WiFi
wifi_init();
}