spa: bluez: use some more spa_auto*

This commit is contained in:
Barnabás Pőcze 2023-07-11 20:16:50 +02:00
parent ca85872e83
commit 4083502e03
7 changed files with 119 additions and 198 deletions

View file

@ -538,7 +538,6 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
struct impl *backend = userdata;
DBusMessageIter arg_i;
const char *transport_path;
int fd;
const char *sender;
const char *endpoint_path = NULL;
const char *air_codec = NULL;
@ -552,6 +551,7 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
struct spa_bt_transport *transport;
struct hsphfpd_transport_data *transport_data;
spa_autoptr(DBusMessage) r = NULL;
spa_autoclose int fd = -1;
if (!check_signature(m, "oha{sv}")) {
r = dbus_message_new_error(m, DBUS_ERROR_INVALID_ARGS, "Invalid signature in method call");
@ -569,7 +569,6 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
sender = dbus_message_get_sender(m);
if (!spa_streq(sender, backend->hsphfpd_service_id)) {
close(fd);
spa_log_error(backend->log, "Sender '%s' is not authorized", sender);
r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Sender '%s' is not authorized", sender);
goto fail;
@ -592,28 +591,24 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
&mtu);
if (!endpoint_path) {
close(fd);
spa_log_error(backend->log, "Endpoint property was not specified");
r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "Endpoint property was not specified");
goto fail;
}
if (!air_codec) {
close(fd);
spa_log_error(backend->log, "AirCodec property was not specified");
r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "AirCodec property was not specified");
goto fail;
}
if (!rx_volume_control) {
close(fd);
spa_log_error(backend->log, "RxVolumeControl property was not specified");
r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "RxVolumeControl property was not specified");
goto fail;
}
if (!tx_volume_control) {
close(fd);
spa_log_error(backend->log, "TxVolumeControl property was not specified");
r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "TxVolumeControl property was not specified");
goto fail;
@ -621,7 +616,6 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
if (rx_volume_control != HSPHFPD_VOLUME_CONTROL_NONE) {
if (rx_volume_gain == (uint16_t)-1) {
close(fd);
spa_log_error(backend->log, "RxVolumeGain property was not specified, but VolumeControl is not none");
r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "RxVolumeGain property was not specified, but VolumeControl is not none");
goto fail;
@ -632,7 +626,6 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
if (tx_volume_control != HSPHFPD_VOLUME_CONTROL_NONE) {
if (tx_volume_gain == (uint16_t)-1) {
close(fd);
spa_log_error(backend->log, "TxVolumeGain property was not specified, but VolumeControl is not none");
r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "TxVolumeGain property was not specified, but VolumeControl is not none");
goto fail;
@ -642,7 +635,6 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
}
if (!mtu) {
close(fd);
spa_log_error(backend->log, "MTU property was not specified");
r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "MTU property was not specified");
goto fail;
@ -650,14 +642,12 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
endpoint = endpoint_find(backend, endpoint_path);
if (!endpoint) {
close(fd);
spa_log_error(backend->log, "Endpoint %s does not exist", endpoint_path);
r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s does not exist", endpoint_path);
goto fail;
}
if (!endpoint->valid) {
close(fd);
spa_log_error(backend->log, "Endpoint %s is not valid", endpoint_path);
r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s is not valid", endpoint_path);
goto fail;
@ -665,7 +655,6 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
transport = spa_bt_transport_find(backend->monitor, endpoint_path);
if (!transport) {
close(fd);
spa_log_error(backend->log, "Endpoint %s is not connected", endpoint_path);
r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s is not connected", endpoint_path);
goto fail;
@ -675,7 +664,6 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
spa_log_warn(backend->log, "Expecting codec to be %d, got %d", transport->codec, codec);
if (transport->fd >= 0) {
close(fd);
spa_log_error(backend->log, "Endpoint %s has already active transport", endpoint_path);
r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s has already active transport", endpoint_path);
goto fail;
@ -698,7 +686,7 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
transport->read_mtu = mtu;
transport->write_mtu = mtu;
transport->fd = fd;
transport->fd = spa_steal_fd(fd);
if ((r = dbus_message_new_method_return(m)) == NULL)
return DBUS_HANDLER_RESULT_NEED_MEMORY;

View file

@ -1383,12 +1383,11 @@ static int sco_create_socket(struct impl *backend, struct spa_bt_adapter *adapte
struct sockaddr_sco addr;
socklen_t len;
bdaddr_t src;
int sock = -1;
sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK, BTPROTO_SCO);
spa_autoclose int sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK, BTPROTO_SCO);
if (sock < 0) {
spa_log_error(backend->log, "socket(SEQPACKET, SCO) %s", strerror(errno));
goto fail;
return -1;
}
str2ba(adapter->address, &src);
@ -1400,7 +1399,7 @@ static int sco_create_socket(struct impl *backend, struct spa_bt_adapter *adapte
if (bind(sock, (struct sockaddr *) &addr, len) < 0) {
spa_log_error(backend->log, "bind(): %s", strerror(errno));
goto fail;
return -1;
}
spa_log_debug(backend->log, "msbc=%d", (int)msbc);
@ -1411,16 +1410,11 @@ static int sco_create_socket(struct impl *backend, struct spa_bt_adapter *adapte
voice_config.setting = BT_VOICE_TRANSPARENT;
if (setsockopt(sock, SOL_BLUETOOTH, BT_VOICE, &voice_config, sizeof(voice_config)) < 0) {
spa_log_error(backend->log, "setsockopt(): %s", strerror(errno));
goto fail;
return -1;
}
}
return sock;
fail:
if (sock >= 0)
close(sock);
return -1;
return spa_steal_fd(sock);
}
static int sco_do_connect(struct spa_bt_transport *t)
@ -1429,11 +1423,7 @@ static int sco_do_connect(struct spa_bt_transport *t)
struct spa_bt_device *d = t->device;
struct transport_data *td = t->user_data;
struct sockaddr_sco addr;
socklen_t len;
int err;
int sock;
bdaddr_t dst;
int retry = 2;
spa_log_debug(backend->log, "transport %p: enter sco_do_connect, codec=%u",
t, t->codec);
@ -1443,52 +1433,45 @@ static int sco_do_connect(struct spa_bt_transport *t)
if (d->adapter == NULL)
return -EIO;
str2ba(d->address, &dst);
again:
sock = sco_create_socket(backend, d->adapter, (t->codec == HFP_AUDIO_CODEC_MSBC));
if (sock < 0)
return -1;
len = sizeof(addr);
memset(&addr, 0, len);
spa_zero(addr);
addr.sco_family = AF_BLUETOOTH;
bacpy(&addr.sco_bdaddr, &dst);
str2ba(d->address, &addr.sco_bdaddr);
spa_log_debug(backend->log, "transport %p: doing connect", t);
err = connect(sock, (struct sockaddr *) &addr, len);
if (err < 0 && errno == ECONNABORTED && retry-- > 0) {
spa_log_warn(backend->log, "connect(): %s. Remaining retry:%d",
strerror(errno), retry);
close(sock);
goto again;
} else if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) {
spa_log_error(backend->log, "connect(): %s", strerror(errno));
for (int retry = 2;;) {
spa_autoclose int sock = sco_create_socket(backend, d->adapter, (t->codec == HFP_AUDIO_CODEC_MSBC));
if (sock < 0)
return -1;
spa_log_debug(backend->log, "transport %p: doing connect", t);
err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
if (err < 0 && errno == ECONNABORTED && retry-- > 0) {
spa_log_warn(backend->log, "connect(): %s. Remaining retry:%d",
strerror(errno), retry);
continue;
} else if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) {
spa_log_error(backend->log, "connect(): %s", strerror(errno));
#ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE
if (errno == EOPNOTSUPP && t->codec == HFP_AUDIO_CODEC_MSBC &&
td->rfcomm->msbc_supported_by_hfp) {
/* Adapter doesn't support msbc. Renegotiate. */
d->adapter->msbc_probed = true;
d->adapter->has_msbc = false;
td->rfcomm->msbc_supported_by_hfp = false;
if (t->profile == SPA_BT_PROFILE_HFP_HF) {
td->rfcomm->hfp_ag_switching_codec = true;
rfcomm_send_reply(td->rfcomm, "+BCS: 1");
} else if (t->profile == SPA_BT_PROFILE_HFP_AG) {
rfcomm_send_cmd(td->rfcomm, "AT+BAC=1");
if (errno == EOPNOTSUPP && t->codec == HFP_AUDIO_CODEC_MSBC &&
td->rfcomm->msbc_supported_by_hfp) {
/* Adapter doesn't support msbc. Renegotiate. */
d->adapter->msbc_probed = true;
d->adapter->has_msbc = false;
td->rfcomm->msbc_supported_by_hfp = false;
if (t->profile == SPA_BT_PROFILE_HFP_HF) {
td->rfcomm->hfp_ag_switching_codec = true;
rfcomm_send_reply(td->rfcomm, "+BCS: 1");
} else if (t->profile == SPA_BT_PROFILE_HFP_AG) {
rfcomm_send_cmd(td->rfcomm, "AT+BAC=1");
}
}
}
#endif
goto fail_close;
return -1;
}
td->err = -EINPROGRESS;
return spa_steal_fd(sock);
}
td->err = -EINPROGRESS;
return sock;
fail_close:
close(sock);
return -1;
}
static int rfcomm_ag_sync_volume(struct rfcomm *rfcomm, bool later);
@ -1719,25 +1702,24 @@ static void sco_listen_event(struct spa_source *source)
struct impl *backend = source->data;
struct sockaddr_sco addr;
socklen_t addrlen;
int sock = -1;
char local_address[18], remote_address[18];
struct rfcomm *rfcomm;
struct spa_bt_transport *t = NULL;
if (source->rmask & (SPA_IO_HUP | SPA_IO_ERR)) {
spa_log_error(backend->log, "error listening SCO connection: %s", strerror(errno));
goto fail;
return;
}
memset(&addr, 0, sizeof(addr));
addrlen = sizeof(addr);
spa_log_debug(backend->log, "doing accept");
sock = accept(source->fd, (struct sockaddr *) &addr, &addrlen);
spa_autoclose int sock = accept(source->fd, (struct sockaddr *) &addr, &addrlen);
if (sock < 0) {
if (errno != EAGAIN)
spa_log_error(backend->log, "SCO accept(): %s", strerror(errno));
goto fail;
return;
}
ba2str(&addr.sco_bdaddr, remote_address);
@ -1747,7 +1729,7 @@ static void sco_listen_event(struct spa_source *source)
if (getsockname(sock, (struct sockaddr *) &addr, &addrlen) < 0) {
spa_log_error(backend->log, "SCO getsockname(): %s", strerror(errno));
goto fail;
return;
}
ba2str(&addr.sco_bdaddr, local_address);
@ -1763,19 +1745,19 @@ static void sco_listen_event(struct spa_source *source)
if (!t) {
spa_log_debug(backend->log, "No transport for adapter %s and remote %s",
local_address, remote_address);
goto fail;
return;
}
/* The Synchronous Connection shall always be established by the AG, i.e. the remote profile
should be a HSP AG or HFP AG profile */
if ((t->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY) == 0) {
spa_log_debug(backend->log, "transport %p: Rejecting incoming audio connection to an AG profile", t);
goto fail;
return;
}
if (t->fd >= 0) {
spa_log_debug(backend->log, "transport %p: Rejecting, audio already connected", t);
goto fail;
return;
}
spa_log_debug(backend->log, "transport %p: codec=%u", t, t->codec);
@ -1792,18 +1774,18 @@ static void sco_listen_event(struct spa_source *source)
voice_config.setting = BT_VOICE_TRANSPARENT;
if (setsockopt(sock, SOL_BLUETOOTH, BT_VOICE, &voice_config, sizeof(voice_config)) < 0) {
spa_log_error(backend->log, "transport %p: setsockopt(): %s", t, strerror(errno));
goto fail;
return;
}
}
/* First read from the accepted socket is non-blocking and returns a zero length buffer. */
if (read(sock, &buff, 1) == -1) {
spa_log_error(backend->log, "transport %p: Couldn't authorize SCO connection: %s", t, strerror(errno));
goto fail;
return;
}
}
t->fd = sock;
t->fd = spa_steal_fd(sock);
sco_start_source(t);
@ -1823,24 +1805,17 @@ static void sco_listen_event(struct spa_source *source)
}
spa_bt_transport_set_state(t, SPA_BT_TRANSPORT_STATE_PENDING);
return;
fail:
if (sock >= 0)
close(sock);
return;
}
static int sco_listen(struct impl *backend)
static void sco_listen(struct impl *backend)
{
struct sockaddr_sco addr;
int sock;
uint32_t defer = 1;
sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, BTPROTO_SCO);
spa_autoclose int sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, BTPROTO_SCO);
if (sock < 0) {
spa_log_error(backend->log, "socket(SEQPACKET, SCO) %m");
return -errno;
return;
}
/* Bind to local address */
@ -1850,7 +1825,7 @@ static int sco_listen(struct impl *backend)
if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
spa_log_error(backend->log, "bind(): %m");
goto fail_close;
return;
}
if (setsockopt(sock, SOL_BLUETOOTH, BT_DEFER_SETUP, &defer, sizeof(defer)) < 0) {
@ -1863,21 +1838,17 @@ static int sco_listen(struct impl *backend)
spa_log_debug(backend->log, "doing listen");
if (listen(sock, 1) < 0) {
spa_log_error(backend->log, "listen(): %m");
goto fail_close;
return;
}
backend->sco.func = sco_listen_event;
backend->sco.data = backend;
backend->sco.fd = sock;
backend->sco.fd = spa_steal_fd(sock);
backend->sco.mask = SPA_IO_IN;
backend->sco.rmask = 0;
spa_loop_add_source(backend->main_loop, &backend->sco);
return sock;
fail_close:
close(sock);
return -1;
return;
}
static int rfcomm_ag_set_volume(struct spa_bt_transport *t, int id)
@ -2195,7 +2166,7 @@ static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessag
struct rfcomm *rfcomm;
struct spa_bt_device *d;
struct spa_bt_transport *t = NULL;
int fd;
spa_autoclose int fd = -1;
if (!dbus_message_has_signature(m, "oha{sv}")) {
spa_log_warn(backend->log, "invalid NewConnection() signature");
@ -2234,7 +2205,7 @@ static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessag
rfcomm->path = strdup(path);
rfcomm->source.func = rfcomm_event;
rfcomm->source.data = rfcomm;
rfcomm->source.fd = fd;
rfcomm->source.fd = spa_steal_fd(fd);
rfcomm->source.mask = SPA_IO_IN;
rfcomm->source.rmask = 0;
/* By default all indicators are enabled */

View file

@ -1073,35 +1073,30 @@ static int adapter_init_bus_type(struct spa_bt_monitor *monitor, struct spa_bt_a
static int adapter_init_modalias(struct spa_bt_monitor *monitor, struct spa_bt_adapter *d)
{
char path[1024];
FILE *f = NULL;
int vendor_id, product_id;
const char *str;
int res = -EINVAL;
/* Lookup vendor/product id for the device, if present */
str = strrchr(d->path, '/'); /* hciXX */
if (str == NULL)
goto fail;
return -EINVAL;
snprintf(path, sizeof(path), "/sys/class/bluetooth/%s/device/modalias", str);
if ((f = fopen(path, "rbe")) == NULL) {
res = -errno;
goto fail;
}
spa_autoptr(FILE) f = fopen(path, "rbe");
if (f == NULL)
return -errno;
if (fscanf(f, "usb:v%04Xp%04X", &vendor_id, &product_id) != 2)
goto fail;
return -EINVAL;
d->source_id = SOURCE_ID_USB;
d->vendor_id = vendor_id;
d->product_id = product_id;
fclose(f);
spa_log_debug(monitor->log, "adapter %p: usb vendor:%04x product:%04x",
d, vendor_id, product_id);
return 0;
fail:
if (f)
fclose(f);
return res;
}
static struct spa_bt_adapter *adapter_create(struct spa_bt_monitor *monitor, const char *path)
@ -2271,11 +2266,10 @@ const struct media_codec **spa_bt_device_get_supported_media_codecs(struct spa_b
{
struct spa_bt_monitor *monitor = device->monitor;
const struct media_codec * const * const media_codecs = monitor->media_codecs;
const struct media_codec **supported_codecs;
spa_autofree const struct media_codec **supported_codecs = NULL;
size_t i, j, size;
*count = 0;
size = 8;
supported_codecs = malloc(size * sizeof(const struct media_codec *));
if (supported_codecs == NULL)
@ -2296,10 +2290,9 @@ const struct media_codec **spa_bt_device_get_supported_media_codecs(struct spa_b
#else
p = realloc(supported_codecs, size * sizeof(const struct media_codec *));
#endif
if (p == NULL) {
free(supported_codecs);
if (p == NULL)
return NULL;
}
supported_codecs = p;
}
}
@ -2307,7 +2300,7 @@ const struct media_codec **spa_bt_device_get_supported_media_codecs(struct spa_b
supported_codecs[j] = NULL;
*count = j;
return supported_codecs;
return spa_steal_ptr(supported_codecs);
}
static struct spa_bt_remote_endpoint *device_remote_endpoint_find(struct spa_bt_device *device, const char *path)
@ -3672,7 +3665,7 @@ static bool media_codec_switch_process_current(struct spa_bt_media_codec_switch
const struct media_codec *codec;
uint8_t config[A2DP_MAX_CAPS_SIZE];
enum spa_bt_media_direction direction;
char *local_endpoint = NULL;
spa_autofree char *local_endpoint = NULL;
int res, config_size;
spa_autoptr(DBusMessage) m = NULL;
DBusMessageIter iter, d;
@ -3691,19 +3684,19 @@ static bool media_codec_switch_process_current(struct spa_bt_media_codec_switch
if (ep == NULL || ep->capabilities == NULL || ep->uuid == NULL) {
spa_log_debug(sw->device->monitor->log, "media codec switch %p: endpoint %s not valid, try next",
sw, *sw->path_iter);
goto next;
return false;
}
/* Setup and check compatible configuration */
if (ep->codec != codec->codec_id) {
spa_log_debug(sw->device->monitor->log, "media codec switch %p: different codec, try next", sw);
goto next;
return false;
}
if (!(sw->profile & spa_bt_profile_from_uuid(ep->uuid))) {
spa_log_debug(sw->device->monitor->log, "media codec switch %p: wrong uuid (%s) for profile, try next",
sw, ep->uuid);
goto next;
return false;
}
if ((sw->profile & SPA_BT_PROFILE_A2DP_SINK) || (sw->profile & SPA_BT_PROFILE_BAP_SINK) ) {
@ -3715,13 +3708,13 @@ static bool media_codec_switch_process_current(struct spa_bt_media_codec_switch
} else {
spa_log_debug(sw->device->monitor->log, "media codec switch %p: bad profile (%d), try next",
sw, sw->profile);
goto next;
return false;
}
if (media_codec_to_endpoint(codec, direction, &local_endpoint) < 0) {
spa_log_debug(sw->device->monitor->log, "media codec switch %p: no endpoint for codec %s, try next",
sw, codec->name);
goto next;
return false;
}
/* Each endpoint can be used by only one device at a time (on each adapter) */
@ -3733,7 +3726,7 @@ static bool media_codec_switch_process_current(struct spa_bt_media_codec_switch
if (spa_streq(t->endpoint_path, local_endpoint)) {
spa_log_debug(sw->device->monitor->log, "media codec switch %p: endpoint %s in use, try next",
sw, local_endpoint);
goto next;
return false;
}
}
@ -3743,7 +3736,7 @@ static bool media_codec_switch_process_current(struct spa_bt_media_codec_switch
if (res < 0) {
spa_log_debug(sw->device->monitor->log, "media codec switch %p: incompatible capabilities (%d), try next",
sw, res);
goto next;
return false;
}
config_size = res;
@ -3758,7 +3751,7 @@ static bool media_codec_switch_process_current(struct spa_bt_media_codec_switch
m = dbus_message_new_method_call(BLUEZ_SERVICE, ep->path, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SetConfiguration");
if (m == NULL) {
spa_log_debug(sw->device->monitor->log, "media codec switch %p: dbus allocation failure, try next", sw);
goto next;
return false;
}
spa_bt_device_update_last_bluez_action_time(sw->device);
@ -3776,15 +3769,10 @@ static bool media_codec_switch_process_current(struct spa_bt_media_codec_switch
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;
return false;
}
free(local_endpoint);
return true;
next:
free(local_endpoint);
return false;
}
static void media_codec_switch_process(struct spa_bt_media_codec_switch *sw)
@ -4376,7 +4364,7 @@ static int bluez_register_endpoint_legacy(struct spa_bt_adapter *adapter,
{
struct spa_bt_monitor *monitor = adapter->monitor;
const char *path = adapter->path;
char *object_path = NULL;
spa_autofree char *object_path = NULL;
spa_autoptr(DBusMessage) m = NULL;
DBusMessageIter object_it, dict_it;
uint8_t caps[A2DP_MAX_CAPS_SIZE];
@ -4388,20 +4376,18 @@ static int bluez_register_endpoint_legacy(struct spa_bt_adapter *adapter,
ret = media_codec_to_endpoint(codec, direction, &object_path);
if (ret < 0)
goto error;
return ret;
ret = caps_size = codec->fill_caps(codec, sink ? MEDIA_CODEC_FLAG_SINK : 0, caps);
if (ret < 0)
goto error;
return ret;
m = dbus_message_new_method_call(BLUEZ_SERVICE,
path,
BLUEZ_MEDIA_INTERFACE,
"RegisterEndpoint");
if (m == NULL) {
ret = -EIO;
goto error;
}
if (m == NULL)
return -EIO;
dbus_message_iter_init_append(m, &object_it);
dbus_message_iter_append_basic(&object_it, DBUS_TYPE_OBJECT_PATH, &object_path);
@ -4414,18 +4400,10 @@ static int bluez_register_endpoint_legacy(struct spa_bt_adapter *adapter,
dbus_message_iter_close_container(&object_it, &dict_it);
if (!send_with_reply(monitor->conn, m, bluez_register_endpoint_legacy_reply, adapter)) {
ret = -EIO;
goto error;
}
free(object_path);
if (!send_with_reply(monitor->conn, m, bluez_register_endpoint_legacy_reply, adapter))
return -EIO;
return 0;
error:
free(object_path);
return ret;
}
static int adapter_register_endpoints_legacy(struct spa_bt_adapter *a)
@ -4522,7 +4500,6 @@ static DBusHandlerResult object_manager_handler(DBusConnection *c, DBusMessage *
struct spa_bt_monitor *monitor = user_data;
const struct media_codec * const * const media_codecs = monitor->media_codecs;
const char *path, *interface, *member;
char *endpoint;
DBusMessageIter iter, array;
DBusHandlerResult res;
int i;
@ -4572,13 +4549,13 @@ static DBusHandlerResult object_manager_handler(DBusConnection *c, DBusMessage *
if (caps_size < 0)
continue;
spa_autofree char *endpoint = NULL;
ret = media_codec_to_endpoint(codec, SPA_BT_MEDIA_SINK, &endpoint);
if (ret == 0) {
spa_log_info(monitor->log, "register media sink codec %s: %s", media_codecs[i]->name, endpoint);
append_media_object(&array, endpoint,
codec->bap ? SPA_BT_UUID_BAP_SINK : SPA_BT_UUID_A2DP_SINK,
codec_id, caps, caps_size);
free(endpoint);
}
}
@ -4587,13 +4564,13 @@ static DBusHandlerResult object_manager_handler(DBusConnection *c, DBusMessage *
if (caps_size < 0)
continue;
spa_autofree char *endpoint = NULL;
ret = media_codec_to_endpoint(codec, SPA_BT_MEDIA_SOURCE, &endpoint);
if (ret == 0) {
spa_log_info(monitor->log, "register media source codec %s: %s", media_codecs[i]->name, endpoint);
append_media_object(&array, endpoint,
codec->bap ? SPA_BT_UUID_BAP_SOURCE : SPA_BT_UUID_A2DP_SOURCE,
codec_id, caps, caps_size);
free(endpoint);
}
}
}
@ -4677,7 +4654,7 @@ static int register_media_endpoint(struct spa_bt_monitor *monitor,
if (!endpoint_should_be_registered(monitor, codec, direction))
return 0;
char *object_path = NULL;
spa_autofree char *object_path = NULL;
int ret = media_codec_to_endpoint(codec, direction, &object_path);
if (ret < 0)
return ret;
@ -4687,12 +4664,9 @@ static int register_media_endpoint(struct spa_bt_monitor *monitor,
if (!dbus_connection_register_object_path(monitor->conn,
object_path,
&vtable_endpoint, monitor))
{
ret = -EIO;
}
return -EIO;
free(object_path);
return ret;
return 0;
}
static int register_media_application(struct spa_bt_monitor * monitor)
@ -4738,7 +4712,7 @@ static void unregister_media_endpoint(struct spa_bt_monitor *monitor,
if (!endpoint_should_be_registered(monitor, codec, direction))
return;
char *object_path = NULL;
spa_autofree char *object_path = NULL;
int ret = media_codec_to_endpoint(codec, direction, &object_path);
if (ret < 0)
return;
@ -4747,8 +4721,6 @@ static void unregister_media_endpoint(struct spa_bt_monitor *monitor,
if (!dbus_connection_unregister_object_path(monitor->conn, object_path))
spa_log_warn(monitor->log, "failed to unregister %s\n", object_path);
free(object_path);
}
static void unregister_media_application(struct spa_bt_monitor * monitor)

View file

@ -29,10 +29,12 @@ int spa_bt_adapter_has_msbc(struct spa_bt_adapter *adapter)
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <spa/utils/cleanup.h>
int spa_bt_adapter_has_msbc(struct spa_bt_adapter *adapter)
{
int hci_id, res;
int sock = -1;
int hci_id;
spa_autoclose int sock = -1;
uint8_t features[8], max_page = 0;
struct sockaddr_hci a;
const char *str;
@ -46,28 +48,20 @@ int spa_bt_adapter_has_msbc(struct spa_bt_adapter *adapter)
sock = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);
if (sock < 0)
goto error;
return -errno;
memset(&a, 0, sizeof(a));
a.hci_family = AF_BLUETOOTH;
a.hci_dev = hci_id;
if (bind(sock, (struct sockaddr *) &a, sizeof(a)) < 0)
goto error;
return -errno;
if (hci_read_local_ext_features(sock, 0, &max_page, features, 1000) < 0)
goto error;
close(sock);
return -errno;
adapter->msbc_probed = true;
adapter->has_msbc = ((features[2] & LMP_TRSP_SCO) && (features[3] & LMP_ESCO)) ? 1 : 0;
return adapter->has_msbc;
error:
res = -errno;
if (sock >= 0)
close(sock);
return res;
}
#endif

View file

@ -9,6 +9,7 @@
*/
#include <spa/utils/string.h>
#include <spa/utils/cleanup.h>
#include "media-codecs.h"
@ -16,7 +17,8 @@ int media_codec_select_config(const struct media_codec_config configs[], size_t
uint32_t cap, int preferred_value)
{
size_t i;
int *scores, res;
spa_autofree int *scores = NULL;
int res;
unsigned int max_priority;
if (n == 0)
@ -54,9 +56,8 @@ int media_codec_select_config(const struct media_codec_config configs[], size_t
}
if (scores[res] < 0)
res = -EINVAL;
return -EINVAL;
free(scores);
return res;
}

View file

@ -786,7 +786,7 @@ bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error)
{
struct impl *this = modemmanager;
struct call *call_object, *call_tmp;
struct dbus_cmd_data *data;
spa_autofree struct dbus_cmd_data *data = NULL;
spa_autoptr(DBusMessage) m = NULL;
call_object = NULL;
@ -828,15 +828,15 @@ bool mm_answer_call(void *modemmanager, void *user_data, enum cmee_error *error)
return false;
}
return true;
return spa_steal_ptr(data), true;
}
bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error)
{
struct impl *this = modemmanager;
struct call *call_object, *call_tmp;
spa_autofree struct dbus_cmd_data *data= NULL;
spa_autoptr(DBusMessage) m = NULL;
struct dbus_cmd_data *data;
call_object = NULL;
spa_list_for_each(call_tmp, &this->call_list, link) {
@ -887,7 +887,7 @@ bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error)
return false;
}
return true;
return spa_steal_ptr(data), true;
}
static void append_basic_variant_dict_entry(DBusMessageIter *dict, const char* key, int variant_type_int, const char* variant_type_str, void* variant) {
@ -913,7 +913,7 @@ static inline bool is_valid_dial_string_char(char c)
bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cmee_error *error)
{
struct impl *this = modemmanager;
struct dbus_cmd_data *data;
spa_autofree struct dbus_cmd_data *data = NULL;
spa_autoptr(DBusMessage) m = NULL;
DBusMessageIter iter, dict;
@ -954,14 +954,14 @@ bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cm
return false;
}
return true;
return spa_steal_ptr(data), true;
}
bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cmee_error *error)
{
struct impl *this = modemmanager;
struct call *call_object, *call_tmp;
struct dbus_cmd_data *data;
spa_autofree struct dbus_cmd_data *data = NULL;
spa_autoptr(DBusMessage) m = NULL;
call_object = NULL;
@ -1015,7 +1015,7 @@ bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cm
return false;
}
return true;
return spa_steal_ptr(data), true;
}
const char *mm_get_incoming_call_number(void *modemmanager)

View file

@ -28,6 +28,7 @@
#include <spa/support/plugin.h>
#include <spa/monitor/device.h>
#include <spa/monitor/utils.h>
#include <spa/utils/cleanup.h>
#include <spa/utils/hook.h>
#include <spa/utils/type.h>
#include <spa/utils/keys.h>
@ -187,27 +188,21 @@ static int load_conf(struct spa_bt_quirks *this, const char *path)
{
char *data;
struct stat sbuf;
int fd = -1;
spa_autoclose int fd = -1;
spa_log_debug(this->log, "loading %s", path);
if ((fd = open(path, O_CLOEXEC | O_RDONLY)) < 0)
goto fail;
return -errno;
if (fstat(fd, &sbuf) < 0)
goto fail;
return -errno;
if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
goto fail;
close(fd);
return -errno;
load_quirks(this, data, sbuf.st_size);
munmap(data, sbuf.st_size);
return 0;
fail:
if (fd >= 0)
close(fd);
return -errno;
}
struct spa_bt_quirks *spa_bt_quirks_create(const struct spa_dict *info, struct spa_log *log)