spa: bluez: add send_with_reply() dbus helper

This function sends a DBusMessage on a DBusConnection
and sets the reply callback of the resulting DBusPendingCall,
as well as properly cancelling the pending call if anything fails.
This commit is contained in:
Barnabás Pőcze 2023-07-11 19:57:23 +02:00
parent 6e581deb91
commit b52d590936
7 changed files with 64 additions and 96 deletions

View file

@ -890,7 +890,6 @@ static int hsphfpd_audio_acquire(void *data, bool optional)
spa_autoptr(DBusMessage) m = NULL;
const char *air_codec = HSPHFP_AIR_CODEC_CVSD;
const char *agent_codec = HSPHFP_AGENT_CODEC_PCM;
DBusPendingCall *call;
spa_log_debug(backend->log, "transport %p: Acquire %s",
transport, transport->path);
@ -911,8 +910,8 @@ static int hsphfpd_audio_acquire(void *data, bool optional)
return -ENOMEM;
dbus_message_append_args(m, DBUS_TYPE_STRING, &air_codec, DBUS_TYPE_STRING, &agent_codec, DBUS_TYPE_INVALID);
dbus_connection_send_with_reply(backend->conn, m, &call, -1);
dbus_pending_call_set_notify(call, hsphfpd_audio_acquire_reply, transport, NULL);
if (!send_with_reply(backend->conn, m, hsphfpd_audio_acquire_reply, transport))
return -EIO;
backend->acquire_in_progress = true;
@ -1250,9 +1249,8 @@ static int hsphfpd_get_endpoints(struct impl *backend)
if (m == NULL)
return -ENOMEM;
DBusPendingCall *call;
dbus_connection_send_with_reply(backend->conn, m, &call, -1);
dbus_pending_call_set_notify(call, hsphfpd_get_endpoints_reply, backend, NULL);
if (!send_with_reply(backend->conn, m, hsphfpd_get_endpoints_reply, backend))
return -EIO;
return 0;
}

View file

@ -2429,7 +2429,6 @@ static int register_profile(struct impl *backend, const char *profile, const cha
dbus_bool_t autoconnect;
dbus_uint16_t version, chan, features;
char *str;
DBusPendingCall *call;
if (!(backend->enabled_profiles & spa_bt_profile_from_uuid(uuid)))
return -ECANCELED;
@ -2522,8 +2521,8 @@ static int register_profile(struct impl *backend, const char *profile, const cha
}
dbus_message_iter_close_container(&it[0], &it[1]);
dbus_connection_send_with_reply(backend->conn, m, &call, -1);
dbus_pending_call_set_notify(call, register_profile_reply, backend, NULL);
if (!send_with_reply(backend->conn, m, register_profile_reply, backend))
return -EIO;
return 0;
}

View file

@ -725,9 +725,8 @@ static int ofono_getcards(struct impl *backend)
if (m == NULL)
return -ENOMEM;
DBusPendingCall *call;
dbus_connection_send_with_reply(backend->conn, m, &call, -1);
dbus_pending_call_set_notify(call, ofono_getcards_reply, backend, NULL);
if (!send_with_reply(backend->conn, m, ofono_getcards_reply, backend))
return -EIO;
return 0;
}

View file

@ -390,23 +390,12 @@ static void register_battery_provider(struct spa_bt_device *device)
dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_OBJECT_PATH,
&object_path);
if (!dbus_connection_send_with_reply(device->monitor->conn, method_call, &device->battery_pending_call,
DBUS_TIMEOUT_USE_DEFAULT)) {
spa_log_error(device->monitor->log, "Failed to register battery provider");
return;
}
device->battery_pending_call = send_with_reply(device->monitor->conn, method_call,
on_battery_provider_registered, device);
if (!device->battery_pending_call) {
spa_log_error(device->monitor->log, "Failed to register battery provider");
return;
}
if (!dbus_pending_call_set_notify(
device->battery_pending_call, on_battery_provider_registered,
device, NULL)) {
spa_log_error(device->monitor->log, "Failed to register battery provider");
cancel_and_unref(&device->battery_pending_call);
}
}
static int media_codec_to_endpoint(const struct media_codec *codec,
@ -3219,7 +3208,6 @@ static void transport_set_property_volume(struct spa_bt_transport *transport, ui
const char *interface = BLUEZ_MEDIA_TRANSPORT_INTERFACE;
const char *name = "Volume";
int res = 0;
dbus_bool_t ret;
cancel_and_unref(&transport->volume_call);
@ -3240,15 +3228,8 @@ static void transport_set_property_volume(struct spa_bt_transport *transport, ui
dbus_message_iter_append_basic(&it[1], DBUS_TYPE_UINT16, &value);
dbus_message_iter_close_container(&it[0], &it[1]);
ret = dbus_connection_send_with_reply(monitor->conn, m, &transport->volume_call, -1);
if (!ret || !transport->volume_call) {
res = -EIO;
goto fail;
}
ret = dbus_pending_call_set_notify(transport->volume_call,
transport_set_property_volume_reply, transport, NULL);
if (!ret) {
transport->volume_call = send_with_reply(monitor->conn, m, transport_set_property_volume_reply, transport);
if (!transport->volume_call) {
res = -EIO;
goto fail;
}
@ -3445,7 +3426,6 @@ static int do_transport_acquire(struct spa_bt_transport *transport)
{
struct spa_bt_monitor *monitor = transport->monitor;
spa_autoptr(DBusMessage) m = NULL;
dbus_bool_t ret;
struct spa_bt_transport *t_linked;
spa_list_for_each(t_linked, &transport->bap_transport_linked, bap_transport_linked) {
@ -3470,12 +3450,8 @@ static int do_transport_acquire(struct spa_bt_transport *transport)
if (m == NULL)
return -ENOMEM;
ret = dbus_connection_send_with_reply(monitor->conn, m, &transport->acquire_call, -1);
if (!ret || transport->acquire_call == NULL)
return -EIO;
ret = dbus_pending_call_set_notify(transport->acquire_call, transport_acquire_reply, transport, NULL);
if (!ret)
transport->acquire_call = send_with_reply(monitor->conn, m, transport_acquire_reply, transport);
if (!transport->acquire_call)
return -EIO;
return 0;
@ -3707,7 +3683,6 @@ static bool media_codec_switch_process_current(struct spa_bt_media_codec_switch
enum spa_bt_media_direction direction;
char *local_endpoint = NULL;
int res, config_size;
dbus_bool_t dbus_ret;
spa_autoptr(DBusMessage) m = NULL;
DBusMessageIter iter, d;
int i;
@ -3807,18 +3782,12 @@ static bool media_codec_switch_process_current(struct spa_bt_media_codec_switch
dbus_message_iter_close_container(&iter, &d);
spa_assert(sw->pending == NULL);
dbus_ret = dbus_connection_send_with_reply(sw->device->monitor->conn, m, &sw->pending, -1);
if (!dbus_ret || sw->pending == NULL) {
sw->pending = send_with_reply(sw->device->monitor->conn, m, media_codec_switch_reply, sw);
if (!sw->pending) {
spa_log_error(sw->device->monitor->log, "media codec switch %p: dbus call failure, try next", sw);
goto next;
}
dbus_ret = dbus_pending_call_set_notify(sw->pending, media_codec_switch_reply, sw, NULL);
if (!dbus_ret) {
spa_log_error(sw->device->monitor->log, "media codec switch %p: dbus set notify failure", sw);
goto next;
}
free(local_endpoint);
return true;
@ -4422,7 +4391,6 @@ static int bluez_register_endpoint_legacy(struct spa_bt_adapter *adapter,
char *object_path = NULL;
spa_autoptr(DBusMessage) m = NULL;
DBusMessageIter object_it, dict_it;
DBusPendingCall *call;
uint8_t caps[A2DP_MAX_CAPS_SIZE];
int ret, caps_size;
uint16_t codec_id = codec->codec_id;
@ -4458,8 +4426,10 @@ static int bluez_register_endpoint_legacy(struct spa_bt_adapter *adapter,
dbus_message_iter_close_container(&object_it, &dict_it);
dbus_connection_send_with_reply(monitor->conn, m, &call, -1);
dbus_pending_call_set_notify(call, bluez_register_endpoint_legacy_reply, adapter, NULL);
if (!send_with_reply(monitor->conn, m, bluez_register_endpoint_legacy_reply, adapter)) {
ret = -EIO;
goto error;
}
free(object_path);
@ -4832,7 +4802,6 @@ static int adapter_register_application(struct spa_bt_adapter *a, bool bap)
const char *ep_type_name = (bap ? "LE Audio" : "A2DP");
spa_autoptr(DBusMessage) m = NULL;
DBusMessageIter i, d;
DBusPendingCall *call;
if (bap && a->bap_application_registered)
return 0;
@ -4866,10 +4835,8 @@ static int adapter_register_application(struct spa_bt_adapter *a, bool bap)
dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY, "{sv}", &d);
dbus_message_iter_close_container(&i, &d);
dbus_connection_send_with_reply(monitor->conn, m, &call, -1);
dbus_pending_call_set_notify(call,
bap ? bluez_register_application_bap_reply : bluez_register_application_a2dp_reply,
a, NULL);
if (!send_with_reply(monitor->conn, m, bap ? bluez_register_application_bap_reply : bluez_register_application_a2dp_reply, a))
return -EIO;
return 0;
}
@ -5147,7 +5114,6 @@ static void get_managed_objects(struct spa_bt_monitor *monitor)
return;
spa_autoptr(DBusMessage) m = NULL;
DBusPendingCall *call;
m = dbus_message_new_method_call(BLUEZ_SERVICE,
"/",
@ -5156,10 +5122,7 @@ static void get_managed_objects(struct spa_bt_monitor *monitor)
dbus_message_set_auto_start(m, false);
dbus_connection_send_with_reply(monitor->conn, m, &call, -1);
dbus_pending_call_set_notify(call, get_managed_objects_reply, monitor, NULL);
monitor->get_managed_objects_call = call;
monitor->get_managed_objects_call = send_with_reply(monitor->conn, m, get_managed_objects_reply, monitor);
}
static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)

View file

@ -44,4 +44,25 @@ static inline bool reply_with_error(DBusConnection *conn,
return reply && dbus_connection_send(conn, reply, NULL);
}
static inline DBusPendingCall *send_with_reply(DBusConnection *conn,
DBusMessage *m,
DBusPendingCallNotifyFunction callback, void *user_data)
{
DBusPendingCall *pending_call;
if (!dbus_connection_send_with_reply(conn, m, &pending_call, DBUS_TIMEOUT_USE_DEFAULT))
return NULL;
if (!pending_call)
return NULL;
if (!dbus_pending_call_set_notify(pending_call, callback, user_data, NULL)) {
dbus_pending_call_cancel(pending_call);
dbus_pending_call_unref(pending_call);
return NULL;
}
return pending_call;
}
#endif /* SPA_BLUEZ5_DBUS_HELPERS_H */

View file

@ -40,30 +40,6 @@ struct dbus_cmd_data {
void *user_data;
};
static bool mm_dbus_connection_send_with_reply(struct impl *this, DBusMessage *m, DBusPendingCall **pending_return,
DBusPendingCallNotifyFunction function, void *user_data)
{
spa_assert(*pending_return == NULL);
DBusPendingCall *pending_call;
if (!dbus_connection_send_with_reply(this->conn, m, &pending_call, -1)) {
spa_log_debug(this->log, "dbus call failure");
return false;
}
spa_assert(pending_call);
if (!dbus_pending_call_set_notify(pending_call, function, user_data, NULL)) {
spa_log_debug(this->log, "dbus set notify failure");
cancel_and_unref(&pending_call);
return false;
}
*pending_return = pending_call;
return true;
}
static int mm_state_to_clcc(struct impl *this, MMCallState state)
{
switch (state) {
@ -620,7 +596,9 @@ static DBusHandlerResult mm_filter_cb(DBusConnection *bus, DBusMessage *m, void
if (m == NULL)
goto finish;
dbus_message_append_args(m, DBUS_TYPE_STRING, &mm_call_interface, DBUS_TYPE_INVALID);
if (!mm_dbus_connection_send_with_reply(this, m, &call_object->pending, mm_get_call_properties_reply, call_object)) {
call_object->pending = send_with_reply(this->conn, m, mm_get_call_properties_reply, call_object);
if (!call_object->pending) {
spa_log_error(this->log, "dbus call failure");
goto finish;
}
@ -849,7 +827,9 @@ bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error)
*error = CMEE_AG_FAILURE;
return false;
}
if (!mm_dbus_connection_send_with_reply(this, m, &call_object->pending, mm_get_call_simple_reply, data)) {
call_object->pending = send_with_reply(this->conn, m, mm_get_call_simple_reply, data);
if (!call_object->pending) {
spa_log_error(this->log, "dbus call failure");
if (error)
*error = CMEE_AG_FAILURE;
@ -906,7 +886,9 @@ bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error)
*error = CMEE_AG_FAILURE;
return false;
}
if (!mm_dbus_connection_send_with_reply(this, m, &call_object->pending, mm_get_call_simple_reply, data)) {
call_object->pending = send_with_reply(this->conn, m, mm_get_call_simple_reply, data);
if (!call_object->pending) {
spa_log_error(this->log, "dbus call failure");
if (error)
*error = CMEE_AG_FAILURE;
@ -971,7 +953,9 @@ bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cm
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
append_basic_variant_dict_entry(&dict, "number", DBUS_TYPE_STRING, "s", &number);
dbus_message_iter_close_container(&iter, &dict);
if (!mm_dbus_connection_send_with_reply(this, m, &this->voice_pending, mm_get_call_create_reply, data)) {
this->voice_pending = send_with_reply(this->conn, m, mm_get_call_create_reply, data);
if (!this->voice_pending) {
spa_log_error(this->log, "dbus call failure");
if (error)
*error = CMEE_AG_FAILURE;
@ -1030,7 +1014,9 @@ bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cm
return false;
}
dbus_message_append_args(m, DBUS_TYPE_STRING, &dtmf, DBUS_TYPE_INVALID);
if (!mm_dbus_connection_send_with_reply(this, m, &call_object->pending, mm_get_call_simple_reply, data)) {
call_object->pending = send_with_reply(this->conn, m, mm_get_call_simple_reply, data);
if (!call_object->pending) {
spa_log_error(this->log, "dbus call failure");
if (error)
*error = CMEE_AG_FAILURE;
@ -1111,7 +1097,8 @@ void *mm_register(struct spa_log *log, void *dbus_connection, const struct spa_d
dbus_message_set_auto_start(m, false);
if (!mm_dbus_connection_send_with_reply(this, m, &this->pending, mm_get_managed_objects_reply, this)) {
this->pending = send_with_reply(this->conn, m, mm_get_managed_objects_reply, this);
if (!this->pending) {
spa_log_error(this->log, "dbus call failure");
return NULL;
}

View file

@ -82,8 +82,9 @@ static int update_battery_percentage(struct impl *this)
DBUS_TYPE_INVALID);
dbus_message_set_auto_start(m, false);
dbus_connection_send_with_reply(this->conn, m, &this->pending_get_call, -1);
dbus_pending_call_set_notify(this->pending_get_call, upower_get_percentage_properties_reply, this, NULL);
this->pending_get_call = send_with_reply(this->conn, m, upower_get_percentage_properties_reply, this);
if (!this->pending_get_call)
return -EIO;
return 0;
}