From e18df4e344f3a4ebc5d8788077a00266ee7bdf65 Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Thu, 18 Mar 2021 21:48:10 +0200 Subject: [PATCH] bluez5: use callback table in hsp/hfp backends --- spa/plugins/bluez5/backend-hsphfpd.c | 75 ++++++++++++++--------- spa/plugins/bluez5/backend-native.c | 89 +++++++++++++++++----------- spa/plugins/bluez5/backend-ofono.c | 66 ++++++++++++++------- spa/plugins/bluez5/bluez5-dbus.c | 36 +++++------ spa/plugins/bluez5/defs.h | 86 ++++++++++++++------------- 5 files changed, 210 insertions(+), 142 deletions(-) diff --git a/spa/plugins/bluez5/backend-hsphfpd.c b/spa/plugins/bluez5/backend-hsphfpd.c index 4549168a1..1fa42aaa6 100644 --- a/spa/plugins/bluez5/backend-hsphfpd.c +++ b/spa/plugins/bluez5/backend-hsphfpd.c @@ -40,7 +40,9 @@ #define NAME "hsphfpd" -struct spa_bt_backend { +struct impl { + struct spa_bt_backend this; + struct spa_bt_monitor *monitor; struct spa_log *log; @@ -169,7 +171,7 @@ struct hsphfpd_endpoint { #define HSPHFPD_ERROR_REJECTED HSPHFPD_SERVICE ".Error.Rejected" #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; 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; } -static int set_dbus_property(struct spa_bt_backend *backend, +static int set_dbus_property(struct impl *backend, const char *service, const char *path, 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) { - 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; 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) { - 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; 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); } -static void parse_transport_properties_values(struct spa_bt_backend *backend, +static void parse_transport_properties_values(struct impl *backend, const char *transport_path, DBusMessageIter *i, 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; 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) { - struct spa_bt_backend *backend = userdata; + struct impl *backend = userdata; DBusMessageIter arg_i; const char *transport_path; int fd; @@ -731,7 +733,7 @@ fail: 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; DBusMessage *r; 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) { - struct spa_bt_backend *backend = userdata; + struct impl *backend = userdata; const char *path, *interface, *member; 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) { - struct spa_bt_backend *backend = user_data; + struct impl *backend = user_data; DBusMessage *r; const char *transport_path; const char *service_id; @@ -895,7 +897,7 @@ finish: static int hsphfpd_audio_acquire(void *data, bool optional) { 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; const char *air_codec = HSPHFP_AIR_CODEC_CVSD; 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) { 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; 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, }; -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; struct spa_bt_device *d; @@ -1100,7 +1102,7 @@ static DBusHandlerResult hsphfpd_parse_endpoint_properties(struct spa_bt_backend t->device = d; spa_list_append(&t->device->transport_list, &t->device_link); - t->backend = backend; + t->backend = &backend->this; t->profile = SPA_BT_PROFILE_NULL; if (endpoint->profile == HSPHFPD_PROFILE_HEADSET) { 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; } -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; 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) { - struct spa_bt_backend *backend = user_data; + struct impl *backend = user_data; DBusMessage *r; DBusMessageIter i, array_i; @@ -1210,8 +1212,9 @@ finish: 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; const char *path = APPLICATION_OBJECT_MANAGER_PATH; DBusPendingCall *call; @@ -1264,8 +1267,9 @@ finish: 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; if (backend->hsphfpd_service_id) { @@ -1275,12 +1279,14 @@ void backend_hsphfpd_unregistered(struct spa_bt_backend *backend) backend->endpoints_listed = false; spa_list_consume(endpoint, &backend->endpoint_list, link) endpoint_free(endpoint); + + return 0; } static DBusHandlerResult hsphfpd_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data) { const char *sender; - struct spa_bt_backend *backend = user_data; + struct impl *backend = user_data; DBusError err; dbus_error_init(&err); @@ -1382,12 +1388,13 @@ finish: 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; if (backend->filters_added) - return; + return 0; dbus_error_init(&err); @@ -1413,14 +1420,16 @@ void backend_hsphfpd_add_filters(struct spa_bt_backend *backend) backend->filters_added = true; - return; + return 0; fail: 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; if (backend->msbc_supported) @@ -1432,15 +1441,25 @@ void backend_hsphfpd_free(struct spa_bt_backend *backend) endpoint_free(endpoint); 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, void *dbus_connection, const struct spa_dict *info, const struct spa_support *support, uint32_t n_support) { - struct spa_bt_backend *backend; + struct impl *backend; const char *str; static const DBusObjectPathVTable vtable_application_object_manager = { .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, }; - backend = calloc(1, sizeof(struct spa_bt_backend)); + backend = calloc(1, sizeof(struct impl)); if (backend == NULL) return NULL; + spa_bt_backend_set_implementation(&backend->this, &backend_impl, backend); + backend->monitor = monitor; backend->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); 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 backend; + return &backend->this; } diff --git a/spa/plugins/bluez5/backend-native.c b/spa/plugins/bluez5/backend-native.c index fa53f3ae3..1b980147c 100644 --- a/spa/plugins/bluez5/backend-native.c +++ b/spa/plugins/bluez5/backend-native.c @@ -47,7 +47,9 @@ #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_log *log; @@ -81,7 +83,7 @@ enum hfp_hf_state { struct rfcomm { struct spa_list link; struct spa_source source; - struct spa_bt_backend *backend; + struct impl *backend; struct spa_bt_device *device; struct spa_bt_transport *transport; struct spa_hook transport_listener; @@ -115,7 +117,7 @@ static DBusHandlerResult profile_release(DBusConnection *conn, DBusMessage *m, v static void transport_destroy(void *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); 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) { - struct spa_bt_backend *backend = rfcomm->backend; + struct impl *backend = rfcomm->backend; struct spa_bt_transport *t = NULL; char* pathfd; @@ -145,7 +147,7 @@ static struct spa_bt_transport *_transport_create(struct rfcomm *rfcomm) t->device = rfcomm->device; spa_list_append(&t->device->transport_list, &t->device_link); t->profile = rfcomm->profile; - t->backend = backend; + t->backend = &backend->this; t->n_channels = 1; 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) { struct rfcomm *rfcomm = source->data; - struct spa_bt_backend *backend = rfcomm->backend; + struct impl *backend = rfcomm->backend; char message[256]; 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) { struct rfcomm *rfcomm = source->data; - struct spa_bt_backend *backend = rfcomm->backend; + struct impl *backend = rfcomm->backend; char message[256]; 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) { struct rfcomm *rfcomm = source->data; - struct spa_bt_backend *backend = rfcomm->backend; + struct impl *backend = rfcomm->backend; unsigned int gain, dummy; /* 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) { struct rfcomm *rfcomm = source->data; - struct spa_bt_backend *backend = rfcomm->backend; + struct impl *backend = rfcomm->backend; unsigned int gain; /* 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 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; uint8_t features[8], max_page = 0; 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) { struct rfcomm *rfcomm = source->data; - struct spa_bt_backend *backend = rfcomm->backend; + struct impl *backend = rfcomm->backend; unsigned int features; unsigned int gain; 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) { struct rfcomm *rfcomm = source->data; - struct spa_bt_backend *backend = rfcomm->backend; + struct impl *backend = rfcomm->backend; unsigned int features; unsigned int gain; 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) { 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)) { 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) { - 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 sockaddr_sco addr; socklen_t len; @@ -733,7 +735,7 @@ fail_close: static int sco_acquire_cb(void *data, bool optional) { 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; socklen_t len; @@ -778,7 +780,7 @@ fail: static int sco_release_cb(void *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); @@ -800,7 +802,7 @@ static int sco_release_cb(void *data) static void sco_event(struct spa_source *source) { 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)) { 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) { - struct spa_bt_backend *backend = source->data; + struct impl *backend = source->data; struct sockaddr_sco addr; socklen_t optlen; int sock = -1; @@ -926,7 +928,7 @@ fail: return; } -static int sco_listen(struct spa_bt_backend *backend) +static int sco_listen(struct impl *backend) { struct sockaddr_sco addr; 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) { - struct spa_bt_backend *backend = userdata; + struct impl *backend = userdata; DBusMessage *r; DBusMessageIter it[5]; const char *handler, *path, *str; @@ -1107,7 +1109,7 @@ fail_need_memory: static DBusHandlerResult profile_request_disconnection(DBusConnection *conn, DBusMessage *m, void *userdata) { - struct spa_bt_backend *backend = userdata; + struct impl *backend = userdata; DBusMessage *r; const char *handler, *path; 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) { - struct spa_bt_backend *backend = userdata; + struct impl *backend = userdata; const char *path, *interface, *member; DBusMessage *r; 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) { - struct spa_bt_backend *backend = user_data; + struct impl *backend = user_data; DBusMessage *r; 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); } -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; DBusMessageIter it[4]; @@ -1341,7 +1343,7 @@ static int register_profile(struct spa_bt_backend *backend, const char *profile, 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; DBusError err; @@ -1375,8 +1377,10 @@ void unregister_profile(struct spa_bt_backend *backend, const char *profile) 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 register_profile(backend, PROFILE_HSP_AG, SPA_BT_UUID_HSP_AG); 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) 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.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); #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) unregister_profile(backend, PROFILE_HFP_HF); #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; sco_close(backend); @@ -1441,9 +1453,11 @@ void backend_native_free(struct spa_bt_backend *backend) rfcomm_free(rfcomm); 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; struct spa_json it, it_array; @@ -1483,22 +1497,31 @@ fallback: 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, void *dbus_connection, const struct spa_dict *info, const struct spa_support *support, uint32_t n_support) { - struct spa_bt_backend *backend; + struct impl *backend; static const DBusObjectPathVTable vtable_profile = { .message_function = profile_handler, }; - backend = calloc(1, sizeof(struct spa_bt_backend)); + backend = calloc(1, sizeof(struct impl)); if (backend == NULL) return NULL; + spa_bt_backend_set_implementation(&backend->this, &backend_impl, backend); + backend->monitor = monitor; backend->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); 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 - return backend; + return &backend->this; #ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE fail3: diff --git a/spa/plugins/bluez5/backend-ofono.c b/spa/plugins/bluez5/backend-ofono.c index 9cb5be65f..054632903 100644 --- a/spa/plugins/bluez5/backend-ofono.c +++ b/spa/plugins/bluez5/backend-ofono.c @@ -42,7 +42,9 @@ #define NAME "oFono" -struct spa_bt_backend { +struct impl { + struct spa_bt_backend this; + struct spa_bt_monitor *monitor; struct spa_log *log; @@ -87,7 +89,7 @@ struct transport_data { #define OFONO_ERROR_NOT_IMPLEMENTED "org.ofono.Error.NotImplemented" #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; 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, struct spa_bt_device *device, enum spa_bt_profile profile, @@ -128,7 +130,7 @@ static struct spa_bt_transport *_transport_create(struct spa_bt_backend *backend t->device = device; spa_list_append(&t->device->transport_list, &t->device_link); - t->backend = backend; + t->backend = &backend->this; t->profile = profile; t->codec = codec; t->n_channels = 1; @@ -138,7 +140,7 @@ finish: 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; DBusError err; @@ -187,7 +189,7 @@ finish: static int ofono_audio_acquire(void *data, bool optional) { 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; int ret = 0; @@ -235,7 +237,7 @@ finish: static int ofono_audio_release(void *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", transport, transport->path); @@ -253,7 +255,7 @@ static int ofono_audio_release(void *data) 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; @@ -284,7 +286,7 @@ static const struct spa_bt_transport_implementation ofono_transport_impl = { .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 *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) { - struct spa_bt_backend *backend = userdata; + struct impl *backend = userdata; DBusMessage *r; 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) { 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)) { 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) { - struct spa_bt_backend *backend = userdata; + struct impl *backend = userdata; const char *path; int fd; uint8_t codec; @@ -456,7 +458,7 @@ fail: 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; DBusMessage *r; 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) { - struct spa_bt_backend *backend = user_data; + struct impl *backend = user_data; DBusMessage *r; DBusMessageIter i, array_i, struct_i, props_i; @@ -531,8 +533,10 @@ finish: 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; const char *path = OFONO_AUDIO_CLIENT; uint8_t codecs[2]; @@ -610,7 +614,7 @@ finish: 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; dbus_error_init(&err); @@ -647,12 +651,14 @@ fail: 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; if (backend->filters_added) - return; + return 0; dbus_error_init(&err); @@ -670,35 +676,49 @@ void backend_ofono_add_filters(struct spa_bt_backend *backend) backend->filters_added = true; - return; + return 0; fail: 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); 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, void *dbus_connection, const struct spa_dict *info, const struct spa_support *support, uint32_t n_support) { - struct spa_bt_backend *backend; + struct impl *backend; const char *str; static const DBusObjectPathVTable vtable_profile = { .message_function = ofono_handler, }; - backend = calloc(1, sizeof(struct spa_bt_backend)); + backend = calloc(1, sizeof(struct impl)); if (backend == NULL) return NULL; + spa_bt_backend_set_implementation(&backend->this, &backend_impl, backend); + backend->monitor = monitor; backend->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); 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 backend; + return &backend->this; } diff --git a/spa/plugins/bluez5/bluez5-dbus.c b/spa/plugins/bluez5/bluez5-dbus.c index 2484bbc2d..991aa83be 100644 --- a/spa/plugins/bluez5/bluez5-dbus.c +++ b/spa/plugins/bluez5/bluez5-dbus.c @@ -2823,7 +2823,7 @@ static void interface_added(struct spa_bt_monitor *monitor, } else if (strcmp(interface_name, BLUEZ_PROFILE_MANAGER_INTERFACE) == 0) { 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; } } @@ -3026,7 +3026,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us monitor->objects_listed = false; 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; } @@ -3048,42 +3048,42 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us if (old_owner && *old_owner) { spa_log_debug(monitor->log, "oFono daemon disappeared"); 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; } if (new_owner && *new_owner) { spa_log_debug(monitor->log, "oFono daemon appeared"); 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; } - if (backend_ofono_register(monitor->backend_ofono) == 0) + if (spa_bt_backend_register_profiles(monitor->backend_ofono) == 0) monitor->backend_ofono_registered = true; else { - backend_native_register_profiles(monitor->backend_native); + spa_bt_backend_register_profiles(monitor->backend_native); monitor->backend_native_registered = true; } } } else if (strcmp(name, HSPHFPD_SERVICE) == 0 && monitor->backend_hsphfpd) { if (old_owner && *old_owner) { 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; - backend_native_register_profiles(monitor->backend_native); + spa_bt_backend_register_profiles(monitor->backend_native); monitor->backend_native_registered = true; } if (new_owner && *new_owner) { spa_log_debug(monitor->log, "hsphfpd daemon appeared"); 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; } - if (backend_hsphfpd_register(monitor->backend_hsphfpd) == 0) + if (spa_bt_backend_register_profiles(monitor->backend_hsphfpd) == 0) monitor->backend_hsphfpd_registered = true; else { - backend_native_register_profiles(monitor->backend_native); + spa_bt_backend_register_profiles(monitor->backend_native); monitor->backend_native_registered = true; } } @@ -3272,10 +3272,10 @@ impl_device_add_listener(void *object, struct spa_hook *listener, get_managed_objects(this); if (this->backend_ofono) - backend_ofono_add_filters(this->backend_ofono); + spa_bt_backend_add_filters(this->backend_ofono); 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); @@ -3326,17 +3326,17 @@ static int impl_clear(struct spa_handle *handle) adapter_free(a); if (monitor->backend_native) { - backend_native_free(monitor->backend_native); + spa_bt_backend_free(monitor->backend_native); monitor->backend_native = NULL; } if (monitor->backend_ofono) { - backend_ofono_free(monitor->backend_ofono); + spa_bt_backend_free(monitor->backend_ofono); monitor->backend_ofono = NULL; } if (monitor->backend_hsphfpd) { - backend_hsphfpd_free(monitor->backend_hsphfpd); + spa_bt_backend_free(monitor->backend_hsphfpd); 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_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; - 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; return 0; diff --git a/spa/plugins/bluez5/defs.h b/spa/plugins/bluez5/defs.h index 24d832b0a..b978e73e5 100644 --- a/spa/plugins/bluez5/defs.h +++ b/spa/plugins/bluez5/defs.h @@ -553,6 +553,48 @@ static inline enum spa_bt_transport_state spa_bt_transport_state_from_string(con 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 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_support *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 -static inline struct spa_bt_backend *backend_native_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; -} -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) {} +#define backend_native_new dummy_backend_new #endif #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_support *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 -static inline struct spa_bt_backend *backend_ofono_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; -} -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) {} +#define backend_ofono_new dummy_backend_new #endif #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_support *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 -static inline struct spa_bt_backend *backend_hsphfpd_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; -} -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) {} +#define backend_hsphfpd_new dummy_backend_new #endif #ifdef __cplusplus