Can nRF5340 keep two links simultaneously? One BLE audio link with another nRF5340, one custom BLE link with Smart Phone for configuration

Hi,

I have kept following BLE audio since the nRF5340 audio DK was available. Recently, we came up with an idea of developing a broadcasting system. While we demoed the idea to potential customer, they required to control the BLE audio nodes with phone app, such as volume up, mute, etc. Is it possible to make a nRF5340 keep connected with 2 devices at the same time, one is on BLE audio, and another is a phone with normal BLE support? If not simultaneously, could be in the same firmware?

Thank you

Junmin

Parents
  • Hello Junmin,

    While we demoed the idea to potential customer, they required to control the BLE audio nodes with phone app, such as volume up, mute, etc. Is it possible to make a nRF5340 keep connected with 2 devices at the same time, one is on BLE audio, and another is a phone with normal BLE support? If not simultaneously, could be in the same firmware?

    Do I understand you correctly that you would like to make a broadcaster (BIS), that also connects to a phone over regular BLE connection (ACL connection) in order to control the broadcast's volume etc.?

    If I have understood you correctly, the answer is:
    Yes - you can add a peripheral or central role to the nRF5340 LE Audio reference application, no problem.
    The current controller is able to hold 2 concurrent ACL connections (regular BLE connections) in addition to the 1 or 2 BIS channels.

    If I have not understood you correctly, could you share a quick diagram for your intended topology, so that I can better understand what you would like to achieve?

    Best regards,
    Karl

  • Hello Karl,

    You understood me pretty well, thank you.

    Actually, in addition to broadcaster volume control, we'd like to control receiver volume independently also, but that's the same thing as broadcaster if we can add a peripheral or central role to receivers. I'll try you suggestion next week.

    Thank you for positive feedback before weekend.Smile

    Have a great weekend

    Junmin

  • Hello Junmin,

    1. Did you also add the necessary changes to your prj.conf, to support the additional ACL link? I am not sure if I understand what you mean about it being defined in 4 different places, but please do not make any changes directly to the LE Audio architecture files like audio_datapath since this is not recommended as this might break something else unexpectedly.

    2. You can use this example as a reference for how to implement this - it is made for v2.3.0, but the steps are identical for v2.4.0.

    Best regards,
    Karl

  • Hello Karl,

    Per your suggestions, I created a new application with nRF5340 LE Audio reference application as template, and furthermore, I created a dedicated thread to run peripheral ISO, using the example you mentioned as reference. Also, prj.conf was modified according to the example. The console outputs are as following, could you give some clues to fix the err "Unable to register ISO server"?

    Thank you and Best Regards

    Junmin

    *** Booting Zephyr OS build v3.3.99-ncs1 ***
    HL [00:00:00.257,476] <inf> fw_info: fw_info_app_print:
    nRF5340 Audio nRF5340 Audio DK cpuapp
    NCS base version: 2.4.0
    Cmake run : Fri Aug 04 20:29:26 2023
    HL [00:00:00.257,507] <inf> fw_info: fw_info_app_print: ------- DEBUG BUILD -------
    HL [00:00:00.257,507] <inf> fw_info: fw_info_app_print: HEADSET left device
    HL [00:00:00.268,127] <inf> board_version: board_version_valid_check: Compatible board/HW version found: 1.0.0
    HL [00:00:00.302,490] <wrn> bt_hci_core: set_flow_control: Controller to host flow control not supported
    HL [00:00:00.307,556] <inf> bt_hci_core: bt_dev_show_info: Identity: C7:48:40:57:8F:D4 (random)
    HL [00:00:00.307,586] <inf> bt_hci_core: bt_dev_show_info: HCI: version 5.2 (0x0b) revision 0x0d15, manufacturer 0x07e8
    HL [00:00:00.307,617] <inf> bt_hci_core: bt_dev_show_info: LMP: version 5.2 (0x0b) subver 0x0d15
    HL [00:00:00.433,776] <inf> ble: mac_print: MAC: 44:43:CF:DA:0F:E1 (random)
    HL [00:00:00.433,990] <inf> ble: on_bt_ready: Controller version: 3349
    HL [00:00:00.527,862] <inf> ble_iso: uart_control_sub_thread: Bluetooth initialized
    HL [00:00:00.527,893] <inf> ble_iso: uart_control_sub_thread: Unable to register ISO server (err -112)
    HL [00:00:00.528,137] <inf> cis_headset: advertising_process: Advertising successfully started

  • Hello again, Junmin

    Junmin said:
    The console outputs are as following, could you give some clues to fix the err "Unable to register ISO server"?

    The -112 error code means 'address already in use', could it be that you are attempting to use the same instance as your CIS ACL for your NUS service?

    For future reference, please use the Insert->Code option when sharing code or logs here on DevZone.

    On a general note I would also recommend that you use the latest 3393 controller version.

    Best regards,
    Karl

  • Hello Karl,

    I checked my code and did some experiments, you are right, I'm attempting to use the same CIS ACL for NUS service. I though a lot and reviewed other people's related questions in DevZone, but still have no idea how to fix it, any suggestions?

    By the way, I have upgraded my code with the latest 3393 controller version.

    Best Regards

    Junmin

  • 	err = bt_enable(NULL);
    	if (err) {
    		LOG_INF("Bluetooth init failed (err %d)", err);
    		return;
    	}
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	LOG_INF("Bluetooth initialized");
    
    	err = bt_iso_server_register(&iso_server);
    	if (err) {
    		LOG_INF("Unable to register ISO server (err %d)", err);
    		return;
    	}
    
    	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
    	if (err) {
    		LOG_INF("Advertising failed to start (err %d)", err);
    		return;
    	}

    *** Booting Zephyr OS build v3.3.99-ncs1 ***
    HL [00:00:00.257,446] <inf> fw_info: fw_info_app_print: 
             nRF5340 Audio nRF5340 Audio DK cpuapp                      
             NCS base version: 2.4.0                            
             Cmake run : Wed Aug 09 23:30:14 2023
    HL [00:00:00.257,446] <inf> fw_info: fw_info_app_print: ------- DEBUG BUILD -------
    HL [00:00:00.257,446] <inf> fw_info: fw_info_app_print: HEADSET left device
    HL [00:00:00.268,066] <inf> board_version: board_version_valid_check: Compatible board/HW version found: 1.0.0
    HL [00:00:00.302,551] <wrn> bt_hci_core: set_flow_control: Controller to host flow control not supported
    HL [00:00:00.307,586] <inf> bt_hci_core: bt_dev_show_info: Identity: D4:A5:74:D6:1E:9F (random)
    HL [00:00:00.307,617] <inf> bt_hci_core: bt_dev_show_info: HCI: version 5.2 (0x0b) revision 0x0d41, manufacturer 0x07e8
    HL [00:00:00.307,617] <inf> bt_hci_core: bt_dev_show_info: LMP: version 5.2 (0x0b) subver 0x0d41
    HL [00:00:00.433,502] <inf> ble: mac_print: MAC: 79:DD:C1:19:AE:31 (random)
    HL [00:00:00.433,715] <inf> ble: on_bt_ready: Controller version: 3393
    HL [00:00:00.527,954] <inf> ble_iso: uart_control_sub_thread: Bluetooth init failed (err -120)
    HL [00:00:00.528,228] <inf> cis_headset: advertising_process: Advertising successfully started

Reply
  • 	err = bt_enable(NULL);
    	if (err) {
    		LOG_INF("Bluetooth init failed (err %d)", err);
    		return;
    	}
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	LOG_INF("Bluetooth initialized");
    
    	err = bt_iso_server_register(&iso_server);
    	if (err) {
    		LOG_INF("Unable to register ISO server (err %d)", err);
    		return;
    	}
    
    	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
    	if (err) {
    		LOG_INF("Advertising failed to start (err %d)", err);
    		return;
    	}

    *** Booting Zephyr OS build v3.3.99-ncs1 ***
    HL [00:00:00.257,446] <inf> fw_info: fw_info_app_print: 
             nRF5340 Audio nRF5340 Audio DK cpuapp                      
             NCS base version: 2.4.0                            
             Cmake run : Wed Aug 09 23:30:14 2023
    HL [00:00:00.257,446] <inf> fw_info: fw_info_app_print: ------- DEBUG BUILD -------
    HL [00:00:00.257,446] <inf> fw_info: fw_info_app_print: HEADSET left device
    HL [00:00:00.268,066] <inf> board_version: board_version_valid_check: Compatible board/HW version found: 1.0.0
    HL [00:00:00.302,551] <wrn> bt_hci_core: set_flow_control: Controller to host flow control not supported
    HL [00:00:00.307,586] <inf> bt_hci_core: bt_dev_show_info: Identity: D4:A5:74:D6:1E:9F (random)
    HL [00:00:00.307,617] <inf> bt_hci_core: bt_dev_show_info: HCI: version 5.2 (0x0b) revision 0x0d41, manufacturer 0x07e8
    HL [00:00:00.307,617] <inf> bt_hci_core: bt_dev_show_info: LMP: version 5.2 (0x0b) subver 0x0d41
    HL [00:00:00.433,502] <inf> ble: mac_print: MAC: 79:DD:C1:19:AE:31 (random)
    HL [00:00:00.433,715] <inf> ble: on_bt_ready: Controller version: 3393
    HL [00:00:00.527,954] <inf> ble_iso: uart_control_sub_thread: Bluetooth init failed (err -120)
    HL [00:00:00.528,228] <inf> cis_headset: advertising_process: Advertising successfully started

Children
  • Hello Karl,

    I'm still waiting for you suggestions. At the same time, I'm trying to take the following discussion as reference,

     nRF5340 Audio DK: LE Audio and UART2 Concurrently 

    Since it's based on NCS 2.20, I'll go down to this version first.

    Any comments?

    Best Regards

    Junmin

  • Hello Junmin,

    Thank you for your extreme patience with this - I was unfortunately out of office for the first few days of this week due to sickness, but now I am back.

    Junmin said:
    I checked my code and did some experiments, you are right, I'm attempting to use the same CIS ACL for NUS service. I though a lot and reviewed other people's related questions in DevZone, but still have no idea how to fix it, any suggestions?

    I see from your latest log that you receive the -120 error (operation already in progress) from your call to start, but it is hard for me to understand the context from which the bt_enable call was made from the code you have shared alone.
    Could you share your full main.c with me, so that I may take a look?

    Judging by this error message alone I wonder if you might be calling bt_enable elsewhere, such as in your uart_control_sub_thread? If so, please know that you only need to call bt_enable once in your main().

    Junmin said:

    At the same time, I'm trying to take the following discussion as reference,

     nRF5340 Audio DK: LE Audio and UART2 Concurrently 

    Since it's based on NCS 2.20, I'll go down to this version first.

    In this case I would recommend that you instead try the same approach with v2.4, instead of downgrading to v2.2, since there are so many important LE Audio related features and improvements that have been introduced since v2.2.

    Best regards,
    Karl

  • Hello Karl,

    Glad to know you are back from sickness!

    My main.c is as following, just adding several line on the reference application. I tried to comment out bt_enable in my thread, the error code became -112, address already in use.

    /*
     * Copyright (c) 2018 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <zephyr/debug/stack.h>
    #include <zephyr/device.h>
    #include <string.h>
    
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/settings/settings.h>
    #include <zephyr/zbus/zbus.h>
    
    #include "macros_common.h"
    #include "fw_info_app.h"
    #include "led.h"
    #include "button_handler.h"
    #include "button_assignments.h"
    #include "nrfx_clock.h"
    #include "ble_core.h"
    #include "sd_card.h"
    #include "board_version.h"
    #include "audio_system.h"
    #include "channel_assignment.h"
    #include "streamctrl.h"
    //#include "ble_peripheral_uart.h"
    #include "ble_peripheral_iso.h"
    static K_SEM_DEFINE(le_audio_ok, 0, 1);
    
    #if defined(CONFIG_AUDIO_DFU_ENABLE)
    #include "dfu_entry.h"
    #endif
    
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(main, CONFIG_MAIN_LOG_LEVEL);
    
    #if defined(CONFIG_INIT_STACKS)
    /* Used for printing stack usage */
    extern struct k_thread z_main_thread;
    #endif /* defined(CONFIG_INIT_STACKS) */
    
    static atomic_t ble_core_is_ready = (atomic_t) false;
    static struct board_version board_rev;
    
    ZBUS_CHAN_DECLARE(button_chan);
    ZBUS_CHAN_DECLARE(le_audio_chan);
    
    ZBUS_OBS_DECLARE(button_sub);
    ZBUS_OBS_DECLARE(le_audio_evt_sub);
    
    static int hfclock_config_and_start(void)
    {
    	int ret;
    
    	/* Use this to turn on 128 MHz clock for cpu_app */
    	ret = nrfx_clock_divider_set(NRF_CLOCK_DOMAIN_HFCLK, NRF_CLOCK_HFCLK_DIV_1);
    
    	ret -= NRFX_ERROR_BASE_NUM;
    	if (ret) {
    		return ret;
    	}
    
    	nrfx_clock_hfclk_start();
    	while (!nrfx_clock_hfclk_is_running()) {
    	}
    
    	return 0;
    }
    
    static int leds_set(void)
    {
    	int ret;
    
    	/* Blink LED 3 to indicate that APP core is running */
    	ret = led_blink(LED_APP_3_GREEN);
    	if (ret) {
    		return ret;
    	}
    
    #if (CONFIG_AUDIO_DEV == HEADSET)
    	enum audio_channel channel;
    
    	channel_assignment_get(&channel);
    
    	if (channel == AUDIO_CH_L) {
    		ret = led_on(LED_APP_RGB, LED_COLOR_BLUE);
    	} else {
    		ret = led_on(LED_APP_RGB, LED_COLOR_MAGENTA);
    	}
    
    	if (ret) {
    		return ret;
    	}
    #elif (CONFIG_AUDIO_DEV == GATEWAY)
    	ret = led_on(LED_APP_RGB, LED_COLOR_GREEN);
    	if (ret) {
    		return ret;
    	}
    #endif /* (CONFIG_AUDIO_DEV == HEADSET) */
    
    	return 0;
    }
    
    static int bonding_clear_check(void)
    {
    	int ret;
    	bool pressed;
    
    	ret = button_pressed(BUTTON_5, &pressed);
    	if (ret) {
    		return ret;
    	}
    
    	if (pressed) {
    		if (IS_ENABLED(CONFIG_SETTINGS)) {
    			LOG_INF("Clearing all bonds");
    			bt_unpair(BT_ID_DEFAULT, NULL);
    		}
    	}
    	return 0;
    }
    
    static int channel_assign_check(void)
    {
    #if (CONFIG_AUDIO_DEV == HEADSET) && CONFIG_AUDIO_HEADSET_CHANNEL_RUNTIME
    	int ret;
    	bool pressed;
    
    	ret = button_pressed(BUTTON_VOLUME_DOWN, &pressed);
    	if (ret) {
    		return ret;
    	}
    
    	if (pressed) {
    		channel_assignment_set(AUDIO_CH_L);
    		return 0;
    	}
    
    	ret = button_pressed(BUTTON_VOLUME_UP, &pressed);
    	if (ret) {
    		return ret;
    	}
    
    	if (pressed) {
    		channel_assignment_set(AUDIO_CH_R);
    		return 0;
    	}
    #endif
    
    	return 0;
    }
    
    /* Callback from ble_core when the ble subsystem is ready */
    void on_ble_core_ready(void)
    {
    	int ret;
    
    	(void)atomic_set(&ble_core_is_ready, (atomic_t) true);
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    
    		ret = bonding_clear_check();
    		ERR_CHK(ret);
    	}
    
    	k_sem_give(&le_audio_ok); 
    }
    
    int main(void)
    {
    	int ret;
    
    	LOG_DBG("nRF5340 APP core started");
    
    	ret = hfclock_config_and_start();
    	ERR_CHK(ret);
    
    	ret = led_init();
    	ERR_CHK(ret);
    
    	if (IS_ENABLED(CONFIG_ZBUS) && (CONFIG_ZBUS_RUNTIME_OBSERVERS_POOL_SIZE > 0)) {
    		ret = zbus_chan_add_obs(&button_chan, &button_sub, K_MSEC(200));
    		ERR_CHK(ret);
    
    		ret = zbus_chan_add_obs(&le_audio_chan, &le_audio_evt_sub, K_MSEC(200));
    		ERR_CHK(ret);
    	}
    
    	ret = button_handler_init();
    	ERR_CHK(ret);
    
    	channel_assignment_init();
    
    	ret = channel_assign_check();
    	ERR_CHK(ret);
    
    	ret = fw_info_app_print();
    	ERR_CHK(ret);
    
    	ret = board_version_valid_check();
    	ERR_CHK(ret);
    
    	ret = board_version_get(&board_rev);
    	ERR_CHK(ret);
    
    	if (board_rev.mask & BOARD_VERSION_VALID_MSK_SD_CARD) {
    		ret = sd_card_init();
    		if (ret != -ENODEV) {
    			ERR_CHK(ret);
    		}
    	}
    
    #if defined(CONFIG_AUDIO_DFU_ENABLE)
    	/* Check DFU BTN before initialize BLE */
    	dfu_entry_check((void *)ble_core_init);
    #endif
    
    	/* Initialize BLE, with callback for when BLE is ready */
    	ret = ble_core_init(on_ble_core_ready);
    	ERR_CHK(ret);
    
    	/* Wait until ble_core/NET core is ready */
    	while (!(bool)atomic_get(&ble_core_is_ready)) {
    		(void)k_sleep(K_MSEC(100));
    	}
    
    	ret = leds_set();
    	ERR_CHK(ret);
    
    	ret = streamctrl_start();
    	ERR_CHK(ret);
    /**/
        /* Don't go any further until BLE is initialized */
        k_sem_take(&le_audio_ok, K_FOREVER);
    
    	ret = uart_start();
    	ERR_CHK(ret);
    
    }
    

    Another thing I always wonder is that why I can't find nRF5340 audio DK board with nRF Connect mobile, as you know, I want to do volume control with phone app, scanning devices is the first step.

    Thank you for your suggestion to stop trying on v2.2, or I would waste more time on it.

    Best Regards

    Junmin

  • Hello Junmin,

    Junmin said:
    Glad to know you are back from sickness!

    Thank you for saying so! :) 

    Junmin said:
    My main.c is as following, just adding several line on the reference application. I tried to comment out bt_enable in my thread, the error code became -112, address already in use.

    Oh, could you include the code where you have added the nus functionality? I incorrectly assumed that you had this added as a thread towards the end of main.c, but it seems you have that implemented in another file somewhere.

    Junmin said:
    Another thing I always wonder is that why I can't find nRF5340 audio DK board with nRF Connect mobile, as you know, I want to do volume control with phone app, scanning devices is the first step.

    The default nRF5340 LE Audio application will advertise using Direct Advertising in the case that it is already bonded with a peer - could this be the case here?
    Also, I think we will need to resolve the current BLE issues in order to ensure that the regular peripheral advertising actually starts in this case, before we look further into this.

    Junmin said:
    Thank you for your suggestion to stop trying on v2.2, or I would waste more time on it.

    No problem at all, I am happy to help! :) 
    It would be more productive to instead apply the same approach to your v2.4 based project, instead of downgrading to v2.2.

    Best regards,
    Karl

  • Hello Karl,

    You are right, my thread is in another file as following,

    /*
     * Copyright (c) 2021 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr/types.h>
    #include <stddef.h>
    #include <string.h>
    #include <errno.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/sys/byteorder.h>
    #include <zephyr/kernel.h>
    
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/hci.h>
    #include <zephyr/bluetooth/conn.h>
    #include <zephyr/bluetooth/iso.h>
    #include <zephyr/settings/settings.h>
    #include <zephyr/logging/log.h>
    
    #include "led.h"
    #include "macros_common.h"
    
    LOG_MODULE_REGISTER(ble_iso);
    
    #define DEVICE_NAME             "Peripheral"
    #define DEVICE_NAME_LEN         (sizeof(DEVICE_NAME) - 1)
    
    static const struct bt_data ad[] = {
    	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
    	BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
    };
    
    static struct k_work_delayable iso_send_work;
    static struct bt_iso_chan iso_chan;
    static uint16_t seq_num;
    static atomic_t iso_tx_pool_alloc;
    NET_BUF_POOL_FIXED_DEFINE(tx_pool, 1, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), 8,
    			  NULL);
    #define HCI_ISO_BUF_ALLOC_PER_CHAN 2
    
    static void iso_timer_timeout(struct k_work *work)
    {
    	int ret;
    	static uint8_t buf_data[CONFIG_BT_ISO_TX_MTU];
    	struct net_buf *buf;
    	static size_t len_to_send = CONFIG_BT_ISO_TX_MTU;
    	static bool hci_wrn_printed;
    
    	if (atomic_get(&iso_tx_pool_alloc) >= HCI_ISO_BUF_ALLOC_PER_CHAN) {
    		if (!hci_wrn_printed) {
    			LOG_WRN("HCI ISO TX overrun");
    			hci_wrn_printed = true;
    		}
    		return;
    	}
    
    	hci_wrn_printed = false;
    
    	buf = net_buf_alloc(&tx_pool, K_FOREVER);
    	net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
    
    	net_buf_add_mem(buf, buf_data, len_to_send);
    
    	atomic_inc(&iso_tx_pool_alloc);
    	ret = bt_iso_chan_send(&iso_chan, buf, seq_num++, BT_ISO_TIMESTAMP_NONE);
    
    	if (ret < 0) {
    		LOG_INF("Failed to send ISO data (%d)", ret);
    		net_buf_unref(buf);
    		atomic_dec(&iso_tx_pool_alloc);
    	}
    
    	k_work_schedule(&iso_send_work, K_MSEC(10));
    }
    
    static void connected(struct bt_conn *conn, uint8_t err)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (err) {
    		LOG_INF("Failed to connect to %s (%u)", addr, err);
    		return;
    	}
    
    	LOG_INF("Connected %s", addr);
    }
    
    static void disconnected(struct bt_conn *conn, uint8_t reason)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	LOG_INF("Disconnected from %s (reason 0x%02x)", addr, reason);
    }
    
    BT_CONN_CB_DEFINE(conn_callbacks) = {
    	.connected = connected,
    	.disconnected = disconnected,
    };
    
    /** Print data as d_0 d_1 d_2 ... d_(n-2) d_(n-1) d_(n) to show the 3 first and 3 last octets
     *
     * Examples:
     * 01
     * 0102
     * 010203
     * 01020304
     * 0102030405
     * 010203040506
     * 010203...050607
     * 010203...060708
     * etc.
     */
    static void iso_print_data(uint8_t *data, size_t data_len)
    {
    	/* Maximum number of octets from each end of the data */
    	const uint8_t max_octets = 3;
    	char data_str[35];
    	size_t str_len;
    
    	str_len = bin2hex(data, MIN(max_octets, data_len), data_str, sizeof(data_str));
    	if (data_len > max_octets) {
    		if (data_len > (max_octets * 2)) {
    			static const char dots[] = "...";
    
    			strcat(&data_str[str_len], dots);
    			str_len += strlen(dots);
    		}
    
    		str_len += bin2hex(data + (data_len - MIN(max_octets, data_len - max_octets)),
    				   MIN(max_octets, data_len - max_octets),
    				   data_str + str_len,
    				   sizeof(data_str) - str_len);
    	}
    
    	LOG_INF("\t %s", data_str);
    }
    
    static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info,
    		struct net_buf *buf)
    {
    	LOG_INF("Incoming data channel %p len %u", chan, buf->len);
    	iso_print_data(buf->data, buf->len);
    }
    
    static void iso_connected(struct bt_iso_chan *chan)
    {
    	LOG_INF("ISO Channel %p connected", chan);
    	k_work_reschedule(&iso_send_work, K_MSEC(100));
    }
    
    static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
    {
    	LOG_INF("ISO Channel %p disconnected (reason 0x%02x)", chan, reason);
    	k_work_cancel_delayable(&iso_send_work);
    	atomic_clear(&iso_tx_pool_alloc);
    }
    
    static void iso_sent(struct bt_iso_chan *chan)
    {
    	atomic_dec(&iso_tx_pool_alloc);
    }
    
    static struct bt_iso_chan_ops iso_ops = {
    	.recv		= iso_recv,
    	.connected	= iso_connected,
    	.disconnected	= iso_disconnected,
    	.sent = iso_sent,
    };
    
    static struct bt_iso_chan_io_qos iso_tx = {
    	.sdu = CONFIG_BT_ISO_TX_MTU,
    	.path = NULL,
    };
    
    static struct bt_iso_chan_qos iso_qos = {
    	.tx = &iso_tx,
    	.rx = NULL,
    };
    
    static struct bt_iso_chan iso_chan = {
    	.ops = &iso_ops,
    	.qos = &iso_qos,
    };
    
    static int iso_accept(const struct bt_iso_accept_info *info,
    		      struct bt_iso_chan **chan)
    {
    	LOG_INF("Incoming request from %p", (void *)info->acl);
    
    	if (iso_chan.iso) {
    		LOG_INF("No channels available");
    		return -ENOMEM;
    	}
    
    	*chan = &iso_chan;
    
    	return 0;
    }
    
    static struct bt_iso_server iso_server = {
    #if defined(CONFIG_BT_SMP)
    	.sec_level = BT_SECURITY_L1,
    #endif /* CONFIG_BT_SMP */
    	.accept = iso_accept,
    };
    
    static struct k_thread uart_control_sub_thread_data;
    static k_tid_t uart_control_sub_thread_id;
    
    #define CONFIG_UART_CONTROL_SUB_STACK_SIZE 2048
    K_THREAD_STACK_DEFINE(uart_control_sub_thread_stack, CONFIG_UART_CONTROL_SUB_STACK_SIZE);
    
    static void uart_control_sub_thread(void)
    {
    	int err;
    
    	err = bt_enable(NULL);
    	if (err) {
    		LOG_INF("Bluetooth init failed (err %d)", err);
    		return;
    	}
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	LOG_INF("Bluetooth initialized");
    
    	err = bt_iso_server_register(&iso_server);
    	if (err) {
    		LOG_INF("Unable to register ISO server (err %d)", err);
    		return;
    	}
    
    	err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
    	if (err) {
    		LOG_INF("Advertising failed to start (err %d)", err);
    		return;
    	}
    
    	LOG_INF("Advertising successfully started");
    	k_work_init_delayable(&iso_send_work, iso_timer_timeout);
    }
    
    int uart_start(void)
    {
    	int ret;
    
    	uart_control_sub_thread_id =
    		k_thread_create(&uart_control_sub_thread_data, uart_control_sub_thread_stack,
    						CONFIG_UART_CONTROL_SUB_STACK_SIZE,
    						(k_thread_entry_t)uart_control_sub_thread, NULL, NULL, NULL,
    						K_PRIO_PREEMPT(CONFIG_BUTTON_MSG_SUB_THREAD_PRIO), 0, K_NO_WAIT);
    	ret = k_thread_name_set(uart_control_sub_thread_id, "UART_CONTROL_SUB");
    	ERR_CHK(ret);
    
    	ret = led_blink(LED_APP_1_BLUE);
    	ERR_CHK(ret);
    
    	return 0;
    }

    I have tested the nRF5340 LE Audio application with a Pixel 7, it's no problem to scan, bond and stream from the phone, but not vice versa. Also, at least once,I have scanned and bonded the application with nRF Connect mobile from another phone without BLE audio support, however I can't repeat the phenomenon anyhow, maybe a previous SDK version.

    Best regards and have a nice weekend,

    Junmin

Related