I'm writing an intentionally trivial wrapper around some socket code for an esp32C6 and I'm stuck at something that might be obvious to someone else.
I have code that works fine, but as I try to lift more out the C I get an timeout response from the server instead of the true response.
Both calls to write return 78 now. Originally the non-working one sent 77 so I figured it was a null termination issue, but appending a 0 didn't seem to work?
I am using a swiftly install of swift 6.2 release but happy to try a different toolchain, still on macOS 15 for a smidge longer, compiling with a CMake file and the esp-idf 5.5 tools.
Works
//NOTE: none of the func mappings use socklen_t ?
internal typealias SocketHandle = CInt
func wrappedWrite(with socket: SocketHandle, to host: String, at path: String) {
let local_host = host.utf8CString
let local_path = path.utf8CString
//TODO: test with span/inline array (esp-idf 6? OS26)
local_path.withContiguousStorageIfAvailable { route_buffer in
local_host.withContiguousStorageIfAvailable { host_buffer in
let resultCode = http_bridge_just_write(
socket, host_buffer.baseAddress, route_buffer.baseAddress)
print("write result code: \(resultCode)")
}
}
}
// int http_bridge_just_write(const socklen_t s, const char *host, const char *path)
int http_bridge_just_write(const int s, const char *host, const char *path) {
char req[128];
printf("requestSize: %u", sizeof(req));
snprintf(req, sizeof(req),
"GET %s HTTP/1.0\r\n"
"Host: %s\r\n"
"User-Agent: esp-idf/5.5\r\n"
"\r\n",
path, host);
printf("stringLength: %u", strlen(req));
int err_or_count = write(s, req, strlen(req));
if (err_or_count < 0) {
printf("send failed");
close(s);
return 4;
}
return err_or_count;
}
Receives 408 (Server Timed Out):
func writeRequest(with socket: SocketHandle, to host: String, at path: String) throws(HTTPClientError) {
let userAgent = "esp-idf/5.5"
var request: ContiguousArray<CChar> =
"GET \(path) HTTP/1.0\r\nHost: \(host)\r\nUser-Agent: \(userAgent)\r\n".utf8CString
//made no change.
request.append(0)
print("request length: \(request.count)")
print("\(request)")
let result = request.withContiguousStorageIfAvailable { request_buffer in
let writeResponse = write(socket, request_buffer.baseAddress, request_buffer.count)
print("writeResponse: \(writeResponse)")
return writeResponse
}
if result != nil && result! < 0 {
throw HTTPClientError.sendFailed
}
if result == nil {
print("what happened?")
throw HTTPClientError.unsendableRequest
}
}
Full project for context if it will help. There are some known glaring flaws but all feedback welcome: GitHub - carlynorama/swift_esp32c6_hello at e_ImproveHTTPClient
(NOTE: if anyone does run this, I find that I have to unplug it and plug it back in while the monitor is still running if I use idf.py build flash monitor
, but that's a esp-idf uncleared cached DNS value thing I still have to chase down I'm pretty sure.)