mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	bluez5: telephony: add Address property on the AudioGateway interface
This allows associating the AG with a remote device on higher level software.
This commit is contained in:
		
							parent
							
								
									a0356cf4ae
								
							
						
					
					
						commit
						7de0419ca3
					
				
					 3 changed files with 90 additions and 36 deletions
				
			
		| 
						 | 
					@ -2159,6 +2159,7 @@ static bool rfcomm_hfp_hf(struct rfcomm *rfcomm, char* token)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			rfcomm->telephony_ag = telephony_ag_new(backend->telephony, 0);
 | 
								rfcomm->telephony_ag = telephony_ag_new(backend->telephony, 0);
 | 
				
			||||||
 | 
								rfcomm->telephony_ag->address = strdup(rfcomm->device->address);
 | 
				
			||||||
			telephony_ag_set_callbacks(rfcomm->telephony_ag,
 | 
								telephony_ag_set_callbacks(rfcomm->telephony_ag,
 | 
				
			||||||
						  &telephony_ag_callbacks, rfcomm);
 | 
											  &telephony_ag_callbacks, rfcomm);
 | 
				
			||||||
			if (rfcomm->transport) {
 | 
								if (rfcomm->transport) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -114,6 +114,9 @@
 | 
				
			||||||
	"<node>"		 						\
 | 
						"<node>"		 						\
 | 
				
			||||||
	" <interface name='" PW_TELEPHONY_AG_IFACE "'>"				\
 | 
						" <interface name='" PW_TELEPHONY_AG_IFACE "'>"				\
 | 
				
			||||||
	PW_TELEPHONY_AG_COMMON_INTROSPECT_XML					\
 | 
						PW_TELEPHONY_AG_COMMON_INTROSPECT_XML					\
 | 
				
			||||||
 | 
						"  <property name='Address' type='s' access='read'>"			\
 | 
				
			||||||
 | 
						"    <annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='const'/>" \
 | 
				
			||||||
 | 
						"  </property>"								\
 | 
				
			||||||
	" </interface>"								\
 | 
						" </interface>"								\
 | 
				
			||||||
	" <interface name='" PW_TELEPHONY_AG_TRANSPORT_IFACE "'>"		\
 | 
						" <interface name='" PW_TELEPHONY_AG_TRANSPORT_IFACE "'>"		\
 | 
				
			||||||
	"  <property name='State' type='s' access='read'/>"			\
 | 
						"  <property name='State' type='s' access='read'/>"			\
 | 
				
			||||||
| 
						 | 
					@ -489,6 +492,33 @@ static const char * const * transport_state_to_string(int state)
 | 
				
			||||||
	return &state_str[state + 1];
 | 
						return &state_str[state + 1];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool
 | 
				
			||||||
 | 
					dbus_iter_append_ag_properties(DBusMessageIter *i, struct spa_bt_telephony_ag *ag, bool all)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DBusMessageIter dict, entry, variant;
 | 
				
			||||||
 | 
						bool changed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "{sv}", &dict);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Address must be set before registering and never changes,
 | 
				
			||||||
 | 
						   so there is no need to check for changes here */
 | 
				
			||||||
 | 
						if (all) {
 | 
				
			||||||
 | 
							dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
 | 
				
			||||||
 | 
							const char *name = "Address";
 | 
				
			||||||
 | 
							dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &name);
 | 
				
			||||||
 | 
							dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
 | 
				
			||||||
 | 
											DBUS_TYPE_STRING_AS_STRING,
 | 
				
			||||||
 | 
											&variant);
 | 
				
			||||||
 | 
							dbus_message_iter_append_basic(&variant, DBUS_TYPE_STRING, &ag->address);
 | 
				
			||||||
 | 
							dbus_message_iter_close_container(&entry, &variant);
 | 
				
			||||||
 | 
							dbus_message_iter_close_container(&dict, &entry);
 | 
				
			||||||
 | 
							changed = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dbus_message_iter_close_container(i, &dict);
 | 
				
			||||||
 | 
						return changed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool
 | 
					static bool
 | 
				
			||||||
dbus_iter_append_ag_transport_properties(DBusMessageIter *i, struct spa_bt_telephony_ag *ag, bool all)
 | 
					dbus_iter_append_ag_transport_properties(DBusMessageIter *i, struct spa_bt_telephony_ag *ag, bool all)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -533,7 +563,7 @@ static void
 | 
				
			||||||
dbus_iter_append_ag_interfaces(DBusMessageIter *i, struct spa_bt_telephony_ag *ag)
 | 
					dbus_iter_append_ag_interfaces(DBusMessageIter *i, struct spa_bt_telephony_ag *ag)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct agimpl *agimpl = SPA_CONTAINER_OF(ag, struct agimpl, this);
 | 
						struct agimpl *agimpl = SPA_CONTAINER_OF(ag, struct agimpl, this);
 | 
				
			||||||
	DBusMessageIter entry, dict, props_dict;
 | 
						DBusMessageIter entry, dict;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbus_message_iter_append_basic(i, DBUS_TYPE_OBJECT_PATH, &agimpl->path);
 | 
						dbus_message_iter_append_basic(i, DBUS_TYPE_OBJECT_PATH, &agimpl->path);
 | 
				
			||||||
	dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "{sa{sv}}", &dict);
 | 
						dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "{sa{sv}}", &dict);
 | 
				
			||||||
| 
						 | 
					@ -541,8 +571,7 @@ dbus_iter_append_ag_interfaces(DBusMessageIter *i, struct spa_bt_telephony_ag *a
 | 
				
			||||||
	const char *interface = PW_TELEPHONY_AG_IFACE;
 | 
						const char *interface = PW_TELEPHONY_AG_IFACE;
 | 
				
			||||||
	dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
 | 
						dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
 | 
				
			||||||
	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &interface);
 | 
						dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &interface);
 | 
				
			||||||
	dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY, "{sv}", &props_dict);
 | 
						dbus_iter_append_ag_properties(&entry, ag, true);
 | 
				
			||||||
	dbus_message_iter_close_container(&entry, &props_dict);
 | 
					 | 
				
			||||||
	dbus_message_iter_close_container(&dict, &entry);
 | 
						dbus_message_iter_close_container(&dict, &entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const char *interface2 = PW_TELEPHONY_AG_TRANSPORT_IFACE;
 | 
						const char *interface2 = PW_TELEPHONY_AG_TRANSPORT_IFACE;
 | 
				
			||||||
| 
						 | 
					@ -611,32 +640,46 @@ static DBusMessage *ag_properties_get(struct agimpl *agimpl, DBusMessage *m)
 | 
				
			||||||
				DBUS_TYPE_INVALID))
 | 
									DBUS_TYPE_INVALID))
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (spa_streq(iface, PW_TELEPHONY_AG_TRANSPORT_IFACE))
 | 
						if (spa_streq(iface, PW_TELEPHONY_AG_IFACE)) {
 | 
				
			||||||
 | 
							if (spa_streq(name, "Address")) {
 | 
				
			||||||
 | 
								r = dbus_message_new_method_return(m);
 | 
				
			||||||
 | 
								if (r == NULL)
 | 
				
			||||||
 | 
									return NULL;
 | 
				
			||||||
 | 
								dbus_message_iter_init_append(r, &i);
 | 
				
			||||||
 | 
								dbus_message_iter_open_container(&i, DBUS_TYPE_VARIANT,
 | 
				
			||||||
 | 
										DBUS_TYPE_STRING_AS_STRING, &v);
 | 
				
			||||||
 | 
								dbus_message_iter_append_basic(&v, DBUS_TYPE_STRING,
 | 
				
			||||||
 | 
										&agimpl->this.address);
 | 
				
			||||||
 | 
								dbus_message_iter_close_container(&i, &v);
 | 
				
			||||||
 | 
								return r;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (spa_streq(iface, PW_TELEPHONY_AG_TRANSPORT_IFACE)) {
 | 
				
			||||||
 | 
							if (spa_streq(name, "Codec")) {
 | 
				
			||||||
 | 
								r = dbus_message_new_method_return(m);
 | 
				
			||||||
 | 
								if (r == NULL)
 | 
				
			||||||
 | 
									return NULL;
 | 
				
			||||||
 | 
								dbus_message_iter_init_append(r, &i);
 | 
				
			||||||
 | 
								dbus_message_iter_open_container(&i, DBUS_TYPE_VARIANT,
 | 
				
			||||||
 | 
										DBUS_TYPE_BYTE_AS_STRING, &v);
 | 
				
			||||||
 | 
								dbus_message_iter_append_basic(&v, DBUS_TYPE_BYTE,
 | 
				
			||||||
 | 
										&agimpl->this.transport.codec);
 | 
				
			||||||
 | 
								dbus_message_iter_close_container(&i, &v);
 | 
				
			||||||
 | 
								return r;
 | 
				
			||||||
 | 
							} else if (spa_streq(name, "State")) {
 | 
				
			||||||
 | 
								r = dbus_message_new_method_return(m);
 | 
				
			||||||
 | 
								if (r == NULL)
 | 
				
			||||||
 | 
									return NULL;
 | 
				
			||||||
 | 
								dbus_message_iter_init_append(r, &i);
 | 
				
			||||||
 | 
								dbus_message_iter_open_container(&i, DBUS_TYPE_VARIANT,
 | 
				
			||||||
 | 
										DBUS_TYPE_STRING_AS_STRING, &v);
 | 
				
			||||||
 | 
								dbus_message_iter_append_basic(&v, DBUS_TYPE_STRING,
 | 
				
			||||||
 | 
										transport_state_to_string(agimpl->this.transport.state));
 | 
				
			||||||
 | 
								dbus_message_iter_close_container(&i, &v);
 | 
				
			||||||
 | 
								return r;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		return dbus_message_new_error(m, DBUS_ERROR_UNKNOWN_INTERFACE,
 | 
							return dbus_message_new_error(m, DBUS_ERROR_UNKNOWN_INTERFACE,
 | 
				
			||||||
				"No such interface");
 | 
									"No such interface");
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (spa_streq(name, "Codec")) {
 | 
					 | 
				
			||||||
		r = dbus_message_new_method_return(m);
 | 
					 | 
				
			||||||
		if (r == NULL)
 | 
					 | 
				
			||||||
			return NULL;
 | 
					 | 
				
			||||||
		dbus_message_iter_init_append(r, &i);
 | 
					 | 
				
			||||||
		dbus_message_iter_open_container(&i, DBUS_TYPE_VARIANT,
 | 
					 | 
				
			||||||
				DBUS_TYPE_BYTE_AS_STRING, &v);
 | 
					 | 
				
			||||||
		dbus_message_iter_append_basic(&v, DBUS_TYPE_BYTE,
 | 
					 | 
				
			||||||
				&agimpl->this.transport.codec);
 | 
					 | 
				
			||||||
		dbus_message_iter_close_container(&i, &v);
 | 
					 | 
				
			||||||
		return r;
 | 
					 | 
				
			||||||
	} else if (spa_streq(name, "State")) {
 | 
					 | 
				
			||||||
		r = dbus_message_new_method_return(m);
 | 
					 | 
				
			||||||
		if (r == NULL)
 | 
					 | 
				
			||||||
			return NULL;
 | 
					 | 
				
			||||||
		dbus_message_iter_init_append(r, &i);
 | 
					 | 
				
			||||||
		dbus_message_iter_open_container(&i, DBUS_TYPE_VARIANT,
 | 
					 | 
				
			||||||
				DBUS_TYPE_STRING_AS_STRING, &v);
 | 
					 | 
				
			||||||
		dbus_message_iter_append_basic(&v, DBUS_TYPE_STRING,
 | 
					 | 
				
			||||||
				transport_state_to_string(agimpl->this.transport.state));
 | 
					 | 
				
			||||||
		dbus_message_iter_close_container(&i, &v);
 | 
					 | 
				
			||||||
		return r;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return dbus_message_new_error(m, DBUS_ERROR_UNKNOWN_PROPERTY,
 | 
						return dbus_message_new_error(m, DBUS_ERROR_UNKNOWN_PROPERTY,
 | 
				
			||||||
| 
						 | 
					@ -654,17 +697,24 @@ static DBusMessage *ag_properties_get_all(struct agimpl *agimpl, DBusMessage *m)
 | 
				
			||||||
				DBUS_TYPE_INVALID))
 | 
									DBUS_TYPE_INVALID))
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!spa_streq(iface, PW_TELEPHONY_AG_TRANSPORT_IFACE))
 | 
						if (spa_streq(iface, PW_TELEPHONY_AG_IFACE)) {
 | 
				
			||||||
 | 
							r = dbus_message_new_method_return(m);
 | 
				
			||||||
 | 
							if (r == NULL)
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							dbus_message_iter_init_append(r, &i);
 | 
				
			||||||
 | 
							dbus_iter_append_ag_properties(&i, &agimpl->this, true);
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						} else if (spa_streq(iface, PW_TELEPHONY_AG_TRANSPORT_IFACE)) {
 | 
				
			||||||
 | 
							r = dbus_message_new_method_return(m);
 | 
				
			||||||
 | 
							if (r == NULL)
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
							dbus_message_iter_init_append(r, &i);
 | 
				
			||||||
 | 
							dbus_iter_append_ag_transport_properties(&i, &agimpl->this, true);
 | 
				
			||||||
 | 
							return r;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		return dbus_message_new_error(m, DBUS_ERROR_UNKNOWN_INTERFACE,
 | 
							return dbus_message_new_error(m, DBUS_ERROR_UNKNOWN_INTERFACE,
 | 
				
			||||||
				"No such interface");
 | 
									"No such interface");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	r = dbus_message_new_method_return(m);
 | 
					 | 
				
			||||||
	if (r == NULL)
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dbus_message_iter_init_append(r, &i);
 | 
					 | 
				
			||||||
	dbus_iter_append_ag_transport_properties(&i, &agimpl->this, true);
 | 
					 | 
				
			||||||
	return r;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusMessage *ag_properties_set(struct agimpl *agimpl, DBusMessage *m)
 | 
					static DBusMessage *ag_properties_set(struct agimpl *agimpl, DBusMessage *m)
 | 
				
			||||||
| 
						 | 
					@ -934,6 +984,8 @@ void telephony_ag_destroy(struct spa_bt_telephony_ag *ag)
 | 
				
			||||||
	telephony_ag_unregister(ag);
 | 
						telephony_ag_unregister(ag);
 | 
				
			||||||
	spa_list_remove(&agimpl->link);
 | 
						spa_list_remove(&agimpl->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free(ag->address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(agimpl);
 | 
						free(agimpl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,6 +42,7 @@ struct spa_bt_telephony_ag {
 | 
				
			||||||
	int id;
 | 
						int id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* D-Bus properties */
 | 
						/* D-Bus properties */
 | 
				
			||||||
 | 
						char *address;
 | 
				
			||||||
	struct spa_bt_telephony_ag_transport transport;
 | 
						struct spa_bt_telephony_ag_transport transport;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue