mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	bluez5-device: Refactor device_set_update for ASHA & BAP
This commit is contained in:
		
							parent
							
								
									445ca819ce
								
							
						
					
					
						commit
						a419f69bbb
					
				
					 1 changed files with 111 additions and 64 deletions
				
			
		| 
						 | 
				
			
			@ -966,7 +966,76 @@ static const struct spa_bt_transport_events device_set_transport_events = {
 | 
			
		|||
	.destroy = device_set_transport_destroy,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void device_set_update(struct impl *this, struct device_set *dset)
 | 
			
		||||
static void device_set_update_asha(struct impl *this, struct device_set *dset)
 | 
			
		||||
{
 | 
			
		||||
	struct spa_bt_device *device = this->bt_dev;
 | 
			
		||||
	struct spa_bt_set_membership *set;
 | 
			
		||||
	struct spa_bt_set_membership tmp_set = {
 | 
			
		||||
		.device = device,
 | 
			
		||||
		.rank = 0,
 | 
			
		||||
		.leader = true,
 | 
			
		||||
		.path = device->path,
 | 
			
		||||
		.others = SPA_LIST_INIT(&tmp_set.others),
 | 
			
		||||
	};
 | 
			
		||||
	struct spa_list tmp_set_list = SPA_LIST_INIT(&tmp_set_list);
 | 
			
		||||
	struct spa_list *membership_list = &device->set_membership_list;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * If no device set, use a dummy one, so that we can handle also those devices
 | 
			
		||||
	 * here (they may have multiple transports regardless).
 | 
			
		||||
	 */
 | 
			
		||||
	if (spa_list_is_empty(membership_list)) {
 | 
			
		||||
		spa_list_append(&tmp_set_list, &tmp_set.link);
 | 
			
		||||
		membership_list = &tmp_set_list;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spa_list_for_each(set, membership_list, link) {
 | 
			
		||||
		struct spa_bt_set_membership *s;
 | 
			
		||||
		int num_devices = 0;
 | 
			
		||||
 | 
			
		||||
		device_set_clear(this, dset);
 | 
			
		||||
 | 
			
		||||
		spa_bt_for_each_set_member(s, set) {
 | 
			
		||||
			struct spa_bt_transport *t;
 | 
			
		||||
			bool active = false;
 | 
			
		||||
			uint32_t sink_id = DEVICE_ID_SINK;
 | 
			
		||||
 | 
			
		||||
			if (!(s->device->connected_profiles & SPA_BT_PROFILE_ASHA_SINK))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			spa_list_for_each(t, &s->device->transport_list, device_link) {
 | 
			
		||||
				if (!transport_enabled(t, SPA_BT_PROFILE_ASHA_SINK))
 | 
			
		||||
					continue;
 | 
			
		||||
				if (dset->sinks >= SPA_N_ELEMENTS(dset->sink))
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				active = true;
 | 
			
		||||
				dset->leader = set->leader = t->asha_right_side;
 | 
			
		||||
				dset->path = strdup(set->path);
 | 
			
		||||
				dset->sink[dset->sinks].impl = this;
 | 
			
		||||
				dset->sink[dset->sinks].transport = t;
 | 
			
		||||
				dset->sink[dset->sinks].id = sink_id;
 | 
			
		||||
				sink_id += 2;
 | 
			
		||||
				spa_bt_transport_add_listener(t, &dset->sink[dset->sinks].listener,
 | 
			
		||||
						&device_set_transport_events, &dset->sink[dset->sinks]);
 | 
			
		||||
				++dset->sinks;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (active)
 | 
			
		||||
				++num_devices;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		spa_log_debug(this->log, "%p: %s belongs to ASHA set %s leader:%d", this,
 | 
			
		||||
				device->path, set->path, set->leader);
 | 
			
		||||
 | 
			
		||||
		if (num_devices > 1)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dset->sink_enabled = dset->path && (dset->sinks > 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void device_set_update_bap(struct impl *this, struct device_set *dset)
 | 
			
		||||
{
 | 
			
		||||
	struct spa_bt_device *device = this->bt_dev;
 | 
			
		||||
	struct spa_bt_set_membership *set;
 | 
			
		||||
| 
						 | 
				
			
			@ -992,7 +1061,6 @@ static void device_set_update(struct impl *this, struct device_set *dset)
 | 
			
		|||
	spa_list_for_each(set, membership_list, link) {
 | 
			
		||||
		struct spa_bt_set_membership *s;
 | 
			
		||||
		int num_devices = 0;
 | 
			
		||||
		bool is_asha_member = false;
 | 
			
		||||
 | 
			
		||||
		device_set_clear(this, dset);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1001,71 +1069,44 @@ static void device_set_update(struct impl *this, struct device_set *dset)
 | 
			
		|||
			bool active = false;
 | 
			
		||||
			uint32_t source_id = DEVICE_ID_SOURCE;
 | 
			
		||||
			uint32_t sink_id = DEVICE_ID_SINK;
 | 
			
		||||
			bool bap_duplex = s->device->connected_profiles & SPA_BT_PROFILE_BAP_DUPLEX;
 | 
			
		||||
			bool is_asha = s->device->connected_profiles & SPA_BT_PROFILE_ASHA_SINK;
 | 
			
		||||
 | 
			
		||||
			if (!bap_duplex && !is_asha)
 | 
			
		||||
			if (!(s->device->connected_profiles & SPA_BT_PROFILE_BAP_DUPLEX))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (is_asha) {
 | 
			
		||||
				spa_list_for_each(t, &s->device->transport_list, device_link) {
 | 
			
		||||
					if (!(s->device->connected_profiles & SPA_BT_PROFILE_ASHA_SINK))
 | 
			
		||||
						continue;
 | 
			
		||||
					if (!transport_enabled(t, SPA_BT_PROFILE_ASHA_SINK))
 | 
			
		||||
						continue;
 | 
			
		||||
					if (dset->sinks >= SPA_N_ELEMENTS(dset->sink))
 | 
			
		||||
						break;
 | 
			
		||||
			spa_list_for_each(t, &s->device->transport_list, device_link) {
 | 
			
		||||
				if (!(s->device->connected_profiles & SPA_BT_PROFILE_BAP_SOURCE))
 | 
			
		||||
					continue;
 | 
			
		||||
				if (!transport_enabled(t, SPA_BT_PROFILE_BAP_SOURCE))
 | 
			
		||||
					continue;
 | 
			
		||||
				if (dset->sources >= SPA_N_ELEMENTS(dset->source))
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
					active = true;
 | 
			
		||||
					is_asha_member = true;
 | 
			
		||||
					dset->leader = set->leader = t->asha_right_side;
 | 
			
		||||
					dset->path = strdup(set->path);
 | 
			
		||||
					dset->sink[dset->sinks].impl = this;
 | 
			
		||||
					dset->sink[dset->sinks].transport = t;
 | 
			
		||||
					dset->sink[dset->sinks].id = sink_id;
 | 
			
		||||
					sink_id += 2;
 | 
			
		||||
					spa_bt_transport_add_listener(t, &dset->sink[dset->sinks].listener,
 | 
			
		||||
							&device_set_transport_events, &dset->sink[dset->sinks]);
 | 
			
		||||
					++dset->sinks;
 | 
			
		||||
				}
 | 
			
		||||
				active = true;
 | 
			
		||||
				dset->source[dset->sources].impl = this;
 | 
			
		||||
				dset->source[dset->sources].transport = t;
 | 
			
		||||
				dset->source[dset->sources].id = source_id;
 | 
			
		||||
				source_id += 2;
 | 
			
		||||
				spa_bt_transport_add_listener(t, &dset->source[dset->sources].listener,
 | 
			
		||||
						&device_set_transport_events, &dset->source[dset->sources]);
 | 
			
		||||
				++dset->sources;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (bap_duplex) {
 | 
			
		||||
				spa_list_for_each(t, &s->device->transport_list, device_link) {
 | 
			
		||||
					if (!(s->device->connected_profiles & SPA_BT_PROFILE_BAP_SOURCE))
 | 
			
		||||
						continue;
 | 
			
		||||
					if (!transport_enabled(t, SPA_BT_PROFILE_BAP_SOURCE))
 | 
			
		||||
						continue;
 | 
			
		||||
					if (dset->sources >= SPA_N_ELEMENTS(dset->source))
 | 
			
		||||
						break;
 | 
			
		||||
			spa_list_for_each(t, &s->device->transport_list, device_link) {
 | 
			
		||||
				if (!(s->device->connected_profiles & SPA_BT_PROFILE_BAP_SINK))
 | 
			
		||||
					continue;
 | 
			
		||||
				if (!transport_enabled(t, SPA_BT_PROFILE_BAP_SINK))
 | 
			
		||||
					continue;
 | 
			
		||||
				if (dset->sinks >= SPA_N_ELEMENTS(dset->sink))
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
					active = true;
 | 
			
		||||
					dset->source[dset->sources].impl = this;
 | 
			
		||||
					dset->source[dset->sources].transport = t;
 | 
			
		||||
					dset->source[dset->sources].id = source_id;
 | 
			
		||||
					source_id += 2;
 | 
			
		||||
					spa_bt_transport_add_listener(t, &dset->source[dset->sources].listener,
 | 
			
		||||
							&device_set_transport_events, &dset->source[dset->sources]);
 | 
			
		||||
					++dset->sources;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				spa_list_for_each(t, &s->device->transport_list, device_link) {
 | 
			
		||||
					if (!(s->device->connected_profiles & SPA_BT_PROFILE_BAP_SINK))
 | 
			
		||||
						continue;
 | 
			
		||||
					if (!transport_enabled(t, SPA_BT_PROFILE_BAP_SINK))
 | 
			
		||||
						continue;
 | 
			
		||||
					if (dset->sinks >= SPA_N_ELEMENTS(dset->sink))
 | 
			
		||||
						break;
 | 
			
		||||
 | 
			
		||||
					active = true;
 | 
			
		||||
					dset->sink[dset->sinks].impl = this;
 | 
			
		||||
					dset->sink[dset->sinks].transport = t;
 | 
			
		||||
					dset->sink[dset->sinks].id = sink_id;
 | 
			
		||||
					sink_id += 2;
 | 
			
		||||
					spa_bt_transport_add_listener(t, &dset->sink[dset->sinks].listener,
 | 
			
		||||
							&device_set_transport_events, &dset->sink[dset->sinks]);
 | 
			
		||||
					++dset->sinks;
 | 
			
		||||
				}
 | 
			
		||||
				active = true;
 | 
			
		||||
				dset->sink[dset->sinks].impl = this;
 | 
			
		||||
				dset->sink[dset->sinks].transport = t;
 | 
			
		||||
				dset->sink[dset->sinks].id = sink_id;
 | 
			
		||||
				sink_id += 2;
 | 
			
		||||
				spa_bt_transport_add_listener(t, &dset->sink[dset->sinks].listener,
 | 
			
		||||
						&device_set_transport_events, &dset->sink[dset->sinks]);
 | 
			
		||||
				++dset->sinks;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (active)
 | 
			
		||||
| 
						 | 
				
			
			@ -1082,10 +1123,8 @@ static void device_set_update(struct impl *this, struct device_set *dset)
 | 
			
		|||
			/* XXX: device set nodes for BAP server not supported,
 | 
			
		||||
			 * XXX: it'll appear as multiple streams
 | 
			
		||||
			 */
 | 
			
		||||
			if (!is_asha_member) {
 | 
			
		||||
				dset->path = NULL;
 | 
			
		||||
				dset->leader = false;
 | 
			
		||||
			}
 | 
			
		||||
			dset->path = NULL;
 | 
			
		||||
			dset->leader = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (num_devices > 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -1096,6 +1135,14 @@ static void device_set_update(struct impl *this, struct device_set *dset)
 | 
			
		|||
	dset->source_enabled = dset->path && (dset->sources > 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void device_set_update(struct impl *this, struct device_set *dset)
 | 
			
		||||
{
 | 
			
		||||
	if (this->profile == DEVICE_PROFILE_BAP)
 | 
			
		||||
		device_set_update_bap(this, dset);
 | 
			
		||||
	else if (this->profile == DEVICE_PROFILE_ASHA)
 | 
			
		||||
		device_set_update_asha(this, dset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool device_set_equal(struct device_set *a, struct device_set *b)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue