mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	bluez5: use callback table in hsp/hfp backends
This commit is contained in:
		
							parent
							
								
									18eccf4289
								
							
						
					
					
						commit
						e18df4e344
					
				
					 5 changed files with 210 additions and 142 deletions
				
			
		| 
						 | 
					@ -40,7 +40,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NAME "hsphfpd"
 | 
					#define NAME "hsphfpd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct spa_bt_backend {
 | 
					struct impl {
 | 
				
			||||||
 | 
						struct spa_bt_backend this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_bt_monitor *monitor;
 | 
						struct spa_bt_monitor *monitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_log *log;
 | 
						struct spa_log *log;
 | 
				
			||||||
| 
						 | 
					@ -169,7 +171,7 @@ struct hsphfpd_endpoint {
 | 
				
			||||||
#define HSPHFPD_ERROR_REJECTED            HSPHFPD_SERVICE ".Error.Rejected"
 | 
					#define HSPHFPD_ERROR_REJECTED            HSPHFPD_SERVICE ".Error.Rejected"
 | 
				
			||||||
#define HSPHFPD_ERROR_CANCELED            HSPHFPD_SERVICE ".Error.Canceled"
 | 
					#define HSPHFPD_ERROR_CANCELED            HSPHFPD_SERVICE ".Error.Canceled"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct hsphfpd_endpoint *endpoint_find(struct spa_bt_backend *backend, const char *path)
 | 
					static struct hsphfpd_endpoint *endpoint_find(struct impl *backend, const char *path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct hsphfpd_endpoint *d;
 | 
						struct hsphfpd_endpoint *d;
 | 
				
			||||||
	spa_list_for_each(d, &backend->endpoint_list, link)
 | 
						spa_list_for_each(d, &backend->endpoint_list, link)
 | 
				
			||||||
| 
						 | 
					@ -197,7 +199,7 @@ static bool hsphfpd_cmp_transport_path(struct spa_bt_transport *t, const void *d
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int set_dbus_property(struct spa_bt_backend *backend,
 | 
					static int set_dbus_property(struct impl *backend,
 | 
				
			||||||
                             const char *service,
 | 
					                             const char *service,
 | 
				
			||||||
                             const char *path,
 | 
					                             const char *path,
 | 
				
			||||||
                             const char *interface,
 | 
					                             const char *interface,
 | 
				
			||||||
| 
						 | 
					@ -239,7 +241,7 @@ static int set_dbus_property(struct spa_bt_backend *backend,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void set_rx_volume_gain_property(const struct spa_bt_transport *transport, uint16_t gain)
 | 
					static inline void set_rx_volume_gain_property(const struct spa_bt_transport *transport, uint16_t gain)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = transport->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
 | 
				
			||||||
	struct hsphfpd_transport_data *transport_data = transport->user_data;
 | 
						struct hsphfpd_transport_data *transport_data = transport->user_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (transport->fd < 0 || transport_data->rx_volume_control <= HSPHFPD_VOLUME_CONTROL_NONE)
 | 
						if (transport->fd < 0 || transport_data->rx_volume_control <= HSPHFPD_VOLUME_CONTROL_NONE)
 | 
				
			||||||
| 
						 | 
					@ -253,7 +255,7 @@ static inline void set_rx_volume_gain_property(const struct spa_bt_transport *tr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void set_tx_volume_gain_property(const struct spa_bt_transport *transport, uint16_t gain)
 | 
					static inline void set_tx_volume_gain_property(const struct spa_bt_transport *transport, uint16_t gain)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = transport->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
 | 
				
			||||||
	struct hsphfpd_transport_data *transport_data = transport->user_data;
 | 
						struct hsphfpd_transport_data *transport_data = transport->user_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (transport->fd < 0 || transport_data->tx_volume_control <= HSPHFPD_VOLUME_CONTROL_NONE)
 | 
						if (transport->fd < 0 || transport_data->tx_volume_control <= HSPHFPD_VOLUME_CONTROL_NONE)
 | 
				
			||||||
| 
						 | 
					@ -265,7 +267,7 @@ static inline void set_tx_volume_gain_property(const struct spa_bt_transport *tr
 | 
				
			||||||
		              (unsigned)gain, transport_data->transport_path);
 | 
							              (unsigned)gain, transport_data->transport_path);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void parse_transport_properties_values(struct spa_bt_backend *backend,
 | 
					static void parse_transport_properties_values(struct impl *backend,
 | 
				
			||||||
                                              const char *transport_path,
 | 
					                                              const char *transport_path,
 | 
				
			||||||
                                              DBusMessageIter *i,
 | 
					                                              DBusMessageIter *i,
 | 
				
			||||||
                                              const char **endpoint_path,
 | 
					                                              const char **endpoint_path,
 | 
				
			||||||
| 
						 | 
					@ -352,7 +354,7 @@ static void parse_transport_properties_values(struct spa_bt_backend *backend,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void hsphfpd_parse_transport_properties(struct spa_bt_backend *backend, struct spa_bt_transport *transport, DBusMessageIter *i)
 | 
					static void hsphfpd_parse_transport_properties(struct impl *backend, struct spa_bt_transport *transport, DBusMessageIter *i)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct hsphfpd_transport_data *transport_data = transport->user_data;
 | 
						struct hsphfpd_transport_data *transport_data = transport->user_data;
 | 
				
			||||||
	const char *endpoint_path = NULL;
 | 
						const char *endpoint_path = NULL;
 | 
				
			||||||
| 
						 | 
					@ -552,7 +554,7 @@ fail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBusMessage *m, const char *path, void *userdata)
 | 
					static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBusMessage *m, const char *path, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = userdata;
 | 
						struct impl *backend = userdata;
 | 
				
			||||||
	DBusMessageIter arg_i;
 | 
						DBusMessageIter arg_i;
 | 
				
			||||||
	const char *transport_path;
 | 
						const char *transport_path;
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
| 
						 | 
					@ -731,7 +733,7 @@ fail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult audio_agent_endpoint_handler(DBusConnection *c, DBusMessage *m, void *userdata)
 | 
					static DBusHandlerResult audio_agent_endpoint_handler(DBusConnection *c, DBusMessage *m, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = userdata;
 | 
						struct impl *backend = userdata;
 | 
				
			||||||
	const char *path, *interface, *member;
 | 
						const char *path, *interface, *member;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
	DBusHandlerResult res;
 | 
						DBusHandlerResult res;
 | 
				
			||||||
| 
						 | 
					@ -797,7 +799,7 @@ static void append_audio_agent_object(DBusMessageIter *iter, const char *endpoin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult application_object_manager_handler(DBusConnection *c, DBusMessage *m, void *userdata)
 | 
					static DBusHandlerResult application_object_manager_handler(DBusConnection *c, DBusMessage *m, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = userdata;
 | 
						struct impl *backend = userdata;
 | 
				
			||||||
	const char *path, *interface, *member;
 | 
						const char *path, *interface, *member;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -840,7 +842,7 @@ static DBusHandlerResult application_object_manager_handler(DBusConnection *c, D
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void hsphfpd_audio_acquire_reply(DBusPendingCall *pending, void *user_data)
 | 
					static void hsphfpd_audio_acquire_reply(DBusPendingCall *pending, void *user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = user_data;
 | 
						struct impl *backend = user_data;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
	const char *transport_path;
 | 
						const char *transport_path;
 | 
				
			||||||
	const char *service_id;
 | 
						const char *service_id;
 | 
				
			||||||
| 
						 | 
					@ -895,7 +897,7 @@ finish:
 | 
				
			||||||
static int hsphfpd_audio_acquire(void *data, bool optional)
 | 
					static int hsphfpd_audio_acquire(void *data, bool optional)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_transport *transport = data;
 | 
						struct spa_bt_transport *transport = data;
 | 
				
			||||||
	struct spa_bt_backend *backend = transport->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
 | 
				
			||||||
	DBusMessage *m;
 | 
						DBusMessage *m;
 | 
				
			||||||
	const char *air_codec = HSPHFP_AIR_CODEC_CVSD;
 | 
						const char *air_codec = HSPHFP_AIR_CODEC_CVSD;
 | 
				
			||||||
	const char *agent_codec = HSPHFP_AGENT_CODEC_PCM;
 | 
						const char *agent_codec = HSPHFP_AGENT_CODEC_PCM;
 | 
				
			||||||
| 
						 | 
					@ -940,7 +942,7 @@ static int hsphfpd_audio_acquire(void *data, bool optional)
 | 
				
			||||||
static int hsphfpd_audio_release(void *data)
 | 
					static int hsphfpd_audio_release(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_transport *transport = data;
 | 
						struct spa_bt_transport *transport = data;
 | 
				
			||||||
	struct spa_bt_backend *backend = transport->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
 | 
				
			||||||
	struct hsphfpd_transport_data *transport_data = transport->user_data;
 | 
						struct hsphfpd_transport_data *transport_data = transport->user_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_debug(backend->log, NAME": transport %p: Release %s",
 | 
						spa_log_debug(backend->log, NAME": transport %p: Release %s",
 | 
				
			||||||
| 
						 | 
					@ -983,7 +985,7 @@ static const struct spa_bt_transport_implementation hsphfpd_transport_impl = {
 | 
				
			||||||
	.destroy = hsphfpd_audio_destroy,
 | 
						.destroy = hsphfpd_audio_destroy,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult hsphfpd_parse_endpoint_properties(struct spa_bt_backend *backend, struct hsphfpd_endpoint *endpoint, DBusMessageIter *i)
 | 
					static DBusHandlerResult hsphfpd_parse_endpoint_properties(struct impl *backend, struct hsphfpd_endpoint *endpoint, DBusMessageIter *i)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	DBusMessageIter element_i;
 | 
						DBusMessageIter element_i;
 | 
				
			||||||
	struct spa_bt_device *d;
 | 
						struct spa_bt_device *d;
 | 
				
			||||||
| 
						 | 
					@ -1100,7 +1102,7 @@ static DBusHandlerResult hsphfpd_parse_endpoint_properties(struct spa_bt_backend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t->device = d;
 | 
						t->device = d;
 | 
				
			||||||
	spa_list_append(&t->device->transport_list, &t->device_link);
 | 
						spa_list_append(&t->device->transport_list, &t->device_link);
 | 
				
			||||||
	t->backend = backend;
 | 
						t->backend = &backend->this;
 | 
				
			||||||
	t->profile = SPA_BT_PROFILE_NULL;
 | 
						t->profile = SPA_BT_PROFILE_NULL;
 | 
				
			||||||
	if (endpoint->profile == HSPHFPD_PROFILE_HEADSET) {
 | 
						if (endpoint->profile == HSPHFPD_PROFILE_HEADSET) {
 | 
				
			||||||
		if (endpoint->role == HSPHFPD_ROLE_CLIENT)
 | 
							if (endpoint->role == HSPHFPD_ROLE_CLIENT)
 | 
				
			||||||
| 
						 | 
					@ -1128,7 +1130,7 @@ static DBusHandlerResult hsphfpd_parse_endpoint_properties(struct spa_bt_backend
 | 
				
			||||||
	return DBUS_HANDLER_RESULT_HANDLED;
 | 
						return DBUS_HANDLER_RESULT_HANDLED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult hsphfpd_parse_interfaces(struct spa_bt_backend *backend, DBusMessageIter *dict_i)
 | 
					static DBusHandlerResult hsphfpd_parse_interfaces(struct impl *backend, DBusMessageIter *dict_i)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	DBusMessageIter element_i;
 | 
						DBusMessageIter element_i;
 | 
				
			||||||
	const char *path;
 | 
						const char *path;
 | 
				
			||||||
| 
						 | 
					@ -1170,7 +1172,7 @@ static DBusHandlerResult hsphfpd_parse_interfaces(struct spa_bt_backend *backend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void hsphfpd_get_endpoints_reply(DBusPendingCall *pending, void *user_data)
 | 
					static void hsphfpd_get_endpoints_reply(DBusPendingCall *pending, void *user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = user_data;
 | 
						struct impl *backend = user_data;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
	DBusMessageIter i, array_i;
 | 
						DBusMessageIter i, array_i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1210,8 +1212,9 @@ finish:
 | 
				
			||||||
	dbus_pending_call_unref(pending);
 | 
						dbus_pending_call_unref(pending);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int backend_hsphfpd_register(struct spa_bt_backend *backend)
 | 
					static int backend_hsphfpd_register(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
	DBusMessage *m, *r;
 | 
						DBusMessage *m, *r;
 | 
				
			||||||
	const char *path = APPLICATION_OBJECT_MANAGER_PATH;
 | 
						const char *path = APPLICATION_OBJECT_MANAGER_PATH;
 | 
				
			||||||
	DBusPendingCall *call;
 | 
						DBusPendingCall *call;
 | 
				
			||||||
| 
						 | 
					@ -1264,8 +1267,9 @@ finish:
 | 
				
			||||||
	return -EIO;
 | 
						return -EIO;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void backend_hsphfpd_unregistered(struct spa_bt_backend *backend)
 | 
					static int backend_hsphfpd_unregistered(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
	struct hsphfpd_endpoint *endpoint;
 | 
						struct hsphfpd_endpoint *endpoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (backend->hsphfpd_service_id) {
 | 
						if (backend->hsphfpd_service_id) {
 | 
				
			||||||
| 
						 | 
					@ -1275,12 +1279,14 @@ void backend_hsphfpd_unregistered(struct spa_bt_backend *backend)
 | 
				
			||||||
	backend->endpoints_listed = false;
 | 
						backend->endpoints_listed = false;
 | 
				
			||||||
	spa_list_consume(endpoint, &backend->endpoint_list, link)
 | 
						spa_list_consume(endpoint, &backend->endpoint_list, link)
 | 
				
			||||||
		endpoint_free(endpoint);
 | 
							endpoint_free(endpoint);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult hsphfpd_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
 | 
					static DBusHandlerResult hsphfpd_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *sender;
 | 
						const char *sender;
 | 
				
			||||||
	struct spa_bt_backend *backend = user_data;
 | 
						struct impl *backend = user_data;
 | 
				
			||||||
	DBusError err;
 | 
						DBusError err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbus_error_init(&err);
 | 
						dbus_error_init(&err);
 | 
				
			||||||
| 
						 | 
					@ -1382,12 +1388,13 @@ finish:
 | 
				
			||||||
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 | 
						return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void backend_hsphfpd_add_filters(struct spa_bt_backend *backend)
 | 
					static int backend_hsphfpd_add_filters(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
	DBusError err;
 | 
						DBusError err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (backend->filters_added)
 | 
						if (backend->filters_added)
 | 
				
			||||||
		return;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbus_error_init(&err);
 | 
						dbus_error_init(&err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1413,14 +1420,16 @@ void backend_hsphfpd_add_filters(struct spa_bt_backend *backend)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	backend->filters_added = true;
 | 
						backend->filters_added = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fail:
 | 
					fail:
 | 
				
			||||||
	dbus_error_free(&err);
 | 
						dbus_error_free(&err);
 | 
				
			||||||
 | 
						return -EIO;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void backend_hsphfpd_free(struct spa_bt_backend *backend)
 | 
					static int backend_hsphfpd_free(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
	struct hsphfpd_endpoint *endpoint;
 | 
						struct hsphfpd_endpoint *endpoint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (backend->msbc_supported)
 | 
						if (backend->msbc_supported)
 | 
				
			||||||
| 
						 | 
					@ -1432,15 +1441,25 @@ void backend_hsphfpd_free(struct spa_bt_backend *backend)
 | 
				
			||||||
		endpoint_free(endpoint);
 | 
							endpoint_free(endpoint);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(backend);
 | 
						free(backend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct spa_bt_backend_implementation backend_impl = {
 | 
				
			||||||
 | 
						SPA_VERSION_BT_BACKEND_IMPLEMENTATION,
 | 
				
			||||||
 | 
						.free = backend_hsphfpd_free,
 | 
				
			||||||
 | 
						.register_profiles = backend_hsphfpd_register,
 | 
				
			||||||
 | 
						.unregistered = backend_hsphfpd_unregistered,
 | 
				
			||||||
 | 
						.add_filters = backend_hsphfpd_add_filters,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct spa_bt_backend *backend_hsphfpd_new(struct spa_bt_monitor *monitor,
 | 
					struct spa_bt_backend *backend_hsphfpd_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
		void *dbus_connection,
 | 
							void *dbus_connection,
 | 
				
			||||||
		const struct spa_dict *info,
 | 
							const struct spa_dict *info,
 | 
				
			||||||
		const struct spa_support *support,
 | 
							const struct spa_support *support,
 | 
				
			||||||
	  uint32_t n_support)
 | 
						  uint32_t n_support)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend;
 | 
						struct impl *backend;
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
	static const DBusObjectPathVTable vtable_application_object_manager = {
 | 
						static const DBusObjectPathVTable vtable_application_object_manager = {
 | 
				
			||||||
		.message_function = application_object_manager_handler,
 | 
							.message_function = application_object_manager_handler,
 | 
				
			||||||
| 
						 | 
					@ -1449,10 +1468,12 @@ struct spa_bt_backend *backend_hsphfpd_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
		.message_function = audio_agent_endpoint_handler,
 | 
							.message_function = audio_agent_endpoint_handler,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	backend = calloc(1, sizeof(struct spa_bt_backend));
 | 
						backend = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (backend == NULL)
 | 
						if (backend == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_bt_backend_set_implementation(&backend->this, &backend_impl, backend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	backend->monitor = monitor;
 | 
						backend->monitor = monitor;
 | 
				
			||||||
	backend->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
 | 
						backend->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
 | 
				
			||||||
	backend->dbus = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DBus);
 | 
						backend->dbus = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DBus);
 | 
				
			||||||
| 
						 | 
					@ -1489,5 +1510,5 @@ struct spa_bt_backend *backend_hsphfpd_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return backend;
 | 
						return &backend->this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PROP_KEY_HEADSET_ROLES "bluez5.headset-roles"
 | 
					#define PROP_KEY_HEADSET_ROLES "bluez5.headset-roles"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct spa_bt_backend {
 | 
					struct impl {
 | 
				
			||||||
 | 
						struct spa_bt_backend this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_bt_monitor *monitor;
 | 
						struct spa_bt_monitor *monitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_log *log;
 | 
						struct spa_log *log;
 | 
				
			||||||
| 
						 | 
					@ -81,7 +83,7 @@ enum hfp_hf_state {
 | 
				
			||||||
struct rfcomm {
 | 
					struct rfcomm {
 | 
				
			||||||
	struct spa_list link;
 | 
						struct spa_list link;
 | 
				
			||||||
	struct spa_source source;
 | 
						struct spa_source source;
 | 
				
			||||||
	struct spa_bt_backend *backend;
 | 
						struct impl *backend;
 | 
				
			||||||
	struct spa_bt_device *device;
 | 
						struct spa_bt_device *device;
 | 
				
			||||||
	struct spa_bt_transport *transport;
 | 
						struct spa_bt_transport *transport;
 | 
				
			||||||
	struct spa_hook transport_listener;
 | 
						struct spa_hook transport_listener;
 | 
				
			||||||
| 
						 | 
					@ -115,7 +117,7 @@ static DBusHandlerResult profile_release(DBusConnection *conn, DBusMessage *m, v
 | 
				
			||||||
static void transport_destroy(void *data)
 | 
					static void transport_destroy(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rfcomm *rfcomm = data;
 | 
						struct rfcomm *rfcomm = data;
 | 
				
			||||||
	struct spa_bt_backend *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_debug(backend->log, "transport %p destroy", rfcomm->transport);
 | 
						spa_log_debug(backend->log, "transport %p destroy", rfcomm->transport);
 | 
				
			||||||
	rfcomm->transport = NULL;
 | 
						rfcomm->transport = NULL;
 | 
				
			||||||
| 
						 | 
					@ -130,7 +132,7 @@ static const struct spa_bt_transport_implementation sco_transport_impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct spa_bt_transport *_transport_create(struct rfcomm *rfcomm)
 | 
					static struct spa_bt_transport *_transport_create(struct rfcomm *rfcomm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
	struct spa_bt_transport *t = NULL;
 | 
						struct spa_bt_transport *t = NULL;
 | 
				
			||||||
	char* pathfd;
 | 
						char* pathfd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,7 +147,7 @@ static struct spa_bt_transport *_transport_create(struct rfcomm *rfcomm)
 | 
				
			||||||
	t->device = rfcomm->device;
 | 
						t->device = rfcomm->device;
 | 
				
			||||||
	spa_list_append(&t->device->transport_list, &t->device_link);
 | 
						spa_list_append(&t->device->transport_list, &t->device_link);
 | 
				
			||||||
	t->profile = rfcomm->profile;
 | 
						t->profile = rfcomm->profile;
 | 
				
			||||||
	t->backend = backend;
 | 
						t->backend = &backend->this;
 | 
				
			||||||
	t->n_channels = 1;
 | 
						t->n_channels = 1;
 | 
				
			||||||
	t->channels[0] = SPA_AUDIO_CHANNEL_MONO;
 | 
						t->channels[0] = SPA_AUDIO_CHANNEL_MONO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,7 +172,7 @@ static void rfcomm_free(struct rfcomm *rfcomm)
 | 
				
			||||||
static void rfcomm_send_cmd(struct spa_source *source, char *data)
 | 
					static void rfcomm_send_cmd(struct spa_source *source, char *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rfcomm *rfcomm = source->data;
 | 
						struct rfcomm *rfcomm = source->data;
 | 
				
			||||||
	struct spa_bt_backend *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
	char message[256];
 | 
						char message[256];
 | 
				
			||||||
	ssize_t len;
 | 
						ssize_t len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,7 +188,7 @@ static void rfcomm_send_cmd(struct spa_source *source, char *data)
 | 
				
			||||||
static void rfcomm_send_reply(struct spa_source *source, char *data)
 | 
					static void rfcomm_send_reply(struct spa_source *source, char *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rfcomm *rfcomm = source->data;
 | 
						struct rfcomm *rfcomm = source->data;
 | 
				
			||||||
	struct spa_bt_backend *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
	char message[256];
 | 
						char message[256];
 | 
				
			||||||
	ssize_t len;
 | 
						ssize_t len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,7 +205,7 @@ static void rfcomm_send_reply(struct spa_source *source, char *data)
 | 
				
			||||||
static bool rfcomm_hsp_ag(struct spa_source *source, char* buf)
 | 
					static bool rfcomm_hsp_ag(struct spa_source *source, char* buf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rfcomm *rfcomm = source->data;
 | 
						struct rfcomm *rfcomm = source->data;
 | 
				
			||||||
	struct spa_bt_backend *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
	unsigned int gain, dummy;
 | 
						unsigned int gain, dummy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* There are only three HSP AT commands:
 | 
						/* There are only three HSP AT commands:
 | 
				
			||||||
| 
						 | 
					@ -238,7 +240,7 @@ static bool rfcomm_hsp_ag(struct spa_source *source, char* buf)
 | 
				
			||||||
static bool rfcomm_hsp_hs(struct spa_source *source, char* buf)
 | 
					static bool rfcomm_hsp_hs(struct spa_source *source, char* buf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rfcomm *rfcomm = source->data;
 | 
						struct rfcomm *rfcomm = source->data;
 | 
				
			||||||
	struct spa_bt_backend *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
	unsigned int gain;
 | 
						unsigned int gain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* There are only three HSP AT result codes:
 | 
						/* There are only three HSP AT result codes:
 | 
				
			||||||
| 
						 | 
					@ -268,7 +270,7 @@ static bool rfcomm_hsp_hs(struct spa_source *source, char* buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE
 | 
					#ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE
 | 
				
			||||||
static bool device_supports_required_mSBC_transport_modes(
 | 
					static bool device_supports_required_mSBC_transport_modes(
 | 
				
			||||||
		struct spa_bt_backend *backend, struct spa_bt_device *device) {
 | 
							struct impl *backend, struct spa_bt_device *device) {
 | 
				
			||||||
	bdaddr_t src;
 | 
						bdaddr_t src;
 | 
				
			||||||
	uint8_t features[8], max_page = 0;
 | 
						uint8_t features[8], max_page = 0;
 | 
				
			||||||
	int device_id;
 | 
						int device_id;
 | 
				
			||||||
| 
						 | 
					@ -322,7 +324,7 @@ static bool device_supports_required_mSBC_transport_modes(
 | 
				
			||||||
static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
 | 
					static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rfcomm *rfcomm = source->data;
 | 
						struct rfcomm *rfcomm = source->data;
 | 
				
			||||||
	struct spa_bt_backend *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
	unsigned int features;
 | 
						unsigned int features;
 | 
				
			||||||
	unsigned int gain;
 | 
						unsigned int gain;
 | 
				
			||||||
	unsigned int len, k, v;
 | 
						unsigned int len, k, v;
 | 
				
			||||||
| 
						 | 
					@ -498,7 +500,7 @@ static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
 | 
				
			||||||
static bool rfcomm_hfp_hf(struct spa_source *source, char* buf)
 | 
					static bool rfcomm_hfp_hf(struct spa_source *source, char* buf)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rfcomm *rfcomm = source->data;
 | 
						struct rfcomm *rfcomm = source->data;
 | 
				
			||||||
	struct spa_bt_backend *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
	unsigned int features;
 | 
						unsigned int features;
 | 
				
			||||||
	unsigned int gain;
 | 
						unsigned int gain;
 | 
				
			||||||
	unsigned int selected_codec;
 | 
						unsigned int selected_codec;
 | 
				
			||||||
| 
						 | 
					@ -621,7 +623,7 @@ static bool rfcomm_hfp_hf(struct spa_source *source, char* buf)
 | 
				
			||||||
static void rfcomm_event(struct spa_source *source)
 | 
					static void rfcomm_event(struct spa_source *source)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct rfcomm *rfcomm = source->data;
 | 
						struct rfcomm *rfcomm = source->data;
 | 
				
			||||||
	struct spa_bt_backend *backend = rfcomm->backend;
 | 
						struct impl *backend = rfcomm->backend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (source->rmask & (SPA_IO_HUP | SPA_IO_ERR)) {
 | 
						if (source->rmask & (SPA_IO_HUP | SPA_IO_ERR)) {
 | 
				
			||||||
		spa_log_info(backend->log, NAME": lost RFCOMM connection.");
 | 
							spa_log_info(backend->log, NAME": lost RFCOMM connection.");
 | 
				
			||||||
| 
						 | 
					@ -667,7 +669,7 @@ static void rfcomm_event(struct spa_source *source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sco_do_connect(struct spa_bt_transport *t)
 | 
					static int sco_do_connect(struct spa_bt_transport *t)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = t->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(t->backend, struct impl, this);
 | 
				
			||||||
	struct spa_bt_device *d = t->device;
 | 
						struct spa_bt_device *d = t->device;
 | 
				
			||||||
	struct sockaddr_sco addr;
 | 
						struct sockaddr_sco addr;
 | 
				
			||||||
	socklen_t len;
 | 
						socklen_t len;
 | 
				
			||||||
| 
						 | 
					@ -733,7 +735,7 @@ fail_close:
 | 
				
			||||||
static int sco_acquire_cb(void *data, bool optional)
 | 
					static int sco_acquire_cb(void *data, bool optional)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_transport *t = data;
 | 
						struct spa_bt_transport *t = data;
 | 
				
			||||||
	struct spa_bt_backend *backend = t->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(t->backend, struct impl, this);
 | 
				
			||||||
	int sock;
 | 
						int sock;
 | 
				
			||||||
	socklen_t len;
 | 
						socklen_t len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -778,7 +780,7 @@ fail:
 | 
				
			||||||
static int sco_release_cb(void *data)
 | 
					static int sco_release_cb(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_transport *t = data;
 | 
						struct spa_bt_transport *t = data;
 | 
				
			||||||
	struct spa_bt_backend *backend = t->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(t->backend, struct impl, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_info(backend->log, NAME": Transport %s released", t->path);
 | 
						spa_log_info(backend->log, NAME": Transport %s released", t->path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -800,7 +802,7 @@ static int sco_release_cb(void *data)
 | 
				
			||||||
static void sco_event(struct spa_source *source)
 | 
					static void sco_event(struct spa_source *source)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_transport *t = source->data;
 | 
						struct spa_bt_transport *t = source->data;
 | 
				
			||||||
	struct spa_bt_backend *backend = t->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(t->backend, struct impl, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (source->rmask & (SPA_IO_HUP | SPA_IO_ERR)) {
 | 
						if (source->rmask & (SPA_IO_HUP | SPA_IO_ERR)) {
 | 
				
			||||||
		spa_log_debug(backend->log, NAME": transport %p: error on SCO socket: %s", t, strerror(errno));
 | 
							spa_log_debug(backend->log, NAME": transport %p: error on SCO socket: %s", t, strerror(errno));
 | 
				
			||||||
| 
						 | 
					@ -817,7 +819,7 @@ static void sco_event(struct spa_source *source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void sco_listen_event(struct spa_source *source)
 | 
					static void sco_listen_event(struct spa_source *source)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = source->data;
 | 
						struct impl *backend = source->data;
 | 
				
			||||||
	struct sockaddr_sco addr;
 | 
						struct sockaddr_sco addr;
 | 
				
			||||||
	socklen_t optlen;
 | 
						socklen_t optlen;
 | 
				
			||||||
	int sock = -1;
 | 
						int sock = -1;
 | 
				
			||||||
| 
						 | 
					@ -926,7 +928,7 @@ fail:
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int sco_listen(struct spa_bt_backend *backend)
 | 
					static int sco_listen(struct impl *backend)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sockaddr_sco addr;
 | 
						struct sockaddr_sco addr;
 | 
				
			||||||
	int sock;
 | 
						int sock;
 | 
				
			||||||
| 
						 | 
					@ -983,7 +985,7 @@ static const struct spa_bt_transport_implementation sco_transport_impl = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
					static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = userdata;
 | 
						struct impl *backend = userdata;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
	DBusMessageIter it[5];
 | 
						DBusMessageIter it[5];
 | 
				
			||||||
	const char *handler, *path, *str;
 | 
						const char *handler, *path, *str;
 | 
				
			||||||
| 
						 | 
					@ -1107,7 +1109,7 @@ fail_need_memory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult profile_request_disconnection(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
					static DBusHandlerResult profile_request_disconnection(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = userdata;
 | 
						struct impl *backend = userdata;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
	const char *handler, *path;
 | 
						const char *handler, *path;
 | 
				
			||||||
	struct spa_bt_device *d;
 | 
						struct spa_bt_device *d;
 | 
				
			||||||
| 
						 | 
					@ -1171,7 +1173,7 @@ static DBusHandlerResult profile_request_disconnection(DBusConnection *conn, DBu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult profile_handler(DBusConnection *c, DBusMessage *m, void *userdata)
 | 
					static DBusHandlerResult profile_handler(DBusConnection *c, DBusMessage *m, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = userdata;
 | 
						struct impl *backend = userdata;
 | 
				
			||||||
	const char *path, *interface, *member;
 | 
						const char *path, *interface, *member;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
	DBusHandlerResult res;
 | 
						DBusHandlerResult res;
 | 
				
			||||||
| 
						 | 
					@ -1209,7 +1211,7 @@ static DBusHandlerResult profile_handler(DBusConnection *c, DBusMessage *m, void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void register_profile_reply(DBusPendingCall *pending, void *user_data)
 | 
					static void register_profile_reply(DBusPendingCall *pending, void *user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = user_data;
 | 
						struct impl *backend = user_data;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r = dbus_pending_call_steal_reply(pending);
 | 
						r = dbus_pending_call_steal_reply(pending);
 | 
				
			||||||
| 
						 | 
					@ -1235,7 +1237,7 @@ static void register_profile_reply(DBusPendingCall *pending, void *user_data)
 | 
				
			||||||
        dbus_pending_call_unref(pending);
 | 
					        dbus_pending_call_unref(pending);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int register_profile(struct spa_bt_backend *backend, const char *profile, const char *uuid)
 | 
					static int register_profile(struct impl *backend, const char *profile, const char *uuid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	DBusMessage *m;
 | 
						DBusMessage *m;
 | 
				
			||||||
	DBusMessageIter it[4];
 | 
						DBusMessageIter it[4];
 | 
				
			||||||
| 
						 | 
					@ -1341,7 +1343,7 @@ static int register_profile(struct spa_bt_backend *backend, const char *profile,
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void unregister_profile(struct spa_bt_backend *backend, const char *profile)
 | 
					static void unregister_profile(struct impl *backend, const char *profile)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	DBusMessage *m, *r;
 | 
						DBusMessage *m, *r;
 | 
				
			||||||
	DBusError err;
 | 
						DBusError err;
 | 
				
			||||||
| 
						 | 
					@ -1375,8 +1377,10 @@ void unregister_profile(struct spa_bt_backend *backend, const char *profile)
 | 
				
			||||||
	dbus_message_unref(r);
 | 
						dbus_message_unref(r);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void backend_native_register_profiles(struct spa_bt_backend *backend)
 | 
					static int backend_native_register_profiles(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_BLUEZ_5_BACKEND_HSP_NATIVE
 | 
					#ifdef HAVE_BLUEZ_5_BACKEND_HSP_NATIVE
 | 
				
			||||||
	register_profile(backend, PROFILE_HSP_AG, SPA_BT_UUID_HSP_AG);
 | 
						register_profile(backend, PROFILE_HSP_AG, SPA_BT_UUID_HSP_AG);
 | 
				
			||||||
	register_profile(backend, PROFILE_HSP_HS, SPA_BT_UUID_HSP_HS);
 | 
						register_profile(backend, PROFILE_HSP_HS, SPA_BT_UUID_HSP_HS);
 | 
				
			||||||
| 
						 | 
					@ -1389,9 +1393,11 @@ void backend_native_register_profiles(struct spa_bt_backend *backend)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (backend->enabled_profiles & SPA_BT_PROFILE_HEADSET_HEAD_UNIT)
 | 
						if (backend->enabled_profiles & SPA_BT_PROFILE_HEADSET_HEAD_UNIT)
 | 
				
			||||||
		sco_listen(backend);
 | 
							sco_listen(backend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void sco_close(struct spa_bt_backend *backend)
 | 
					static void sco_close(struct impl *backend)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (backend->sco.fd >= 0) {
 | 
						if (backend->sco.fd >= 0) {
 | 
				
			||||||
		if (backend->sco.loop)
 | 
							if (backend->sco.loop)
 | 
				
			||||||
| 
						 | 
					@ -1402,8 +1408,10 @@ void sco_close(struct spa_bt_backend *backend)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void backend_native_unregister_profiles(struct spa_bt_backend *backend)
 | 
					static int backend_native_unregister_profiles(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sco_close(backend);
 | 
						sco_close(backend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_BLUEZ_5_BACKEND_HSP_NATIVE
 | 
					#ifdef HAVE_BLUEZ_5_BACKEND_HSP_NATIVE
 | 
				
			||||||
| 
						 | 
					@ -1419,10 +1427,14 @@ void backend_native_unregister_profiles(struct spa_bt_backend *backend)
 | 
				
			||||||
	if (backend->enabled_profiles & SPA_BT_PROFILE_HFP_HF)
 | 
						if (backend->enabled_profiles & SPA_BT_PROFILE_HFP_HF)
 | 
				
			||||||
		unregister_profile(backend, PROFILE_HFP_HF);
 | 
							unregister_profile(backend, PROFILE_HFP_HF);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void backend_native_free(struct spa_bt_backend *backend)
 | 
					static int backend_native_free(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct rfcomm *rfcomm;
 | 
						struct rfcomm *rfcomm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sco_close(backend);
 | 
						sco_close(backend);
 | 
				
			||||||
| 
						 | 
					@ -1441,9 +1453,11 @@ void backend_native_free(struct spa_bt_backend *backend)
 | 
				
			||||||
		rfcomm_free(rfcomm);
 | 
							rfcomm_free(rfcomm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(backend);
 | 
						free(backend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int parse_headset_roles(struct spa_bt_backend *backend, const struct spa_dict *info)
 | 
					static int parse_headset_roles(struct impl *backend, const struct spa_dict *info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
	struct spa_json it, it_array;
 | 
						struct spa_json it, it_array;
 | 
				
			||||||
| 
						 | 
					@ -1483,22 +1497,31 @@ fallback:
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct spa_bt_backend_implementation backend_impl = {
 | 
				
			||||||
 | 
						SPA_VERSION_BT_BACKEND_IMPLEMENTATION,
 | 
				
			||||||
 | 
						.free = backend_native_free,
 | 
				
			||||||
 | 
						.register_profiles = backend_native_register_profiles,
 | 
				
			||||||
 | 
						.unregister_profiles = backend_native_unregister_profiles,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct spa_bt_backend *backend_native_new(struct spa_bt_monitor *monitor,
 | 
					struct spa_bt_backend *backend_native_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
		void *dbus_connection,
 | 
							void *dbus_connection,
 | 
				
			||||||
		const struct spa_dict *info,
 | 
							const struct spa_dict *info,
 | 
				
			||||||
		const struct spa_support *support,
 | 
							const struct spa_support *support,
 | 
				
			||||||
	  uint32_t n_support)
 | 
						  uint32_t n_support)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend;
 | 
						struct impl *backend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const DBusObjectPathVTable vtable_profile = {
 | 
						static const DBusObjectPathVTable vtable_profile = {
 | 
				
			||||||
		.message_function = profile_handler,
 | 
							.message_function = profile_handler,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	backend = calloc(1, sizeof(struct spa_bt_backend));
 | 
						backend = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (backend == NULL)
 | 
						if (backend == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_bt_backend_set_implementation(&backend->this, &backend_impl, backend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	backend->monitor = monitor;
 | 
						backend->monitor = monitor;
 | 
				
			||||||
	backend->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
 | 
						backend->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
 | 
				
			||||||
	backend->dbus = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DBus);
 | 
						backend->dbus = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DBus);
 | 
				
			||||||
| 
						 | 
					@ -1539,7 +1562,7 @@ struct spa_bt_backend *backend_native_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return backend;
 | 
						return &backend->this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE
 | 
					#ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE
 | 
				
			||||||
fail3:
 | 
					fail3:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define NAME "oFono"
 | 
					#define NAME "oFono"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct spa_bt_backend {
 | 
					struct impl {
 | 
				
			||||||
 | 
						struct spa_bt_backend this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_bt_monitor *monitor;
 | 
						struct spa_bt_monitor *monitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_log *log;
 | 
						struct spa_log *log;
 | 
				
			||||||
| 
						 | 
					@ -87,7 +89,7 @@ struct transport_data {
 | 
				
			||||||
#define OFONO_ERROR_NOT_IMPLEMENTED "org.ofono.Error.NotImplemented"
 | 
					#define OFONO_ERROR_NOT_IMPLEMENTED "org.ofono.Error.NotImplemented"
 | 
				
			||||||
#define OFONO_ERROR_IN_USE "org.ofono.Error.InUse"
 | 
					#define OFONO_ERROR_IN_USE "org.ofono.Error.InUse"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ofono_transport_get_mtu(struct spa_bt_backend *backend, struct spa_bt_transport *t)
 | 
					static void ofono_transport_get_mtu(struct impl *backend, struct spa_bt_transport *t)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sco_options sco_opt;
 | 
						struct sco_options sco_opt;
 | 
				
			||||||
	socklen_t len;
 | 
						socklen_t len;
 | 
				
			||||||
| 
						 | 
					@ -108,7 +110,7 @@ static void ofono_transport_get_mtu(struct spa_bt_backend *backend, struct spa_b
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct spa_bt_transport *_transport_create(struct spa_bt_backend *backend,
 | 
					static struct spa_bt_transport *_transport_create(struct impl *backend,
 | 
				
			||||||
                                                  const char *path,
 | 
					                                                  const char *path,
 | 
				
			||||||
                                                  struct spa_bt_device *device,
 | 
					                                                  struct spa_bt_device *device,
 | 
				
			||||||
                                                  enum spa_bt_profile profile,
 | 
					                                                  enum spa_bt_profile profile,
 | 
				
			||||||
| 
						 | 
					@ -128,7 +130,7 @@ static struct spa_bt_transport *_transport_create(struct spa_bt_backend *backend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t->device = device;
 | 
						t->device = device;
 | 
				
			||||||
	spa_list_append(&t->device->transport_list, &t->device_link);
 | 
						spa_list_append(&t->device->transport_list, &t->device_link);
 | 
				
			||||||
	t->backend = backend;
 | 
						t->backend = &backend->this;
 | 
				
			||||||
	t->profile = profile;
 | 
						t->profile = profile;
 | 
				
			||||||
	t->codec = codec;
 | 
						t->codec = codec;
 | 
				
			||||||
	t->n_channels = 1;
 | 
						t->n_channels = 1;
 | 
				
			||||||
| 
						 | 
					@ -138,7 +140,7 @@ finish:
 | 
				
			||||||
	return t;
 | 
						return t;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int _audio_acquire(struct spa_bt_backend *backend, const char *path, uint8_t *codec)
 | 
					static int _audio_acquire(struct impl *backend, const char *path, uint8_t *codec)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	DBusMessage *m, *r;
 | 
						DBusMessage *m, *r;
 | 
				
			||||||
	DBusError err;
 | 
						DBusError err;
 | 
				
			||||||
| 
						 | 
					@ -187,7 +189,7 @@ finish:
 | 
				
			||||||
static int ofono_audio_acquire(void *data, bool optional)
 | 
					static int ofono_audio_acquire(void *data, bool optional)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_transport *transport = data;
 | 
						struct spa_bt_transport *transport = data;
 | 
				
			||||||
	struct spa_bt_backend *backend = transport->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
 | 
				
			||||||
	uint8_t codec;
 | 
						uint8_t codec;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -235,7 +237,7 @@ finish:
 | 
				
			||||||
static int ofono_audio_release(void *data)
 | 
					static int ofono_audio_release(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_transport *transport = data;
 | 
						struct spa_bt_transport *transport = data;
 | 
				
			||||||
	struct spa_bt_backend *backend = transport->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_debug(backend->log, NAME": transport %p: Release %s",
 | 
						spa_log_debug(backend->log, NAME": transport %p: Release %s",
 | 
				
			||||||
			transport, transport->path);
 | 
								transport, transport->path);
 | 
				
			||||||
| 
						 | 
					@ -253,7 +255,7 @@ static int ofono_audio_release(void *data)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult ofono_audio_card_removed(struct spa_bt_backend *backend, const char *path)
 | 
					static DBusHandlerResult ofono_audio_card_removed(struct impl *backend, const char *path)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_transport *transport;
 | 
						struct spa_bt_transport *transport;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -284,7 +286,7 @@ static const struct spa_bt_transport_implementation ofono_transport_impl = {
 | 
				
			||||||
	.release = ofono_audio_release,
 | 
						.release = ofono_audio_release,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult ofono_audio_card_found(struct spa_bt_backend *backend, char *path, DBusMessageIter *props_i)
 | 
					static DBusHandlerResult ofono_audio_card_found(struct impl *backend, char *path, DBusMessageIter *props_i)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *remote_address = NULL;
 | 
						const char *remote_address = NULL;
 | 
				
			||||||
	const char *local_address = NULL;
 | 
						const char *local_address = NULL;
 | 
				
			||||||
| 
						 | 
					@ -366,7 +368,7 @@ static DBusHandlerResult ofono_audio_card_found(struct spa_bt_backend *backend,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult ofono_release(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
					static DBusHandlerResult ofono_release(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = userdata;
 | 
						struct impl *backend = userdata;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_warn(backend->log, NAME": release");
 | 
						spa_log_warn(backend->log, NAME": release");
 | 
				
			||||||
| 
						 | 
					@ -385,7 +387,7 @@ static DBusHandlerResult ofono_release(DBusConnection *conn, DBusMessage *m, voi
 | 
				
			||||||
static void sco_event(struct spa_source *source)
 | 
					static void sco_event(struct spa_source *source)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_transport *t = source->data;
 | 
						struct spa_bt_transport *t = source->data;
 | 
				
			||||||
	struct spa_bt_backend *backend = t->backend;
 | 
						struct impl *backend = SPA_CONTAINER_OF(t->backend, struct impl, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (source->rmask & (SPA_IO_HUP | SPA_IO_ERR)) {
 | 
						if (source->rmask & (SPA_IO_HUP | SPA_IO_ERR)) {
 | 
				
			||||||
		spa_log_debug(backend->log, NAME": transport %p: error on SCO socket: %s", t, strerror(errno));
 | 
							spa_log_debug(backend->log, NAME": transport %p: error on SCO socket: %s", t, strerror(errno));
 | 
				
			||||||
| 
						 | 
					@ -402,7 +404,7 @@ static void sco_event(struct spa_source *source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult ofono_new_audio_connection(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
					static DBusHandlerResult ofono_new_audio_connection(DBusConnection *conn, DBusMessage *m, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = userdata;
 | 
						struct impl *backend = userdata;
 | 
				
			||||||
	const char *path;
 | 
						const char *path;
 | 
				
			||||||
	int fd;
 | 
						int fd;
 | 
				
			||||||
	uint8_t codec;
 | 
						uint8_t codec;
 | 
				
			||||||
| 
						 | 
					@ -456,7 +458,7 @@ fail:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult ofono_handler(DBusConnection *c, DBusMessage *m, void *userdata)
 | 
					static DBusHandlerResult ofono_handler(DBusConnection *c, DBusMessage *m, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = userdata;
 | 
						struct impl *backend = userdata;
 | 
				
			||||||
	const char *path, *interface, *member;
 | 
						const char *path, *interface, *member;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
	DBusHandlerResult res;
 | 
						DBusHandlerResult res;
 | 
				
			||||||
| 
						 | 
					@ -492,7 +494,7 @@ static DBusHandlerResult ofono_handler(DBusConnection *c, DBusMessage *m, void *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ofono_getcards_reply(DBusPendingCall *pending, void *user_data)
 | 
					static void ofono_getcards_reply(DBusPendingCall *pending, void *user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = user_data;
 | 
						struct impl *backend = user_data;
 | 
				
			||||||
	DBusMessage *r;
 | 
						DBusMessage *r;
 | 
				
			||||||
	DBusMessageIter i, array_i, struct_i, props_i;
 | 
						DBusMessageIter i, array_i, struct_i, props_i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -531,8 +533,10 @@ finish:
 | 
				
			||||||
	dbus_pending_call_unref(pending);
 | 
						dbus_pending_call_unref(pending);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int backend_ofono_register(struct spa_bt_backend *backend)
 | 
					static int backend_ofono_register(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DBusMessage *m, *r;
 | 
						DBusMessage *m, *r;
 | 
				
			||||||
	const char *path = OFONO_AUDIO_CLIENT;
 | 
						const char *path = OFONO_AUDIO_CLIENT;
 | 
				
			||||||
	uint8_t codecs[2];
 | 
						uint8_t codecs[2];
 | 
				
			||||||
| 
						 | 
					@ -610,7 +614,7 @@ finish:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DBusHandlerResult ofono_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
 | 
					static DBusHandlerResult ofono_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend = user_data;
 | 
						struct impl *backend = user_data;
 | 
				
			||||||
	DBusError err;
 | 
						DBusError err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbus_error_init(&err);
 | 
						dbus_error_init(&err);
 | 
				
			||||||
| 
						 | 
					@ -647,12 +651,14 @@ fail:
 | 
				
			||||||
	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 | 
						return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void backend_ofono_add_filters(struct spa_bt_backend *backend)
 | 
					static int backend_ofono_add_filters(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DBusError err;
 | 
						DBusError err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (backend->filters_added)
 | 
						if (backend->filters_added)
 | 
				
			||||||
		return;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbus_error_init(&err);
 | 
						dbus_error_init(&err);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -670,35 +676,49 @@ void backend_ofono_add_filters(struct spa_bt_backend *backend)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	backend->filters_added = true;
 | 
						backend->filters_added = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fail:
 | 
					fail:
 | 
				
			||||||
	dbus_error_free(&err);
 | 
						dbus_error_free(&err);
 | 
				
			||||||
 | 
						return -EIO;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void backend_ofono_free(struct spa_bt_backend *backend)
 | 
					static int backend_ofono_free(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct impl *backend = data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbus_connection_unregister_object_path(backend->conn, OFONO_AUDIO_CLIENT);
 | 
						dbus_connection_unregister_object_path(backend->conn, OFONO_AUDIO_CLIENT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(backend);
 | 
						free(backend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct spa_bt_backend_implementation backend_impl = {
 | 
				
			||||||
 | 
						SPA_VERSION_BT_BACKEND_IMPLEMENTATION,
 | 
				
			||||||
 | 
						.free = backend_ofono_free,
 | 
				
			||||||
 | 
						.register_profiles = backend_ofono_register,
 | 
				
			||||||
 | 
						.add_filters = backend_ofono_add_filters,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct spa_bt_backend *backend_ofono_new(struct spa_bt_monitor *monitor,
 | 
					struct spa_bt_backend *backend_ofono_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
		void *dbus_connection,
 | 
							void *dbus_connection,
 | 
				
			||||||
		const struct spa_dict *info,
 | 
							const struct spa_dict *info,
 | 
				
			||||||
		const struct spa_support *support,
 | 
							const struct spa_support *support,
 | 
				
			||||||
		uint32_t n_support)
 | 
							uint32_t n_support)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct spa_bt_backend *backend;
 | 
						struct impl *backend;
 | 
				
			||||||
	const char *str;
 | 
						const char *str;
 | 
				
			||||||
	static const DBusObjectPathVTable vtable_profile = {
 | 
						static const DBusObjectPathVTable vtable_profile = {
 | 
				
			||||||
		.message_function = ofono_handler,
 | 
							.message_function = ofono_handler,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	backend = calloc(1, sizeof(struct spa_bt_backend));
 | 
						backend = calloc(1, sizeof(struct impl));
 | 
				
			||||||
	if (backend == NULL)
 | 
						if (backend == NULL)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_bt_backend_set_implementation(&backend->this, &backend_impl, backend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	backend->monitor = monitor;
 | 
						backend->monitor = monitor;
 | 
				
			||||||
	backend->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
 | 
						backend->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
 | 
				
			||||||
	backend->dbus = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DBus);
 | 
						backend->dbus = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DBus);
 | 
				
			||||||
| 
						 | 
					@ -716,5 +736,5 @@ struct spa_bt_backend *backend_ofono_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return backend;
 | 
						return &backend->this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2823,7 +2823,7 @@ static void interface_added(struct spa_bt_monitor *monitor,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (strcmp(interface_name, BLUEZ_PROFILE_MANAGER_INTERFACE) == 0) {
 | 
						else if (strcmp(interface_name, BLUEZ_PROFILE_MANAGER_INTERFACE) == 0) {
 | 
				
			||||||
		if (!monitor->backend_ofono_registered && !monitor->backend_hsphfpd_registered) {
 | 
							if (!monitor->backend_ofono_registered && !monitor->backend_hsphfpd_registered) {
 | 
				
			||||||
			backend_native_register_profiles(monitor->backend_native);
 | 
								spa_bt_backend_register_profiles(monitor->backend_native);
 | 
				
			||||||
			monitor->backend_native_registered = true;
 | 
								monitor->backend_native_registered = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -3026,7 +3026,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
 | 
				
			||||||
				monitor->objects_listed = false;
 | 
									monitor->objects_listed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (monitor->backend_native_registered) {
 | 
									if (monitor->backend_native_registered) {
 | 
				
			||||||
					backend_native_unregister_profiles(monitor->backend_native);
 | 
										spa_bt_backend_unregister_profiles(monitor->backend_native);
 | 
				
			||||||
					monitor->backend_native_registered = false;
 | 
										monitor->backend_native_registered = false;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3048,42 +3048,42 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
 | 
				
			||||||
			if (old_owner && *old_owner) {
 | 
								if (old_owner && *old_owner) {
 | 
				
			||||||
				spa_log_debug(monitor->log, "oFono daemon disappeared");
 | 
									spa_log_debug(monitor->log, "oFono daemon disappeared");
 | 
				
			||||||
				monitor->backend_ofono_registered = false;
 | 
									monitor->backend_ofono_registered = false;
 | 
				
			||||||
				backend_native_register_profiles(monitor->backend_native);
 | 
									spa_bt_backend_register_profiles(monitor->backend_native);
 | 
				
			||||||
				monitor->backend_native_registered = true;
 | 
									monitor->backend_native_registered = true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (new_owner && *new_owner) {
 | 
								if (new_owner && *new_owner) {
 | 
				
			||||||
				spa_log_debug(monitor->log, "oFono daemon appeared");
 | 
									spa_log_debug(monitor->log, "oFono daemon appeared");
 | 
				
			||||||
				if (monitor->backend_native_registered) {
 | 
									if (monitor->backend_native_registered) {
 | 
				
			||||||
					backend_native_unregister_profiles(monitor->backend_native);
 | 
										spa_bt_backend_unregister_profiles(monitor->backend_native);
 | 
				
			||||||
					monitor->backend_native_registered = false;
 | 
										monitor->backend_native_registered = false;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if (backend_ofono_register(monitor->backend_ofono) == 0)
 | 
									if (spa_bt_backend_register_profiles(monitor->backend_ofono) == 0)
 | 
				
			||||||
					monitor->backend_ofono_registered = true;
 | 
										monitor->backend_ofono_registered = true;
 | 
				
			||||||
				else {
 | 
									else {
 | 
				
			||||||
					backend_native_register_profiles(monitor->backend_native);
 | 
										spa_bt_backend_register_profiles(monitor->backend_native);
 | 
				
			||||||
					monitor->backend_native_registered = true;
 | 
										monitor->backend_native_registered = true;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else if (strcmp(name, HSPHFPD_SERVICE) == 0 && monitor->backend_hsphfpd) {
 | 
							} else if (strcmp(name, HSPHFPD_SERVICE) == 0 && monitor->backend_hsphfpd) {
 | 
				
			||||||
			if (old_owner && *old_owner) {
 | 
								if (old_owner && *old_owner) {
 | 
				
			||||||
				spa_log_debug(monitor->log, "hsphfpd daemon disappeared");
 | 
									spa_log_debug(monitor->log, "hsphfpd daemon disappeared");
 | 
				
			||||||
				backend_hsphfpd_unregistered(monitor->backend_hsphfpd);
 | 
									spa_bt_backend_unregistered(monitor->backend_hsphfpd);
 | 
				
			||||||
				monitor->backend_hsphfpd_registered = false;
 | 
									monitor->backend_hsphfpd_registered = false;
 | 
				
			||||||
				backend_native_register_profiles(monitor->backend_native);
 | 
									spa_bt_backend_register_profiles(monitor->backend_native);
 | 
				
			||||||
				monitor->backend_native_registered = true;
 | 
									monitor->backend_native_registered = true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (new_owner && *new_owner) {
 | 
								if (new_owner && *new_owner) {
 | 
				
			||||||
				spa_log_debug(monitor->log, "hsphfpd daemon appeared");
 | 
									spa_log_debug(monitor->log, "hsphfpd daemon appeared");
 | 
				
			||||||
				if (monitor->backend_native_registered) {
 | 
									if (monitor->backend_native_registered) {
 | 
				
			||||||
					backend_native_unregister_profiles(monitor->backend_native);
 | 
										spa_bt_backend_unregister_profiles(monitor->backend_native);
 | 
				
			||||||
					monitor->backend_native_registered = false;
 | 
										monitor->backend_native_registered = false;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if (backend_hsphfpd_register(monitor->backend_hsphfpd) == 0)
 | 
									if (spa_bt_backend_register_profiles(monitor->backend_hsphfpd) == 0)
 | 
				
			||||||
					monitor->backend_hsphfpd_registered = true;
 | 
										monitor->backend_hsphfpd_registered = true;
 | 
				
			||||||
				else {
 | 
									else {
 | 
				
			||||||
					backend_native_register_profiles(monitor->backend_native);
 | 
										spa_bt_backend_register_profiles(monitor->backend_native);
 | 
				
			||||||
					monitor->backend_native_registered = true;
 | 
										monitor->backend_native_registered = true;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -3272,10 +3272,10 @@ impl_device_add_listener(void *object, struct spa_hook *listener,
 | 
				
			||||||
	get_managed_objects(this);
 | 
						get_managed_objects(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->backend_ofono)
 | 
						if (this->backend_ofono)
 | 
				
			||||||
		backend_ofono_add_filters(this->backend_ofono);
 | 
							spa_bt_backend_add_filters(this->backend_ofono);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->backend_hsphfpd)
 | 
						if (this->backend_hsphfpd)
 | 
				
			||||||
		backend_hsphfpd_add_filters(this->backend_hsphfpd);
 | 
							spa_bt_backend_add_filters(this->backend_hsphfpd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        spa_hook_list_join(&this->hooks, &save);
 | 
					        spa_hook_list_join(&this->hooks, &save);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3326,17 +3326,17 @@ static int impl_clear(struct spa_handle *handle)
 | 
				
			||||||
		adapter_free(a);
 | 
							adapter_free(a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (monitor->backend_native) {
 | 
						if (monitor->backend_native) {
 | 
				
			||||||
		backend_native_free(monitor->backend_native);
 | 
							spa_bt_backend_free(monitor->backend_native);
 | 
				
			||||||
		monitor->backend_native = NULL;
 | 
							monitor->backend_native = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (monitor->backend_ofono) {
 | 
						if (monitor->backend_ofono) {
 | 
				
			||||||
		backend_ofono_free(monitor->backend_ofono);
 | 
							spa_bt_backend_free(monitor->backend_ofono);
 | 
				
			||||||
		monitor->backend_ofono = NULL;
 | 
							monitor->backend_ofono = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (monitor->backend_hsphfpd) {
 | 
						if (monitor->backend_hsphfpd) {
 | 
				
			||||||
		backend_hsphfpd_free(monitor->backend_hsphfpd);
 | 
							spa_bt_backend_free(monitor->backend_hsphfpd);
 | 
				
			||||||
		monitor->backend_hsphfpd = NULL;
 | 
							monitor->backend_hsphfpd = NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3497,9 +3497,9 @@ impl_init(const struct spa_handle_factory *factory,
 | 
				
			||||||
	this->backend_ofono = backend_ofono_new(this, this->conn, info, support, n_support);
 | 
						this->backend_ofono = backend_ofono_new(this, this->conn, info, support, n_support);
 | 
				
			||||||
	this->backend_hsphfpd = backend_hsphfpd_new(this, this->conn, info, support, n_support);
 | 
						this->backend_hsphfpd = backend_hsphfpd_new(this, this->conn, info, support, n_support);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->backend_ofono && backend_ofono_register(this->backend_ofono) == 0)
 | 
						if (this->backend_ofono && spa_bt_backend_register_profiles(this->backend_ofono) == 0)
 | 
				
			||||||
		this->backend_ofono_registered = true;
 | 
							this->backend_ofono_registered = true;
 | 
				
			||||||
	else if (this->backend_hsphfpd && backend_hsphfpd_register(this->backend_hsphfpd) == 0)
 | 
						else if (this->backend_hsphfpd && spa_bt_backend_register_profiles(this->backend_hsphfpd) == 0)
 | 
				
			||||||
		this->backend_hsphfpd_registered = true;
 | 
							this->backend_hsphfpd_registered = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -553,6 +553,48 @@ static inline enum spa_bt_transport_state spa_bt_transport_state_from_string(con
 | 
				
			||||||
		return SPA_BT_TRANSPORT_STATE_IDLE;
 | 
							return SPA_BT_TRANSPORT_STATE_IDLE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct spa_bt_backend_implementation {
 | 
				
			||||||
 | 
					#define SPA_VERSION_BT_BACKEND_IMPLEMENTATION	0
 | 
				
			||||||
 | 
						uint32_t version;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int (*free) (void *data);
 | 
				
			||||||
 | 
						int (*register_profiles) (void *data);
 | 
				
			||||||
 | 
						int (*unregister_profiles) (void *data);
 | 
				
			||||||
 | 
						int (*unregistered) (void *data);
 | 
				
			||||||
 | 
						int (*add_filters) (void *data);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct spa_bt_backend {
 | 
				
			||||||
 | 
						struct spa_callbacks impl;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define spa_bt_backend_set_implementation(b,_impl,_data) \
 | 
				
			||||||
 | 
								(b)->impl = SPA_CALLBACKS_INIT(_impl, _data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define spa_bt_backend_impl(b,m,v,...)				\
 | 
				
			||||||
 | 
					({								\
 | 
				
			||||||
 | 
						int res = -ENOTSUP;					\
 | 
				
			||||||
 | 
						if (b)							\
 | 
				
			||||||
 | 
							spa_callbacks_call_res(&(b)->impl,		\
 | 
				
			||||||
 | 
								struct spa_bt_backend_implementation,	\
 | 
				
			||||||
 | 
								res, m, v, ##__VA_ARGS__);		\
 | 
				
			||||||
 | 
						res;							\
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define spa_bt_backend_free(b)			spa_bt_backend_impl(b, free, 0)
 | 
				
			||||||
 | 
					#define spa_bt_backend_register_profiles(b)	spa_bt_backend_impl(b, register_profiles, 0)
 | 
				
			||||||
 | 
					#define spa_bt_backend_unregister_profiles(b)	spa_bt_backend_impl(b, unregister_profiles, 0)
 | 
				
			||||||
 | 
					#define spa_bt_backend_unregistered(b)		spa_bt_backend_impl(b, unregistered, 0)
 | 
				
			||||||
 | 
					#define spa_bt_backend_add_filters(b)		spa_bt_backend_impl(b, add_filters, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline struct spa_bt_backend *dummy_backend_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
 | 
							void *dbus_connection,
 | 
				
			||||||
 | 
							const struct spa_dict *info,
 | 
				
			||||||
 | 
							const struct spa_support *support,
 | 
				
			||||||
 | 
							uint32_t n_support)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_BLUEZ_5_BACKEND_NATIVE
 | 
					#ifdef HAVE_BLUEZ_5_BACKEND_NATIVE
 | 
				
			||||||
struct spa_bt_backend *backend_native_new(struct spa_bt_monitor *monitor,
 | 
					struct spa_bt_backend *backend_native_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
| 
						 | 
					@ -560,20 +602,8 @@ struct spa_bt_backend *backend_native_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
		const struct spa_dict *info,
 | 
							const struct spa_dict *info,
 | 
				
			||||||
		const struct spa_support *support,
 | 
							const struct spa_support *support,
 | 
				
			||||||
		uint32_t n_support);
 | 
							uint32_t n_support);
 | 
				
			||||||
void backend_native_free(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
void backend_native_register_profiles(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
void backend_native_unregister_profiles(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static inline struct spa_bt_backend *backend_native_new(struct spa_bt_monitor *monitor,
 | 
					#define backend_native_new	dummy_backend_new
 | 
				
			||||||
		void *dbus_connection,
 | 
					 | 
				
			||||||
		const struct spa_dict *info,
 | 
					 | 
				
			||||||
		const struct spa_support *support,
 | 
					 | 
				
			||||||
		uint32_t n_support) {
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline void backend_native_free(struct spa_bt_backend *backend) {}
 | 
					 | 
				
			||||||
static inline void backend_native_register_profiles(struct spa_bt_backend *backend) {}
 | 
					 | 
				
			||||||
static inline void backend_native_unregister_profiles(struct spa_bt_backend *backend) {}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OFONO_SERVICE "org.ofono"
 | 
					#define OFONO_SERVICE "org.ofono"
 | 
				
			||||||
| 
						 | 
					@ -583,20 +613,8 @@ struct spa_bt_backend *backend_ofono_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
		const struct spa_dict *info,
 | 
							const struct spa_dict *info,
 | 
				
			||||||
		const struct spa_support *support,
 | 
							const struct spa_support *support,
 | 
				
			||||||
		uint32_t n_support);
 | 
							uint32_t n_support);
 | 
				
			||||||
void backend_ofono_free(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
int backend_ofono_register(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
void backend_ofono_add_filters(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static inline struct spa_bt_backend *backend_ofono_new(struct spa_bt_monitor *monitor,
 | 
					#define backend_ofono_new	dummy_backend_new
 | 
				
			||||||
		void *dbus_connection,
 | 
					 | 
				
			||||||
		const struct spa_dict *info,
 | 
					 | 
				
			||||||
		const struct spa_support *support,
 | 
					 | 
				
			||||||
		uint32_t n_support) {
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline void backend_ofono_free(struct spa_bt_backend *backend) {}
 | 
					 | 
				
			||||||
static inline int backend_ofono_register(struct spa_bt_backend *backend) { return -ENOTSUP; }
 | 
					 | 
				
			||||||
static inline void backend_ofono_add_filters(struct spa_bt_backend *backend) {}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define HSPHFPD_SERVICE "org.hsphfpd"
 | 
					#define HSPHFPD_SERVICE "org.hsphfpd"
 | 
				
			||||||
| 
						 | 
					@ -606,22 +624,8 @@ struct spa_bt_backend *backend_hsphfpd_new(struct spa_bt_monitor *monitor,
 | 
				
			||||||
		const struct spa_dict *info,
 | 
							const struct spa_dict *info,
 | 
				
			||||||
		const struct spa_support *support,
 | 
							const struct spa_support *support,
 | 
				
			||||||
		uint32_t n_support);
 | 
							uint32_t n_support);
 | 
				
			||||||
void backend_hsphfpd_free(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
int backend_hsphfpd_register(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
void backend_hsphfpd_unregistered(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
void backend_hsphfpd_add_filters(struct spa_bt_backend *backend);
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static inline struct spa_bt_backend *backend_hsphfpd_new(struct spa_bt_monitor *monitor,
 | 
					#define backend_hsphfpd_new	dummy_backend_new
 | 
				
			||||||
		void *dbus_connection,
 | 
					 | 
				
			||||||
		const struct spa_dict *info,
 | 
					 | 
				
			||||||
		const struct spa_support *support,
 | 
					 | 
				
			||||||
		uint32_t n_support) {
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
static inline void backend_hsphfpd_free(struct spa_bt_backend *backend) {}
 | 
					 | 
				
			||||||
static inline int backend_hsphfpd_register(struct spa_bt_backend *backend) { return -ENOTSUP; }
 | 
					 | 
				
			||||||
static inline void backend_hsphfpd_unregistered(struct spa_bt_backend *backend) {}
 | 
					 | 
				
			||||||
static inline void backend_hsphfpd_add_filters(struct spa_bt_backend *backend) {}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue