https server on nrf7002ek failed

I'm trying to build an HTTPS server application using zephyr http library, but the client connection is always being rejected. Can anyone help?


here is the logs

SEGGER J-Link V8.44 - Real time terminal output
SEGGER J-Link V10.1, SN=600115917
Process: JLinkGDBServerCLExe
[00:00:00.004,000] <inf> wifi_nrf_bus: SPIM spi@40013000: freq = 8 MHz
[00:00:00.004,000] <inf> wifi_nrf_bus: SPIM spi@40013000: latency = 0
[00:00:00.272,000] <inf> wifi_nrf: Management buffer offload enabled

*** Booting Zephyr OS build v4.1.0 ***
[00:00:00.398,000] <inf> MAIN_CPP: Starting Zephyr HTTP Server
[00:00:00.398,000] <inf> wifi_supplicant: wpa_supplicant initialized
[00:00:01.398,000] <inf> WIFI_MANAGER: WiFi manager initialized successfully
[00:00:01.398,000] <inf> MAIN_CPP: WiFi Manager initialized, starting in STA mode
[00:00:01.398,000] <inf> WIFI_MANAGER: Starting WiFi in Station mode
[00:00:01.398,000] <inf> WIFI_MANAGER: Connecting to SSID: Qwerty
[00:00:03.401,000] <inf> WIFI_MANAGER: Connected to Qwerty
[00:00:07.443,000] <inf> net_dhcpv4: Received: 192.168.19.80
[00:00:12.001,000] <dbg> net_http_server: http_server_init: Initialized HTTP Service 192.168.19.80:8080
[00:00:12.001,000] <dbg> net_http_server: http_server_start: Starting HTTP server
[13] accept failed (-23)
[00:00:19.023,000] <dbg> net_http_server: http_server_run: accept: -23
[00:00:19.032,000] <err> net_tcp: conn: 0x2004d2b8, new bytes 248 during TIME-WAIT state sending reset
RTT:0> 


#include <stdio.h>
#include <errno.h>

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/kernel.h>
#include <zephyr/net/http/service.h>
#include <zephyr/logging/log.h>
#include <zephyr/data/json.h>
#include <zephyr/net/socket.h>
#include <string.h>
#include <stdio.h>

#include "WifiManager.hpp"

#include <zephyr/net/tls_credentials.h>

#define APP_SEC_TAG  42  

LOG_MODULE_REGISTER(MAIN_CPP, LOG_LEVEL_INF);

static const sec_tag_t tls_sec_tags[] = { APP_SEC_TAG };

static const uint8_t psk[]     = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
                                   0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF };

static const char     psk_id[] = "mydevice-01";

static int register_psk(void)
{
    int ret;

    ret = tls_credential_add(APP_SEC_TAG, TLS_CREDENTIAL_PSK,
                             psk, sizeof(psk));
    if (ret < 0) { return ret; }

    ret = tls_credential_add(APP_SEC_TAG, TLS_CREDENTIAL_PSK_ID,
                             psk_id, strlen(psk_id));
    return ret;
}



static uint16_t http_service_port = 8080;

HTTPS_SERVICE_DEFINE(
    api,           
    "192.168.19.80",              
    &http_service_port,       
    1,                 
    1,                
    NULL,             
    NULL,                         
    tls_sec_tags,    
    sizeof(tls_sec_tags)
);

struct device_status {
    uint32_t uptime_ms;
    int32_t  temperature_c;
    bool     wifi_connected;
};

struct device_config {
    int  sample_rate_hz;
    bool enabled;
    char name[16];
};

static struct device_config g_cfg = {
    .sample_rate_hz = 10, .enabled = true, .name = "U5+nRF7002"
};

static const struct json_obj_descr status_descr[] = {
    JSON_OBJ_DESCR_PRIM(struct device_status, uptime_ms,     JSON_TOK_NUMBER),
    JSON_OBJ_DESCR_PRIM(struct device_status, temperature_c, JSON_TOK_NUMBER),
    JSON_OBJ_DESCR_PRIM(struct device_status, wifi_connected,JSON_TOK_TRUE),
};

static const struct json_obj_descr config_descr[] = {
    JSON_OBJ_DESCR_PRIM(struct device_config, sample_rate_hz, JSON_TOK_NUMBER),
    JSON_OBJ_DESCR_PRIM(struct device_config, enabled,        JSON_TOK_TRUE),
    JSON_OBJ_DESCR_PRIM(struct device_config, name,           JSON_TOK_STRING),
};

static const struct http_header JSON_HDRS[] = {
    { .name = "Content-Type", .value = "application/json" },
    { .name = "Cache-Control", .value = "no-store" },
};

#define MAX_REQ_BODY 512
static char req_buf[MAX_REQ_BODY];

static int status_cb(struct http_client_ctx *client,
                     enum http_data_status status,
                     const struct http_request_ctx *req,
                     struct http_response_ctx *rsp,
                     void *user_data)
{
    ARG_UNUSED(client); ARG_UNUSED(req); ARG_UNUSED(user_data);

    if (status != HTTP_SERVER_DATA_FINAL) {
        return 0;
    }

    struct device_status st = {
        .uptime_ms = (uint32_t)k_uptime_get(),
        .temperature_c = 25,            
        .wifi_connected = true,        
    };

    static char out[160];
    int n = json_obj_encode_buf(status_descr, ARRAY_SIZE(status_descr), &st, out, sizeof(out));
    if (n < 0) {
        rsp->status = HTTP_500_INTERNAL_SERVER_ERROR;
        rsp->body = reinterpret_cast<const uint8_t*>("{\"error\":\"encode\"}");
        rsp->body_len = strlen(reinterpret_cast<const char*>(rsp->body));
        rsp->headers = JSON_HDRS; rsp->header_count = ARRAY_SIZE(JSON_HDRS);
        rsp->final_chunk = true;
        return 0;
    }

    rsp->status = HTTP_200_OK;
    rsp->headers = JSON_HDRS; rsp->header_count = ARRAY_SIZE(JSON_HDRS);
    rsp->body = reinterpret_cast<uint8_t*>(out);
    rsp->body_len = sizeof(out);
    rsp->final_chunk = true;
    return 0;
}

/* --------- /api/config  (GET/PUT) --------- */
static int config_cb(struct http_client_ctx *client,
                     enum http_data_status status,
                     const struct http_request_ctx *req,
                     struct http_response_ctx *rsp,
                     void *user_data)
{
    ARG_UNUSED(user_data);

    const enum http_method m = client->method;

    if (m == HTTP_GET) {
        if (status != HTTP_SERVER_DATA_FINAL) {
            return 0;
        }
        static char out[160];
        int n = json_obj_encode_buf(config_descr, ARRAY_SIZE(config_descr), &g_cfg, out, sizeof(out));
        if (n < 0) {
            rsp->status = HTTP_500_INTERNAL_SERVER_ERROR;
            rsp->body = reinterpret_cast<const uint8_t*>("{\"error\":\"encode\"}");
            rsp->body_len = strlen(reinterpret_cast<const char*>(rsp->body));
            rsp->headers = JSON_HDRS; rsp->header_count = ARRAY_SIZE(JSON_HDRS);
            rsp->final_chunk = true;
            return 0;
        }
        rsp->status = HTTP_200_OK;
        rsp->headers = JSON_HDRS; rsp->header_count = ARRAY_SIZE(JSON_HDRS);
        rsp->body = reinterpret_cast<uint8_t*>(out);
        rsp->body_len = sizeof(out);
        rsp->final_chunk = true;
        return 0;
    }

    if (m == HTTP_PUT) {
        static size_t acc = 0;
        if (status == HTTP_SERVER_DATA_ABORTED) { acc = 0; return 0; }
        /* accumulate request body */
        if (req->data && req->data_len) {
            size_t room = sizeof(req_buf) - acc;
            size_t to_copy = MIN(room, req->data_len);
            memcpy(req_buf + acc, req->data, to_copy);
            acc += to_copy;
        }
        if (status != HTTP_SERVER_DATA_FINAL) {
            return 0; /* wait for the final chunk */
        }

        /* Parse JSON in-place (json_obj_parse modifies buffer) */
        struct device_config cfg_tmp = {0};
        int ret = json_obj_parse(req_buf, acc, config_descr, ARRAY_SIZE(config_descr), &cfg_tmp);
        acc = 0;
        if (ret < 0) {
            rsp->status = HTTP_400_BAD_REQUEST;
            rsp->headers = JSON_HDRS; rsp->header_count = ARRAY_SIZE(JSON_HDRS);
            rsp->body = reinterpret_cast<const uint8_t*>("{\"error\":\"bad json\"}");
            rsp->body_len = strlen(reinterpret_cast<const char*>(rsp->body));
            rsp->final_chunk = true;
            return 0;
        }

        /* Persist: copy string field; ints/bools already copied */
        /* cfg_tmp.name points inside req_buf -> copy to g_cfg.name */
        if (cfg_tmp.name) {
            snprintk(g_cfg.name, sizeof(g_cfg.name), "%s", cfg_tmp.name);
        }
        g_cfg.sample_rate_hz = cfg_tmp.sample_rate_hz;
        g_cfg.enabled        = cfg_tmp.enabled;

        rsp->status = HTTP_204_NO_CONTENT; /* No Content */
        rsp->headers = JSON_HDRS; 
        rsp->header_count = ARRAY_SIZE(JSON_HDRS);
        rsp->final_chunk = true;
        return 0;
    }

    /* Method not allowed for this resource */
    rsp->status = HTTP_405_METHOD_NOT_ALLOWED;
    rsp->headers = JSON_HDRS; rsp->header_count = ARRAY_SIZE(JSON_HDRS);
    rsp->body = reinterpret_cast<const uint8_t*>("{\"error\":\"method not allowed\"}");
    rsp->body_len = strlen(reinterpret_cast<const char*>(rsp->body));
    rsp->final_chunk = true;
    return 0;
}

/* --------- /api/command  (POST) --------- */
struct cmd_req { const char *action; };
static const struct json_obj_descr cmd_req_descr[] = {
    JSON_OBJ_DESCR_PRIM(struct cmd_req, action, JSON_TOK_STRING),
};

static int command_cb(struct http_client_ctx *client,
                      enum http_data_status status,
                      const struct http_request_ctx *req,
                      struct http_response_ctx *rsp,
                      void *user_data)
{
    ARG_UNUSED(client); ARG_UNUSED(user_data);
    static size_t acc = 0;

    if (status == HTTP_SERVER_DATA_ABORTED) { acc = 0; return 0; }

    /* accumulate body */
    if (req->data && req->data_len) {
        size_t room = sizeof(req_buf) - acc;
        size_t to_copy = MIN(room, req->data_len);
        memcpy(req_buf + acc, req->data, to_copy);
        acc += to_copy;
    }
    if (status != HTTP_SERVER_DATA_FINAL) {
        return 0;
    }

    /* parse and act */
    struct cmd_req cmd = {0};
    int ret = json_obj_parse(req_buf, acc, cmd_req_descr, ARRAY_SIZE(cmd_req_descr), &cmd);
    acc = 0;
    if (ret < 0 || cmd.action == NULL) {
        rsp->status = HTTP_400_BAD_REQUEST;
        rsp->headers = JSON_HDRS; rsp->header_count = ARRAY_SIZE(JSON_HDRS);
        rsp->body = reinterpret_cast<const uint8_t*>("{\"error\":\"bad json\"}");
        rsp->body_len = strlen(reinterpret_cast<const char*>(rsp->body));
        rsp->final_chunk = true;
        return 0;
    }

    /* Example actions */
    bool ok = true;
    if (!strcmp(cmd.action, "reboot")) {
        /* sys_reboot(SYS_REBOOT_WARM);  // if you want */
        ok = true;
    } else if (!strcmp(cmd.action, "factory_reset")) {
        /* TODO: wipe config */
        ok = true;
    } else {
        ok = false;
    }

    static char out[64];
    int n = snprintk(out, sizeof(out), "{\"ok\":%s}", ok ? "true" : "false");
    rsp->status = ok ? HTTP_200_OK : HTTP_422_UNPROCESSABLE_ENTITY;
    rsp->headers = JSON_HDRS; rsp->header_count = ARRAY_SIZE(JSON_HDRS);
    rsp->body = reinterpret_cast<uint8_t*>(out); 
    rsp->body_len = sizeof(out);
    rsp->final_chunk = true;
    return 0;
}

static struct http_resource_detail_dynamic status_detail = {
    .common = {
        .bitmask_of_supported_http_methods = BIT(HTTP_GET),
        .type = HTTP_RESOURCE_TYPE_DYNAMIC,
    },
    .cb = status_cb,
};
HTTP_RESOURCE_DEFINE(api_status, api, "/api/status", &status_detail);

static struct http_resource_detail_dynamic config_detail = {
    .common = {
        .bitmask_of_supported_http_methods = BIT(HTTP_GET) | BIT(HTTP_PUT),
        .type = HTTP_RESOURCE_TYPE_DYNAMIC,
    },
    .cb = config_cb,
};
HTTP_RESOURCE_DEFINE(api_config, api, "/api/config", &config_detail);

static struct http_resource_detail_dynamic command_detail = {
    .common = {
        .bitmask_of_supported_http_methods = BIT(HTTP_POST),
        .type = HTTP_RESOURCE_TYPE_DYNAMIC,
    },
    .cb = command_cb,
};
HTTP_RESOURCE_DEFINE(api_command, api, "/api/command", &command_detail);


int main(void)
{
    LOG_INF("Starting Zephyr HTTP Server");

    WiFiManager wifitask;
	NetworkSetupParams::currentNetParams.station.StaSsid = "Qwerty";
    NetworkSetupParams::currentNetParams.station.Psk = "12345678";
    
    wifi_manager_state wifiManagerResult = wifitask.initialize();

	if (wifiManagerResult == wifi_manager_state::success) {
        LOG_INF("WiFi Manager initialized, starting in STA mode");
        wifitask.start(wifi_mode::sta);
        k_sleep(K_SECONDS(10));
	} else {
		LOG_ERR("WiFi Manager initialization failed going to sleep....\n");
		
	}
    if (register_psk() < 0) {
        LOG_ERR("Failed to register PSK credentials");
    }
	http_server_start();
    while (1) {
        k_sleep(K_SECONDS(1));
    }

    return 0;
}



CONFIG_CPP=y
CONFIG_STD_CPP17=y
CONFIG_REQUIRES_FULL_LIBCPP=y


CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=n
CONFIG_NET_TCP=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_SOCKOPT_TLS=y


# WiFi Configuration
CONFIG_WIFI=y
CONFIG_WIFI_NRF70=y
CONFIG_NET_L2_WIFI_MGMT=y
CONFIG_NET_DHCPV4=y

# TLS Configuration
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_BUILTIN=y
CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y
CONFIG_MBEDTLS_TLS_VERSION_1_2=y
CONFIG_HTTP_SERVER=y


CONFIG_MBEDTLS_CIPHER_AES_ENABLED=y
CONFIG_MBEDTLS_CIPHER_GCM_ENABLED=y

CONFIG_HTTP_SERVER_SAMPLE_PEER_VERIFICATION_REQUIRE=n

# Logging
CONFIG_LOG=y
CONFIG_NET_LOG=y
CONFIG_LOG_DEFAULT_LEVEL=3

# Memory
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_HEAP_MEM_POOL_SIZE=16384

CONFIG_NET_IF_MAX_IPV6_COUNT=2
CONFIG_NET_IF_MAX_IPV4_COUNT=2
CONFIG_NET_DEFAULT_IF_WIFI=y

CONFIG_NET_DHCPV4_SERVER=n
CONFIG_NRF70_AP_MODE=n
CONFIG_WIFI_NM_WPA_SUPPLICANT_AP=n

CONFIG_WIFI_NM_WPA_SUPPLICANT_THREAD_STACK_SIZE=20480

CONFIG_WIFI_SCAN_DWELL_TIME_ACTIVE=50
CONFIG_WIFI_SCAN_DWELL_TIME_PASSIVE=130

CONFIG_UART_CONSOLE=n
CONFIG_RTT_CONSOLE=y
CONFIG_USE_SEGGER_RTT=y

CONFIG_JSON_LIBRARY=y

CONFIG_HTTP_SERVER_SAMPLE_PEER_VERIFICATION_REQUIRE=n

CONFIG_NET_CONNECTION_MANAGER=y

CONFIG_WIFI_CREDENTIALS=y
CONFIG_WIFI_CREDENTIALS_STATIC=y
CONFIG_WIFI_CREDENTIALS_STATIC_SSID="Qwerty"
CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="12345678"

CONFIG_POSIX_API=y
CONFIG_EVENTFD=y
CONFIG_ZVFS_OPEN_MAX=16
CONFIG_ZVFS_POLL_MAX=16
CONFIG_ZVFS_EVENTFD_MAX=2
CONFIG_HTTP_SERVER_STACK_SIZE=16384

CONFIG_NET_HTTP_SERVER_LOG_LEVEL_DBG=y 

CONFIG_NET_MAX_CONTEXTS=24

Parents Reply Children
No Data
Related