Enable or disable TWT with notification

I am studying Lesson 6/wifi fund_1ess6uexer2 and I can run the provided code normally.

(academy.nordicsemi.com/.../)
But I still want to control whether to send packets by pressing button 2 when turning off the TWT function.
As shown in step 3 of the diagram, when I turn off TWT, I press button 2 to enable the send package, but no data packet is sent. I tried to modify the code as shown in step 4 of the diagram, but couldn't. Could you please provide some help and guidance? Thank you very much!

Parents
  • Hi,

    This is due to how the exercise is implemented in such a way that it only sends a message during the awake state when TWT is enabled:

    static void twt_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
    				   struct net_if *iface)
    {
    	switch (mgmt_event) {
    	/* STEP 3.2.1 - Upon a TWT event, call handle_wifi_twt_event() to handle the response */
    	case NET_EVENT_WIFI_TWT:
    		handle_wifi_twt_event(cb);
    		break;
    	/* STEP 3.2.2 -	Upon TWT sleep state event, inform the user of the current sleep state.
    	 * When the device is in the awake state, send a packet to the server and check for any
    	 * received packets if sending packets is enabled. */
    	case NET_EVENT_WIFI_TWT_SLEEP_STATE:
    		int *twt_state;
    		twt_state = (int *)(cb->info);
    		LOG_INF("TWT sleep state: %s", *twt_state ? "awake" : "sleeping");
    		if ((*twt_state == WIFI_TWT_STATE_AWAKE) & sending_packets_enabled) {
    			send_packet();
    			receive_packet();
    		}
    		break;
    	}
    }

    If you want to be able to send packets when TWT is not enabled, you can call the function to send the packet directly in the button_handler() or schedule that it should be called. This code snippet shows how to call it directly in the button_handler():

    static void button_handler(uint32_t button_state, uint32_t has_changed)
    {
    	uint32_t button = button_state & has_changed;
    
    	/* STEP 5.1 - Call wifi_set_twt() to enable or disable TWT when button 1 is pressed. */
    	if (button & DK_BTN1_MSK) {
    		wifi_set_twt();
    	}
    
    	/* STEP 5.2 - Enable or disable sending packets during TWT awake when button 2 is pressed.
    	 */
    	if (button & DK_BTN2_MSK) {
    		send_packet();
    	}
    }

    If you want to schedule it, you can take a look at the TWT example here: https://github.com/martelmy/NCS_examples/blob/main/wifi/twt_provisioning_demo. In this example, pressing button 2 will schedule a ping that will either be sent immediately when TWT is not enabled or during the next wakeup when TWT is enabled. You can use work queue to schedule the UDP packet in the DevAcademy exercise in a similar way.
    Please note that this example is not official and should be considered provided “as-is”.

    Best regards,
    Marte

Reply
  • Hi,

    This is due to how the exercise is implemented in such a way that it only sends a message during the awake state when TWT is enabled:

    static void twt_mgmt_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
    				   struct net_if *iface)
    {
    	switch (mgmt_event) {
    	/* STEP 3.2.1 - Upon a TWT event, call handle_wifi_twt_event() to handle the response */
    	case NET_EVENT_WIFI_TWT:
    		handle_wifi_twt_event(cb);
    		break;
    	/* STEP 3.2.2 -	Upon TWT sleep state event, inform the user of the current sleep state.
    	 * When the device is in the awake state, send a packet to the server and check for any
    	 * received packets if sending packets is enabled. */
    	case NET_EVENT_WIFI_TWT_SLEEP_STATE:
    		int *twt_state;
    		twt_state = (int *)(cb->info);
    		LOG_INF("TWT sleep state: %s", *twt_state ? "awake" : "sleeping");
    		if ((*twt_state == WIFI_TWT_STATE_AWAKE) & sending_packets_enabled) {
    			send_packet();
    			receive_packet();
    		}
    		break;
    	}
    }

    If you want to be able to send packets when TWT is not enabled, you can call the function to send the packet directly in the button_handler() or schedule that it should be called. This code snippet shows how to call it directly in the button_handler():

    static void button_handler(uint32_t button_state, uint32_t has_changed)
    {
    	uint32_t button = button_state & has_changed;
    
    	/* STEP 5.1 - Call wifi_set_twt() to enable or disable TWT when button 1 is pressed. */
    	if (button & DK_BTN1_MSK) {
    		wifi_set_twt();
    	}
    
    	/* STEP 5.2 - Enable or disable sending packets during TWT awake when button 2 is pressed.
    	 */
    	if (button & DK_BTN2_MSK) {
    		send_packet();
    	}
    }

    If you want to schedule it, you can take a look at the TWT example here: https://github.com/martelmy/NCS_examples/blob/main/wifi/twt_provisioning_demo. In this example, pressing button 2 will schedule a ping that will either be sent immediately when TWT is not enabled or during the next wakeup when TWT is enabled. You can use work queue to schedule the UDP packet in the DevAcademy exercise in a similar way.
    Please note that this example is not official and should be considered provided “as-is”.

    Best regards,
    Marte

Children
  • Thank you, . Your guidance is detailed and easy to understand.

    I still have questions, as shown in the picture, TWT mode and DTIM mode. How is the peak in the image caused in TWT mode? 

  • Hi,

    Can you share what you are setting the TWT parameters to in your code, and share the application log from the device?

    Best regards,
    Marte

  • The log is:

    > wifi_cred auto_connect
    wifi_cred auto_connect
    [00:00:36.831,787] <inf> wifi_mgmt_ext: Connection requested
    [00:00:41.863,525] <inf> Lesson6_Exercise2: Network connected
    [00:00:41.864,288] <inf> Lesson6_Exercise2: Connected to server
    [00:00:41.864,288] <inf> Lesson6_Exercise2: Press button 1 on your DK to enable or disable TWT
    [00:00:41.865,753] <inf> Lesson6_Exercise2: Successfully sent message: Hello from nRF70 Series! 0
    [00:00:42.865,936] <inf> Lesson6_Exercise2: Data received from the server: (Hello from nRF70 Series! 0)
    [00:01:15.183,654] <inf> Lesson6_Exercise2: -------------------------------
    [00:01:15.183,685] <inf> Lesson6_Exercise2: TWT operation TWT setup requested
    [00:01:15.183,715] <inf> Lesson6_Exercise2: -------------------------------
    [00:01:15.231,750] <inf> Lesson6_Exercise2: TWT response: TWT accept
    [00:01:15.231,781] <inf> Lesson6_Exercise2: == TWT negotiated parameters ==
    [00:01:15.231,781] <inf> Lesson6_Exercise2: TWT Dialog token: 1
    [00:01:15.231,781] <inf> Lesson6_Exercise2: TWT flow ID: 1
    [00:01:15.231,811] <inf> Lesson6_Exercise2: TWT negotiation type: TWT individual negotiation
    [00:01:15.231,842] <inf> Lesson6_Exercise2: TWT responder: true
    [00:01:15.231,872] <inf> Lesson6_Exercise2: TWT implicit: true
    [00:01:15.231,903] <inf> Lesson6_Exercise2: TWT announce: false
    [00:01:15.231,903] <inf> Lesson6_Exercise2: TWT trigger: false
    [00:01:15.231,933] <inf> Lesson6_Exercise2: TWT wake interval: 65 ms (65024 us)
    [00:01:15.231,933] <inf> Lesson6_Exercise2: TWT interval: 0 s (100000 us)
    [00:01:15.231,933] <inf> Lesson6_Exercise2: ===============================
    [00:01:15.232,574] <inf> Lesson6_Exercise2: TWT sleep state: sleeping
    [00:01:15.333,343] <inf> Lesson6_Exercise2: TWT sleep state: awake

    I do not change the code from the Lesson 6/wifi fund_1ess6uexer2:https://github.com/NordicDeveloperAcademy/wifi-fund/blob/main/lesson6/wififund_less6_exer2_solution/src/main.c

    Is it due to a negotiation process in TWT, but why does it appear so regularly?

  • I captured the package by wireshark, the track is shown in figure below, I tried to analyze the reason for the peak.

    I think the peak is caused by the "QoS null function" package.

    do you think it is reasonable or not?

Related