Help with TLS Socket Creation on Thingy53 - ENOMEM (Error 23) #87837
Replies: 4 comments
-
The error is actually too many files open, but if I close some sockets the wifi doesnt work, if i open then i get the error. |
Beta Was this translation helpful? Give feedback.
-
Whole code: /*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
/** @file
* @brief WiFi station sample
*/
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(sta, CONFIG_LOG_DEFAULT_LEVEL);
#include <zephyr/kernel.h>
#include <stdio.h>
#include <stdlib.h>
#include <zephyr/shell/shell.h>
#include <zephyr/sys/printk.h>
#include <zephyr/init.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/wifi_mgmt.h>
#include <zephyr/net/net_event.h>
#include <zephyr/drivers/gpio.h>
#include <net/wifi_mgmt_ext.h>
#include <net/wifi_ready.h>
/* HTTP client includes */
#include <zephyr/net/socket.h>
#include <zephyr/net/http/client.h>
#include <zephyr/net/dns_resolve.h>
/* TLS credential includes */
#include <zephyr/net/tls_credentials.h>
#include <zephyr/fs/fs.h>
#if defined(CONFIG_BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP) || \
defined(CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP)
#include <zephyr/drivers/wifi/nrf_wifi/bus/qspi_if.h>
#endif
#include "net_private.h"
#include "ca_certificate.h"
#define WIFI_SHELL_MODULE "wifi"
#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_CONNECT_RESULT | \
NET_EVENT_WIFI_DISCONNECT_RESULT)
#define MAX_SSID_LEN 32
#define STATUS_POLLING_MS 300
/* 1000 msec = 1 sec */
#define LED_SLEEP_TIME_MS 100
/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)
/*
* A build error on this line means your board is unsupported.
* See the sample documentation for information on how to fix this.
*/
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static struct net_mgmt_event_callback wifi_shell_mgmt_cb;
static struct net_mgmt_event_callback net_shell_mgmt_cb;
#ifdef CONFIG_WIFI_READY_LIB
static K_SEM_DEFINE(wifi_ready_state_changed_sem, 0, 1);
static bool wifi_ready_status;
#endif /* CONFIG_WIFI_READY_LIB */
static struct {
const struct shell *sh;
union {
struct {
uint8_t connected : 1;
uint8_t connect_result : 1;
uint8_t disconnect_requested : 1;
uint8_t _unused : 5;
};
uint8_t all;
};
} context;
/* HTTP client defines */
#define HTTP_PORT 80
#define HTTPS_PORT 443
#define MAX_RECV_BUF_LEN 512
#define MAX_SOCKET_RETRIES 3 /* Maximum number of socket creation retries */
/* TLS certificate defines */
#define CA_CERT_TAG 1
/* Socket tracking for debugging */
static int active_sockets = 0;
/* HTTP client variables */
static uint8_t recv_buf_ipv4[MAX_RECV_BUF_LEN];
static int sock4 = -1;
static struct sockaddr_in addr4;
/* Function declarations */
static void handle_wifi_disconnect_result(struct net_mgmt_event_callback *cb);
static void handle_wifi_connect_result(struct net_mgmt_event_callback *cb);
static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb,
uint32_t mgmt_event, struct net_if *iface);
static int connect_to_server(const char *server, uint16_t port);
static void disconnect_from_server(int sock);
static int perform_http_get(int sock, const char *server, const char *path);
static int get_azure_auth_token(void);
static int test_http_connection(void);
static int start_app(void);
/* Forward declarations */
void net_mgmt_callback_init(void);
void toggle_led(void)
{
int ret;
if (!device_is_ready(led.port)) {
LOG_ERR("LED device is not ready");
return;
}
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
if (ret < 0) {
LOG_ERR("Error %d: failed to configure LED pin", ret);
return;
}
while (1) {
if (context.connected) {
gpio_pin_toggle_dt(&led);
k_msleep(LED_SLEEP_TIME_MS);
} else {
gpio_pin_set_dt(&led, 0);
k_msleep(LED_SLEEP_TIME_MS);
}
}
}
K_THREAD_DEFINE(led_thread_id, 1024, toggle_led, NULL, NULL, NULL,
7, 0, 0);
static int cmd_wifi_status(void)
{
struct net_if *iface = net_if_get_default();
struct wifi_iface_status status = { 0 };
if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &status,
sizeof(struct wifi_iface_status))) {
LOG_INF("Status request failed");
return -ENOEXEC;
}
LOG_INF("==================");
LOG_INF("State: %s", wifi_state_txt(status.state));
if (status.state >= WIFI_STATE_ASSOCIATED) {
uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")];
LOG_INF("Interface Mode: %s",
wifi_mode_txt(status.iface_mode));
LOG_INF("Link Mode: %s",
wifi_link_mode_txt(status.link_mode));
LOG_INF("SSID: %.32s", status.ssid);
LOG_INF("BSSID: %s",
net_sprint_ll_addr_buf(
status.bssid, WIFI_MAC_ADDR_LEN,
mac_string_buf, sizeof(mac_string_buf)));
LOG_INF("Band: %s", wifi_band_txt(status.band));
LOG_INF("Channel: %d", status.channel);
LOG_INF("Security: %s", wifi_security_txt(status.security));
LOG_INF("MFP: %s", wifi_mfp_txt(status.mfp));
LOG_INF("RSSI: %d", status.rssi);
}
return 0;
}
static void handle_wifi_connect_result(struct net_mgmt_event_callback *cb)
{
const struct wifi_status *status =
(const struct wifi_status *) cb->info;
if (context.connected) {
return;
}
if (status->status) {
LOG_ERR("Connection failed (%d)", status->status);
} else {
LOG_INF("Connected");
context.connected = true;
}
context.connect_result = true;
}
static void handle_wifi_disconnect_result(struct net_mgmt_event_callback *cb)
{
const struct wifi_status *status =
(const struct wifi_status *) cb->info;
if (!context.connected) {
return;
}
if (context.disconnect_requested) {
LOG_INF("Disconnection request %s (%d)",
status->status ? "failed" : "done",
status->status);
context.disconnect_requested = false;
} else {
LOG_INF("Received Disconnected");
context.connected = false;
}
cmd_wifi_status();
}
static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb,
uint32_t mgmt_event, struct net_if *iface)
{
switch (mgmt_event) {
case NET_EVENT_WIFI_CONNECT_RESULT:
handle_wifi_connect_result(cb);
break;
case NET_EVENT_WIFI_DISCONNECT_RESULT:
handle_wifi_disconnect_result(cb);
break;
default:
break;
}
}
static void print_dhcp_ip(struct net_mgmt_event_callback *cb)
{
/* Get DHCP info from struct net_if_dhcpv4 and print */
const struct net_if_dhcpv4 *dhcpv4 = cb->info;
const struct in_addr *addr = &dhcpv4->requested_ip;
char dhcp_info[128];
net_addr_ntop(AF_INET, addr, dhcp_info, sizeof(dhcp_info));
LOG_INF("DHCP IP address: %s", dhcp_info);
}
static void net_mgmt_event_handler(struct net_mgmt_event_callback *cb,
uint32_t mgmt_event, struct net_if *iface)
{
switch (mgmt_event) {
case NET_EVENT_IPV4_DHCP_BOUND:
print_dhcp_ip(cb);
break;
default:
break;
}
}
static int wifi_connect(void)
{
struct net_if *iface = net_if_get_first_wifi();
context.connected = false;
context.connect_result = false;
if (net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, NULL, 0)) {
LOG_ERR("Connection request failed");
return -ENOEXEC;
}
LOG_INF("Connection requested");
return 0;
}
int bytes_from_str(const char *str, uint8_t *bytes, size_t bytes_len)
{
size_t i;
char byte_str[3];
if (strlen(str) != bytes_len * 2) {
LOG_ERR("Invalid string length: %zu (expected: %d)\n",
strlen(str), bytes_len * 2);
return -EINVAL;
}
for (i = 0; i < bytes_len; i++) {
memcpy(byte_str, str + i * 2, 2);
byte_str[2] = '\0';
bytes[i] = strtol(byte_str, NULL, 16);
}
return 0;
}
/* HTTP client implementation */
static int connect_to_server(const char *server, uint16_t port)
{
int sock;
struct addrinfo *result;
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM
};
/* Check if WiFi is connected before attempting to connect */
if (!context.connected) {
LOG_ERR("WiFi not connected. Cannot connect to server.");
return -ENOTCONN;
}
LOG_INF("Resolving address for %s", server);
int err = getaddrinfo(server, NULL, &hints, &result);
if (err) {
LOG_ERR("getaddrinfo() failed, err: %d", err);
return -EIO;
}
if (result == NULL) {
LOG_ERR("Error: Address not found");
return -ENOENT;
}
/* Create socket */
if (port == HTTPS_PORT) {
/* Create TLS socket for HTTPS */
LOG_INF("Creating TLS socket for HTTPS connection (current active sockets: %d)", active_sockets);
/* Delete any existing credentials with the same tag first */
err = tls_credential_delete(CA_CERT_TAG, TLS_CREDENTIAL_CA_CERTIFICATE);
LOG_INF("Deleted existing TLS credentials: %s", err < 0 ? "Failed" : "Success");
/* Add CA certificate to TLS credentials before creating socket */
LOG_INF("Adding embedded certificate to TLS credentials (size: %d bytes)", sizeof(azure_ca_certificate));
err = tls_credential_add(CA_CERT_TAG, TLS_CREDENTIAL_CA_CERTIFICATE,
azure_ca_certificate, sizeof(azure_ca_certificate));
if (err < 0) {
LOG_ERR("Failed to add embedded CA certificate: %d", err);
freeaddrinfo(result);
return err;
}
LOG_INF("Embedded CA certificate added to TLS credentials");
/* Retry socket creation a few times if it fails */
int retry_count = 0;
while (retry_count < MAX_SOCKET_RETRIES) {
/* Now create the TLS socket after credentials are set up */
sock = socket(result->ai_family, SOCK_STREAM, IPPROTO_TLS_1_2);
if (sock >= 0) {
/* Socket created successfully */
active_sockets++;
break;
}
LOG_ERR("Failed to create TLS socket, err: %d (%s), retry %d/%d",
errno, strerror(errno), retry_count + 1, MAX_SOCKET_RETRIES);
/* If we're out of file descriptors, try to clean up and wait */
if (errno == ENFILE || errno == EMFILE) {
/* Clean up TLS credentials */
tls_credential_delete(CA_CERT_TAG, TLS_CREDENTIAL_CA_CERTIFICATE);
LOG_INF("Waiting for resources to be freed...");
k_sleep(K_SECONDS(1));
}
retry_count++;
}
if (sock < 0) {
LOG_ERR("Failed to create TLS socket after %d retries", MAX_SOCKET_RETRIES);
/* Clean up TLS credentials if socket creation fails */
tls_credential_delete(CA_CERT_TAG, TLS_CREDENTIAL_CA_CERTIFICATE);
freeaddrinfo(result);
return -errno;
}
LOG_INF("TLS Socket created successfully with fd: %d (active sockets: %d)", sock, active_sockets);
/* TLS configuration */
sec_tag_t sec_tag_list[] = { CA_CERT_TAG };
int verify = TLS_PEER_VERIFY_REQUIRED;
/* Set TLS security tag list */
LOG_INF("Setting TLS security tag list");
err = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list, sizeof(sec_tag_list));
if (err < 0) {
LOG_ERR("Failed to set TLS_SEC_TAG_LIST, err %d (%s)", errno, strerror(errno));
close(sock);
freeaddrinfo(result);
return -errno;
}
LOG_INF("TLS security tag list set successfully");
/* Set TLS peer verification to required */
LOG_INF("Setting TLS peer verification to required");
err = setsockopt(sock, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));
if (err < 0) {
LOG_ERR("Failed to set TLS_PEER_VERIFY, err %d (%s)", errno, strerror(errno));
close(sock);
freeaddrinfo(result);
return -errno;
}
LOG_INF("TLS peer verification set to required");
/* Set TLS hostname for verification */
LOG_INF("Setting TLS hostname to: %s", server);
err = setsockopt(sock, SOL_TLS, TLS_HOSTNAME, server, strlen(server) + 1);
if (err < 0) {
LOG_ERR("Failed to set TLS_HOSTNAME option: %d (%s)", errno, strerror(errno));
close(sock);
freeaddrinfo(result);
return -errno;
}
LOG_INF("TLS hostname set successfully");
} else {
/* Create regular TCP socket for HTTP */
LOG_INF("Creating regular TCP socket for HTTP connection");
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
LOG_ERR("Failed to create socket, err: %d (%s)", errno, strerror(errno));
freeaddrinfo(result);
return -errno;
}
}
/* Set up address struct */
memcpy(&addr4, result->ai_addr, sizeof(struct sockaddr_in));
addr4.sin_port = htons(port);
char ip_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &addr4.sin_addr, ip_str, sizeof(ip_str));
LOG_INF("Connecting to server at %s:%d", ip_str, port);
freeaddrinfo(result);
/* Connect to server */
err = connect(sock, (struct sockaddr *)&addr4, sizeof(addr4));
if (err < 0) {
LOG_ERR("Failed to connect to server, err: %d (%s)", errno, strerror(errno));
close(sock);
return -errno;
}
if (port == HTTPS_PORT) {
LOG_INF("Connected to server over HTTPS (socket fd: %d)", sock);
/* Verify TLS connection was established successfully */
int verify_result = 0;
socklen_t verify_size = sizeof(verify_result);
err = getsockopt(sock, SOL_TLS, TLS_PEER_VERIFY, &verify_result, &verify_size);
if (err < 0) {
LOG_ERR("Failed to get TLS verification result: %d (%s)", errno, strerror(errno));
} else if (verify_result != 0) {
LOG_ERR("TLS certificate verification failed: %d", verify_result);
close(sock);
return -EACCES;
} else {
LOG_INF("TLS certificate verification succeeded");
}
} else {
LOG_INF("Connected to server over HTTP (socket fd: %d)", sock);
}
return sock;
}
static void disconnect_from_server(int sock)
{
if (sock > 0) {
LOG_INF("Closing socket fd: %d (active sockets: %d)", sock, active_sockets);
(void)close(sock);
active_sockets--;
LOG_INF("Socket closed. Active sockets remaining: %d", active_sockets);
}
}
static int perform_http_get(int sock, const char *server, const char *path)
{
int sent;
int total_sent = 0;
int received;
char request[256];
int request_len;
/* Format HTTP GET request */
request_len = snprintf(request, sizeof(request),
"GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Connection: close\r\n"
"\r\n",
path, server);
if (request_len <= 0) {
LOG_ERR("Failed to create HTTP request");
return -EINVAL;
}
/* Send HTTP request */
do {
sent = send(sock, &request[total_sent], request_len - total_sent, 0);
if (sent < 0) {
LOG_ERR("Failed to send HTTP request, err: %d", errno);
return -errno;
}
total_sent += sent;
} while (total_sent < request_len);
LOG_INF("HTTP request sent: %d bytes", total_sent);
/* Receive HTTP response */
LOG_INF("HTTP response:");
do {
received = recv(sock, recv_buf_ipv4, sizeof(recv_buf_ipv4) - 1, 0);
if (received < 0) {
LOG_ERR("Failed to receive HTTP response, err: %d", errno);
return -errno;
}
if (received > 0) {
/* Null-terminate the received data for printing */
recv_buf_ipv4[received] = 0;
LOG_INF("%s", recv_buf_ipv4);
}
} while (received > 0);
return 0;
}
static int test_http_connection(void)
{
int ret;
const char *server = "httpbin.org";
const char *path = "/get";
LOG_INF("Connecting to %s...", server);
/* Connect to server */
sock4 = connect_to_server(server, HTTP_PORT);
if (sock4 < 0) {
LOG_ERR("Failed to connect to server: %d", sock4);
return sock4;
}
LOG_INF("Connected to %s", server);
/* Perform HTTP GET request */
ret = perform_http_get(sock4, server, path);
if (ret < 0) {
LOG_ERR("Failed to perform HTTP GET request: %d", ret);
disconnect_from_server(sock4);
return ret;
}
/* Disconnect from server */
disconnect_from_server(sock4);
sock4 = -1;
LOG_INF("HTTP test completed successfully");
return 0;
}
/* Define Microsoft Speech API key */
#define MS_SPEECH_KEY "5Mkszj3yFl2vmbRDchDUHDAOMiZAYmzaLzA508JrnpRYYKBsv4nqJQQJ99BCAC5RqLJXJ3w3AAAYACOGVfQg"
/* Function to get Microsoft Speech API authentication token */
static int get_azure_auth_token(void)
{
int sock;
const char *server = "westeurope.api.cognitive.microsoft.com";
const char *path = "/sts/v1.0/issuetoken"; /* Actual token endpoint */
char request[512];
int request_len;
int sent;
int total_sent = 0;
int received;
char recv_buf[512];
LOG_INF("Getting Azure authentication token...");
/* Check if WiFi is connected before attempting to connect */
if (!context.connected) {
LOG_ERR("WiFi not connected. Cannot connect to Azure server.");
return -ENOTCONN;
}
/* Connect to Azure server using HTTPS for secure connection */
sock = connect_to_server(server, HTTPS_PORT);
if (sock < 0) {
LOG_ERR("Failed to connect to Azure server: %d", sock);
return sock;
}
LOG_INF("Connected to Azure server, socket fd: %d", sock);
/* Format HTTP POST request with API key */
request_len = snprintf(request, sizeof(request),
"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Ocp-Apim-Subscription-Key: %s\r\n"
"Content-Length: 0\r\n"
"Connection: close\r\n"
"\r\n",
path, server, MS_SPEECH_KEY);
/* Send the request */
do {
sent = send(sock, &request[total_sent], request_len - total_sent, 0);
if (sent < 0) {
LOG_ERR("Failed to send HTTP request, err: %d", errno);
disconnect_from_server(sock);
return -errno;
}
total_sent += sent;
} while (total_sent < request_len);
LOG_INF("Azure authentication request sent: %d bytes", total_sent);
/* Receive the response */
LOG_INF("Azure authentication response:");
do {
received = recv(sock, recv_buf, sizeof(recv_buf) - 1, 0);
if (received < 0) {
LOG_ERR("Failed to receive HTTP response, err: %d", errno);
disconnect_from_server(sock);
return -errno;
}
if (received > 0) {
/* Null-terminate the received data for printing */
recv_buf[received] = 0;
LOG_INF("%s", recv_buf);
}
} while (received > 0);
disconnect_from_server(sock);
LOG_INF("Azure authentication token retrieval completed");
return 0;
}
int start_app(void)
{
int ret;
#if defined(CONFIG_BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP) || \
defined(CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP)
/* Initialize the bus */
ret = nrf_wifi_init_qspi();
if (ret) {
LOG_ERR("nrf_wifi_init_qspi() failed with %d", ret);
return ret;
}
#endif /* CONFIG_BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP */
/* Initialize net_mgmt callbacks */
net_mgmt_callback_init();
/* Connect to WiFi network */
ret = wifi_connect();
if (ret) {
LOG_ERR("wifi_connect() failed with %d", ret);
return ret;
}
/* Wait for connection to complete */
LOG_INF("Waiting for WiFi connection...");
int timeout_counter = 0;
const int max_timeout = 30; // 30 seconds timeout
while (!context.connected && timeout_counter < max_timeout) {
k_sleep(K_MSEC(1000));
timeout_counter++;
LOG_INF("Waiting for WiFi connection... %d/%d", timeout_counter, max_timeout);
}
if (!context.connected) {
LOG_ERR("WiFi connection timed out after %d seconds", max_timeout);
return -ETIMEDOUT;
}
/* Wait a bit more to ensure DHCP is completed */
LOG_INF("WiFi connected, waiting for DHCP...");
k_sleep(K_SECONDS(3));
/* Check WiFi status */
cmd_wifi_status();
/* Test HTTP connection */
LOG_INF("Testing HTTP connection...");
ret = test_http_connection();
if (ret) {
LOG_ERR("HTTP connection test failed: %d", ret);
} else {
LOG_INF("HTTP test completed successfully");
}
/* Allow some time for resources to be freed */
LOG_INF("Waiting for resources to be freed before Azure test...");
k_sleep(K_SECONDS(5));
/* Test Azure authentication */
LOG_INF("Getting Azure authentication token...");
ret = get_azure_auth_token();
if (ret) {
LOG_ERR("Azure authentication failed: %d", ret);
} else {
LOG_INF("Azure authentication completed successfully");
}
return 0;
}
#ifdef CONFIG_WIFI_READY_LIB
void start_wifi_thread(void);
#define THREAD_PRIORITY K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1)
K_THREAD_DEFINE(start_wifi_thread_id, CONFIG_STA_SAMPLE_START_WIFI_THREAD_STACK_SIZE,
start_wifi_thread, NULL, NULL, NULL,
THREAD_PRIORITY, 0, -1);
void start_wifi_thread(void)
{
start_app();
}
void wifi_ready_cb(bool wifi_ready)
{
LOG_DBG("Is Wi-Fi ready?: %s", wifi_ready ? "yes" : "no");
wifi_ready_status = wifi_ready;
k_sem_give(&wifi_ready_state_changed_sem);
}
#endif /* CONFIG_WIFI_READY_LIB */
void net_mgmt_callback_init(void)
{
memset(&context, 0, sizeof(context));
net_mgmt_init_event_callback(&wifi_shell_mgmt_cb,
wifi_mgmt_event_handler,
WIFI_SHELL_MGMT_EVENTS);
net_mgmt_add_event_callback(&wifi_shell_mgmt_cb);
net_mgmt_init_event_callback(&net_shell_mgmt_cb,
net_mgmt_event_handler,
NET_EVENT_IPV4_DHCP_BOUND);
net_mgmt_add_event_callback(&net_shell_mgmt_cb);
LOG_INF("Starting %s with CPU frequency: %d MHz", CONFIG_BOARD, SystemCoreClock/MHZ(1));
k_sleep(K_SECONDS(1));
}
#ifdef CONFIG_WIFI_READY_LIB
static int register_wifi_ready(void)
{
int ret = 0;
wifi_ready_callback_t cb;
struct net_if *iface = net_if_get_first_wifi();
if (!iface) {
LOG_ERR("Failed to get Wi-Fi interface");
return -1;
}
cb.wifi_ready_cb = wifi_ready_cb;
LOG_DBG("Registering Wi-Fi ready callbacks");
ret = register_wifi_ready_callback(cb, iface);
if (ret) {
LOG_ERR("Failed to register Wi-Fi ready callbacks %s", strerror(ret));
return ret;
}
return ret;
}
#endif /* CONFIG_WIFI_READY_LIB */
int main(void)
{
int ret = 0;
net_mgmt_callback_init();
#ifdef CONFIG_WIFI_READY_LIB
ret = register_wifi_ready();
if (ret) {
return ret;
}
k_thread_start(start_wifi_thread_id);
#else
start_app();
#endif /* CONFIG_WIFI_READY_LIB */
return ret;
} |
Beta Was this translation helpful? Give feedback.
-
Maybe too much sockets, I am not sure but I need help to optimize it. |
Beta Was this translation helpful? Give feedback.
-
What I've done to fix the Azure authentication issue: I have inspected the Zephyr code which couldn't successfully complete Azure cognitive services authentication. TLS socket options failing with error 109 (ENOTSUP) I've tried multiple approaches: Fixed HTTP request formatting to match curl exactly Nothing did work. The latest log shows:
Current code /* TLS configuration in connect_to_server */
if (use_tls) {
ret = setup_tls_credentials();
if (ret < 0) {
LOG_ERR("Failed to set up TLS credentials: %d", ret);
close(sock);
untrack_socket(sock);
zsock_freeaddrinfo(result);
return ret;
}
/* Set TLS options */
int tls_options = TLS_PEER_VERIFY_REQUIRED;
ret = zsock_setsockopt(sock, SOL_TLS, TLS_PEER_VERIFY, &tls_options, sizeof(tls_options));
if (ret < 0) {
LOG_ERR("Failed to set TLS peer verification: %d", errno);
close(sock);
untrack_socket(sock);
zsock_freeaddrinfo(result);
return -EIO;
}
/* Set TLS certificate */
struct tls_credential cert = {
.type = TLS_CREDENTIAL_CA_CERTIFICATE,
.tag = CA_CERT_TAG
};
ret = zsock_setsockopt(sock, SOL_TLS, TLS_CREDENTIAL, &cert, sizeof(cert));
if (ret < 0) {
LOG_ERR("Failed to set TLS certificate: %d", errno);
close(sock);
untrack_socket(sock);
zsock_freeaddrinfo(result);
return -EIO;
}
LOG_INF("Proceeding with TLS connection");
} /* HTTP request sent in two parts in get_azure_auth_token */
const char *http_headers =
"POST /sts/v1.0/issuetoken HTTP/1.1\r\n"
"Host: westeurope.api.cognitive.microsoft.com\r\n"
"Ocp-Apim-Subscription-Key: 5Mkszj3yFl2vmbRDchDUHDAOMiZAYmzaLzA508JrnpRYYKBsv4nqJQQJ99BCAC5RqLJXJ3w3AAAYACOGVfQg\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: 0\r\n";
/* Empty line to separate headers from body */
const char *empty_line = "\r\n";
/* Send headers first */
int sent = zsock_send(sock, http_headers, headers_len, 0);
/* Add small delay to ensure headers are processed */
k_sleep(K_MSEC(100));
/* Now send the empty line separately */
sent = zsock_send(sock, empty_line, 2, 0); /* print_tls_error_info function to debug TLS issues */
void print_tls_error_info(int sock)
{
int err;
socklen_t optlen = sizeof(err);
if (getsockopt(sock, SOL_TLS, TLS_ERROR_OPTION, &err, &optlen) == 0) {
LOG_ERR("TLS error code: %d", err);
switch (err) {
case MBEDTLS_ERR_SSL_CONN_RESET:
LOG_ERR("Connection reset by peer");
break;
case MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO:
LOG_ERR("Bad server hello message");
break;
/* Other error cases... */
}
}
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm working on a Thingy53 project with Zephyr RTOS that requires TLS connections, but I'm encountering persistent "Failed to create TLS socket: 23" errors (ENOMEM - out of memory). I've implemented several memory optimizations and error handling strategies but still face issues with TLS socket creation.
Initial Problem Identification
k_malloc_free_get
Configuration Optimization
prj.conf
TLS Cipher Configuration Issues
CONFIG_MBEDTLS_SSL_CIPHERSUITES
configurationFirst Socket Implementation Approach
Second Socket Implementation Approach
IPPROTO_TLS_1_2
Memory Management Improvements
Current Status
k_yield()
and socket trackingI'm tracking sockets and cleaning them up:
void track_socket(int sock)
{
// Track socket for potential cleanup
}
void untrack_socket(int sock)
{
// Remove socket from tracking
}
void close_all_sockets(void)
{
// Close all tracked sockets to free resources
}
I've made the following memory optimizations in prj.conf:
Increase heap memory pool size
CONFIG_HEAP_MEM_POOL_SIZE=200000
CONFIG_HEAP_MEM_POOL_IGNORE_MIN=y
TLS Configuration
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=85000
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=1536
Reduce TLS resource usage
CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=2
CONFIG_NET_SOCKETS_TLS_MAX_CREDENTIALS=2
CONFIG_NET_CONTEXT_MAX_CONN=4
Are there additional memory optimizations I should be making for TLS on constrained devices like the Thingy53?
Could there be any memory leaks or resource allocation issues that I'm missing in my implementation?
Are there specific mbedTLS configurations I should be adjusting to reduce memory usage further?
Is there a way to debug exactly what's happening during TLS socket creation that's causing the ENOMEM error?
Should I be implementing a different approach for TLS on this device?
Beta Was this translation helpful? Give feedback.
All reactions