DevAcademy Lesson 5, HTTP over Wi-Fi (Exercise 2), does not build with nrf7002dk_nrf5340_cpuapp when CONFIG_WPA_SUPP_CRYPTO_PSA=y is enabled

Hi,

I am following DevAcademy Lesson 5, HTTP over Wi-Fi (Exercise 2), which involves adding TLS to an HTTP connection.

When I remove CONFIG_WPA_SUPP_CRYPTO_PSA=y, I am able to successfully build the code for nrf7002dk_nrf5340_cpuapp.

Will removing this configuration affect HTTP functionality?

Additionally, with CONFIG_MBEDTLS_RSA_C=y enabled, I receive the following warning:

CONFIG_MBEDTLS_RSA_C was assigned the value y, but got the value n. Missing dependencies: NET_L2_OPENTHREAD || ((PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || !MBEDTLS_USE_PSA_CRYPTO) && MBEDTLS_LEGACY_CRYPTO_C && NRF_SECURITY)

 

below is prj.conf file

# Wi-Fi
CONFIG_WIFI=y
CONFIG_WIFI_NRF700X=y
CONFIG_WPA_SUPP=y
# CONFIG_WPA_SUPP_CRYPTO_PSA=y

# Wi-Fi Credentials
CONFIG_WIFI_CREDENTIALS=y
CONFIG_WIFI_CREDENTIALS_STATIC=n

# Networking Management API
CONFIG_NET_MGMT=y
CONFIG_NET_MGMT_EVENT=y
CONFIG_NET_MGMT_EVENT_INFO=y
CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096
CONFIG_NET_CONNECTION_MANAGER=y
CONFIG_WIFI_MGMT_EXT=y

# Support for shell commands
CONFIG_SHELL=y
CONFIG_WIFI_CREDENTIALS_SHELL=y
CONFIG_SHELL_STACK_SIZE=4400

# Logging
CONFIG_LOG=y

# DK library
CONFIG_DK_LIBRARY=y

# System settings
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_NANO=n

# Networking
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_POSIX_MAX_FDS=16

CONFIG_NET_L2_ETHERNET=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_TCP=y
CONFIG_NET_DHCPV4=y
CONFIG_DNS_RESOLVER=y

# TLS
# STEP 1.1 - Enable the TLS library and security relevant configurations
CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
CONFIG_TLS_CREDENTIALS=y
CONFIG_MBEDTLS_RSA_C=y
CONFIG_MBEDTLS_DHM_C=y 

# STEP 1.2 - Enable support for server name indication (SNI)
CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=y

# Memory
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_HEAP_MEM_POOL_SIZE=153600

CONFIG_NET_TCP_WORKQ_STACK_SIZE=2048
CONFIG_NET_TX_STACK_SIZE=4096
CONFIG_NET_RX_STACK_SIZE=4096
CONFIG_NET_BUF_RX_COUNT=16
CONFIG_NET_BUF_TX_COUNT=16
CONFIG_NET_BUF_DATA_SIZE=256
CONFIG_NET_TC_TX_COUNT=0

# HTTP
CONFIG_HTTP_CLIENT=y
# For storing Wi-Fi credentials
CONFIG_WIFI_CREDENTIALS_BACKEND_SETTINGS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y
CONFIG_SETTINGS_NVS=y

CONFIG_NET_L2_WIFI_SHELL=y

Parents
  • Hi,

     

    That sample/exercise is made for the non-secure board, ie. nrf7002dk_nrf5340_cpuapp_ns, and lacks handling of the connection if used without the TF-M part.

    I would recommend that you look at samples/net/https_client in v2.5.x to show how to connect to a website using the nrf7002dk_nrf5340_cpuapp board.

     

    Kind regards,

    Håkon 

  • Hi,

    I encountered the following errors when using HTTP with TLS & build this with nrf7002dk_nrf5340_cpuapp. Could you help me resolve them?

    • Failed to set TLS security TAG list, err: 109
    • Failed to initialize client

    Below is my code. Please review it and provide your feedback.

    /*
     * Copyright (c) 2023 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <errno.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.h>
    #include <zephyr/kernel.h>
    #include <zephyr/types.h>
    #include <zephyr/logging/log.h>
    
    #include <dk_buttons_and_leds.h>
    
    /* STEP 3 - Include the necessary header files */
    #include <zephyr/net/wifi.h>
    #include <zephyr/net/wifi_mgmt.h>
    #include <zephyr/net/net_mgmt.h>
    #include <net/wifi_mgmt_ext.h>
    
    /* STEP 12.4 - Include the header file for the Wi-FI credentials library */
    #include <net/wifi_credentials.h>
    #include <zephyr/net/socket.h>
    
    #include <zephyr/net/net_if.h>
    #include <zephyr/sys/printk.h>
    
    // #define SERVER_IP_ADDR "192.168.1.10" // Replace with your server's IP
    // #define SERVER_PORT 8080
    
    // LOG_MODULE_REGISTER(Lesson2_Exercise2, LOG_LEVEL_INF);
    
    /* STEP 4 - Define a macro for the relevant network events */
    // #define EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)
    
    /* STEP 1.2 - Include the header file of the HTTP client library */
    #include <zephyr/net/http/client.h>
    /* STEP 1.4 - Include the header file for the TLS credentials library */
    #include <zephyr/net/tls_credentials.h>
    
    /* STEP 2.3 - Include the certificate */
    static const char ca_certificate[] = {
    #include "certificate.h"
    };
    
    LOG_MODULE_REGISTER(Lesson5_Exercise1);
    
    #define EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)
    
    /* STEP 5 - Declare the callback structure for Wi-Fi events */
    static struct net_mgmt_event_callback mgmt_cb;
    
    /* STEP 6.1 - Define the boolean connected and the semaphore run_app */
    static bool connected = 0;
    static bool firsttime = 1;
    static K_SEM_DEFINE(run_app, 0, 1);
    
    /* STEP 4.1 - Define a macro for the credential security tag */
    #define HTTP_TLS_SEC_TAG 1
    
    /* STEP 2 - Define the macros for the HTTP server hostname and port */
    #define HTTP_HOSTNAME "echo.thingy.rocks" //staging.api.nexkey.com
    #define HTTP_PORT     443
    
    /* STEP 3 - Declare the necessary buffers for receiving messages */
    #define RECV_BUF_SIZE  2048
    #define CLIENT_ID_SIZE 36
    
    static char recv_buf[RECV_BUF_SIZE];
    static char client_id_buf[CLIENT_ID_SIZE + 2];
    
    /* STEP 4 - Define the variable for the counter as 0 */
    static int counter = 0;
    
    static int sock;
    static struct sockaddr_storage server;
    
    //static struct net_mgmt_event_callback mgmt_cb;
    //static bool connected;
    //static K_SEM_DEFINE(run_app, 0, 1);
    
    
    
    static int server_resolve(void)
    {
    	int err;
    	struct addrinfo *result;
    	struct addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM};
    
    	err = getaddrinfo(HTTP_HOSTNAME, STRINGIFY(HTTP_PORT), &hints, &result);
    	if (err != 0) {
    		LOG_ERR("getaddrinfo failed, err: %d, %s", err, gai_strerror(err));
    		return -EIO;
    	}
    
    	if (result == NULL) {
    		LOG_ERR("Error, address not found");
    		return -ENOENT;
    	}
    
    	struct sockaddr_in *server4 = ((struct sockaddr_in *)&server);
    	server4->sin_addr.s_addr = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
    	server4->sin_family = AF_INET;
    	server4->sin_port = ((struct sockaddr_in *)result->ai_addr)->sin_port;
    
    	char ipv4_addr[NET_IPV4_ADDR_LEN];
    	inet_ntop(AF_INET, &server4->sin_addr.s_addr, ipv4_addr, sizeof(ipv4_addr));
    	LOG_INF("IPv4 address of HTTP server found %s", ipv4_addr);
    
    	freeaddrinfo(result);
    
    	return 0;
    }
    
    static int setup_credentials(void)
    {
    	
    	/* STEP 4.2 - Add the credential to the device */
    	int err = tls_credential_add(HTTP_TLS_SEC_TAG, TLS_CREDENTIAL_CA_CERTIFICATE, ca_certificate,
    				 sizeof(ca_certificate));
    	if (err < 0) {
    		LOG_ERR("Failed to add TLS credentials, err: %d", err);
    		return err;
    	}
    
    	return 0;
    }
    
    static int server_connect(void)
    {
    	int err;
    	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	if (sock < 0) {
    		LOG_ERR("Failed to create socket, err: %d, %s", errno, strerror(errno));
    		return -errno;
    	}
    
    	/* STEP 5.1 - Configure the socket with the security tag for the certificate */
    	sec_tag_t sec_tag_opt[] = {
    		HTTP_TLS_SEC_TAG,
    	};
    	err = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_opt, sizeof(sec_tag_opt));
    	if (err < 0) {
    		LOG_ERR("Failed to set TLS security TAG list, err: %d", errno);
    		(void)close(sock);
    		return -errno;
    	}
    	/* STEP 5.2 - Configure the socket with the hostname of the HTTP server */
    	err = setsockopt(sock, SOL_TLS, TLS_HOSTNAME, HTTP_HOSTNAME, sizeof(HTTP_HOSTNAME));
    	if (err < 0) {
    		LOG_ERR("Failed to set TLS_HOSTNAME option. Err: %d", errno);
    		(void)close(sock);
    		return -errno;
    	}
    
    	err = connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
    	if (err < 0) {
    		LOG_ERR("Connecting to server failed, err: %d, %s", errno, strerror(errno));
    		return -errno;
    	}
    
    	LOG_INF("Connected to server");
    	return 0;
    }
    
    static void response_cb(struct http_response *rsp, enum http_final_call final_data, void *user_data)
    {
    	/* STEP 9 - Define the callback function to print the body */
    	LOG_INF("Response status: %s", rsp->http_status);
    
    	if (rsp->body_frag_len > 0) {
    		char body_buf[rsp->body_frag_len];
    		strncpy(body_buf, rsp->body_frag_start, rsp->body_frag_len);
    		body_buf[rsp->body_frag_len] = '\0';
    		LOG_INF("Received: %s", body_buf);
    	}
    
    	LOG_INF("Closing socket: %d", sock);
    	close(sock);
    }
    
    static void client_id_cb(struct http_response *rsp, enum http_final_call final_data,
    			 void *user_data)
    {
    	/* STEP 6.1 - Log the HTTP response status */
    	LOG_INF("Response status: %s", rsp->http_status);
    
    	/* STEP 6.2 - Retrieve and format the client ID */
    	char client_id_buf_tmp[CLIENT_ID_SIZE + 1];
    	strncpy(client_id_buf_tmp, rsp->body_frag_start, CLIENT_ID_SIZE);
    	client_id_buf_tmp[CLIENT_ID_SIZE] = '\0';
    	client_id_buf[0] = '/';
    	strcat(client_id_buf, client_id_buf_tmp);
    
    	LOG_INF("Successfully acquired client ID: %s", client_id_buf);
    
    	/* STEP 6.3 - Close the socket */
    	LOG_INF("Closing socket: %d", sock);
    	close(sock);
    }
    
    static int client_http_put(void)
    {
    	/* STEP 7 - Define the function to send a PUT request to the HTTP server */
    	int err = 0;
    	int bytes_written;
    	const char *headers[] = {"Connection: close\r\n", NULL};
    
    	struct http_request req;
    	memset(&req, 0, sizeof(req));
    
    	char buffer[12] = {0};
    	bytes_written = snprintf(buffer, 12, "%d", counter);
    	if (bytes_written < 0) {
    		LOG_INF("Unable to write to buffer, err: %d", bytes_written);
    		return bytes_written;
    	}
    
    	req.header_fields = headers;
    	req.method = HTTP_PUT;
    	req.url = client_id_buf;
    	req.host = HTTP_HOSTNAME;
    	req.protocol = "HTTP/1.1";
    	req.payload = buffer;
    	req.payload_len = bytes_written;
    	req.response = response_cb;
    	req.recv_buf = recv_buf;
    	req.recv_buf_len = sizeof(recv_buf);
    
    	LOG_INF("HTTP PUT request: %s", buffer);
    	err = http_client_req(sock, &req, 5000, NULL);
    	if (err < 0) {
    		LOG_ERR("Failed to send HTTP PUT request %s, err: %d", buffer, err);
    	}
    
    	return err;
    }
    
    static int client_http_get(void)
    {
    	/* STEP 8 - Define the function to send a GET request to the HTTP server */
    	int err = 0;
    	const char *headers[] = {"Connection: close\r\n", NULL};
    	
    	struct http_request req;
    	memset(&req, 0, sizeof(req));
    
    	req.header_fields = headers;
    	req.method = HTTP_GET;
    	req.url = client_id_buf;
    	req.host = HTTP_HOSTNAME;
    	req.protocol = "HTTP/1.1";
    	req.response = response_cb;
    	req.recv_buf = recv_buf;
    	req.recv_buf_len = sizeof(recv_buf);
    
    	LOG_INF("HTTP GET request");
    	err = http_client_req(sock, &req, 5000, NULL);
    	if (err < 0) {
    		LOG_ERR("Failed to send HTTP GET request, err: %d", err);
    	}
    
    	return err;
    }
    
    static int client_get_new_id(void)
    {
    	int err = 0;
    
    	/* STEP 5.1 - Define the structure http_request and fill the block of memory */
    	struct http_request req;
    	memset(&req, 0, sizeof(req));
    
    	/* STEP 5.2 - Populate the http_request structure */
    	const char *headers[] = {"Connection: close\r\n", NULL};
    	req.header_fields = headers;
    	req.method = HTTP_POST;
    	req.url = "/new";
    	req.host = HTTP_HOSTNAME;
    	req.protocol = "HTTP/1.1";
    	req.response = client_id_cb;
    	req.recv_buf = recv_buf;
    	req.recv_buf_len = sizeof(recv_buf);
    
    	/* STEP 5.3 - Send the request to the HTTP server */
    	LOG_INF("HTTP POST request");
    	err = http_client_req(sock, &req, 5000, NULL);
    	if (err < 0) {
    		LOG_ERR("Failed to send HTTP POST request, err: %d", err);
    	}
    	return err;
    }
    
    /* STEP 6.2 - Define the callback function for network events */
    static void net_mgmt_event_handler(struct net_mgmt_event_callback *cb,
    			  uint32_t mgmt_event, struct net_if *iface)
    {
    	if ((mgmt_event & EVENT_MASK) != mgmt_event) {
    		return;
    	}
    	if (mgmt_event == NET_EVENT_L4_CONNECTED) {
    		LOG_INF("Network connected");
    		connected = true;
    		dk_set_led_on(DK_LED1);
    		//k_sem_give(&run_app);
    		return;
    	}
    	if (mgmt_event == NET_EVENT_L4_DISCONNECTED) {
    		if (connected == false) {
    			LOG_INF("Waiting for network to be connected");
    		} else {
    			dk_set_led_off(DK_LED1);
    			LOG_INF("Network disconnected");
    			connected = false;
    		}
    		//k_sem_reset(&run_app);
    		return;
    	}
    }
    
    /* STEP 7 - Define the function to populate the Wi-Fi credential parameters */
    //static int wifi_args_to_params(struct wifi_connect_req_params *params)
    //{
    
    	/* STEP 7.1 Populate the SSID and password */
    	//params->ssid = CONFIG_WIFI_CREDENTIALS_STATIC_SSID;
    	//params->ssid_length = strlen(params->ssid);
    
    	//params->psk = CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD;
    	//params->psk_length = strlen(params->psk);
    
    	/* STEP 7.2 - Populate the rest of the relevant members */
    	//params->channel = WIFI_CHANNEL_ANY;
    	//params->security = WIFI_SECURITY_TYPE_PSK;
    	//params->mfp = WIFI_MFP_OPTIONAL;
    	//params->timeout = SYS_FOREVER_MS;
    	//params->band = WIFI_FREQ_BAND_UNKNOWN;
    	//#if NCS_VERSION_NUMBER > 0x20600
    	//memset(params->bssid, 0, sizeof(params->bssid));
    	//#endif
    	//return 0;
    //}
    
    static struct wifi_credentials_personal wifi_cred;
    void set_wifi_credentials_struct() 
    {
    
    	char *wifi_ssid = "realme";
    	char *wifi_password = "Chirag@1527";
    
    	wifi_cred.header.type = WIFI_SECURITY_TYPE_PSK;
    	memset(wifi_cred.header.bssid, 0, sizeof(wifi_cred.header.bssid));
    	wifi_cred.header.flags = 0;
    	//wifi_cred.header.channel = WIFI_CHANNEL_ANY;
    	//wifi_cred.header.timeout = 10;
    
    	wifi_cred.header.ssid_len = strlen(wifi_ssid);
    	memcpy(wifi_cred.header.ssid, wifi_ssid, wifi_cred.header.ssid_len);
    	
    	wifi_cred.password_len = strlen(wifi_password);
    	memcpy(wifi_cred.password, wifi_password, wifi_cred.password_len);
    
    	int ret = wifi_credentials_set_personal_struct(&wifi_cred);
    
    	if (ret != 0) {
    		LOG_ERR("Failed to set credentials, err: %d", ret);
    	}
    }
    static void button_handler(uint32_t button_state, uint32_t has_changed)
    {
    	/* STEP 10 - Define the button handler to send requests upon button triggers */
    	if (has_changed & DK_BTN1_MSK && button_state & DK_BTN1_MSK) {
    		if (server_connect() >= 0) {
    			client_http_put();
    			counter++;
    		}
    	} else if (has_changed & DK_BTN2_MSK && button_state & DK_BTN2_MSK) {
    		if (server_connect() >= 0) {
    			client_http_get();
    		}
    	}
    }
    
    int main(void)
    {
    	/* STEP 8.1 - Declare the variable for the network configuration parameters */
    	//struct wifi_connect_req_params cnx_params;
    
    
    
    	/* STEP 8.2 - Get the network interface */
    	struct net_if *iface = net_if_get_first_wifi();
    	if (iface == NULL) {
    		LOG_ERR("Returned network interface is NULL");
    		return -1;
    	}
    
    	if (dk_leds_init() != 0) {
    		LOG_ERR("Failed to initialize the LED library");
    	}
    
    	/* Sleep to allow initialization of Wi-Fi driver */
    	k_sleep(K_SECONDS(1));
    
    	/* STEP 9 - Initialize and add the callback function for network events */
    	net_mgmt_init_event_callback(&mgmt_cb, net_mgmt_event_handler, EVENT_MASK);
    	net_mgmt_add_event_callback(&mgmt_cb);
    
    	/* STEP 10 - Populate cnx_params with the network configuration */
    	//wifi_args_to_params(&cnx_params);
    
        set_wifi_credentials_struct();
    	/* STEP 11 - Call net_mgmt() to request the Wi-Fi connection */
    	LOG_INF("Connecting to Wi-Fi");
    	//printf("try to connect with wifi");
    	//LOG_ERR("buttons library");
    	//int err = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, &wifi_cred, sizeof(struct wifi_credentials_personal));
    	//LOG_ERR("buttons library");
    	// if (err) {
    	// 	LOG_ERR("Connecting to Wi-Fi failed, err: %d", err);
    	// 	//return ENOEXEC;
    	// }
    
    	//k_sem_take(&run_app, K_FOREVER);
    
    	if (dk_buttons_init(button_handler) != 0) {
    		LOG_ERR("Failed to initialize the buttons library ");
    	}
    	while(1)
    	{
    		//LOG_ERR("Failed to initialize the buttons library ");
    		k_sleep(K_SECONDS(1));
    		if(!connected)
    		{
    			int err = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, &wifi_cred, sizeof(struct wifi_credentials_personal));
    		}
    		if(connected && firsttime == 1)
    		{
    			if (server_resolve() != 0) {
    				LOG_ERR("Failed to resolve server name");
    				return 0;
    			}
    			
    			if (setup_credentials() != 0) {
    		        LOG_ERR("Setup credentials failed");
    	        }
    
    			if (server_connect() != 0) {
    				LOG_ERR("Failed to initialize client");
    				return 0;
    			}	
    
    			/* STEP 11 - Retrieve the client ID upon connection */
    			if (client_get_new_id() < 0) {
    				LOG_ERR("Failed to get client ID");
    				return 0;
    			}
    			firsttime = 0;
    			LOG_ERR("buttons library");
    		}
    		//return 0;
    	}
    
    	
    
    		
    }

    #
    # Copyright (c) 2022 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    
    # Wi-Fi
    # STEP 1.1 - Enable the Wi-Fi relevant configurations
    CONFIG_WIFI=y
    CONFIG_WIFI_NRF700X=y
    CONFIG_WPA_SUPP=y
    
    
    # STEP 2 - Configure the Wi-Fi credentials
    CONFIG_WIFI_CREDENTIALS=y
    # STEP 12.1 - Diasble static Wi-Fi network configuration
    CONFIG_WIFI_CREDENTIALS_STATIC=n
    #CONFIG_WIFI_CREDENTIALS_STATIC_SSID="<your_network_SSID>"
    #CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="<your_network_password>"
    
    # Networking Management API
    # STEP 1.2 Enable the Network Management relevant configurations
    CONFIG_NET_MGMT=y
    CONFIG_NET_MGMT_EVENT=y
    CONFIG_NET_MGMT_EVENT_INFO=y
    CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096
    CONFIG_NET_CONNECTION_MANAGER=y
    CONFIG_WIFI_MGMT_EXT=y
    
    # STEP 13 Enable support for shell commands
    # CONFIG_SHELL=y
    # CONFIG_WIFI_CREDENTIALS_SHELL=y
    # CONFIG_SHELL_STACK_SIZE=4400
    
    # Logging
    CONFIG_LOG=y
    
    # DK library
    CONFIG_DK_LIBRARY=y
    
    # System settings
    CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC_NANO=n
    
    # Networking
    CONFIG_NETWORKING=y
    CONFIG_NET_NATIVE=y
    CONFIG_NET_SOCKETS=y
    CONFIG_NET_SOCKETS_POSIX_NAMES=y
    CONFIG_POSIX_MAX_FDS=16
    CONFIG_NET_L2_ETHERNET=y
    CONFIG_NET_IPV6=y
    CONFIG_NET_IPV4=y
    CONFIG_NET_DHCPV4=y
    CONFIG_NET_TCP=y
    CONFIG_DNS_RESOLVER=y
    
    # Memory
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_HEAP_MEM_POOL_SIZE=153600
    
    CONFIG_STA_KEY_MGMT_WPA2=y
    
    CONFIG_NET_TCP_WORKQ_STACK_SIZE=2048
    CONFIG_NET_TX_STACK_SIZE=4096
    CONFIG_NET_RX_STACK_SIZE=4096
    CONFIG_NET_BUF_RX_COUNT=16
    CONFIG_NET_BUF_TX_COUNT=16
    CONFIG_NET_BUF_DATA_SIZE=256
    CONFIG_NET_TC_TX_COUNT=0
    
    # HTTP
    # STEP 1 -  Enable the HTTP client library
    CONFIG_HTTP_CLIENT=y
    
    # For storing Wi-Fi credentials
    CONFIG_WIFI_CREDENTIALS_BACKEND_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS=y
    CONFIG_SETTINGS_NVS=y
    # Enable Wi-Fi shell
    # CONFIG_NET_L2_WIFI_SHELL=y
    
    # CONFIG_RTT_CONSOLE=y
    # CONFIG_STDOUT_CONSOLE=y
    
    CONFIG_MPU_ALLOW_FLASH_WRITE=y
    
    CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y
    CONFIG_FCB=y
    
    CONFIG_SETTINGS_FCB=y
    
    # TLS
    # STEP 1.1 - Enable the TLS library and security relevant configurations
    CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
    CONFIG_TLS_CREDENTIALS=y
    CONFIG_MBEDTLS_RSA_C=y
    CONFIG_MBEDTLS_DHM_C=y 
    
    # STEP 1.2 - Enable support for server name indication (SNI)
    CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=y
    

Reply
  • Hi,

    I encountered the following errors when using HTTP with TLS & build this with nrf7002dk_nrf5340_cpuapp. Could you help me resolve them?

    • Failed to set TLS security TAG list, err: 109
    • Failed to initialize client

    Below is my code. Please review it and provide your feedback.

    /*
     * Copyright (c) 2023 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <errno.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.h>
    #include <zephyr/kernel.h>
    #include <zephyr/types.h>
    #include <zephyr/logging/log.h>
    
    #include <dk_buttons_and_leds.h>
    
    /* STEP 3 - Include the necessary header files */
    #include <zephyr/net/wifi.h>
    #include <zephyr/net/wifi_mgmt.h>
    #include <zephyr/net/net_mgmt.h>
    #include <net/wifi_mgmt_ext.h>
    
    /* STEP 12.4 - Include the header file for the Wi-FI credentials library */
    #include <net/wifi_credentials.h>
    #include <zephyr/net/socket.h>
    
    #include <zephyr/net/net_if.h>
    #include <zephyr/sys/printk.h>
    
    // #define SERVER_IP_ADDR "192.168.1.10" // Replace with your server's IP
    // #define SERVER_PORT 8080
    
    // LOG_MODULE_REGISTER(Lesson2_Exercise2, LOG_LEVEL_INF);
    
    /* STEP 4 - Define a macro for the relevant network events */
    // #define EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)
    
    /* STEP 1.2 - Include the header file of the HTTP client library */
    #include <zephyr/net/http/client.h>
    /* STEP 1.4 - Include the header file for the TLS credentials library */
    #include <zephyr/net/tls_credentials.h>
    
    /* STEP 2.3 - Include the certificate */
    static const char ca_certificate[] = {
    #include "certificate.h"
    };
    
    LOG_MODULE_REGISTER(Lesson5_Exercise1);
    
    #define EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)
    
    /* STEP 5 - Declare the callback structure for Wi-Fi events */
    static struct net_mgmt_event_callback mgmt_cb;
    
    /* STEP 6.1 - Define the boolean connected and the semaphore run_app */
    static bool connected = 0;
    static bool firsttime = 1;
    static K_SEM_DEFINE(run_app, 0, 1);
    
    /* STEP 4.1 - Define a macro for the credential security tag */
    #define HTTP_TLS_SEC_TAG 1
    
    /* STEP 2 - Define the macros for the HTTP server hostname and port */
    #define HTTP_HOSTNAME "echo.thingy.rocks" //staging.api.nexkey.com
    #define HTTP_PORT     443
    
    /* STEP 3 - Declare the necessary buffers for receiving messages */
    #define RECV_BUF_SIZE  2048
    #define CLIENT_ID_SIZE 36
    
    static char recv_buf[RECV_BUF_SIZE];
    static char client_id_buf[CLIENT_ID_SIZE + 2];
    
    /* STEP 4 - Define the variable for the counter as 0 */
    static int counter = 0;
    
    static int sock;
    static struct sockaddr_storage server;
    
    //static struct net_mgmt_event_callback mgmt_cb;
    //static bool connected;
    //static K_SEM_DEFINE(run_app, 0, 1);
    
    
    
    static int server_resolve(void)
    {
    	int err;
    	struct addrinfo *result;
    	struct addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM};
    
    	err = getaddrinfo(HTTP_HOSTNAME, STRINGIFY(HTTP_PORT), &hints, &result);
    	if (err != 0) {
    		LOG_ERR("getaddrinfo failed, err: %d, %s", err, gai_strerror(err));
    		return -EIO;
    	}
    
    	if (result == NULL) {
    		LOG_ERR("Error, address not found");
    		return -ENOENT;
    	}
    
    	struct sockaddr_in *server4 = ((struct sockaddr_in *)&server);
    	server4->sin_addr.s_addr = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
    	server4->sin_family = AF_INET;
    	server4->sin_port = ((struct sockaddr_in *)result->ai_addr)->sin_port;
    
    	char ipv4_addr[NET_IPV4_ADDR_LEN];
    	inet_ntop(AF_INET, &server4->sin_addr.s_addr, ipv4_addr, sizeof(ipv4_addr));
    	LOG_INF("IPv4 address of HTTP server found %s", ipv4_addr);
    
    	freeaddrinfo(result);
    
    	return 0;
    }
    
    static int setup_credentials(void)
    {
    	
    	/* STEP 4.2 - Add the credential to the device */
    	int err = tls_credential_add(HTTP_TLS_SEC_TAG, TLS_CREDENTIAL_CA_CERTIFICATE, ca_certificate,
    				 sizeof(ca_certificate));
    	if (err < 0) {
    		LOG_ERR("Failed to add TLS credentials, err: %d", err);
    		return err;
    	}
    
    	return 0;
    }
    
    static int server_connect(void)
    {
    	int err;
    	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	if (sock < 0) {
    		LOG_ERR("Failed to create socket, err: %d, %s", errno, strerror(errno));
    		return -errno;
    	}
    
    	/* STEP 5.1 - Configure the socket with the security tag for the certificate */
    	sec_tag_t sec_tag_opt[] = {
    		HTTP_TLS_SEC_TAG,
    	};
    	err = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_opt, sizeof(sec_tag_opt));
    	if (err < 0) {
    		LOG_ERR("Failed to set TLS security TAG list, err: %d", errno);
    		(void)close(sock);
    		return -errno;
    	}
    	/* STEP 5.2 - Configure the socket with the hostname of the HTTP server */
    	err = setsockopt(sock, SOL_TLS, TLS_HOSTNAME, HTTP_HOSTNAME, sizeof(HTTP_HOSTNAME));
    	if (err < 0) {
    		LOG_ERR("Failed to set TLS_HOSTNAME option. Err: %d", errno);
    		(void)close(sock);
    		return -errno;
    	}
    
    	err = connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
    	if (err < 0) {
    		LOG_ERR("Connecting to server failed, err: %d, %s", errno, strerror(errno));
    		return -errno;
    	}
    
    	LOG_INF("Connected to server");
    	return 0;
    }
    
    static void response_cb(struct http_response *rsp, enum http_final_call final_data, void *user_data)
    {
    	/* STEP 9 - Define the callback function to print the body */
    	LOG_INF("Response status: %s", rsp->http_status);
    
    	if (rsp->body_frag_len > 0) {
    		char body_buf[rsp->body_frag_len];
    		strncpy(body_buf, rsp->body_frag_start, rsp->body_frag_len);
    		body_buf[rsp->body_frag_len] = '\0';
    		LOG_INF("Received: %s", body_buf);
    	}
    
    	LOG_INF("Closing socket: %d", sock);
    	close(sock);
    }
    
    static void client_id_cb(struct http_response *rsp, enum http_final_call final_data,
    			 void *user_data)
    {
    	/* STEP 6.1 - Log the HTTP response status */
    	LOG_INF("Response status: %s", rsp->http_status);
    
    	/* STEP 6.2 - Retrieve and format the client ID */
    	char client_id_buf_tmp[CLIENT_ID_SIZE + 1];
    	strncpy(client_id_buf_tmp, rsp->body_frag_start, CLIENT_ID_SIZE);
    	client_id_buf_tmp[CLIENT_ID_SIZE] = '\0';
    	client_id_buf[0] = '/';
    	strcat(client_id_buf, client_id_buf_tmp);
    
    	LOG_INF("Successfully acquired client ID: %s", client_id_buf);
    
    	/* STEP 6.3 - Close the socket */
    	LOG_INF("Closing socket: %d", sock);
    	close(sock);
    }
    
    static int client_http_put(void)
    {
    	/* STEP 7 - Define the function to send a PUT request to the HTTP server */
    	int err = 0;
    	int bytes_written;
    	const char *headers[] = {"Connection: close\r\n", NULL};
    
    	struct http_request req;
    	memset(&req, 0, sizeof(req));
    
    	char buffer[12] = {0};
    	bytes_written = snprintf(buffer, 12, "%d", counter);
    	if (bytes_written < 0) {
    		LOG_INF("Unable to write to buffer, err: %d", bytes_written);
    		return bytes_written;
    	}
    
    	req.header_fields = headers;
    	req.method = HTTP_PUT;
    	req.url = client_id_buf;
    	req.host = HTTP_HOSTNAME;
    	req.protocol = "HTTP/1.1";
    	req.payload = buffer;
    	req.payload_len = bytes_written;
    	req.response = response_cb;
    	req.recv_buf = recv_buf;
    	req.recv_buf_len = sizeof(recv_buf);
    
    	LOG_INF("HTTP PUT request: %s", buffer);
    	err = http_client_req(sock, &req, 5000, NULL);
    	if (err < 0) {
    		LOG_ERR("Failed to send HTTP PUT request %s, err: %d", buffer, err);
    	}
    
    	return err;
    }
    
    static int client_http_get(void)
    {
    	/* STEP 8 - Define the function to send a GET request to the HTTP server */
    	int err = 0;
    	const char *headers[] = {"Connection: close\r\n", NULL};
    	
    	struct http_request req;
    	memset(&req, 0, sizeof(req));
    
    	req.header_fields = headers;
    	req.method = HTTP_GET;
    	req.url = client_id_buf;
    	req.host = HTTP_HOSTNAME;
    	req.protocol = "HTTP/1.1";
    	req.response = response_cb;
    	req.recv_buf = recv_buf;
    	req.recv_buf_len = sizeof(recv_buf);
    
    	LOG_INF("HTTP GET request");
    	err = http_client_req(sock, &req, 5000, NULL);
    	if (err < 0) {
    		LOG_ERR("Failed to send HTTP GET request, err: %d", err);
    	}
    
    	return err;
    }
    
    static int client_get_new_id(void)
    {
    	int err = 0;
    
    	/* STEP 5.1 - Define the structure http_request and fill the block of memory */
    	struct http_request req;
    	memset(&req, 0, sizeof(req));
    
    	/* STEP 5.2 - Populate the http_request structure */
    	const char *headers[] = {"Connection: close\r\n", NULL};
    	req.header_fields = headers;
    	req.method = HTTP_POST;
    	req.url = "/new";
    	req.host = HTTP_HOSTNAME;
    	req.protocol = "HTTP/1.1";
    	req.response = client_id_cb;
    	req.recv_buf = recv_buf;
    	req.recv_buf_len = sizeof(recv_buf);
    
    	/* STEP 5.3 - Send the request to the HTTP server */
    	LOG_INF("HTTP POST request");
    	err = http_client_req(sock, &req, 5000, NULL);
    	if (err < 0) {
    		LOG_ERR("Failed to send HTTP POST request, err: %d", err);
    	}
    	return err;
    }
    
    /* STEP 6.2 - Define the callback function for network events */
    static void net_mgmt_event_handler(struct net_mgmt_event_callback *cb,
    			  uint32_t mgmt_event, struct net_if *iface)
    {
    	if ((mgmt_event & EVENT_MASK) != mgmt_event) {
    		return;
    	}
    	if (mgmt_event == NET_EVENT_L4_CONNECTED) {
    		LOG_INF("Network connected");
    		connected = true;
    		dk_set_led_on(DK_LED1);
    		//k_sem_give(&run_app);
    		return;
    	}
    	if (mgmt_event == NET_EVENT_L4_DISCONNECTED) {
    		if (connected == false) {
    			LOG_INF("Waiting for network to be connected");
    		} else {
    			dk_set_led_off(DK_LED1);
    			LOG_INF("Network disconnected");
    			connected = false;
    		}
    		//k_sem_reset(&run_app);
    		return;
    	}
    }
    
    /* STEP 7 - Define the function to populate the Wi-Fi credential parameters */
    //static int wifi_args_to_params(struct wifi_connect_req_params *params)
    //{
    
    	/* STEP 7.1 Populate the SSID and password */
    	//params->ssid = CONFIG_WIFI_CREDENTIALS_STATIC_SSID;
    	//params->ssid_length = strlen(params->ssid);
    
    	//params->psk = CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD;
    	//params->psk_length = strlen(params->psk);
    
    	/* STEP 7.2 - Populate the rest of the relevant members */
    	//params->channel = WIFI_CHANNEL_ANY;
    	//params->security = WIFI_SECURITY_TYPE_PSK;
    	//params->mfp = WIFI_MFP_OPTIONAL;
    	//params->timeout = SYS_FOREVER_MS;
    	//params->band = WIFI_FREQ_BAND_UNKNOWN;
    	//#if NCS_VERSION_NUMBER > 0x20600
    	//memset(params->bssid, 0, sizeof(params->bssid));
    	//#endif
    	//return 0;
    //}
    
    static struct wifi_credentials_personal wifi_cred;
    void set_wifi_credentials_struct() 
    {
    
    	char *wifi_ssid = "realme";
    	char *wifi_password = "Chirag@1527";
    
    	wifi_cred.header.type = WIFI_SECURITY_TYPE_PSK;
    	memset(wifi_cred.header.bssid, 0, sizeof(wifi_cred.header.bssid));
    	wifi_cred.header.flags = 0;
    	//wifi_cred.header.channel = WIFI_CHANNEL_ANY;
    	//wifi_cred.header.timeout = 10;
    
    	wifi_cred.header.ssid_len = strlen(wifi_ssid);
    	memcpy(wifi_cred.header.ssid, wifi_ssid, wifi_cred.header.ssid_len);
    	
    	wifi_cred.password_len = strlen(wifi_password);
    	memcpy(wifi_cred.password, wifi_password, wifi_cred.password_len);
    
    	int ret = wifi_credentials_set_personal_struct(&wifi_cred);
    
    	if (ret != 0) {
    		LOG_ERR("Failed to set credentials, err: %d", ret);
    	}
    }
    static void button_handler(uint32_t button_state, uint32_t has_changed)
    {
    	/* STEP 10 - Define the button handler to send requests upon button triggers */
    	if (has_changed & DK_BTN1_MSK && button_state & DK_BTN1_MSK) {
    		if (server_connect() >= 0) {
    			client_http_put();
    			counter++;
    		}
    	} else if (has_changed & DK_BTN2_MSK && button_state & DK_BTN2_MSK) {
    		if (server_connect() >= 0) {
    			client_http_get();
    		}
    	}
    }
    
    int main(void)
    {
    	/* STEP 8.1 - Declare the variable for the network configuration parameters */
    	//struct wifi_connect_req_params cnx_params;
    
    
    
    	/* STEP 8.2 - Get the network interface */
    	struct net_if *iface = net_if_get_first_wifi();
    	if (iface == NULL) {
    		LOG_ERR("Returned network interface is NULL");
    		return -1;
    	}
    
    	if (dk_leds_init() != 0) {
    		LOG_ERR("Failed to initialize the LED library");
    	}
    
    	/* Sleep to allow initialization of Wi-Fi driver */
    	k_sleep(K_SECONDS(1));
    
    	/* STEP 9 - Initialize and add the callback function for network events */
    	net_mgmt_init_event_callback(&mgmt_cb, net_mgmt_event_handler, EVENT_MASK);
    	net_mgmt_add_event_callback(&mgmt_cb);
    
    	/* STEP 10 - Populate cnx_params with the network configuration */
    	//wifi_args_to_params(&cnx_params);
    
        set_wifi_credentials_struct();
    	/* STEP 11 - Call net_mgmt() to request the Wi-Fi connection */
    	LOG_INF("Connecting to Wi-Fi");
    	//printf("try to connect with wifi");
    	//LOG_ERR("buttons library");
    	//int err = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, &wifi_cred, sizeof(struct wifi_credentials_personal));
    	//LOG_ERR("buttons library");
    	// if (err) {
    	// 	LOG_ERR("Connecting to Wi-Fi failed, err: %d", err);
    	// 	//return ENOEXEC;
    	// }
    
    	//k_sem_take(&run_app, K_FOREVER);
    
    	if (dk_buttons_init(button_handler) != 0) {
    		LOG_ERR("Failed to initialize the buttons library ");
    	}
    	while(1)
    	{
    		//LOG_ERR("Failed to initialize the buttons library ");
    		k_sleep(K_SECONDS(1));
    		if(!connected)
    		{
    			int err = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, &wifi_cred, sizeof(struct wifi_credentials_personal));
    		}
    		if(connected && firsttime == 1)
    		{
    			if (server_resolve() != 0) {
    				LOG_ERR("Failed to resolve server name");
    				return 0;
    			}
    			
    			if (setup_credentials() != 0) {
    		        LOG_ERR("Setup credentials failed");
    	        }
    
    			if (server_connect() != 0) {
    				LOG_ERR("Failed to initialize client");
    				return 0;
    			}	
    
    			/* STEP 11 - Retrieve the client ID upon connection */
    			if (client_get_new_id() < 0) {
    				LOG_ERR("Failed to get client ID");
    				return 0;
    			}
    			firsttime = 0;
    			LOG_ERR("buttons library");
    		}
    		//return 0;
    	}
    
    	
    
    		
    }

    #
    # Copyright (c) 2022 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    
    # Wi-Fi
    # STEP 1.1 - Enable the Wi-Fi relevant configurations
    CONFIG_WIFI=y
    CONFIG_WIFI_NRF700X=y
    CONFIG_WPA_SUPP=y
    
    
    # STEP 2 - Configure the Wi-Fi credentials
    CONFIG_WIFI_CREDENTIALS=y
    # STEP 12.1 - Diasble static Wi-Fi network configuration
    CONFIG_WIFI_CREDENTIALS_STATIC=n
    #CONFIG_WIFI_CREDENTIALS_STATIC_SSID="<your_network_SSID>"
    #CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="<your_network_password>"
    
    # Networking Management API
    # STEP 1.2 Enable the Network Management relevant configurations
    CONFIG_NET_MGMT=y
    CONFIG_NET_MGMT_EVENT=y
    CONFIG_NET_MGMT_EVENT_INFO=y
    CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096
    CONFIG_NET_CONNECTION_MANAGER=y
    CONFIG_WIFI_MGMT_EXT=y
    
    # STEP 13 Enable support for shell commands
    # CONFIG_SHELL=y
    # CONFIG_WIFI_CREDENTIALS_SHELL=y
    # CONFIG_SHELL_STACK_SIZE=4400
    
    # Logging
    CONFIG_LOG=y
    
    # DK library
    CONFIG_DK_LIBRARY=y
    
    # System settings
    CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC_NANO=n
    
    # Networking
    CONFIG_NETWORKING=y
    CONFIG_NET_NATIVE=y
    CONFIG_NET_SOCKETS=y
    CONFIG_NET_SOCKETS_POSIX_NAMES=y
    CONFIG_POSIX_MAX_FDS=16
    CONFIG_NET_L2_ETHERNET=y
    CONFIG_NET_IPV6=y
    CONFIG_NET_IPV4=y
    CONFIG_NET_DHCPV4=y
    CONFIG_NET_TCP=y
    CONFIG_DNS_RESOLVER=y
    
    # Memory
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_HEAP_MEM_POOL_SIZE=153600
    
    CONFIG_STA_KEY_MGMT_WPA2=y
    
    CONFIG_NET_TCP_WORKQ_STACK_SIZE=2048
    CONFIG_NET_TX_STACK_SIZE=4096
    CONFIG_NET_RX_STACK_SIZE=4096
    CONFIG_NET_BUF_RX_COUNT=16
    CONFIG_NET_BUF_TX_COUNT=16
    CONFIG_NET_BUF_DATA_SIZE=256
    CONFIG_NET_TC_TX_COUNT=0
    
    # HTTP
    # STEP 1 -  Enable the HTTP client library
    CONFIG_HTTP_CLIENT=y
    
    # For storing Wi-Fi credentials
    CONFIG_WIFI_CREDENTIALS_BACKEND_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS=y
    CONFIG_SETTINGS_NVS=y
    # Enable Wi-Fi shell
    # CONFIG_NET_L2_WIFI_SHELL=y
    
    # CONFIG_RTT_CONSOLE=y
    # CONFIG_STDOUT_CONSOLE=y
    
    CONFIG_MPU_ALLOW_FLASH_WRITE=y
    
    CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y
    CONFIG_FCB=y
    
    CONFIG_SETTINGS_FCB=y
    
    # TLS
    # STEP 1.1 - Enable the TLS library and security relevant configurations
    CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
    CONFIG_TLS_CREDENTIALS=y
    CONFIG_MBEDTLS_RSA_C=y
    CONFIG_MBEDTLS_DHM_C=y 
    
    # STEP 1.2 - Enable support for server name indication (SNI)
    CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=y
    

Children
  • Hi, 

    ChiragBhavsar said:
    I encountered the following errors when using HTTP with TLS & build this with nrf7002dk_nrf5340_cpuapp.

    Please try to build for nrf7002dk_nrf5340_cpuapp_ns with nrf7002dk_nrf5340_cpuapp_ns.conf

    -Amanda H.

  • Hi,

    i used SDK v2.6.1,

    Built the project with nrf7002dk_nrf5340_cpuapp_ns and initially encountered the same error. After changing IPPROTO_TCP to IPPROTO_TLS_1_2 able to build successfully,

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) to sock = socket(AF_INET, SOCK_STREAM,IPPROTO_TLS_1_2);

    I am currently working with nrf7002dk_nrf5340_cpuapp and made some changes to the prj.conf file. After these adjustments, I was able to build the project and get the expected output.

    Could you please provide feedback on the code below? (I'm using nrf7002dk_nrf5340_cpuapp).

    /*
     * Copyright (c) 2023 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <errno.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdio.h>
    #include <zephyr/kernel.h>
    #include <zephyr/types.h>
    #include <zephyr/logging/log.h>
    
    #include <dk_buttons_and_leds.h>
    
    /* STEP 3 - Include the necessary header files */
    #include <zephyr/net/wifi.h>
    #include <zephyr/net/wifi_mgmt.h>
    #include <zephyr/net/net_mgmt.h>
    #include <net/wifi_mgmt_ext.h>
    
    /* STEP 12.4 - Include the header file for the Wi-FI credentials library */
    #include <net/wifi_credentials.h>
    #include <zephyr/net/socket.h>
    
    #include <zephyr/net/net_if.h>
    #include <zephyr/sys/printk.h>
    
    // #define SERVER_IP_ADDR "192.168.1.10" // Replace with your server's IP
    // #define SERVER_PORT 8080
    
    // LOG_MODULE_REGISTER(Lesson2_Exercise2, LOG_LEVEL_INF);
    
    /* STEP 4 - Define a macro for the relevant network events */
    // #define EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)
    
    /* STEP 1.2 - Include the header file of the HTTP client library */
    #include <zephyr/net/http/client.h>
    /* STEP 1.4 - Include the header file for the TLS credentials library */
    #include <zephyr/net/tls_credentials.h>
    
    /* STEP 2.3 - Include the certificate */
    static const char ca_certificate[] = {
    #include "certificate.h"
    };
    
    LOG_MODULE_REGISTER(Lesson5_Exercise1);
    
    #define EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)
    
    /* STEP 5 - Declare the callback structure for Wi-Fi events */
    static struct net_mgmt_event_callback mgmt_cb;
    
    /* STEP 6.1 - Define the boolean connected and the semaphore run_app */
    static bool connected = 0;
    static bool firsttime = 1;
    static K_SEM_DEFINE(run_app, 0, 1);
    
    /* STEP 4.1 - Define a macro for the credential security tag */
    #define HTTP_TLS_SEC_TAG 1
    
    /* STEP 2 - Define the macros for the HTTP server hostname and port */
    #define HTTP_HOSTNAME "echo.thingy.rocks" //staging.api.nexkey.com
    #define HTTP_PORT     443
    
    /* STEP 3 - Declare the necessary buffers for receiving messages */
    #define RECV_BUF_SIZE  2048
    #define CLIENT_ID_SIZE 36
    
    static char recv_buf[RECV_BUF_SIZE];
    static char client_id_buf[CLIENT_ID_SIZE + 2];
    
    /* STEP 4 - Define the variable for the counter as 0 */
    static int counter = 0;
    
    static int sock;
    static struct sockaddr_storage server;
    
    //static struct net_mgmt_event_callback mgmt_cb;
    //static bool connected;
    //static K_SEM_DEFINE(run_app, 0, 1);
    
    
    
    static int server_resolve(void)
    {
    	int err;
    	struct addrinfo *result;
    	struct addrinfo hints = {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM};
    
    	err = getaddrinfo(HTTP_HOSTNAME, STRINGIFY(HTTP_PORT), &hints, &result);
    	if (err != 0) {
    		LOG_ERR("getaddrinfo failed, err: %d, %s", err, gai_strerror(err));
    		return -EIO;
    	}
    
    	if (result == NULL) {
    		LOG_ERR("Error, address not found");
    		return -ENOENT;
    	}
    
    	struct sockaddr_in *server4 = ((struct sockaddr_in *)&server);
    	server4->sin_addr.s_addr = ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
    	server4->sin_family = AF_INET;
    	server4->sin_port = ((struct sockaddr_in *)result->ai_addr)->sin_port;
    
    	char ipv4_addr[NET_IPV4_ADDR_LEN];
    	inet_ntop(AF_INET, &server4->sin_addr.s_addr, ipv4_addr, sizeof(ipv4_addr));
    	LOG_INF("IPv4 address of HTTP server found %s", ipv4_addr);
    
    	freeaddrinfo(result);
    
    	return 0;
    }
    
    static int setup_credentials(void)
    {
    	
    	/* STEP 4.2 - Add the credential to the device */
    	int err = tls_credential_add(HTTP_TLS_SEC_TAG, TLS_CREDENTIAL_CA_CERTIFICATE, ca_certificate,
    				 sizeof(ca_certificate));
    	if (err < 0) {
    		LOG_ERR("Failed to add TLS credentials, err: %d", err);
    		return err;
    	}
    
    	return 0;
    }
    
    static int server_connect(void)
    {
    	int err;
    	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2);
    	if (sock < 0) {
    		LOG_ERR("Failed to create socket, err: %d, %s", errno, strerror(errno));
    		return -errno;
    	}
    
    	/* STEP 5.1 - Configure the socket with the security tag for the certificate */
    	sec_tag_t sec_tag_opt[] = {
    		HTTP_TLS_SEC_TAG,
    	};
    	err = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_opt, sizeof(sec_tag_opt));
    	if (err < 0) {
    		LOG_ERR("Failed to set TLS security TAG list, err: %d", errno);
    		(void)close(sock);
    		return -errno;
    	}
    	/* STEP 5.2 - Configure the socket with the hostname of the HTTP server */
    	err = setsockopt(sock, SOL_TLS, TLS_HOSTNAME, HTTP_HOSTNAME, sizeof(HTTP_HOSTNAME));
    	if (err < 0) {
    		LOG_ERR("Failed to set TLS_HOSTNAME option. Err: %d", errno);
    		(void)close(sock);
    		return -errno;
    	}
    
    	err = connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
    	if (err < 0) {
    		LOG_ERR("Connecting to server failed, err: %d, %s", errno, strerror(errno));
    		return -errno;
    	}
    
    	LOG_INF("Connected to server");
    	return 0;
    }
    
    static void response_cb(struct http_response *rsp, enum http_final_call final_data, void *user_data)
    {
    	/* STEP 9 - Define the callback function to print the body */
    	LOG_INF("Response status: %s", rsp->http_status);
    
    	if (rsp->body_frag_len > 0) {
    		char body_buf[rsp->body_frag_len];
    		strncpy(body_buf, rsp->body_frag_start, rsp->body_frag_len);
    		body_buf[rsp->body_frag_len] = '\0';
    		LOG_INF("Received: %s", body_buf);
    	}
    
    	LOG_INF("Closing socket: %d", sock);
    	close(sock);
    }
    
    static void client_id_cb(struct http_response *rsp, enum http_final_call final_data,
    			 void *user_data)
    {
    	/* STEP 6.1 - Log the HTTP response status */
    	LOG_INF("Response status: %s", rsp->http_status);
    
    	/* STEP 6.2 - Retrieve and format the client ID */
    	char client_id_buf_tmp[CLIENT_ID_SIZE + 1];
    	strncpy(client_id_buf_tmp, rsp->body_frag_start, CLIENT_ID_SIZE);
    	client_id_buf_tmp[CLIENT_ID_SIZE] = '\0';
    	client_id_buf[0] = '/';
    	strcat(client_id_buf, client_id_buf_tmp);
    
    	LOG_INF("Successfully acquired client ID: %s", client_id_buf);
    
    	/* STEP 6.3 - Close the socket */
    	LOG_INF("Closing socket: %d", sock);
    	close(sock);
    }
    
    static int client_http_put(void)
    {
    	/* STEP 7 - Define the function to send a PUT request to the HTTP server */
    	int err = 0;
    	int bytes_written;
    	const char *headers[] = {"Connection: close\r\n", NULL};
    
    	struct http_request req;
    	memset(&req, 0, sizeof(req));
    
    	char buffer[12] = {0};
    	bytes_written = snprintf(buffer, 12, "%d", counter);
    	if (bytes_written < 0) {
    		LOG_INF("Unable to write to buffer, err: %d", bytes_written);
    		return bytes_written;
    	}
    
    	req.header_fields = headers;
    	req.method = HTTP_PUT;
    	req.url = client_id_buf;
    	req.host = HTTP_HOSTNAME;
    	req.protocol = "HTTP/1.1";
    	req.payload = buffer;
    	req.payload_len = bytes_written;
    	req.response = response_cb;
    	req.recv_buf = recv_buf;
    	req.recv_buf_len = sizeof(recv_buf);
    
    	LOG_INF("HTTP PUT request: %s", buffer);
    	err = http_client_req(sock, &req, 5000, NULL);
    	if (err < 0) {
    		LOG_ERR("Failed to send HTTP PUT request %s, err: %d", buffer, err);
    	}
    
    	return err;
    }
    
    static int client_http_get(void)
    {
    	/* STEP 8 - Define the function to send a GET request to the HTTP server */
    	int err = 0;
    	const char *headers[] = {"Connection: close\r\n", NULL};
    	
    	struct http_request req;
    	memset(&req, 0, sizeof(req));
    
    	req.header_fields = headers;
    	req.method = HTTP_GET;
    	req.url = client_id_buf;
    	req.host = HTTP_HOSTNAME;
    	req.protocol = "HTTP/1.1";
    	req.response = response_cb;
    	req.recv_buf = recv_buf;
    	req.recv_buf_len = sizeof(recv_buf);
    
    	LOG_INF("HTTP GET request");
    	err = http_client_req(sock, &req, 5000, NULL);
    	if (err < 0) {
    		LOG_ERR("Failed to send HTTP GET request, err: %d", err);
    	}
    
    	return err;
    }
    
    static int client_get_new_id(void)
    {
    	int err = 0;
    
    	/* STEP 5.1 - Define the structure http_request and fill the block of memory */
    	struct http_request req;
    	memset(&req, 0, sizeof(req));
    
    	/* STEP 5.2 - Populate the http_request structure */
    	const char *headers[] = {"Connection: close\r\n", NULL};
    	req.header_fields = headers;
    	req.method = HTTP_POST;
    	req.url = "/new";
    	req.host = HTTP_HOSTNAME;
    	req.protocol = "HTTP/1.1";
    	req.response = client_id_cb;
    	req.recv_buf = recv_buf;
    	req.recv_buf_len = sizeof(recv_buf);
    
    	/* STEP 5.3 - Send the request to the HTTP server */
    	LOG_INF("HTTP POST request");
    	err = http_client_req(sock, &req, 5000, NULL);
    	if (err < 0) {
    		LOG_ERR("Failed to send HTTP POST request, err: %d", err);
    	}
    	return err;
    }
    
    /* STEP 6.2 - Define the callback function for network events */
    static void net_mgmt_event_handler(struct net_mgmt_event_callback *cb,
    			  uint32_t mgmt_event, struct net_if *iface)
    {
    	if ((mgmt_event & EVENT_MASK) != mgmt_event) {
    		return;
    	}
    	if (mgmt_event == NET_EVENT_L4_CONNECTED) {
    		LOG_INF("Network connected");
    		connected = true;
    		dk_set_led_on(DK_LED1);
    		//k_sem_give(&run_app);
    		return;
    	}
    	if (mgmt_event == NET_EVENT_L4_DISCONNECTED) {
    		if (connected == false) {
    			LOG_INF("Waiting for network to be connected");
    		} else {
    			dk_set_led_off(DK_LED1);
    			LOG_INF("Network disconnected");
    			connected = false;
    		}
    		//k_sem_reset(&run_app);
    		return;
    	}
    }
    
    /* STEP 7 - Define the function to populate the Wi-Fi credential parameters */
    //static int wifi_args_to_params(struct wifi_connect_req_params *params)
    //{
    
    	/* STEP 7.1 Populate the SSID and password */
    	//params->ssid = CONFIG_WIFI_CREDENTIALS_STATIC_SSID;
    	//params->ssid_length = strlen(params->ssid);
    
    	//params->psk = CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD;
    	//params->psk_length = strlen(params->psk);
    
    	/* STEP 7.2 - Populate the rest of the relevant members */
    	//params->channel = WIFI_CHANNEL_ANY;
    	//params->security = WIFI_SECURITY_TYPE_PSK;
    	//params->mfp = WIFI_MFP_OPTIONAL;
    	//params->timeout = SYS_FOREVER_MS;
    	//params->band = WIFI_FREQ_BAND_UNKNOWN;
    	//#if NCS_VERSION_NUMBER > 0x20600
    	//memset(params->bssid, 0, sizeof(params->bssid));
    	//#endif
    	//return 0;
    //}
    
    static struct wifi_credentials_personal wifi_cred;
    void set_wifi_credentials_struct() 
    {
    
    	char *wifi_ssid = "realme";
    	char *wifi_password = "Chirag@1527";
    
    	wifi_cred.header.type = WIFI_SECURITY_TYPE_PSK;
    	memset(wifi_cred.header.bssid, 0, sizeof(wifi_cred.header.bssid));
    	wifi_cred.header.flags = 0;
    	//wifi_cred.header.channel = WIFI_CHANNEL_ANY;
    	//wifi_cred.header.timeout = 10;
    
    	wifi_cred.header.ssid_len = strlen(wifi_ssid);
    	memcpy(wifi_cred.header.ssid, wifi_ssid, wifi_cred.header.ssid_len);
    	
    	wifi_cred.password_len = strlen(wifi_password);
    	memcpy(wifi_cred.password, wifi_password, wifi_cred.password_len);
    
    	int ret = wifi_credentials_set_personal_struct(&wifi_cred);
    
    	if (ret != 0) {
    		LOG_ERR("Failed to set credentials, err: %d", ret);
    	}
    }
    static void button_handler(uint32_t button_state, uint32_t has_changed)
    {
    	/* STEP 10 - Define the button handler to send requests upon button triggers */
    	if (has_changed & DK_BTN1_MSK && button_state & DK_BTN1_MSK) {
    		if (server_connect() >= 0) {
    			client_http_put();
    			counter++;
    		}
    	} else if (has_changed & DK_BTN2_MSK && button_state & DK_BTN2_MSK) {
    		if (server_connect() >= 0) {
    			client_http_get();
    		}
    	}
    }
    
    int main(void)
    {
    	/* STEP 8.1 - Declare the variable for the network configuration parameters */
    	//struct wifi_connect_req_params cnx_params;
    
    
    
    	/* STEP 8.2 - Get the network interface */
    	struct net_if *iface = net_if_get_first_wifi();
    	if (iface == NULL) {
    		LOG_ERR("Returned network interface is NULL");
    		return -1;
    	}
    
    	if (dk_leds_init() != 0) {
    		LOG_ERR("Failed to initialize the LED library");
    	}
    
    	/* Sleep to allow initialization of Wi-Fi driver */
    	k_sleep(K_SECONDS(1));
    
    	/* STEP 9 - Initialize and add the callback function for network events */
    	net_mgmt_init_event_callback(&mgmt_cb, net_mgmt_event_handler, EVENT_MASK);
    	net_mgmt_add_event_callback(&mgmt_cb);
    
    	/* STEP 10 - Populate cnx_params with the network configuration */
    	//wifi_args_to_params(&cnx_params);
    
        set_wifi_credentials_struct();
    	/* STEP 11 - Call net_mgmt() to request the Wi-Fi connection */
    	LOG_INF("Connecting to Wi-Fi");
    	//printf("try to connect with wifi");
    	//LOG_ERR("buttons library");
    	//int err = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, &wifi_cred, sizeof(struct wifi_credentials_personal));
    	//LOG_ERR("buttons library");
    	// if (err) {
    	// 	LOG_ERR("Connecting to Wi-Fi failed, err: %d", err);
    	// 	//return ENOEXEC;
    	// }
    
    	//k_sem_take(&run_app, K_FOREVER);
    
    	if (dk_buttons_init(button_handler) != 0) {
    		LOG_ERR("Failed to initialize the buttons library ");
    	}
    	while(1)
    	{
    		//LOG_ERR("Failed to initialize the buttons library ");
    		k_sleep(K_SECONDS(1));
    		if(!connected)
    		{
    			int err = net_mgmt(NET_REQUEST_WIFI_CONNECT_STORED, iface, &wifi_cred, sizeof(struct wifi_credentials_personal));
    		}
    		if(connected && firsttime == 1)
    		{
    			k_sleep(K_SECONDS(1));
    			if (server_resolve() != 0) {
    				LOG_ERR("Failed to resolve server name");
    				return 0;
    			}
    			
    			if (setup_credentials() != 0) {
    		        LOG_ERR("Setup credentials failed");
    	        }
    
    			if (server_connect() != 0) {
    				LOG_ERR("Failed to initialize client");
    				return 0;
    			}	
    
    			/* STEP 11 - Retrieve the client ID upon connection */
    			if (client_get_new_id() < 0) {
    				LOG_ERR("Failed to get client ID");
    				return 0;
    			}
    			firsttime = 0;
    			LOG_ERR("buttons library");
    		}
    		//return 0;
    	}
    
    	
    
    		
    }
    # Wi-Fi
    CONFIG_WIFI=y
    CONFIG_WIFI_NRF700X=y
    CONFIG_WPA_SUPP=y
    # CONFIG_WPA_SUPP_CRYPTO_PSA=y
    
    # Wi-Fi Credentials
    CONFIG_WIFI_CREDENTIALS=y
    CONFIG_WIFI_CREDENTIALS_STATIC=n
    
    # Networking Management API
    CONFIG_NET_MGMT=y
    CONFIG_NET_MGMT_EVENT=y
    CONFIG_NET_MGMT_EVENT_INFO=y
    CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096
    CONFIG_NET_CONNECTION_MANAGER=y
    CONFIG_WIFI_MGMT_EXT=y
    
    # Support for shell commands
    # CONFIG_SHELL=y
    # CONFIG_WIFI_CREDENTIALS_SHELL=y
    # CONFIG_SHELL_STACK_SIZE=4400
    
    # Logging
    CONFIG_LOG=y
    
    # DK library
    CONFIG_DK_LIBRARY=y
    
    # System settings
    CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC_NANO=n
    
    # Networking
    CONFIG_NETWORKING=y
    CONFIG_NET_NATIVE=y
    CONFIG_NET_SOCKETS=y
    CONFIG_NET_SOCKETS_POSIX_NAMES=y
    CONFIG_POSIX_MAX_FDS=16
    
    CONFIG_NET_L2_ETHERNET=y
    CONFIG_NET_IPV4=y
    CONFIG_NET_IPV6=y
    CONFIG_NET_TCP=y
    CONFIG_NET_DHCPV4=y
    CONFIG_DNS_RESOLVER=y
    
    # TLS
    # STEP 1.1 - Enable the TLS library and security relevant configurations
    CONFIG_NET_SOCKETS_SOCKOPT_TLS=y
    CONFIG_TLS_CREDENTIALS=y
    CONFIG_MBEDTLS_RSA_C=y
    CONFIG_MBEDTLS_DHM_C=y 
    
    # STEP 1.2 - Enable support for server name indication (SNI)
    CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=y
    
    # Memory
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_HEAP_MEM_POOL_SIZE=153600
    
    CONFIG_NET_TCP_WORKQ_STACK_SIZE=2048
    CONFIG_NET_TX_STACK_SIZE=4096
    CONFIG_NET_RX_STACK_SIZE=4096
    CONFIG_NET_BUF_RX_COUNT=16
    CONFIG_NET_BUF_TX_COUNT=16
    CONFIG_NET_BUF_DATA_SIZE=256
    CONFIG_NET_TC_TX_COUNT=0
    
    # HTTP
    CONFIG_HTTP_CLIENT=y
    # For storing Wi-Fi credentials
    CONFIG_WIFI_CREDENTIALS_BACKEND_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS=y
    CONFIG_SETTINGS_NVS=y
    
    # CONFIG_NET_L2_WIFI_SHELL=y
    
    # General
    CONFIG_POSIX_CLOCK=y
    
    # Optimize Wi-Fi stack to save some memory
    
    CONFIG_NRF700X_MAX_TX_AGGREGATION=4
    
    # Wi-Fi
    
    
    CONFIG_WIFI_NRF700X_LOG_LEVEL_ERR=y
    
    
    # WPA supplicant
    
    CONFIG_WPA_SUPP_LOG_LEVEL_ERR=y
    
    # Zephyr NET Connection Manager connectivity layer
    CONFIG_L2_WIFI_CONNECTIVITY=y
    # CONFIG_L2_WIFI_CONNECTIVITY_AUTO_DOWN=n
    # CONFIG_L2_WIFI_CONNECTIVITY_AUTO_CONNECT=n
    
    # DNS
    
    # CONFIG_NET_SOCKETS_DNS_TIMEOUT=30000
    
    # NET sockets
    
    CONFIG_NET_UDP=y
    # CONFIG_NET_SOCKETS_OFFLOAD=n
    
    # CONFIG_NET_CONTEXT_SNDTIMEO=y
    
    # TLS networking
    CONFIG_NET_SOCKETS_ENABLE_DTLS=n
    CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=2
    
    
    # TLS credentials
    
    # Here is the overlay I used for nrf7002dk_nrf5340_cpuapp
    
    # CONFIG_TLS_CREDENTIALS_BACKEND_VOLATILE=y
    
    # mbedTLS
    CONFIG_NRF_SECURITY=y
    CONFIG_MBEDTLS=y
    CONFIG_MBEDTLS_ENABLE_HEAP=y
    CONFIG_MBEDTLS_HEAP_SIZE=81920
    CONFIG_PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY=y
    CONFIG_PSA_WANT_RSA_KEY_SIZE_2048=y
    
    CONFIG_MBEDTLS_TLS_LIBRARY=y
    
    CONFIG_PM_SINGLE_IMAGE=y
  • ChiragBhavsar said:

    Built the project with nrf7002dk_nrf5340_cpuapp_ns and initially encountered the same error. After changing IPPROTO_TCP to IPPROTO_TLS_1_2 able to build successfully,

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) to sock = socket(AF_INET, SOCK_STREAM,IPPROTO_TLS_1_2);

    I am currently working with nrf7002dk_nrf5340_cpuapp and made some changes to the prj.conf file. After these adjustments, I was able to build the project and get the expected output.

    Good to hear about the success. 

    ChiragBhavsar said:
    Could you please provide feedback on the code below? (I'm using nrf7002dk_nrf5340_cpuapp).

    I don't see the issue from that. 

  •  I was able to connect to the HTTP host, but I encountered issues when trying to connect to the WebSocket host.

    i disable the http portion from the code and try to connect with WebSocket host but i am not able to connect with it.

    Could you please review my code and provide feedback to help me resolve the WebSocket connection issue?

    HTTP_web.zip

Related