nus_send_enabled_cb invoked before connected

Hi

In my firmware, i setup a NUS service, piece of code as below:

...

static struct bt_nus_cb nus_cb = {
	.sent = nus_sent_cb,
	.send_enabled = nus_send_enabled_cb,
	.received = nus_receive_cb,
};

...

static struct bt_conn_cb conn_callbacks = {
    .connected = connected,
    .disconnected = disconnected,
    .le_param_req = le_param_req,
    .le_param_updated = le_param_updated,

#if defined(CONFIG_BT_SMP)
    .security_changed = security_changed,
#endif /* CONFIG_BT_SMP */

#if defined(CONFIG_BT_USER_PHY_UPDATE)
    .le_phy_updated = le_phy_updated,
#endif /* CONFIG_BT_USER_PHY_UPDATE */

#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE)
    .le_data_len_updated = le_data_len_updated,
#endif /* CONFIG_BT_USER_DATA_LEN_UPDATE */
};

...

int main()
{
...
    bt_conn_cb_register(&conn_callbacks);
...
    bt_nus_init(&nus_cb);
...
}

I found that the nus_send_enabled_cb function is always invoked before connected function in ncs sdk v2.0.0.

In my mind, it should be connected first, then ccc_cfg_changed of service can be called. Is it right?

logo
Parents Reply Children
  • Hi, Hung Bui

    Our project integrated Multi-link and Central and Peripheral role features.

    There are some reference codes, 

    static void connected(struct bt_conn *conn, uint8_t conn_err)
    {
    	char addr[BT_ADDR_LE_STR_LEN];
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	struct bt_conn_info info;
    	bt_conn_get_info(conn, &info);
    
    	if (conn_err) {
    		LOG_WRN("Failed to connect to %s error %u", log_strdup(addr), conn_err);
    		if(info.role == BT_CONN_ROLE_CENTRAL) {
    			start_scan();
    			return;
    		}
    	}
    
    	struct bt_conn *cur_conn = bt_conn_ref(conn);
    
    	if(info.role == BT_CONN_ROLE_CENTRAL) {
    
    		central_conn_count++;
    		LOG_INF("CENTRAL(%u), connected: %s", central_conn_count, log_strdup(addr));
    
    	} else {
    
    		peripheral_conn_count++;
    
    		peri_conn = cur_conn;
    		
    		LOG_INF("PERIPHERAL(%u), connected: %s", peripheral_conn_count, log_strdup(addr));
    
    		request_security(conn);
    	}
    
    #if defined(CONFIG_BT_GATT_CLIENT)
    	mtu_exchange(conn);
    #endif
    }
    
    
    static void discovery_completed_cb(struct bt_gatt_dm *dm, void *context)
    {
    	int err;
    	char uuid_str[37];
    
    	const struct bt_gatt_dm_attr *gatt_service_attr = bt_gatt_dm_service_get(dm);
    	const struct bt_gatt_service_val *gatt_service = bt_gatt_dm_attr_service_val(gatt_service_attr);
    
    	size_t attr_count = bt_gatt_dm_attr_cnt(dm);
    
    	bt_uuid_to_str(gatt_service->uuid, uuid_str, sizeof(uuid_str));
    	//LOG_INF("Discovery found service %s, attribute count %d", log_strdup(uuid_str), attr_count);
    
    
    	struct bt_conn* conn = bt_gatt_dm_conn_get(dm);
    	struct bt_conn_info info;
    	bt_conn_get_info(conn, &info);
    	uint8_t conn_index = bt_conn_index(conn);
    
    	if(info.role == BT_CONN_ROLE_CENTRAL) {
    
    		if(bt_uuid_cmp(gatt_service->uuid, BT_UUID_NUS_SERVICE) == 0) {
    
    			LOG_INF("Discovery found NUS...");
    
    			err = bt_nus_handles_assign(dm, &nus_clients[conn_index]);
    			if (err) {
    				LOG_WRN("Could not assign nus client object: err %d", err);
    			}
    
    			err = bt_nus_subscribe_receive(&nus_clients[conn_index]);
    
    		} else if(bt_uuid_cmp(gatt_service->uuid, BT_UUID_ANCS) == 0) {
    
    		}
    	}
    
    	bt_gatt_dm_data_print(dm);
    	bt_gatt_dm_data_release(dm);
    
    	bt_gatt_dm_continue(dm, NULL);
    }
    static void nus_send_enabled_cb(enum bt_nus_send_status status)
    {
    	LOG_INF("nus send status changed: %d", (status==BT_NUS_SEND_STATUS_ENABLED));
    }

    You can see that the bt_nus_subscribe_receive function will not be called until the NUS service was found in the Central unit.

    The log is from the Peripheral unit:

Related