Enabling the TLS layer to get a HTTPS connection going.

7343.nrf7002dk_nrf5340_cpuapp_ns.conf3124.prj.confHello everyone.

WE're trying to make a https connection with google.com and execute a GET request.

Wifi connection is working; DHCP seems to be working (my personal assumption given the log message we get: "Resolved: [(1, 1, 6, '', ('142.250.201.206', 443))]" which indicates that getaddrinfo() works); but when trying to initiate the socket via TLS, something strange happens: we get the error "OSError: 109".

Inserting some debug prints inside subsys/net/lib/sockets/, we found the culprit to be the function "int zsock_setsockopt_ctx(struct net_context *ctx, int level, int optnameconst void *optval, socklen_t optlen)".

The function call that triggers error 109 is:  res = setsockopt(socket->ctx, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));

No matter what other option we try to set via setsockopt(), it will fail with the 109 error since the implementation for setsockopt() is somehow set to sockets_inet.c (whose implementation does not recognise SOL_TLS as a valid in its switches) instead of sockets_tls.c (which has handling for SOL_TLS in its switches). My personal hunch is that the config options set in the project are somehow wrong. Can someone please take a look over our .conf files? Maybe we can find the culprit. :)

We can provide any extra code snippets that are necessary for debugging and/ or run any tests. Have a great day and hope to hear from you soon!

Parents
  • Hi,

     

    I used net/https_client for this exercise.

    You need to download r1.pem from here: https://pki.goog/repository/

     

    Place this in certs/ folder, and make sure that you change the file in CMakeLists.txt, change the domain in kconfig, and add the required configurations in the board .conf file:

    diff --git a/samples/net/https_client/CMakeLists.txt b/samples/net/https_client/CMakeLists.txt
    index 2a937786ed..39276fd2e2 100644
    --- a/samples/net/https_client/CMakeLists.txt
    +++ b/samples/net/https_client/CMakeLists.txt
    @@ -14,7 +14,7 @@ set(gen_dir ${CMAKE_CURRENT_BINARY_DIR}/certs)
     zephyr_include_directories(${gen_dir})
     generate_inc_file_for_target(
         app
    -    cert/DigiCertGlobalG2.pem
    +    cert/r1.pem
         ${gen_dir}/DigiCertGlobalG2.pem.inc
         )
     
    diff --git a/samples/net/https_client/Kconfig b/samples/net/https_client/Kconfig
    index 90ad33f42e..bb22e82794 100644
    --- a/samples/net/https_client/Kconfig
    +++ b/samples/net/https_client/Kconfig
    @@ -15,7 +15,7 @@ config SAMPLE_TFM_MBEDTLS
     
     config HTTPS_HOSTNAME
            string "HTTPS hostname"
    -       default "example.com"
    +       default "google.com"
     
     endmenu
     
    diff --git a/samples/net/https_client/boards/nrf7002dk_nrf5340_cpuapp_ns.conf b/samples/net/https_client/boards/nrf7002dk_nrf5340_cpuapp_ns.conf
    index 9eb362cb16..8366313af8 100644
    --- a/samples/net/https_client/boards/nrf7002dk_nrf5340_cpuapp_ns.conf
    +++ b/samples/net/https_client/boards/nrf7002dk_nrf5340_cpuapp_ns.conf
    @@ -69,3 +69,20 @@ CONFIG_MBEDTLS_TLS_LIBRARY=y
     CONFIG_TFM_PROFILE_TYPE_SMALL=y
     CONFIG_PM_PARTITION_SIZE_TFM_SRAM=0xc000
     CONFIG_PM_PARTITION_SIZE_TFM=0x20000
    +
    +CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=y
    +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y
    +CONFIG_MBEDTLS_SSL_MAX_FRAGMENT_LENGTH=y
    +CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y
    +CONFIG_PSA_WANT_RSA_KEY_SIZE_4096=y
    +CONFIG_MBEDTLS_MPI_MAX_SIZE=512
    +
    +CONFIG_LOG=y
    +CONFIG_MBEDTLS_DEBUG=y
    +CONFIG_MBEDTLS_SSL_DEBUG_ALL=y
    +CONFIG_MBEDTLS_LOG_LEVEL_DBG=y
    +CONFIG_MBEDTLS_DEBUG_C=y
    +CONFIG_MBEDTLS_DEBUG_LEVEL=4
    +# Handle the large influx of prints
    +CONFIG_LOG_BUFFER_SIZE=16384
    +CONFIG_LOG_BACKEND_UART=y
    

    I also need to add CONFIG_NET_IPV6=n due to a local network issue at my end.

     

    Kind regards,

    Håkon

  • There are many options and suboptions in the link you sent me. Which one is the correct one?

    When attempting to get it working, I got r1.der and then created r1.der.inc. But I'm not sure which option I chose.

  • Hi!

     

    Great to hear that you fixed the socket issue.

    Tudor B. said:
    actually prints what you saw in my logs:
    [00:00:36.237,976] <err> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:1402: alloc(zu bytes) failed
    I inserted my own debug code above:
    printk("Dead here...55. Tried to allocate %d bytes and failed\n", in_buf_len);
    and it printed:
    Dead here...55. Tried to allocate 16717 bytes and failed

    Could you share the full .config file? I suspect the configured mbedtls heap is too low here.

    Tudor B. said:
    The way things are looking, I think we need to find a solution to reduce the RAM usage since we're currently at:
    RAM:      383248 B       416 KB     89.97%

    You have enabled station and softap, where as only softap uses approx. 222kB RAM, as shown here:

    https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/wifi/sap_mode/mem_requirements_sap.html

    In addition, mbedtls will add approx. 80 kB.

     

    Your memory fit is tight, especially when adding micropython into the feature list.

     

    Kind regards,

    Håkon

  • We can drop the AP mode (comment it out) and make an internal note akin to: "if you want sockets and https communication -> AP off; AP on -> sockets and https off".

    8360.nrf7002dk_nrf5340_cpuapp_ns.conf

    8787.prj.conf

  • How can I disable SoftAP and leave just STA mode active?

  • Running the "west build -d ./build/zephyr -t ram_report" command produces the following output:
    ram_report.txt

    I've filtered through it and found only a few major RAM hoggers:
    │ ├── _k_mem_slab_buf_tcp_conns_slab 3000 0.49% 0x20063440 noinit
    │ ├── fw_patch 81572 13.36% 0x000b7d68 rodata
    │ ├── heap.lto_priv.0 32768 5.37% 0x2000f024 bss
    │ ├── iface_wq_stack 4400 0.72% 0x20030108 noinit
    │ ├── kheap__system_heap 65536 10.74% 0x2001b1e8 noinit
    │ ├── kheap_net_buf_mem_pool_rx_bufs 4096 0.67% 0x20031238 noinit
    │ ├── kheap_net_buf_mem_pool_tx_bufs 4096 0.67% 0x20032238 noinit
    │ ├── kheap_wifi_drv_ctrl_mem_pool 20000 3.28% 0x20056f60 noinit
    │ ├── kheap_wifi_drv_data_mem_pool 130000 21.30% 0x20037390 noinit
    │ ├── mbedtls_heap 16384 2.68% 0x200171c4 bss
    │ ├── mgmt_stack 4600 0.75% 0x20033638 noinit
    │ ├── mp_thread_stack_array 20480 3.36% 0x2005de80 noinit
    │ ├── supplicant_thread_stack 5600 0.92% 0x2002eb28 noinit
    │ ├── z_main_stack 12288 2.01% 0x2002b328 noinit

    Also worth noting: I suspect AP is disabled based on the most recent .conf files that I've uploaded. I even tried to tune some RX and TX buffs, but it only lowered RAM usage by ~1.65%:

    RAM:      374936 B       416 KB     88.02%

    Also, I've explicitly set: CONFIG_NRF70_AP_MODE=n

    and I found and took in virtually everything from: https://github.com/nrfconnect/sdk-nrf/blob/main/samples/wifi/throughput/overlay-memory-optimized.conf

    which was suggested in the "WiFi stack configuration and performance" documentation page: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/wifi/stack_configuration.html

    I even tried disabling CONFIG_WIFI_NM_WPA_SUPPLICANT, but RAM usage didn't lower by much and anyway I suspect we need this one to enable STA mode to connect to a WiFi.

Reply
  • Running the "west build -d ./build/zephyr -t ram_report" command produces the following output:
    ram_report.txt

    I've filtered through it and found only a few major RAM hoggers:
    │ ├── _k_mem_slab_buf_tcp_conns_slab 3000 0.49% 0x20063440 noinit
    │ ├── fw_patch 81572 13.36% 0x000b7d68 rodata
    │ ├── heap.lto_priv.0 32768 5.37% 0x2000f024 bss
    │ ├── iface_wq_stack 4400 0.72% 0x20030108 noinit
    │ ├── kheap__system_heap 65536 10.74% 0x2001b1e8 noinit
    │ ├── kheap_net_buf_mem_pool_rx_bufs 4096 0.67% 0x20031238 noinit
    │ ├── kheap_net_buf_mem_pool_tx_bufs 4096 0.67% 0x20032238 noinit
    │ ├── kheap_wifi_drv_ctrl_mem_pool 20000 3.28% 0x20056f60 noinit
    │ ├── kheap_wifi_drv_data_mem_pool 130000 21.30% 0x20037390 noinit
    │ ├── mbedtls_heap 16384 2.68% 0x200171c4 bss
    │ ├── mgmt_stack 4600 0.75% 0x20033638 noinit
    │ ├── mp_thread_stack_array 20480 3.36% 0x2005de80 noinit
    │ ├── supplicant_thread_stack 5600 0.92% 0x2002eb28 noinit
    │ ├── z_main_stack 12288 2.01% 0x2002b328 noinit

    Also worth noting: I suspect AP is disabled based on the most recent .conf files that I've uploaded. I even tried to tune some RX and TX buffs, but it only lowered RAM usage by ~1.65%:

    RAM:      374936 B       416 KB     88.02%

    Also, I've explicitly set: CONFIG_NRF70_AP_MODE=n

    and I found and took in virtually everything from: https://github.com/nrfconnect/sdk-nrf/blob/main/samples/wifi/throughput/overlay-memory-optimized.conf

    which was suggested in the "WiFi stack configuration and performance" documentation page: https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/wifi/stack_configuration.html

    I even tried disabling CONFIG_WIFI_NM_WPA_SUPPLICANT, but RAM usage didn't lower by much and anyway I suspect we need this one to enable STA mode to connect to a WiFi.

Children
  • I tried playing with various stacks, including CONFIG_MAIN_STACK_SIZE. But lowering other stacks and squeezing in CONFIG_MBEDTLS_HEAP_SIZE=81920, I reach a RAM usage of:

    RAM:      407704 B       416 KB     95.71%

    The image flashes, but when I try the same scenario of connecting to WiFi, doing getaddrinfo(), then opening a socket, I get a Stack Overflow when trying to connect to the WiFi network:

    Network ID: DIGI-4TYa & Network MAC: AC:CC:36:55:68:E9
    Network ID: DIGI-4uE3 & Network MAC: AC:CC:36:4D:9A:51
    Network ID: DIGI-C7uG & Network MAC: 28:F8:D6:C7:E5:91
    Network ID: DIGI-kTWh & Network MAC: 1C:BF:CE:9E:E2:38
    Network ID: Tea2.4 & Network MAC: AE:CC:36:1D:9A:51
    Network ID: DIGI-9x4D & Network MAC: F0:A7:31:6F:2D:7A
    Network ID: DIGI-Wpk7 & Network MAC: 74:31:AF:15:E0:41
    Network ID: HomeA&A & Network MAC: 92:A2:F4:9E:B3:D8
    MAC: F4:CE:36:00:1C:F4
    [(b'', b'62:ED:00:CD:74:72\x00', 44, -47, 1, False), (b'TP-Link_7474', b'40:ED:00:CD:74:72\x00', 44, -47, 1, False), (b'', b'62:ED:00:CD:74:73\x00', 4, -47, 1, False), (b'TP-Link_7474', b'40:ED:00:CD:74:]
    >>>
    >>> wlan.connect("TP-Link_7474", "55920322", network.SECURITY_PSK, 4)
    [00:00:27.243,804] <err> os: ***** USAGE FAULT *****
    [00:00:27.249,450] <err> os:   Stack overflow (context area not valid)
    [00:00:27.256,713] <err> os: r0/a1:  0x20033528  r1/a2:  0x00000001  r2/a3:  0x00078000
    [00:00:27.265,472] <err> os: r3/a4:  0x00000000 r12/ip:  0x00008000 r14/lr:  0x0002446d
    [00:00:27.274,200] <err> os:  xpsr:  0x41000200
    [00:00:27.279,479] <err> os: s[ 0]:  0xaaaaaaaa  s[ 1]:  0xaaaaaaaa  s[ 2]:  0xaaaaaaaa  s[ 3]:  0xaaaaaaaa
    [00:00:27.289,978] <err> os: s[ 4]:  0xaaaaaaaa  s[ 5]:  0xaaaaaaaa  s[ 6]:  0xaaaaaaaa  s[ 7]:  0xaaaaaaaa
    [00:00:27.300,445] <err> os: s[ 8]:  0xaaaaaaaa  s[ 9]:  0xaaaaaaaa  s[10]:  0xaaaaaaaa  s[11]:  0xaaaaaaaa
    [00:00:27.310,943] <err> os: s[12]:  0x00000000  s[13]:  0x000730db  s[14]:  0x2000a060  s[15]:  0x2000a060
    [00:00:27.321,411] <err> os: fpscr:  0x000f4240
    [00:00:27.326,690] <err> os: Faulting instruction address (r15/pc): 0x0002879a
    [00:00:27.334,655] <err> os: >>> ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0
    [00:00:27.342,590] <err> os: Current thread: 0x20009e08 (mp_main)
    [00:00:27.349,426] <err> os: Halting system

  • Håkon! More progress was made!!! :D

    So, I disabled:

    # CONFIG_MBEDTLS_ENABLE_HEAP=y
    # CONFIG_MBEDTLS_HEAP_SIZE=16384

    since I had a suspicion that allowing MBEDTLS to have its own stack would somehow use up more RAM than by not letting it.

    This seems to have COMPLETELY unlocked MBEDTLS!

    Here's a log of it in action:

    >>>
    >>> s = None
    >>> s = socket.socket()
    Trying to initialize socket...
    Family: 1, socktype: 1, proto: 258
    Dead here...15
    [00:01:27.568,298] <dbg> net_sock_tls: tls_alloc: (mp_main): Allocated TLS context, 0x2000a190
    Dead here...17
    Checking stupid errno...1.1: 0
    [00:01:27.582,305] <dbg> net_sock: zsock_socket_internal: (mp_main): socket: ctx=0x2000b0e8, fd=16
    Dead here...18
    Dead here...19
    Returned value: 15
    Done initializing socket!
    >>>
    >>> print("Connecting to:", result[0][-1])
    Connecting to: ('142.251.39.78', 443)
    >>> s.connect(result[0][-1])
    Dead here...5. DNS message size: 44
    DNS message content (hex):9d ae 81 80 00 01 00 01 00 00 00 00 06 67 6f 6f 67 6c 65 03 63 6f 6d 00 00 01 00 01 c0 0c 00 01 00 01 00 00 00 48 00 04 8e fb 27 4e
    Dead here...6
    Dead here...7
    [00:01:27.715,545] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:1331: The SSL configuration is tls12 only.
    [00:01:27.735,412] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:4663: => handshake
    [00:01:27.745,727] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2354: => flush output
    [00:01:27.756,317] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2363: <= flush output
    [00:01:27.766,937] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:4582: client state: MBEDTLS_SSL_HELLO_REQUEST
    [00:01:27.779,571] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2354: => flush output
    [00:01:27.790,161] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2363: <= flush output
    [00:01:27.800,781] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:4582: client state: MBEDTLS_SSL_CLIENT_HELLO
    [00:01:27.813,354] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0921: => write client hello
    [00:01:27.825,134] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0487: dumping 'client hello, random bytes' (32 bytes)
    [00:01:27.838,775] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0487: 0000:  d6 ff 0c 29 d8 e1 2c 45 37 c2 62 83 05 1a b5 30  ...)..,E7.b....0
    [00:01:27.854,553] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0487: 0010:  db 44 82 22 9a 48 98 8c 48 89 c6 dc 2f a7 74 2c  .D.".H..H.../.t,
    [00:01:27.870,117] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0512: dumping 'session id' (0 bytes)
    [00:01:27.882,049] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c024, TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384
    [00:01:27.898,010] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c028, TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384
    [00:01:27.913,757] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c00a, TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA
    [00:01:27.929,412] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c014, TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA
    [00:01:27.944,915] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c023, TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256
    [00:01:27.960,845] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c027, TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256
    [00:01:27.976,623] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c009, TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA
    [00:01:27.992,279] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c013, TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA
    [00:01:28.007,812] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: 003d, TLS-RSA-WITH-AES-256-CBC-SHA256
    [00:01:28.023,040] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: 0035, TLS-RSA-WITH-AES-256-CBC-SHA
    [00:01:28.038,024] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c02a, TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384
    [00:01:28.053,680] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c00f, TLS-ECDH-RSA-WITH-AES-256-CBC-SHA
    [00:01:28.069,091] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c026, TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384
    [00:01:28.084,960] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c005, TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA
    [00:01:28.100,524] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: 003c, TLS-RSA-WITH-AES-128-CBC-SHA256
    [00:01:28.115,783] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: 002f, TLS-RSA-WITH-AES-128-CBC-SHA
    [00:01:28.130,737] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c029, TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256
    [00:01:28.146,423] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c00e, TLS-ECDH-RSA-WITH-AES-128-CBC-SHA
    [00:01:28.161,834] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c025, TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256
    [00:01:28.177,673] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0370: client hello, add ciphersuite: c004, TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA
    [00:01:28.193,267] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0388: adding EMPTY_RENEGOTIATION_INFO_SCSV
    [00:01:28.205,657] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0397: client hello, got zu cipher suites
    [00:01:28.217,895] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0041: client hello, adding server name extension:
    [00:01:28.231,018] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0231: client hello, adding supported_groups extension
    [00:01:28.244,415] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0250: got supported group(001d)
    [00:01:28.255,859] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0282: NamedGroup: x25519 ( 1d )
    [00:01:28.267,333] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0250: got supported group(0017)
    [00:01:28.278,778] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0282: NamedGroup: secp256r1 ( 17 )
    [00:01:28.290,527] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0302: dumping 'Supported groups extension' (6 bytes)
    [00:01:28.303,955] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0302: 0000:  00 04 00 1d 00 17                                ......
    [00:01:28.318,603] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9505: adding signature_algorithms extension
    [00:01:28.330,902] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9525: got signature scheme [603] ecdsa_secp521r1_sha512
    [00:01:28.344,177] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9534: sent signature scheme [603] ecdsa_secp521r1_sha512
    [00:01:28.357,543] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9525: got signature scheme [601] rsa_pkcs1_sha512
    [00:01:28.370,330] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9534: sent signature scheme [601] rsa_pkcs1_sha512
    [00:01:28.383,178] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9525: got signature scheme [503] ecdsa_secp384r1_sha384
    [00:01:28.396,484] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9534: sent signature scheme [503] ecdsa_secp384r1_sha384
    [00:01:28.409,851] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9525: got signature scheme [501] rsa_pkcs1_sha384
    [00:01:28.422,607] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9534: sent signature scheme [501] rsa_pkcs1_sha384
    [00:01:28.435,485] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9525: got signature scheme [403] ecdsa_secp256r1_sha256
    [00:01:28.448,760] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9534: sent signature scheme [403] ecdsa_secp256r1_sha256
    [00:01:28.462,127] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9525: got signature scheme [401] rsa_pkcs1_sha256
    [00:01:28.474,914] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:9534: sent signature scheme [401] rsa_pkcs1_sha256
    [00:01:28.487,731] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls12_client.c:0105: client hello, adding supported_point_formats extension
    [00:01:28.502,258] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls12_client.c:0150: client hello, adding ecjpake_kkpp extension
    [00:01:28.515,808] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls12_client.c:0165: generating new ecjpake parameters
    [00:01:28.624,450] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls12_client.c:0338: client hello, adding extended_master_secret extension
    [00:01:28.638,854] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls12_client.c:0372: client hello, adding session ticket extension
    [00:01:28.652,587] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0689: client hello, total extension length: zu
    [00:01:28.665,374] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: dumping 'client hello extensions' (385 bytes)
    [00:01:28.678,833] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0000:  01 81 00 00 00 05 00 03 00 00 00 00 0a 00 06 00  ................
    [00:01:28.694,641] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0010:  04 00 1d 00 17 00 0d 00 0e 00 0c 06 03 06 01 05  ................
    [00:01:28.710,479] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0020:  03 05 01 04 03 04 01 00 0b 00 02 01 00 01 00 01  ................
    [00:01:28.726,257] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0030:  4a 41 04 44 45 b2 d9 27 08 d6 36 21 e8 f1 2c 89  JA.DE..'..6!..,.
    [00:01:28.742,065] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0040:  0d bd 5d fe db 7b c0 9b a7 c8 b1 bd d8 a3 50 ec  ..]..{........P.
    [00:01:28.757,873] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0050:  06 14 0b d2 e0 b0 05 87 2f 3d 5d 26 2d 20 ba 45  ......../=]&- .E
    [00:01:28.773,681] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0060:  92 c3 59 26 a2 e5 52 42 f5 3b 7f dd 74 ae ed ce  ..Y&..RB.;..t...
    [00:01:28.789,489] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0070:  da 6c 71 41 04 00 15 b1 87 5e 56 af a4 b7 ee a8  .lqA.....^V.....
    [00:01:28.805,297] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0080:  78 4b c6 3f 86 60 7f 82 2b 04 91 48 11 47 cc ce  xK.?.`..+..H.G..
    [00:01:28.821,105] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0090:  65 8a ad 6b 95 f3 f3 b2 0a c9 0a 72 f8 de 8e 85  e..k.......r....
    [00:01:28.836,914] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 00a0:  6d e6 45 6e 47 e1 74 ab c2 fd 19 15 3c 70 15 9d  m.EnG.t.....<p..
    [00:01:28.852,691] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 00b0:  ba ba 66 51 bc 20 03 fc fe aa 97 1a bf 98 20 fe  ..fQ. ........ .
    [00:01:28.868,499] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 00c0:  5d c2 29 ff bb 71 15 a6 36 7c f9 f4 1a eb 90 67  ].)..q..6|.....g
    [00:01:28.884,307] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 00d0:  dc 2e 4f 9a 55 7d 41 04 1f 6c ad 32 3d 6f c2 f4  ..O.U}A..l.2=o..
    [00:01:28.900,115] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 00e0:  b3 95 c2 85 ce 38 e7 c1 9c 51 37 8a 25 b9 fc 82  .....8...Q7.%...
    [00:01:28.915,893] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 00f0:  b9 5f 88 f7 a7 8a 3d b7 1a 13 5c ec f3 c4 df 33  ._....=...\....3
    [00:01:28.931,701] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0100:  4a d8 d4 1a 62 23 8d f6 01 a3 e4 28 3f 2f 22 4b  J...b#.....(?/"K
    [00:01:28.947,509] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0110:  b1 56 28 09 31 ed bb bf 41 04 30 64 0e 22 dc a6  .V(.1...A.0d."..
    [00:01:28.963,317] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0120:  b1 ec 0f 5e 6f 04 cc 31 11 d7 17 69 6c 55 63 5c  ...^o..1...ilUc\
    [00:01:28.979,125] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0130:  c8 13 a5 38 a7 74 2f 37 84 4b b8 a7 b3 34 83 10  ...8.t/7.K...4..
    [00:01:28.994,934] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0140:  02 af 7e 70 c7 28 92 6b 33 6d 2f b2 f2 14 17 1b  ..~p.(.k3m/.....
    [00:01:29.010,742] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0150:  ef d8 c8 0d 93 83 01 17 87 5a 20 51 29 8a b8 4e  .........Z Q)..N
    [00:01:29.026,519] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0160:  7d 52 bf 92 ad 1e 82 f7 3a c2 e7 77 10 2d a6 e3  }R......:..w.-..
    [00:01:29.042,327] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0170:  f9 95 de f5 fa fa ca 67 49 32 5b 00 17 00 00 00  .......gI2[.....
    [00:01:29.057,983] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:0691: 0180:  23                                               #
    [00:01:29.073,425] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2784: => write handshake message
    [00:01:29.084,930] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2944: => write record
    [00:01:29.095,581] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3028: output record: msgtype = 22, version = [3:3], msglen = zu
    [00:01:29.109,588] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: dumping 'output record sent to network' (477 bytes)
    [00:01:29.125,213] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0000:  16 03 03 01 d8 01 00 01 d4 03 03 d6 ff 0c 29 d8  ..............).
    [00:01:29.142,700] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0010:  e1 2c 45 37 c2 62 83 05 1a b5 30 db 44 82 22 9a  .,E7.b....0.D.".
    [00:01:29.160,156] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0020:  48 98 8c 48 89 c6 dc 2f a7 74 2c 00 00 2a c0 24  H..H.../.t,..*.$
    [00:01:29.177,612] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0030:  c0 28 c0 0a c0 14 c0 23 c0 27 c0 09 c0 13 00 3d  .(.....#.'.....=
    [00:01:29.195,068] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0040:  00 35 c0 2a c0 0f c0 26 c0 05 00 3c 00 2f c0 29  .5.*...&...<./.)
    [00:01:29.212,554] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0050:  c0 0e c0 25 c0 04 00 ff 01 00 01 81 00 00 00 05  ...%............
    [00:01:29.230,041] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0060:  00 03 00 00 00 00 0a 00 06 00 04 00 1d 00 17 00  ................
    [00:01:29.247,497] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0070:  0d 00 0e 00 0c 06 03 06 01 05 03 05 01 04 03 04  ................
    [00:01:29.264,984] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0080:  01 00 0b 00 02 01 00 01 00 01 4a 41 04 44 45 b2  ..........JA.DE.
    [00:01:29.282,440] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0090:  d9 27 08 d6 36 21 e8 f1 2c 89 0d bd 5d fe db 7b  .'..6!..,...]..{
    [00:01:29.299,896] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 00a0:  c0 9b a7 c8 b1 bd d8 a3 50 ec 06 14 0b d2 e0 b0  ........P.......
    [00:01:29.317,382] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 00b0:  05 87 2f 3d 5d 26 2d 20 ba 45 92 c3 59 26 a2 e5  ../=]&- .E..Y&..
    [00:01:29.334,838] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 00c0:  52 42 f5 3b 7f dd 74 ae ed ce da 6c 71 41 04 00  RB.;..t....lqA..
    [00:01:29.352,294] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 00d0:  15 b1 87 5e 56 af a4 b7 ee a8 78 4b c6 3f 86 60  ...^V.....xK.?.`
    [00:01:29.369,750] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 00e0:  7f 82 2b 04 91 48 11 47 cc ce 65 8a ad 6b 95 f3  ..+..H.G..e..k..
    [00:01:29.387,207] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 00f0:  f3 b2 0a c9 0a 72 f8 de 8e 85 6d e6 45 6e 47 e1  .....r....m.EnG.
    [00:01:29.404,693] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0100:  74 ab c2 fd 19 15 3c 70 15 9d ba ba 66 51 bc 20  t.....<p....fQ.
    [00:01:29.422,149] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0110:  03 fc fe aa 97 1a bf 98 20 fe 5d c2 29 ff bb 71  ........ .].)..q
    [00:01:29.439,605] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0120:  15 a6 36 7c f9 f4 1a eb 90 67 dc 2e 4f 9a 55 7d  ..6|.....g..O.U}
    [00:01:29.457,061] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0130:  41 04 1f 6c ad 32 3d 6f c2 f4 b3 95 c2 85 ce 38  A..l.2=o.......8
    [00:01:29.474,548] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0140:  e7 c1 9c 51 37 8a 25 b9 fc 82 b9 5f 88 f7 a7 8a  ...Q7.%...._....
    [00:01:29.492,004] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0150:  3d b7 1a 13 5c ec f3 c4 df 33 4a d8 d4 1a 62 23  =...\....3J...b#
    [00:01:29.509,460] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0160:  8d f6 01 a3 e4 28 3f 2f 22 4b b1 56 28 09 31 ed  .....(?/"K.V(.1.
    [00:01:29.526,916] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0170:  bb bf 41 04 30 64 0e 22 dc a6 b1 ec 0f 5e 6f 04  ..A.0d.".....^o.
    [00:01:29.544,372] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0180:  cc 31 11 d7 17 69 6c 55 63 5c c8 13 a5 38 a7 74  .1...ilUc\...8.t
    [00:01:29.561,859] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 0190:  2f 37 84 4b b8 a7 b3 34 83 10 02 af 7e 70 c7 28  /7.K...4....~p.(
    [00:01:29.579,315] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 01a0:  92 6b 33 6d 2f b2 f2 14 17 1b ef d8 c8 0d 93 83  .k3m/...........
    [00:01:29.596,771] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 01b0:  01 17 87 5a 20 51 29 8a b8 4e 7d 52 bf 92 ad 1e  ...Z Q)..N}R....
    [00:01:29.614,227] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 01c0:  82 f7 3a c2 e7 77 10 2d a6 e3 f9 95 de f5 fa fa  ..:..w.-........
    [00:01:29.631,652] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3033: 01d0:  ca 67 49 32 5b 00 17 00 00 00 23 00 00           .gI2[.....#..
    [00:01:29.648,590] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3081: <= write record
    [00:01:29.659,179] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2905: <= write handshake message
    [00:01:29.670,715] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_client.c:1014: <= write client hello
    [00:01:29.682,067] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2354: => flush output
    [00:01:29.692,687] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2368: message length: zu, out_left: zu
    [00:01:29.705,444] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2375: ssl->f_send() returned 477 (-0xfffffe23)
    [00:01:29.718,170] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2402: <= flush output
    [00:01:29.728,790] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:4582: client state: MBEDTLS_SSL_SERVER_HELLO
    [00:01:29.741,333] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls12_client.c:1196: => parse server hello
    [00:01:29.753,234] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:4298: => read record
    [00:01:29.763,732] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2156: => fetch input
    [00:01:29.774,230] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2296: in_left: zu, nb_want: zu
    [00:01:29.785,644] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2316: in_left: zu, nb_want: zu
    [00:01:29.796,966] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:4674: <= handshake
    [00:01:29.995,971] <dbg> net_sock: zsock_received_cb: (rx_q[0]): ctx=0x2000b0e8, pkt=0x2005f0a0, st=0, user_data=(nil)
    [00:01:30.007,873] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:4663: => handshake
    [00:01:30.018,371] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2354: => flush output
    [00:01:30.028,991] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2363: <= flush output
    [00:01:30.042,114] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:4582: client state: MBEDTLS_SSL_SERVER_HELLO
    [00:01:30.054,779] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls12_client.c:1196: => parse server hello
    [00:01:30.066,650] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:4298: => read record
    [00:01:30.077,148] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2156: => fetch input
    [00:01:30.087,677] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2296: in_left: zu, nb_want: zu
    [00:01:30.099,090] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2316: in_left: zu, nb_want: zu
    [00:01:30.110,473] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2319: ssl->f_recv(_timeout)() returned 5 (-0xfffffffb)
    [00:01:30.123,901] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2341: <= fetch input
    [00:01:30.134,460] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3964: dumping 'input record header' (5 bytes)
    [00:01:30.148,925] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3964: 0000:  15 03 01 00 02                                   .....
    [00:01:30.165,191] <inf> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:3966: input record: msgtype = 21, version = [0x301], msglen = zu
    [00:01:30.179,229] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2156: => fetch input
    [00:01:30.189,758] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2296: in_left: zu, nb_want: zu
    [00:01:30.201,202] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2316: in_left: zu, nb_want: zu
    [00:01:30.212,585] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2319: ssl->f_recv(_timeout)() returned 2 (-0xfffffffe)
    [00:01:30.226,013] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:2341: <= fetch input
    [00:01:30.236,541] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:4073: dumping 'input record from network' (7 bytes)
    [00:01:30.251,556] <dbg> mbedtls: zephyr_mbedtls_debug: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:4073: 0000:  15 03 01 00 02 02 70                             ......p
    [00:01:30.268,005] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:5218: got an alert message, type: [2:112]
    [00:01:30.280,303] <err> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:5225: is a fatal alert message (msg 112)
    [00:01:30.292,602] <err> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_msg.c:4353: mbedtls_ssl_handle_message_type() returned -30592 (-0x7780)
    [00:01:30.307,037] <err> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls12_client.c:1200: mbedtls_ssl_read_record() returned -30592 (-0x7780)
    [00:01:30.321,533] <wrn> mbedtls: WEST_TOPDIR/modules/crypto/mbedtls/library/ssl_tls.c:4674: <= handshake
    [00:01:30.332,153] <err> net_sock_tls: TLS handshake error: -0x7780

    Will continue to investigate the new error:
    "TLS handshake error: -0x7780"

    Edit: Also, a quick question: Currently I'm using "IPPROTO_TLS_1_2", but I saw that "IPPROTO_TLS_1_3" also exists. Is the 1.3 version smaller/ more optimised (less RAM and ROM)?

  • Current hypothesis is that the error comes from "MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME". This might come from the order I'm trying to do the request.

    My order: connect to WiFi network -> getaddrinfo() -> setup socket -> socket connect -> PEER_VERIFY, TAG_LIST, HOSTNAME socket options being set -> send socket request

    What I saw in the https_client sample: connect to WiFi network -> getaddrinfo() -> setup socket -> PEER_VERIFY, TAG_LIST, HOSTNAME socket options being set -> socket connect -> send socket request

    I assume the https_client sample's order is the right one, so trying to do it that way now. Sadly, that brings a new error when trying to socket connect:

    >>> print("Connecting to:", result[0][-1])
    Connecting to: ('142.251.39.14', 443)
    >>> s.connect(result[0][-1])
    DNS message size: 44
    DNS message content (hex):50 4e 81 80 00 01 00 01 00 00 00 00 06 67 6f 6f 67 6c 65 03 63 6f 6d 00 00 01 00 01 c0 0c 00 01 00 01 00 00 00 c0 00 04 8e fb 27 0e
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OSError: [Errno 2] ENOENT

    Adding even more debugging code, I reached the function "tls_mbedtls_set_credentials()" inside sockets_tls.c. In there, there's a loop:

    while ((cred = credential_next_get(tag, cred)) != NULL) {

    which doesn't even enter, so it goes to the next section where it throws the above error:

    if (!tag_found) {
        err = -ENOENT;
        goto exit;
    }

  • Hi,

     

    Tudor B. said:

    since I had a suspicion that allowing MBEDTLS to have its own stack would somehow use up more RAM than by not letting it.

    This seems to have COMPLETELY unlocked MBEDTLS!

    Disabling the dedicated mbedtls .heap can cause issues, as this will then fallback to using the system heap (CONFIG_HEAP_MEM_POOL_SIZE).

    If you do not use alot of heap, then you're fine, but this will require added runtime test and verification to ensure no heap overflow.

     

    Tudor B. said:

    Current hypothesis is that the error comes from "MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME". This might come from the order I'm trying to do the request.

    My order: connect to WiFi network -> getaddrinfo() -> setup socket -> socket connect -> PEER_VERIFY, TAG_LIST, HOSTNAME socket options being set -> send socket request

    What I saw in the https_client sample: connect to WiFi network -> getaddrinfo() -> setup socket -> PEER_VERIFY, TAG_LIST, HOSTNAME socket options being set -> socket connect -> send socket request

    So, we know that a https_client sample is able to respond to the SERVER_HELLO with a CLIENT_HELLO (which is the one that we're missing here).

    There can be several reasons for this, but the server tells us a fatal error with 112, which is a strange response, but might point to missing mbedtls features, if you read into this stack overflow thread:

    https://stackoverflow.com/questions/74678330/ssl-tls-handshake-failed-unrecognized-name

     

    Q1: Do you have SNI enabled in mbedtls?

    CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION

     

    Q2: Could you share your full .config file? I want to see which mbedtls features are enabled, and which are not.

     

    Q3: Recreating this locally at my end will require micropy. Can you share which version of micropy (and zephyr) that you use and a brief of the socket commands that you use, so I can try this on my end?

     

    Kind regards,

    Håkon

  • Hello Hakon.

    A1: "CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION" explicitly enabled in the board.conf.

    A2:

    6036.nrf7002dk_nrf5340_cpuapp_ns.conf

    4174.prj.conf

    A3:

    The Zephyr when I do a --pristine build:

    -- Zephyr version: 4.0.99 (/opt/nordic/ncs/v3.0.0/zephyr)

    Or maybe it's best to give you the one that shows up when connecting over serial?:
    *** Booting nRF Connect SDK v3.0.0-3bfc46578e42 ***
    *** Using Zephyr OS v4.0.99-a0e545cb437a ***

    As for the micropython: MicroPython 9ea566c69-dirty on 2025-05-28; zephyr-nrf7002dk with nrf5340

    Socket commands depend a lot on the current implementation. We took over another implementation and started adapting it to get it to work. This is the modsocket.c file:

    /*
     * This file is part of the MicroPython project, http://micropython.org/
     *
     * The MIT License (MIT)
     *
     * Copyright (c) 2023 Mariano Goluboff
     * Copyright (c) 2017 Linaro Limited
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
    
     #include "py/mpconfig.h"
     #if (CONFIG_NET_SOCKETS && !CONFIG_EXCLUDE_PY_SOCKETS)
     
     #include "py/runtime.h"
     #include "py/stream.h"
     #include "mpthreadport.c"
     
     #include <stdio.h>
     #include <errno.h>
     #include <zephyr/kernel.h>
     // Zephyr's generated version header
     #include <version.h>
     #include <zephyr/net/net_pkt.h>
     #include <zephyr/net/dns_resolve.h>
     #include <zephyr/net/socket.h>
     #include <zephyr/posix/fcntl.h>
    
     #include <zephyr/net/tls_credentials.h>
     #if (CONFIG_NET_SOCKETS_SOCKOPT_TLS || CONFIG_NET_SOCKETS_OFFLOAD)
     #endif
     
     #define DEBUG_PRINT 1
     #if DEBUG_PRINT // print debugging info
     #define DEBUG_printf printf
     #else // don't print debugging info
     #define DEBUG_printf(...) (void)0
     #endif
    
    #include <string.h>
    #include <zephyr/kernel.h>
    #include <stdlib.h>
    #include <zephyr/net/socket.h>
    #include <zephyr/net/conn_mgr_monitor.h>
    #include <zephyr/net/conn_mgr_connectivity.h>
    #include <zephyr/net/tls_credentials.h>
    
    #if defined(CONFIG_POSIX_API)
    #include <zephyr/posix/arpa/inet.h>
    #include <zephyr/posix/netdb.h>
    #include <zephyr/posix/unistd.h>
    #include <zephyr/posix/sys/socket.h>
    #endif
    
    
    
    
    
    // Potentiallt necessary...?
    // #include "psa/storage_common.h"
    // #include "psa/protected_storage.h"
    
     #define GOOGLE_CA_SEC_TAG 16842753  // any unused sec_tag you pick
    
    /* Binary DER-encoded certificate data */
    #include "cert/r1.crt.inc"
    #define MBEDTLS_SSL_TLS_C 1
     typedef struct _socket_obj_t {
         mp_obj_base_t base;
         int ctx;
     
         #define STATE_NEW 0
         #define STATE_CONNECTING 1
         #define STATE_CONNECTED 2
         #define STATE_PEER_CLOSED 3
         int8_t state;
         sa_family_t family;
     } socket_obj_t;
     
    //  static struct dns_resolve_context my_ctx;
     STATIC const mp_obj_type_t socket_type;
     
     // Helper functions
     
     #define RAISE_ERRNO(x) { int _err = x; if (_err < 0) mp_raise_OSError(-_err); }
     #define RAISE_SOCK_ERRNO(x) { if ((int)(x) == -1) mp_raise_OSError(errno); }
     
     STATIC void socket_check_closed(socket_obj_t *socket) {
         if (socket->ctx == -1) {
             // already closed
             mp_raise_OSError(EBADF);
         }
     }
     
     STATIC void parse_inet_addr(socket_obj_t *socket, mp_obj_t addr_in, struct sockaddr *sockaddr) {
         // We employ the fact that port and address offsets are the same for IPv4 & IPv6
         struct sockaddr_in *sockaddr_in = (struct sockaddr_in *)sockaddr;
     
         mp_obj_t *addr_items;
     
         sockaddr_in->sin_family = socket->family;
         size_t address_array_size = (sockaddr_in->sin_family == AF_INET6) ? 4 : 2;
         mp_obj_get_array_fixed_n(addr_in, address_array_size, &addr_items);
         RAISE_ERRNO(net_addr_pton(sockaddr_in->sin_family, mp_obj_str_get_str(addr_items[0]), &sockaddr_in->sin_addr));
         sockaddr_in->sin_port = htons(mp_obj_get_int(addr_items[1]));
     }
     
     STATIC mp_obj_t format_inet_addr(struct sockaddr *addr, mp_obj_t port) {
         // We employ the fact that port and address offsets are the same for IPv4 & IPv6
         struct sockaddr_in6 *sockaddr_in6 = (struct sockaddr_in6 *)addr;
         char buf[40];
         net_addr_ntop(addr->sa_family, &sockaddr_in6->sin6_addr, buf, sizeof(buf));
         mp_obj_tuple_t *tuple = mp_obj_new_tuple(addr->sa_family == AF_INET ? 2 : 4, NULL);
     
         tuple->items[0] = mp_obj_new_str(buf, strlen(buf));
         // We employ the fact that port offset is the same for IPv4 & IPv6
         // not filled in
         // tuple->items[1] = mp_obj_new_int(ntohs(((struct sockaddr_in*)addr)->sin_port));
         tuple->items[1] = port;
     
         if (addr->sa_family == AF_INET6) {
             tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); // flow_info
             tuple->items[3] = MP_OBJ_NEW_SMALL_INT(sockaddr_in6->sin6_scope_id);
         }
     
         return MP_OBJ_FROM_PTR(tuple);
     }
     
     socket_obj_t *socket_new(void) {
         socket_obj_t *socket = m_new_obj(socket_obj_t);
         socket->base.type = (mp_obj_t)&socket_type;
         socket->state = STATE_NEW;
         return socket;
     }
     
     // Methods
     
     STATIC void socket_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
         socket_obj_t *self = self_in;
         if (self->ctx == -1) {
             mp_printf(print, "<socket NULL>");
         } else {
             mp_printf(print, "<socket %p family=%d>", self->ctx, self->family);
         }
     }
     #include <time.h>
     #include <date_time.h>
     #include <stdio.h> // For printk
    
    void set_nordic_date_time(void) {
        struct tm dt;
        int ret;
    
        // Set the desired date and time
        // Example: May 21, 2024, 10:30:00 UTC
        dt.tm_year = 125;
        dt.tm_mon = 5;
        dt.tm_mday = 21;
        dt.tm_hour = 11; // Use UTC hours
        dt.tm_min = 25;
        dt.tm_sec = 0;
        dt.tm_wday = 2; // 0=Sunday, 1=Monday, ..., 6=Saturday (Tuesday)
        // dt.tz = 0; // Timezone offset in minutes from UTC (0 for UTC)
    
        printk("Attempting to set date and time (YYYY-MM-DD HH:MM:SS) to %04d-%02d-%02d %02d:%02d:%02d...\n",
               dt.tm_year, dt.tm_mon, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);
    
        // Initialize the date_time library if not already done
        // Depending on your application's init, this might be needed.
        // Check date_time_init() API if required. For simplicity, we assume
        // it might be handled elsewhere or implicitly.
    
        ret = date_time_set(&dt);
    
        if (ret == 0) {
            printk("Date and time set successfully using date_time_set.\n");
        } else {
            printk("Failed to set date and time using date_time_set, error: %d\n", ret);
        }
    }
    #include <mbedtls/debug.h>
     STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
         mp_arg_check_num(n_args, n_kw, 0, 4, false);
     
        //  set_nordic_date_time();
         mbedtls_debug_set_threshold(4); 
         socket_obj_t *socket = socket_new();
     
         int family = AF_INET;
         int socktype = SOCK_STREAM;
         int proto = -1;
     
         if (n_args >= 1) {
             family = mp_obj_get_int(args[0]);
             if (n_args >= 2) {
                 socktype = mp_obj_get_int(args[1]);
                 if (n_args >= 3) {
                     proto = mp_obj_get_int(args[2]);
                 }
             }
         }
     
         if (proto == -1) {
             proto = IPPROTO_TLS_1_2;
             if (socktype != SOCK_STREAM) {
                 proto = IPPROTO_UDP;
             }
         }
         
        gc_collect();
    
         int res = tls_credential_add(GOOGLE_CA_SEC_TAG, TLS_CREDENTIAL_CA_CERTIFICATE, r1_crt, r1_crt_len);
         RAISE_SOCK_ERRNO(res);
         printk("Trying to initialize socket...\n");
         printk("Family: %d, socktype: %d, proto: %d \n", family, socktype, proto);
         socket->ctx = zsock_socket(family, socktype, proto);
         printk("Returned value: %d \n", socket->ctx);
         RAISE_SOCK_ERRNO(socket->ctx);
         printk("Done initializing socket! \n");
         socket->family = family;
         return MP_OBJ_FROM_PTR(socket);
     }  
     
    //  #if CONFIG_NET_SOCKETS_OFFLOAD
     STATIC mp_obj_t socket_tlswrap(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kwargs) {
         enum { ARG_sec_tag, ARG_verify, ARG_hostname };
         
         static const mp_arg_t allowed_args[] = {
             { MP_QSTR_sec_tag, MP_ARG_REQUIRED | MP_ARG_INT },
             { MP_QSTR_verify, MP_ARG_INT, {.u_int = TLS_PEER_VERIFY_REQUIRED} },
             { MP_QSTR_hostname, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
         };
     
         // parse args
         mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
         mp_arg_parse_all(n_args - 1, pos_args + 1, kwargs, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
    
         socket_obj_t *socket = pos_args[0];
         sec_tag_t sec_tag = args[ARG_sec_tag].u_int;
         int res;
         printk("Trying 1...\n");
         int verify = args[ARG_verify].u_int;
         res = setsockopt(socket->ctx, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));
        //  printk("Failed to setup TLS sec tag, err %d\n", errno);
         RAISE_SOCK_ERRNO(res);
         printk("1 is done\n");
         res = setsockopt(socket->ctx, SOL_TLS, TLS_SEC_TAG_LIST, &sec_tag, sizeof(sec_tag));
         RAISE_SOCK_ERRNO(res);
         printk("2 is done\n");
         if (args[ARG_hostname].u_obj != mp_const_none) {
             const char *hostname = mp_obj_str_get_str(args[ARG_hostname].u_obj);
             setsockopt(socket->ctx, SOL_TLS, TLS_HOSTNAME, hostname, strlen(hostname));
             RAISE_SOCK_ERRNO(res);
             printk("3 is done\n");
         }
         return mp_const_none;
     }
     MP_DEFINE_CONST_FUN_OBJ_KW(socket_tlswrap_obj, 1, socket_tlswrap);
    //  #endif
    
     STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
         socket_obj_t *socket = self_in;
         socket_check_closed(socket);
     
         struct sockaddr sockaddr;
         parse_inet_addr(socket, addr_in, &sockaddr);
     
         int res = zsock_bind(socket->ctx, &sockaddr, sizeof(sockaddr));
         RAISE_SOCK_ERRNO(res);
     
         return mp_const_none;
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind);
     
     STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
         socket_obj_t *socket = self_in;
         socket_check_closed(socket);
     
         struct sockaddr sockaddr;
         parse_inet_addr(socket, addr_in, &sockaddr);
     
         int res = zsock_connect(socket->ctx, &sockaddr, sizeof(sockaddr));
         RAISE_SOCK_ERRNO(res);
     
         return mp_const_none;
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
     
     // method socket.listen([backlog])
     STATIC mp_obj_t socket_listen(size_t n_args, const mp_obj_t *args) {
         socket_obj_t *socket = args[0];
         socket_check_closed(socket);
     
         mp_int_t backlog = MICROPY_PY_SOCKET_LISTEN_BACKLOG_DEFAULT;
         if (n_args > 1) {
             backlog = mp_obj_get_int(args[1]);
             backlog = (backlog < 0) ? 0 : backlog;
         }
     
         int res = zsock_listen(socket->ctx, backlog);
         RAISE_SOCK_ERRNO(res);
     
         return mp_const_none;
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_listen_obj, 1, 2, socket_listen);
     
     STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
         socket_obj_t *socket = self_in;
         socket_check_closed(socket);
     
         struct sockaddr sockaddr;
         socklen_t addrlen = sizeof(sockaddr);
         int ctx = zsock_accept(socket->ctx, &sockaddr, &addrlen);
     
         socket_obj_t *socket2 = socket_new();
         socket2->ctx = ctx;
     
         mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
         client->items[0] = MP_OBJ_FROM_PTR(socket2);
         // TODO
         client->items[1] = mp_const_none;
     
         return MP_OBJ_FROM_PTR(client);
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
     
     STATIC mp_uint_t sock_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
         socket_obj_t *socket = self_in;
         if (socket->ctx == -1) {
             // already closed
             *errcode = EBADF;
             return MP_STREAM_ERROR;
         }
     
         ssize_t len = zsock_send(socket->ctx, buf, size, 0);
         if (len == -1) {
             *errcode = errno;
             return MP_STREAM_ERROR;
         }
     
         return len;
     }
     
     STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
         mp_buffer_info_t bufinfo;
         mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
         int err = 0;
         mp_uint_t len = sock_write(self_in, bufinfo.buf, bufinfo.len, &err);
         if (len == MP_STREAM_ERROR) {
             mp_raise_OSError(err);
         }
         return mp_obj_new_int_from_uint(len);
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send);
     
     STATIC mp_uint_t sock_read(mp_obj_t self_in, void *buf, mp_uint_t max_len, int *errcode) {
         socket_obj_t *socket = self_in;
         if (socket->ctx == -1) {
             // already closed
             *errcode = EBADF;
             return MP_STREAM_ERROR;
         }
     
         ssize_t recv_len = zsock_recv(socket->ctx, buf, max_len, 0);
         if (recv_len == -1) {
             *errcode = errno;
             return MP_STREAM_ERROR;
         }
     
         return recv_len;
     }
     
     STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
         mp_int_t max_len = mp_obj_get_int(len_in);
         vstr_t vstr;
         // +1 to accommodate for trailing \0
         vstr_init_len(&vstr, max_len + 1);
     
         int err;
         mp_uint_t len = sock_read(self_in, vstr.buf, max_len, &err);
     
         if (len == MP_STREAM_ERROR) {
             vstr_clear(&vstr);
             mp_raise_OSError(err);
         }
     
         if (len == 0) {
             vstr_clear(&vstr);
             return mp_const_empty_bytes;
         }
     
         vstr.len = len;
         return mp_obj_new_bytes_from_vstr(&vstr);
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv);
     
     STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) {
         (void)n_args; // always 4
         mp_warning(MP_WARN_CAT(RuntimeWarning), "setsockopt() not implemented");
         return mp_const_none;
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt);
    
     // method socket.settimeout(value)
    // timeout=0 means non-blocking
    // timeout=None means blocking
    // otherwise, timeout is in seconds
    // static mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
    //     mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
    //     mp_uint_t timeout;
    //     if (timeout_in == mp_const_none) {
    //         timeout = -1;
    //     } else {
    //         #if MICROPY_PY_BUILTINS_FLOAT
    //         timeout = (mp_uint_t)(MICROPY_FLOAT_CONST(1000.0) * mp_obj_get_float(timeout_in));
    //         #else
    //         timeout = 1000 * mp_obj_get_int(timeout_in);
    //         #endif
    //     }
    //     if (self->nic == MP_OBJ_NULL) {
    //         #if MICROPY_PY_SOCKET_EXTENDED_STATE
    //         // store the timeout in the socket state until a NIC is bound
    //         self->timeout = timeout;
    //         #else
    //         // not connected
    //         mp_raise_OSError(MP_ENOTCONN);
    //         #endif
    //     } else {
    //         int _errno;
    //         if (self->nic_protocol->settimeout(self, timeout, &_errno) != 0) {
    //             mp_raise_OSError(_errno);
    //         }
    //     }
    //     return mp_const_none;
    // }
    // static MP_DEFINE_CONST_FUN_OBJ_2(socket_settimeout_obj, socket_settimeout);
     
     STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) {
         socket_obj_t *socket = self_in;
         int ret = zsock_fcntl(socket->ctx, F_GETFL, 0);
         if (ret == -1) {
             mp_raise_OSError(-errno);
         }
         if (mp_obj_is_true(blocking)) {
             ret = zsock_fcntl(socket->ctx, F_SETFL, ret & ~(O_NONBLOCK));
         } else {
             ret = zsock_fcntl(socket->ctx, F_SETFL, ret | O_NONBLOCK);
         }
         if (ret == -1) {
             mp_raise_OSError(-errno);
         }
         return mp_const_none;
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
     
     STATIC mp_obj_t socket_makefile(size_t n_args, const mp_obj_t *args) {
         (void)n_args;
         return args[0];
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_makefile_obj, 1, 3, socket_makefile);
     
     STATIC mp_uint_t sock_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) {
         socket_obj_t *socket = o_in;
         (void)arg;
         switch (request) {
             case MP_STREAM_CLOSE:
                 if (socket->ctx != -1) {
                     int res = zsock_close(socket->ctx);
                     RAISE_SOCK_ERRNO(res);
                     if (res == -1) {
                         *errcode = errno;
                         return MP_STREAM_ERROR;
                     }
                     socket->ctx = -1;
                 }
                 return 0;
     
             default:
                 *errcode = MP_EINVAL;
                 return MP_STREAM_ERROR;
         }
     }
     
     #if CONFIG_PDN
     STATIC mp_obj_t socket_pdn(mp_obj_t self_in, mp_obj_t id) {
         if (!mp_obj_is_int(id)) {
             mp_raise_TypeError(MP_ERROR_TEXT("ID must be an integer"));
         }
         socket_obj_t *socket = self_in;
         int pdn_id = mp_obj_get_int(id);
         int ret = setsockopt(socket->ctx, SOL_SOCKET, SO_BINDTOPDN, &pdn_id, sizeof(pdn_id));
         if (ret) {
             mp_raise_OSError(ret);
         }
         return mp_const_none;
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_pdn_obj, socket_pdn);
     #endif
     
     STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = {
         { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_stream_close_obj) },
         { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) },
         { MP_ROM_QSTR(MP_QSTR_bind), MP_ROM_PTR(&socket_bind_obj) },
         { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&socket_connect_obj) },
         { MP_ROM_QSTR(MP_QSTR_listen), MP_ROM_PTR(&socket_listen_obj) },
         { MP_ROM_QSTR(MP_QSTR_accept), MP_ROM_PTR(&socket_accept_obj) },
         { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&socket_send_obj) },
         { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&socket_recv_obj) },
         { MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) },
        //  { MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) },
         { MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
     
         { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
         { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
         { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
         { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
         { MP_ROM_QSTR(MP_QSTR_makefile), MP_ROM_PTR(&socket_makefile_obj) },
        //  #if CONFIG_NET_SOCKETS_OFFLOAD
         { MP_ROM_QSTR(MP_QSTR_tlswrap), MP_ROM_PTR(&socket_tlswrap_obj) },
         #if CONFIG_PDN
         { MP_ROM_QSTR(MP_QSTR_pdn), MP_ROM_PTR(&socket_pdn_obj) },
         #endif
        //  #endif
     };
     STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
     
     STATIC const mp_stream_p_t socket_stream_p = {
         .read = sock_read,
         .write = sock_write,
         .ioctl = sock_ioctl,
     };
     
     STATIC MP_DEFINE_CONST_OBJ_TYPE(
         socket_type,
         MP_QSTR_socket,
         MP_TYPE_FLAG_NONE,
         make_new, socket_make_new,
         print, socket_print,
         protocol, &socket_stream_p,
         locals_dict, &socket_locals_dict
         );
     
     //
     // getaddrinfo() implementation
     //
     
     typedef struct _getaddrinfo_state_t {
         mp_obj_t result;
         struct k_sem sem;
         mp_obj_t port;
         int status;
         mp_thread_t *calling_thread_state;
     } getaddrinfo_state_t;
     
     void dns_resolve_cb(enum dns_resolve_status status, struct dns_addrinfo *info, void *user_data) {
        if (!user_data) {
            printk("DNS CALLBACK: user_data is NULL!\n");
            return;
        }
    
        getaddrinfo_state_t *state = user_data;
    
        // Set the MicroPython thread state for this callback
        mp_thread_set_state(state->calling_thread_state);
    
        printk("DNS CALLBACK: status=%d\n", status);
    
        // Process valid info
        if (info != NULL && info->ai_addr.sa_family != 0) {
            // Safety: make sure address is valid
            if (info->ai_addr.sa_family != AF_INET && info->ai_addr.sa_family != AF_INET6) {
                printk("DNS CALLBACK: invalid sa_family=%d\n", info->ai_addr.sa_family);
                // We could set an error here, but for now, just ignore this invalid entry.
                // state->status = -EINVAL; // Consider setting this if needed
                return;
            }
    
            mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
            tuple->items[0] = MP_OBJ_NEW_SMALL_INT(info->ai_family);
            tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCK_STREAM);
            tuple->items[2] = MP_OBJ_NEW_SMALL_INT(IPPROTO_TCP);
            tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
            tuple->items[4] = format_inet_addr(&info->ai_addr, state->port);
    
            mp_obj_list_append(state->result, MP_OBJ_FROM_PTR(tuple));
            // Do NOT give semaphore here, wait for final info == NULL call
            return;
        }
    
        // If info is NULL, it signals the end of results for this query type or an error
        if (info == NULL) {
             if (status != DNS_EAI_ALLDONE && state->status == 0) {
                // If it's an error status and we haven't recorded one yet
                state->status = status;
                printk("Setting final error status: %d\n", status);
            } else if (status == DNS_EAI_ALLDONE && state->status == 0 && mp_obj_len(state->result) == 0) {
                 // Handle the case where ALLDONE is received but no addresses were found, and no error was set yet.
                 // This might indicate a resolution failure even if status was 0 initially.
                 state->status = -ENOENT; // Or another appropriate error code for no address found
                 printk("Setting status to ENOENT: %d\n", state->status);
            }
    
            // Always give the semaphore when info is NULL to signal completion for this query type
            printk("Giving semaphore on info == NULL\n");
            k_sem_give(&state->sem);
        }
     }
     
     STATIC mp_obj_t mod_getaddrinfo(size_t n_args, const mp_obj_t *args) {
        mp_obj_t host_in = args[0], port_in = args[1];
        const char *host = mp_obj_str_get_str(host_in);
        mp_int_t family = AF_INET;
        if (n_args > 2) {
            family = mp_obj_get_int(args[2]);
        }
    
        printk("Using system DNS resolver...\n");
        
        getaddrinfo_state_t state;
        state.port = port_in;
        state.result = mp_obj_new_list(0, NULL);
        state.calling_thread_state = mp_thread_get_state();
        k_sem_init(&state.sem, 0, UINT_MAX);
    
        for (int i = 2; i--;) {
            int type = (family != AF_INET6 ? DNS_QUERY_TYPE_A : DNS_QUERY_TYPE_AAAA);
            printk("Querying DNS for %s (type %d)...\n", host, type);
            RAISE_ERRNO(dns_get_addr_info(host, type, NULL, dns_resolve_cb, &state, 5000));
            
            printk("semaphore wait...1\n");
            if (k_sem_take(&state.sem, K_SECONDS(10)) != 0) {
                printk("semaphore wait...2\n");
                mp_raise_OSError(ETIMEDOUT);
            }
    
            if (family != 0) {
                break;
            }
            family = AF_INET6;
        }
    
        printk("something...1\n");
        mp_int_t len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(state.result));
        if (state.status != 0 && len == 0) {
            mp_raise_OSError(state.status);
        }
    
        return state.result;
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_getaddrinfo_obj, 2, 3, mod_getaddrinfo);
     
     #if !CONFIG_NET_SOCKETS_OFFLOAD
     STATIC mp_obj_t pkt_get_info(void) {
         struct k_mem_slab *rx, *tx;
         struct net_buf_pool *rx_data, *tx_data;
         net_pkt_get_info(&rx, &tx, &rx_data, &tx_data);
         mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(4, NULL));
         t->items[0] = MP_OBJ_NEW_SMALL_INT(k_mem_slab_num_free_get(rx));
         t->items[1] = MP_OBJ_NEW_SMALL_INT(k_mem_slab_num_free_get(tx));
         t->items[2] = MP_OBJ_NEW_SMALL_INT(rx_data->avail_count);
         t->items[3] = MP_OBJ_NEW_SMALL_INT(tx_data->avail_count);
         return MP_OBJ_FROM_PTR(t);
     }
     STATIC MP_DEFINE_CONST_FUN_OBJ_0(pkt_get_info_obj, pkt_get_info);
     #endif
     
     STATIC const mp_rom_map_elem_t mp_module_socket_globals_table[] = {
         { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_socket) },
         // objects
         { MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&socket_type) },
         // class constants
         { MP_ROM_QSTR(MP_QSTR_AF_INET), MP_ROM_INT(AF_INET) },
         { MP_ROM_QSTR(MP_QSTR_AF_INET6), MP_ROM_INT(AF_INET6) },
         { MP_ROM_QSTR(MP_QSTR_AF_PACKET), MP_ROM_INT(AF_PACKET) },
     
         { MP_ROM_QSTR(MP_QSTR_SOCK_STREAM), MP_ROM_INT(SOCK_STREAM) },
         { MP_ROM_QSTR(MP_QSTR_SOCK_DGRAM), MP_ROM_INT(SOCK_DGRAM) },
         { MP_ROM_QSTR(MP_QSTR_SOCK_RAW), MP_ROM_INT(SOCK_RAW) },
         #if CONFIG_NET_SOCKETS_OFFLOAD
         { MP_ROM_QSTR(MP_QSTR_IPPROTO_TLS_1_2), MP_ROM_INT(IPPROTO_TLS_1_2) },
         { MP_ROM_QSTR(MP_QSTR_TLS_PEER_VERIFY_NONE), MP_ROM_INT(TLS_PEER_VERIFY_NONE) },
         { MP_ROM_QSTR(MP_QSTR_TLS_PEER_VERIFY_OPTIONAL), MP_ROM_INT(TLS_PEER_VERIFY_OPTIONAL) },
         { MP_ROM_QSTR(MP_QSTR_TLS_PEER_VERIFY_REQUIRED), MP_ROM_INT(TLS_PEER_VERIFY_REQUIRED) },
         #endif
     
         { MP_ROM_QSTR(MP_QSTR_SOL_SOCKET), MP_ROM_INT(1) },
         { MP_ROM_QSTR(MP_QSTR_SO_REUSEADDR), MP_ROM_INT(2) },
     
         { MP_ROM_QSTR(MP_QSTR_getaddrinfo), MP_ROM_PTR(&mod_getaddrinfo_obj) },
         #if !CONFIG_NET_SOCKETS_OFFLOAD
         { MP_ROM_QSTR(MP_QSTR_pkt_get_info), MP_ROM_PTR(&pkt_get_info_obj) },
         #endif
     };
     
     STATIC MP_DEFINE_CONST_DICT(mp_module_socket_globals, mp_module_socket_globals_table);
     
     const mp_obj_module_t mp_module_socket = {
         .base = { &mp_type_module },
         .globals = (mp_obj_dict_t *)&mp_module_socket_globals,
     };
     
     MP_REGISTER_EXTENSIBLE_MODULE(MP_QSTR_socket, mp_module_socket);
     
     #endif // (CONFIG_NET_SOCKETS && !CONFIG_EXCLUDE_PY_SOCKETS)

    And the "Wifi file" (as I like to call it):

    /*
     * This file is part of the MicroPython project, http://micropython.org/
     *
     * Development of the code in this file was sponsored by Microbric Pty Ltd
     * and Mnemote Pty Ltd
     *
     * The MIT License (MIT)
     *
     * Copyright (c) 2016, 2017 Nick Moore @mnemote
     * Copyright (c) 2017 "Eric Poulsen" <[email protected]>
     *
     * Based on esp8266/modnetwork.c which is Copyright (c) 2015 Paul Sokolovsky
     * And the ESP IDF example code which is Public Domain / CC0
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
    
     #include <string.h>
    
     #include "py/objlist.h"
     #include "py/runtime.h"
     #include "py/mphal.h"
     #include "extmod/modnetwork.h"
     #include "modnetwork.h"
     
     
     #if MICROPY_PY_NETWORK_WLAN
     
     #include <zephyr/logging/log.h>
     LOG_MODULE_REGISTER(wifimod, 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/wifi_utils.h>
     #include <net/wifi_ready.h>
     #include <zephyr/net/dhcpv4_server.h>
     #include <zephyr/net/net_event.h>
     #include <zephyr/net/ethernet.h>
     #include <zephyr/net/ethernet_mgmt.h>
     
     #include <zephyr/drivers/gpio.h>
     
     #include "net_private.h"
     
     #define WIFI_SHELL_MODULE "wifi"
     
     #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY
     #define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_RAW_SCAN_RESULT |                \
    				 NET_EVENT_WIFI_SCAN_DONE)
     #else
     #define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_SCAN_RESULT |		\
    				 NET_EVENT_WIFI_SCAN_DONE |		\
    				 NET_EVENT_WIFI_RAW_SCAN_RESULT)
     #endif
     #define SCAN_TIMEOUT_MS 10000
     #define WIFI_MAC_MAX_LEN 17
     
     #define STATUS_POLLING_MS   300
    
    // WiFi security type definitions for MicroPython
    #define MP_WIFI_SECURITY_NONE (0)
    #define MP_WIFI_SECURITY_PSK (1)
    #define MP_WIFI_SECURITY_PSK_SHA256 (2)
    #define MP_WIFI_SECURITY_SAE (3)
    #define MP_WIFI_SECURITY_SAE_HNP (3)  // Same as SAE
    #define MP_WIFI_SECURITY_SAE_H2E (4)
    #define MP_WIFI_SECURITY_SAE_AUTO (5)
    #define MP_WIFI_SECURITY_WAPI (6)
    #define MP_WIFI_SECURITY_EAP (7)
    #define MP_WIFI_SECURITY_EAP_TLS (7)  // Same as EAP
    #define MP_WIFI_SECURITY_WEP (8)
    #define MP_WIFI_SECURITY_WPA_PSK (9)
    #define MP_WIFI_SECURITY_WPA_AUTO_PERSONAL (10)
    #define MP_WIFI_SECURITY_DPP (11)
    #define MP_WIFI_SECURITY_EAP_PEAP_MSCHAPV2 (12)
    #define MP_WIFI_SECURITY_EAP_PEAP_GTC (13)
    #define MP_WIFI_SECURITY_EAP_TTLS_MSCHAPV2 (14)
    #define MP_WIFI_SECURITY_EAP_PEAP_TLS (15)
    #define MP_WIFI_SECURITY_EAP_TLS_SHA256 (16)
    
    /* AP Mode Configuration */
    #define WIFI_AP_SSID       "Pulsar-mPy"
    #define WIFI_AP_PSK        ""
    #define WIFI_AP_IP_ADDRESS "192.168.1.1"
    #define WIFI_AP_NETMASK    "255.255.255.0"
    
    static struct net_mgmt_event_callback wifi_shell_mgmt_cb;
    static struct net_mgmt_event_callback net_shell_mgmt_cb;
    static struct net_if *ap_iface;
    static struct wifi_connect_req_params ap_config;
    
    static uint32_t scan_result;
     
     /* The devicetree node identifier for the "led0" alias. */
    //  #define LED0_NODE DT_ALIAS(led0)
    //  #define LED_SLEEP_TIME_MS   100
     
    //  static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
    
     static K_SEM_DEFINE(wifi_ready_state_changed_sem, 0, 1);
     static bool wifi_ready_status;
    
     K_SEM_DEFINE(scan_sem, 0, 1);
     
     // struct wifi_scan_result wifi_entries[100] = {0};
     struct wifi_scan_result *wifi_entries;
     uint8_t wifi_entries_idx=0;
    
     
     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;
    
     typedef struct _wlan_obj_t {
    	mp_obj_base_t base;
    	int mode;  // network.STA_IF or network.AP_IF
    	bool is_active;
    } wlan_obj_t;
     
    // TODO: Do we need to blink the led when connecting/ connected to the WiFi?
    //  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 void clear_ipv4_addresses(struct net_if *iface)
    {
        struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4;
        
        if (ipv4) {
            ARRAY_FOR_EACH(ipv4->unicast, i) {
                if (ipv4->unicast[i].ipv4.is_used) {
                    net_if_ipv4_addr_rm(iface, &ipv4->unicast[i].ipv4.address.in_addr);
                }
            }
        }
    }
    
    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;
     }
     
     
     
     #if defined CONFIG_WIFI_NRF70_SKIP_LOCAL_ADMIN_MAC
     static bool local_mac_check(const uint8_t *const mac)
     {
     return ((mac[0] & 0x02) ||
     ((mac[0] == 0x00) && (mac[1] == 0x00) && (mac[2] == 0x5E)));
     }
     #endif /* CONFIG_WIFI_NRF70_SKIP_LOCAL_ADMIN_MAC */
     
     static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb)
     {
    	 const struct wifi_scan_result *entry =
    		 (const struct wifi_scan_result *)cb->info;
    	 uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")];
    	 uint8_t ssid_print[WIFI_SSID_MAX_LEN + 1];
    	 
    	 wifi_entries[wifi_entries_idx] = *entry;
    	 wifi_entries_idx++;
     
    	 scan_result++;
     
    	 if (scan_result == 1U) {
    		 printk("%-4s | %-32s %-5s | %-4s | %-4s | %-5s | %s\n",
    				"Num", "SSID", "(len)", "Chan", "RSSI", "Security", "BSSID");
    	 }
     
    	 strncpy(ssid_print, entry->ssid, sizeof(ssid_print) - 1);
    	 ssid_print[sizeof(ssid_print) - 1] = '\0';
     
     #if defined CONFIG_WIFI_NRF70_SKIP_LOCAL_ADMIN_MAC
    	 __ASSERT(!local_mac_check(entry->mac), "Locally administered MAC found: %s\n", ssid_print);
     #endif /* CONFIG_WIFI_NRF70_SKIP_LOCAL_ADMIN_MAC */
     
    	 printk("%-4d | %-32s %-5u | %-4u | %-4d | %-5s | %s\n",
    			 scan_result, ssid_print, entry->ssid_length,
    			 entry->channel, entry->rssi,
    			 wifi_security_txt(entry->security),
    			 ((entry->mac_length) ?
    			 net_sprint_ll_addr_buf(entry->mac, WIFI_MAC_ADDR_LEN, mac_string_buf,
    						 sizeof(mac_string_buf)) : ""));
     }
     
     static void handle_wifi_scan_done(struct net_mgmt_event_callback *cb)
     {
    	 const struct wifi_status *status =
    		 (const struct wifi_status *)cb->info;
     
    	 if (status->status) {
    		 LOG_ERR("Scan request failed (%d)", status->status);
    	 } else {
    		 printk("Scan request done\n");
    	 }
     
    	 scan_result = 0U;
    	 k_sem_give(&scan_sem);
     }
     
     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_SCAN_RESULT:
    		 handle_wifi_scan_result(cb);
    		 break;
     #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS
    	 case NET_EVENT_WIFI_RAW_SCAN_RESULT:
    		 handle_raw_scan_result(cb);
    		 break;
     #endif
    	 case NET_EVENT_WIFI_SCAN_DONE:
    		 handle_wifi_scan_done(cb);
    		 break;
    	 case NET_EVENT_IPV4_DHCP_BOUND:
    		 LOG_INF("Wifi: Got IP via DHCP");
    		 break;
    	 case NET_EVENT_WIFI_CONNECT_RESULT:
    		 LOG_INF("Wi-Fi connect result: status...");
    
    		const struct wifi_status *status = (const struct wifi_status *)cb->info;
    		if (status->status) {
    			LOG_ERR("Connection failed (reason: %d)", status->status);
    			context.connect_result = true; // Ensure we don't hang
    		}
    
    		 handle_wifi_connect_result(cb);
    		 break;
    	 case NET_EVENT_WIFI_DISCONNECT_RESULT:
    		 LOG_INF("Wi-Fi disconnect result: status...");
    		 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));
     
    	 printk("DHCP IP address: %s\r\n", 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:
    		 LOG_INF("Net MGMT: Got IP via DHCP");
    		 print_dhcp_ip(cb);
    		 break;
    	 default:
    		 break;
    	 }
     }
     
     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);
     
    	 printk("Starting %s with CPU frequency: %d MHz\r\n", CONFIG_BOARD, SystemCoreClock/MHZ(1));
    	 k_sleep(K_SECONDS(1));
     }
     
     #ifdef CONFIG_WIFI_READY_LIB
     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);
     }
     
     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 */
     
     static mp_obj_t wlan_isconnected(mp_obj_t self_in) {
    	 struct net_if *iface = net_if_get_wifi_sta();
     
    	 if (!iface) {
    		 return mp_const_false;
    	 }
     
    	 struct wifi_iface_status status = {0};
    	 int ret = net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface,
    						&status, sizeof(struct wifi_iface_status));
     
    	 if (ret == 0 && status.state == WIFI_STATE_COMPLETED) {
    		 return mp_const_true;
    	 }
     
    	 return mp_const_false;
     }
     static MP_DEFINE_CONST_FUN_OBJ_1(wlan_isconnected_obj, wlan_isconnected);
     
     static bool is_mac_addr_set(struct net_if *iface)
     {
    	 struct net_linkaddr *linkaddr = net_if_get_link_addr(iface);
    	 struct net_eth_addr wifi_addr;
     
    	 if (!linkaddr || linkaddr->len != WIFI_MAC_ADDR_LEN) {
    		 return false;
    	 }
     
    	 memcpy(wifi_addr.addr, linkaddr->addr, WIFI_MAC_ADDR_LEN);
     
    	 return net_eth_is_addr_valid(&wifi_addr);
     }
     
     static mp_obj_t wlan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    	 mp_arg_check_num(n_args, n_kw, 1, 1, false);
    	 int mode = mp_obj_get_int(args[0]);
    	 int ret = 0;
    	 
    	 if (mode != 0 && mode != 1) {
    		 mp_raise_ValueError(MP_ERROR_TEXT("invalid mode"));
    	 }
     
    	 wlan_obj_t *self = m_new_obj(wlan_obj_t);
    	 self->base.type = &zephyr_network_wlan_type;
    	 self->mode = mode;
    	 self->is_active = false;
     
    	 net_mgmt_callback_init();
    	 ret = register_wifi_ready();
    	 if (ret) {
    		 return ret;
    	 }
     
    	 if (!is_mac_addr_set(net_if_get_default())) {
    		 struct net_if *iface = net_if_get_default();
    		 int ret;
    		 struct ethernet_req_params params;
     
    		 /* Set a local MAC address with Nordic OUI */
    		 if (net_if_is_admin_up(iface)) {
    			 ret = net_if_down(iface);
    			 if (ret < 0 && ret != -EALREADY) {
    				 printk("Cannot bring down iface (%d)\r\n", ret);
    				 goto _end;
    			 }
    		 }
     
    		 ret = net_bytes_from_str(params.mac_address.addr, sizeof(CONFIG_WIFI_MAC_ADDRESS),
    					  CONFIG_WIFI_MAC_ADDRESS);
    		 if (ret) {
    			 printk("Failed to parse MAC address: %s (%d)\r\n", CONFIG_WIFI_MAC_ADDRESS, ret);
    			 goto _end;
    		 }
     
    		 net_mgmt (NET_REQUEST_ETHERNET_SET_MAC_ADDRESS, iface, &params, sizeof(params));
     
    		 ret = net_if_up(iface);
    		 if (ret < 0 && ret != -EALREADY) {
    			 printk("Cannot bring up iface (%d)\r\n", ret);
    			 mp_raise_OSError(ret);
    			 goto _end;
    		 }
    		 printk("OTP not programmed, proceeding with local MAC: %s\r\n", net_sprint_ll_addr(net_if_get_link_addr(iface)->addr, net_if_get_link_addr(iface)->len));
    	 }
    
    	 if (mode == 1) { // AP mode
    		// clear assigned IPs when starting
    		struct net_if *iface = net_if_get_default();
    		clear_ipv4_addresses(iface);
    	 }
     
    	 self->is_active = true;
     
     _end:
     
    	 return MP_OBJ_FROM_PTR(self);
     }
     
     static mp_obj_t wlan_active(size_t n_args, const mp_obj_t *args) {
    	 wlan_obj_t *self = MP_OBJ_TO_PTR(args[0]);
     
    	 if (n_args == 1) {
    		 return mp_obj_new_bool(self->is_active);
    	 } else {
    		 return mp_const_none;
    	 }
     }
     static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_active_obj, 1, 2, wlan_active);
     
     static mp_obj_t network_wlan_scan(mp_obj_t self_in) {
    	 struct net_if *iface = net_if_get_default();
    	 struct wifi_scan_params params = {.scan_type = WIFI_SCAN_TYPE_ACTIVE, .bands = 0 };
    	 mp_obj_t wifi_networks_list = mp_obj_new_list(0, NULL);
    	 // CLear buffers
    	 wifi_entries = calloc(100, sizeof(struct wifi_scan_result));
    	 wifi_entries_idx=0;
     
    	 if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, &params,
    			 sizeof(struct wifi_scan_params))) {
    				 printk("Scan request failed\r\n");
    		 goto _end;
    	 }
     
    	 printk("Scan requested\n\r");
    	 k_sem_take(&scan_sem, K_MSEC(SCAN_TIMEOUT_MS));
    	 
    	 printk("Found %d networks. \n\r", wifi_entries_idx);
    	 for (int i=0; i< wifi_entries_idx; i++)
    	 {
    		 uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")];
    		 
    		 strncpy(mac_string_buf, net_sprint_ll_addr_buf(wifi_entries[i].mac, WIFI_MAC_ADDR_LEN, mac_string_buf, sizeof(mac_string_buf)), strlen(mac_string_buf));
    		 printk("Network ID: %s & Network MAC: %s \n\r", wifi_entries[i].ssid, mac_string_buf);
    		 // Debug code
    		 // printk("Network ID: %s & Network MAC: %s \n\r", wifi_entries[i].ssid, net_sprint_ll_addr_buf(wifi_entries[i].mac, WIFI_MAC_ADDR_LEN, mac_string_buf, sizeof(mac_string_buf)));
     
    		 mp_obj_tuple_t *t = mp_obj_new_tuple(6, NULL);
    		 t->items[0] = mp_obj_new_bytes(wifi_entries[i].ssid, wifi_entries[i].ssid_length);
    		 t->items[1] = mp_obj_new_bytes(mac_string_buf, sizeof(mac_string_buf));
    		 t->items[2] = MP_OBJ_NEW_SMALL_INT(wifi_entries[i].channel);
    		 t->items[3] = MP_OBJ_NEW_SMALL_INT(wifi_entries[i].rssi);
    		 t->items[4] = MP_OBJ_NEW_SMALL_INT(wifi_entries[i].security);
    		 t->items[5] = mp_const_false; // XXX hidden?
    		 mp_obj_list_append(wifi_networks_list, MP_OBJ_FROM_PTR(t));
    	 }
    	 free(wifi_entries);
     
    	 // print our board's own MAC address:
    	 // ==================================
    	 const struct net_linkaddr *link_addr = net_if_get_link_addr(iface);
     
    	 printk("MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
    		 link_addr->addr[0], link_addr->addr[1], link_addr->addr[2],
    		 link_addr->addr[3], link_addr->addr[4], link_addr->addr[5]);
    	 // ==================================
     
     _end:
    	 return wifi_networks_list;
     }
     static MP_DEFINE_CONST_FUN_OBJ_1(network_wlan_scan_obj, network_wlan_scan);
     
     static mp_obj_t network_wlan_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
    	 enum { ARG_ssid, ARG_key, ARG_security, ARG_channel };
    	 static const mp_arg_t allowed_args[] = {
    		 { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
    		 { MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
    		 { MP_QSTR_, MP_ARG_INT, {.u_int = mp_const_none} },
    		 { MP_QSTR_, MP_ARG_INT, {.u_int = mp_const_none} },
    	 };
     
    	 // parse args
    	 mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
    	 mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
    
    	struct net_if *iface = net_if_get_default();
    	struct wifi_connect_req_params cnx_params = {0};
    	
    	size_t len;
    	const char *p;
    	p = mp_obj_str_get_data(args[ARG_ssid].u_obj, &len);
    	cnx_params.ssid = p;
    	cnx_params.ssid_length = MIN(len, WIFI_SSID_MAX_LEN);
    	
    	if (args[ARG_key].u_obj != mp_const_none) {
    		p = mp_obj_str_get_data(args[ARG_key].u_obj, &len);
    		cnx_params.psk = (uint8_t *)p;
    		cnx_params.psk_length = MIN(len, WIFI_PSK_MAX_LEN);
    	}
    
    	if (args[ARG_security].u_int > WIFI_SECURITY_TYPE_MAX) {
            mp_raise_ValueError(MP_ERROR_TEXT("Auth value not valid"));
        }
    
    	if (args[ARG_channel].u_int != WIFI_CHANNEL_ANY &&
            args[ARG_channel].u_int > WIFI_CHANNEL_MAX) {
            mp_raise_ValueError(MP_ERROR_TEXT("invalid channel number"));
        }
    	
    	 cnx_params.security = WIFI_SECURITY_TYPE_PSK;
    	//  cnx_params.channel = 11;
    	cnx_params.security = args[ARG_security].u_int;
        cnx_params.channel = args[ARG_channel].u_int;
    	cnx_params.mfp = WIFI_MFP_DISABLE;
    	cnx_params.timeout = 10000;
    
    	// Make sure the interface is up
    	if (!net_if_is_up(iface)) {
    		int ret = net_if_up(iface);
    		if (ret < 0 && ret != -EALREADY) {
    			mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to bring interface up"));
    		}
    	}
    
    	 // Ensure WPA supplicant thread is fully initialized
    	 k_sleep(K_MSEC(3000));
    	
    	 if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &cnx_params, sizeof(struct wifi_connect_req_params))) {
    			mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Connection failed"));
    		return mp_obj_new_bool(false);
    	 }
    
    	LOG_INF("Connection requested");
    
    	while (!context.connect_result) {
    		cmd_wifi_status();
    		
    		struct wifi_iface_status iface_status;
    
    		if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &iface_status, sizeof(struct wifi_iface_status))) {
    			mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Error getting status"));
    		}
    		// return the RFC 2863 operational status (see enum net_if_oper_state):
    		// 0 - NET_IF_OPER_UNKNOWN,        /**< Initial (unknown) value */
    		// 1 - NET_IF_OPER_NOTPRESENT,     /**< Hardware missing */
    		// 2 - NET_IF_OPER_DOWN,           /**< Interface is down */
    		// 3 - NET_IF_OPER_LOWERLAYERDOWN, /**< Lower layer interface is down */
    		// 4 - NET_IF_OPER_TESTING,        /**< Training mode */
    		// 5 - NET_IF_OPER_DORMANT,        /**< Waiting external action */
    		// 6 - NET_IF_OPER_UP,             /**< Interface is up */
    		LOG_INF("Net If state: %d ", iface->if_dev->oper_state);
    
    		k_sleep(K_MSEC(STATUS_POLLING_MS));
    	}
    
    	 return mp_const_none;
     }
     static MP_DEFINE_CONST_FUN_OBJ_KW(network_wlan_connect_obj, 1, network_wlan_connect);
    
     STATIC mp_obj_t network_wlan_status(size_t n_args, const mp_obj_t *args) {
    	wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
    	if (self->if_id == MOD_NETWORK_AP_IF) {
    		mp_raise_NotImplementedError(MP_ERROR_TEXT("Status only on Station interface"));
    	}
    
    	struct wifi_iface_status iface_status;
    	struct net_if *iface = net_if_get_default();
    
    	if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &iface_status, sizeof(struct wifi_iface_status))) {
    		mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Error getting status"));
    	}
    
    	if (n_args == 1) {
    		if (self->if_id != MOD_NETWORK_STA_IF) {
    			return mp_const_none;
    		}
    		uint8_t retval = WIFI_STATE_DISCONNECTED;
    
    		// TODO: it makes more sense to completely remove this. TBD if that's the case or not
    		// switch (iface_status.state) {
    		// 	case WIFI_STATE_DISCONNECTED:
    		// 	case WIFI_STATE_INTERFACE_DISABLED:
    		// 	case WIFI_STATE_INACTIVE:
    		// 		retval = WIFI_STATE_DISCONNECTED;
    		// 		break;
    		// 	case WIFI_STATE_SCANNING:
    		// 	case WIFI_STATE_ASSOCIATING:
    		// 	case WIFI_STATE_ASSOCIATED:
    		// 	case WIFI_STATE_4WAY_HANDSHAKE:
    		// 		// Return negative status code if authentication failed
    		// 		// if (iface_status.status != 0) {
    		// 		// 	return MP_OBJ_NEW_SMALL_INT(-iface_status.status);
    		// 		// }
    
    		// 		// return the RFC 2863 operational status (see enum net_if_oper_state)
    		// 		return MP_OBJ_NEW_SMALL_INT(-iface->if_dev->oper_state);
    		// 		break;
    		// 	case WIFI_STATE_GROUP_HANDSHAKE:
    		// 		retval = WIFI_STATE_AUTHENTICATING;
    		// 		break;
    		// 	case WIFI_STATE_COMPLETED:
    		// 		retval = WIFI_STATE_COMPLETED;
    		// 		break;
    		// }
    
    		retval = iface_status.state;
    		return mp_obj_new_int_from_uint(retval);
    	}
    
    	// There's one more argument
    	if (iface_status.state != WIFI_STATE_COMPLETED) {
    		mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("Device not connected"));
    	}
    	switch ((uintptr_t)args[1]) {
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_rssi): {
    			return MP_OBJ_NEW_SMALL_INT(iface_status.rssi);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_ssid): {
    			return mp_obj_new_str(iface_status.ssid, iface_status.ssid_len);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_band): {
    			return mp_obj_new_int_from_uint(iface_status.band);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_channel): {
    			return mp_obj_new_int(iface_status.channel);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_link_mode): {
    			return mp_obj_new_int_from_uint(iface_status.link_mode);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_security): {
    			return mp_obj_new_int_from_uint(iface_status.security);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_mfp): {
    			return mp_obj_new_int_from_uint(iface_status.mfp);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_bssid): {
    			return mp_obj_new_bytes(iface_status.bssid, WIFI_MAC_ADDR_LEN);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_dtim): {
    			return mp_obj_new_int_from_uint(iface_status.dtim_period);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_beacon_interval): {
    			return mp_obj_new_int_from_uint(iface_status.beacon_interval);
    		}
    		case (uintptr_t)MP_OBJ_NEW_QSTR(MP_QSTR_twt_capable): {
    			return mp_obj_new_bool(iface_status.twt_capable);
    		}
    		default:
    			mp_raise_ValueError(MP_ERROR_TEXT("unknown status param"));
    	}
    	return mp_const_none;
    }
    STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_wlan_status_obj, 1, 2, network_wlan_status);
    
    STATIC mp_obj_t network_wlan_disconnect(mp_obj_t self_in) {
        wlan_if_obj_t *self = MP_OBJ_TO_PTR(self_in);
        if (self->if_id == MOD_NETWORK_AP_IF) {
            mp_raise_NotImplementedError(MP_ERROR_TEXT("Disconnect only on Station interface"));
        }
        struct net_if *iface = net_if_get_default();
        if (net_mgmt(NET_REQUEST_WIFI_DISCONNECT, iface, NULL, 0)) {
            LOG_ERR("Disconnect request failed");
            return mp_obj_new_bool(false);
        }
        return mp_const_none;
    }
    STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_wlan_disconnect_obj, network_wlan_disconnect);
    
    static void enable_dhcpv4_server(void)
    {
    	static struct in_addr addr;
    	static struct in_addr netmaskAddr;
    
    	if (net_addr_pton(AF_INET, WIFI_AP_IP_ADDRESS, &addr)) {
    		LOG_ERR("Invalid address: %s", WIFI_AP_IP_ADDRESS);
    		return;
    	}
    
    	if (net_addr_pton(AF_INET, WIFI_AP_NETMASK, &netmaskAddr)) {
    		LOG_ERR("Invalid netmask: %s", WIFI_AP_NETMASK);
    		return;
    	}
    
    	net_if_ipv4_set_gw(ap_iface, &addr);
    
    	if (net_if_ipv4_addr_add(ap_iface, &addr, NET_ADDR_MANUAL, 0) == NULL) {
    		LOG_ERR("unable to set IP address for AP interface");
    	}
    
    	if (!net_if_ipv4_set_netmask_by_addr(ap_iface, &addr, &netmaskAddr)) {
    		LOG_ERR("Unable to set netmask for AP interface: %s", WIFI_AP_NETMASK);
    	}
    
    	addr.s4_addr[3] += 10; /* Starting IPv4 address for DHCPv4 address pool. */
    
    	if (net_dhcpv4_server_start(ap_iface, &addr) != 0) {
    		LOG_ERR("DHCP server is not started for desired IP");
    		return;
    	}
    
    	LOG_INF("DHCPv4 server started...\n");
    }
    
    STATIC mp_obj_t network_wlan_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
    	/* Get AP interface in AP-STA mode. */
    	ap_iface = net_if_get_wifi_sap();
    	
    	if (!ap_iface) {
    		LOG_INF("AP: is not initialized");
    		return mp_obj_new_int(-EIO);
    	}
    
    	LOG_INF("Turning on AP Mode");
    	ap_config.ssid = (const uint8_t *)WIFI_AP_SSID;
    	ap_config.ssid_length = strlen(WIFI_AP_SSID);
    	ap_config.psk = (const uint8_t *)WIFI_AP_PSK;
    	ap_config.psk_length = strlen(WIFI_AP_PSK);
    	ap_config.channel = 11;
    	ap_config.band = WIFI_FREQ_BAND_2_4_GHZ;
    
    	if (strlen(WIFI_AP_PSK) == 0) {
    		ap_config.security = WIFI_SECURITY_TYPE_NONE;
    	} else {
    		ap_config.security = WIFI_SECURITY_TYPE_PSK;
    	}
    
    	if (!wifi_utils_validate_chan(ap_config.band, ap_config.channel)) {
    		LOG_ERR("Invalid channel %d in %d band", ap_config.channel, ap_config.band);
    		return mp_const_none;
    	}
    
    	enable_dhcpv4_server();
    
    	int ret = net_mgmt(NET_REQUEST_WIFI_AP_ENABLE, ap_iface, &ap_config, sizeof(struct wifi_connect_req_params));
    	if (ret) {
    		LOG_ERR("NET_REQUEST_WIFI_AP_ENABLE failed, err: %d", ret);
    	}
    
    	return mp_obj_new_int(ret);
    }
    STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_wlan_config_obj, 1, network_wlan_config);
    
    static const mp_rom_map_elem_t wlan_locals_dict_table[] = {
    	{ MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&wlan_active_obj) },
    	{ MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&network_wlan_scan_obj) },
    	{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&network_wlan_connect_obj) },
    	{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&network_wlan_disconnect_obj) },
    	{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_wlan_config_obj) },
    	// { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&wlan_ifconfig_obj) },
    	{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&wlan_isconnected_obj) },
    	{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_wlan_status_obj) },
    };
    static MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table);
    
    MP_DEFINE_CONST_OBJ_TYPE(
    	zephyr_network_wlan_type,
    	MP_QSTR_WLAN,
    	MP_TYPE_FLAG_NONE,
    	make_new, wlan_make_new,
    	locals_dict, &wlan_locals_dict
    );
    
    
    #endif // MICROPY_PY_NETWORK_WLAN

    The steps that I take over serial to get these errors:

    import network
    import usocket as socket
    import time
    
    wlan = network.WLAN(network.STA_IF)  # Wi-Fi client
    wlan.scan()
    
    wlan.connect("TP-Link_7474", "55920322", network.SECURITY_PSK, 4)
    
    def getaddrinfo_to_host(host, port):
        try:
            print("Resolving " + host + "...")
            addr = socket.getaddrinfo(host, port)
            print("Resolved:", addr)
            return addr
        except Exception as e:
            print("DNS Error:", e)
            return None
        return None
    
    result = getaddrinfo_to_host("google.com", 443)
    if result:
        print("Success!")
    else:
        print("Failed to resolve host")
    
    s = None
    s = socket.socket()
    
    ## point 1
    trusted_ca_tag = 16842753
    
    print("Performing TLS handshake...")
    s.tlswrap(sec_tag=trusted_ca_tag, hostname="google.com")
    print("TLS Handshake complete.")
    
    ## point 2
    print("Connecting to:", result[0][-1])
    s.connect(result[0][-1])
    print("TCP Connected.")

    Note: depending on what error you want to pop up, you can reverse point 1 and 2. Currently I'm debugging with them not reversed and slowly inching forward. For now, I discovered that the correct value is "trusted_ca_tag = 16842753".

Related