Target Wake Time (TWT) on nRF7002-DK is not working properly

Hi,

I wrote an application based on the wifi-sta sample to test the Target Wake Time (TWT) feature and measure the current consumption while the nRF7002 is in sleep mode.

My test-setup consists of one nRF7002-DK operating as "Wifi-sta" and one Fritz!Box 7530 AX operating as "Wifi-AP" and a power porfiler kit II to measure the current.

A udp-server was implemented in the application so that the station receives incoming messages from a udp-client (PC) over the Wifi 6 network created by the Wifi-AP ( Fritz!Box 7530 AX ).

The station (nRF7002-DK) was able to connect to the network and receive messages from the udp client.

But when the TWT mode is activated the station (nRF7002-DK) does not receive any messages from the udp-client .

In the next photo you can see the current consumption of the nRF7002 (PPK is connected to P23 on the DK).

As you can see the nRF7002 goes to sleep for the amount of time which was set (wifi twt setup 0 0 1 1 0 0 0 0 150 2000) which is a good indicator but the station does not receive the messages any more form the udp-client !

When i deactivate the TWT feature by (wifi twt teardown_all) the station will be able to receive messages again from the udp cleint.

So, Why cant the station receive messages when the TWT mode is active?

I also repeated the test with different settings for the TWT like:

wifi twt setup 0 0 1 1 1 1 1 1 100 2000
wifi twt setup 0 0 1 1 1 1 0 1 255 2000
wifi twt setup 0 0 1 1 1 1 0 1 255 300
wifi twt setup 1 0 1 1 1 1 0 1 255 300
wifi twt setup 1 0 1 1 0 0 0 0 255 300
wifi twt setup 2 0 1 1 1 1 0 1 200 300

But the result is the same.

No messages were received when the TWT mode is active.

I would be very thankful if you could provide me with solutions or ideas to solve this problem!

Best regards

Tareq

  • Hi dejans,
    Thank you for your reply.

    The results for the Experiment 2
    1) Connect to AP : successful
    2) Create Static ARP table at both devices

    The command (# arp -s 192.168.0.65 00:50:ba:85:85:ca) worked on the udp-client device Laptop (ubuntu) but not on the udp-server device(nRF7002-dk). See next image:


    3) Setup TWT : successful for three variants:

    For: 0 0 1 1 1 1 1 1 100 3000

    and for: 0 0 1 1 1 1 1 1 100 15000

    and for: 0 0 1 1 1 1 1 1 100 10000

    The results were:

    For: 0 0 1 1 1 1 1 1 100 3000

    The udp-server was able to receive some of the messages but not all of them!

    See the next image:

    For: 0 0 1 1 1 1 1 1 100 15000

    The udp-server was able to receive just the second message and then no more!

    For: 0 0 1 1 1 1 1 1 100 10000

    Again the udp-server was able to receive some of the messages but not all of them until the <inf> message came. After that udp-server was not able to receive any messages.

    I've also found that there's a higher chance of receiving a message if the message is sent just before the UDP-server device wakes up.

    In this test the ncs v2.2.0 was used.

    As Wifi 6 AP the FRITZ!Box 6690 was used.

    Here is the used code:

    /* Minimal UDP+Shell source code (was tested on nRF connect sdk 2.22) 
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(codi, LOG_LEVEL_DBG);
    
    #include <nrfx_clock.h>
    #include <zephyr/kernel.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <zephyr/shell/shell.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/net/socket.h>
    
    
    #define PORT	 1337
    #define MAXLINE 1024
    #define IP_ADDR "192.168.50.54"
    #define Receive_Stack    1024
    
    
    int send_udp_datagram(void) {
    	int err;
    	struct sockaddr_in server;
    
    	server.sin_family = AF_INET;
    	server.sin_port = htons(1337);
    	if (inet_pton(AF_INET, IP_ADDR, &server.sin_addr) != 1) {
    		LOG_ERR("Could not convert IP addr %s\n", IP_ADDR);
    		return -1;
    	}
    
    	int coap_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    	if (coap_socket < 0) {
    		LOG_ERR("Failed to create CoAP socket: %d.\n", errno);
    		return -errno;
    	}
    
    	err = connect(coap_socket, (struct sockaddr *)&server,sizeof(struct sockaddr_in));
    	if (err < 0) {
    		LOG_ERR("Failed to connect UDP socket (err %d)\n", err);
    		return err;
    	}
    
    	const char * payload = "Hello from the nRF7002";
    	
    	err = send(coap_socket, payload, strlen(payload), 0);
    	if (err < 0) {
    		LOG_ERR("Failed to send message via UDP socket (errno %d)\n", -errno);
    		return -errno;
    	}
    	
    	err = sendto(coap_socket, payload, strlen(payload),0, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
    	if (err < 0) {
    		LOG_ERR("Failed to send message via UDP socket (errno %d)\n", -errno);
    		return -errno;
    	}
    	LOG_INF("Message sent");
    	
    
    	close(coap_socket);
    
    	return 0;
    }
    
    
    int udp_server(void) {
    int sockfd;
    	char buffer[MAXLINE];
    	char *hello = "Hello from server";
    	struct sockaddr_in servaddr, cliaddr;
    	
    	// Creating socket file descriptor
    	if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
    		printk("socket creation failed");
    		return -errno;
    	}
    		
    	memset(&servaddr, 0, sizeof(servaddr));
    	memset(&cliaddr, 0, sizeof(cliaddr));
    	
    	// Filling server information
    	servaddr.sin_family = AF_INET; // IPv4
    	servaddr.sin_addr.s_addr = INADDR_ANY;
    	servaddr.sin_port = htons(PORT);
    	
    	// Bind the socket with the server address
    	if ( bind(sockfd, (const struct sockaddr *)&servaddr,
    			sizeof(servaddr)) < 0 )
    	{
    		printk("bind faileed");
    		return -errno;
    	}
    	
    	int len, n;
    	len = sizeof(cliaddr); //len is value/result
    
    	while(true) {		
    		n = recvfrom(sockfd, (char *)buffer, MAXLINE,
    		 			MSG_WAITALL, ( struct sockaddr *) &cliaddr,
    		 			&len);
    		buffer[n] = '\0';
    		printk("Message client : %s\n", buffer);
    			}
    		
    	return 0;
    }
    
    
    void main(void)
    {
    #ifdef CLOCK_FEATURE_HFCLK_DIVIDE_PRESENT
    	/* For now hardcode to 128MHz */
    	nrfx_clock_divider_set(NRF_CLOCK_DOMAIN_HFCLK,
    			       NRF_CLOCK_HFCLK_DIV_1);
    #endif
    	printk("Starting %s with CPU frequency: %d MHz\n", CONFIG_BOARD, SystemCoreClock/MHZ(1));
    k_sleep(K_SECONDS(1));
    send_udp_datagram();
    udp_server();
    }

    Experiment 3:

    I was not able to set the Legacy power mode on the nRF7002-dk using the ncs v2.2

    See the next image:

    So i tried to use the same code and the same configurations (prj.conf) in an new application created with ncs v3. The result was that i was able to set the legacy power mode but the creation of the udp socket was always not successful. I dont why is that. The creation of the udp socket with the same code work fine with the ncs v2.2.

    I will be thankful if you have new information that could help solve this problem.

    Best regards.

    Tareq

  • Hi Tareq,

    Thank you for providing the results of your experiments. I'll get back to you when I get new information related to this issue, probably during next week.

    Best regards,
    Dejan

  • Hi Tareq,

    We would need to investigate this issue further. Please note that looking into this issue might require longer time. I'll get back to you when I get new information. 

    Best regards,
    Dejan

  • Hi Tareq,

    Could you provide wireless sniffer capture for all experiments?

    Best regards,
    Dejan

  • Hi Tareq,

    Could you try using Wi-Fi Shell sample (from NCS v2.3.0) instead of STA? Please use 4 steps shown below and provide results.

    1) Compile shell sample with zperf
    2) Connect to AP
    3) Setup TWT
    4) Run UDP RX

    Best regards,
    Dejan

Related