ESP32平台C语言Raw Socket抽离为独立函数后触发SW_CPU_RESET重启问题求助
Hey there! As a fellow C/ESP32 developer, I can spot a few critical issues in your refactored send_data function that are causing the CPU reset. Let's walk through each problem and fix them step by step.
Key Issues Causing the Crash
1. Incorrect Function Parameter Type
Your send_data function is declared to take a single char instead of a pointer to a char array (string). When you pass buf (a char array) to this function, it gets implicitly converted to the first character of the array, and the rest of the string is lost. This leads to invalid memory access when you try to use it later.
Fix: Change the parameter type to char* buf:
void send_data(char* buf) { // ... rest of the code }
2. Mismatched Pointer Type for Base64 Input
The line char* *input = buf; tries to assign a char* (buf) to a char** (input)—this is a type mismatch that causes undefined behavior (like accessing memory it shouldn't). The mbedtls_base64_encode function expects a const unsigned char* for the input, so you can directly cast buf to that type.
Fix: Replace that line with a direct cast, or skip the intermediate variable entirely:
// Option 1: Use a correctly typed variable const unsigned char* input = (const unsigned char*)buf; mbedtls_base64_encode(output, 64, &outlen, input, strlen(buf)); // Option 2: Pass buf directly (cleaner) mbedtls_base64_encode(output, 64, &outlen, (const unsigned char*)buf, strlen(buf));
3. Wrong Address Size in connect()
You're using sizeof(struct sockaddr_in6) (for IPv6 addresses) but your dest_addr is a struct sockaddr_in (IPv4). Passing the wrong size here can cause memory corruption or failed connections, leading to crashes when you try to use the socket.
Fix: Use the size of your actual dest_addr structure:
connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
4. Missing Error Handling for Socket Operations
Neither socket() nor connect() are guaranteed to succeed. If either returns an error (like -1), continuing to use the invalid socket descriptor will cause undefined behavior, including crashes.
Fix: Add basic error checking to handle failures gracefully:
int sock = socket(addr_family, SOCK_STREAM, ip_protocol); if (sock < 0) { ESP_LOGE("SEND_DATA", "Failed to create socket: %d", errno); return; } int conn_ret = connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); if (conn_ret != 0) { ESP_LOGE("SEND_DATA", "Failed to connect: %d", errno); close(sock); return; }
Corrected send_data Function
Here's the full fixed version of your function (with a few extra improvements):
#include <errno.h> // Don't forget to include this for errno handling void send_data(char* buf) { char host_ip[] = HOST_IP_ADDR; int addr_family = AF_INET; int ip_protocol = IPPROTO_IP; struct sockaddr_in dest_addr; dest_addr.sin_addr.s_addr = inet_addr(host_ip); dest_addr.sin_family = AF_INET; dest_addr.sin_port = htons(PORT); int sock = socket(addr_family, SOCK_STREAM, ip_protocol); if (sock < 0) { ESP_LOGE("SEND_DATA", "Socket creation failed: %d", errno); return; } int conn_status = connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); if (conn_status != 0) { ESP_LOGE("SEND_DATA", "Connection failed: %d", errno); close(sock); return; } unsigned char output[64]; size_t outlen; mbedtls_base64_encode(output, sizeof(output), &outlen, (const unsigned char*)buf, strlen(buf)); // Use outlen instead of strlen(output) - it's the exact length returned by the encode function send(sock, output, outlen, 0); send(sock, "\n", 1, 0); // strlen("\n") is always 1, so we can use this directly shutdown(sock, 0); close(sock); }
Additional Notes
- I swapped
strlen((const char*) output)foroutlenbecause the base64 encode function returns the exact length of the encoded data—this is more reliable than relying onstrlen(even though base64 output is usually null-terminated). - For better efficiency, consider reusing the socket instead of creating a new one for every AP entry. This reduces overhead and avoids hitting socket limits on the ESP32.
内容的提问来源于stack exchange,提问作者Security Researcher

