mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
bluez5: better error/malformed input handling
Safer parsing of AT commands, additional null and error checks.
This commit is contained in:
parent
f0a2b6d01f
commit
f330446291
5 changed files with 56 additions and 21 deletions
|
|
@ -724,8 +724,11 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
|
|||
|
||||
fail:
|
||||
if (r) {
|
||||
dbus_connection_send(backend->conn, r, NULL);
|
||||
dbus_message_unref(r);
|
||||
DBusHandlerResult res = DBUS_HANDLER_RESULT_HANDLED;
|
||||
if (!dbus_connection_send(backend->conn, r, NULL))
|
||||
res = DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||
dbus_message_unref(r);
|
||||
return res;
|
||||
}
|
||||
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
|
|
@ -1069,6 +1072,11 @@ static DBusHandlerResult hsphfpd_parse_endpoint_properties(struct impl *backend,
|
|||
if (!endpoint->valid && endpoint->local_address && endpoint->remote_address && endpoint->profile && endpoint->role)
|
||||
endpoint->valid = true;
|
||||
|
||||
if (!endpoint->remote_address || !endpoint->local_address) {
|
||||
spa_log_debug(backend->log, NAME": Missing addresses for %s", endpoint->path);
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
d = spa_bt_device_find_by_address(backend->monitor, endpoint->remote_address, endpoint->local_address);
|
||||
if (!d) {
|
||||
spa_log_debug(backend->log, NAME": No device for %s", endpoint->path);
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
|
|||
struct impl *backend = rfcomm->backend;
|
||||
unsigned int features;
|
||||
unsigned int gain;
|
||||
unsigned int len, k, v;
|
||||
unsigned int len;
|
||||
unsigned int selected_codec;
|
||||
|
||||
if (sscanf(buf, "AT+BRSF=%u", &features) == 1) {
|
||||
|
|
@ -423,9 +423,10 @@ static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
|
|||
if (rfcomm->transport == NULL) {
|
||||
spa_log_warn(backend->log, NAME": can't create transport: %m");
|
||||
// TODO: We should manage the missing transport
|
||||
} else {
|
||||
rfcomm->transport->codec = HFP_AUDIO_CODEC_CVSD;
|
||||
spa_bt_device_connect_profile(rfcomm->device, rfcomm->profile);
|
||||
}
|
||||
rfcomm->transport->codec = HFP_AUDIO_CODEC_CVSD;
|
||||
spa_bt_device_connect_profile(rfcomm->device, rfcomm->profile);
|
||||
}
|
||||
|
||||
} else if (!rfcomm->slc_configured) {
|
||||
|
|
@ -489,21 +490,32 @@ static bool rfcomm_hfp_ag(struct spa_source *source, char* buf)
|
|||
// We expect battery status only (bitmask 10)
|
||||
rfcomm_send_reply(source, "+XAPL: iPhone,2");
|
||||
rfcomm_send_reply(source, "OK");
|
||||
} else if (sscanf(buf, "AT+IPHONEACCEV=%d", &len) == 1) {
|
||||
if (len < 1) {
|
||||
return false;
|
||||
}
|
||||
} else if (sscanf(buf, "AT+IPHONEACCEV=%u", &len) == 1) {
|
||||
unsigned int i;
|
||||
int k, v;
|
||||
|
||||
for (unsigned int i = 1; i <= len; i++) {
|
||||
buf = strchr(buf, ',') + 1;
|
||||
if (sscanf(buf, "%d", &k) != 1) return false;
|
||||
buf = strchr(buf, ',') + 1;
|
||||
if (sscanf(buf, "%d", &v) != 1) return false;
|
||||
if (len < 1 || len > 100)
|
||||
return false;
|
||||
|
||||
for (i = 1; i <= len; i++) {
|
||||
buf = strchr(buf, ',');
|
||||
if (buf == NULL)
|
||||
return false;
|
||||
++buf;
|
||||
if (sscanf(buf, "%d", &k) != 1)
|
||||
return false;
|
||||
|
||||
buf = strchr(buf, ',');
|
||||
if (buf == NULL)
|
||||
return false;
|
||||
++buf;
|
||||
if (sscanf(buf, "%d", &v) != 1)
|
||||
return false;
|
||||
|
||||
if (k == SPA_BT_HFP_HF_IPHONEACCEV_KEY_BATTERY) {
|
||||
// Battery level is reported in range of 0-9, convert to 0-100%
|
||||
uint8_t level = (v + 1) * 10;
|
||||
spa_log_debug(backend->log, NAME": battery level: %d%%", level);
|
||||
uint8_t level = (SPA_CLAMP(v, 0, 9) + 1) * 10;
|
||||
spa_log_debug(backend->log, NAME": battery level: %d%%", (int)level);
|
||||
|
||||
// TODO: report without Battery Provider (using props)
|
||||
spa_bt_device_report_battery_level(rfcomm->device, level);
|
||||
|
|
@ -625,9 +637,10 @@ static bool rfcomm_hfp_hf(struct spa_source *source, char* buf)
|
|||
if (rfcomm->transport == NULL) {
|
||||
spa_log_warn(backend->log, NAME": can't create transport: %m");
|
||||
// TODO: We should manage the missing transport
|
||||
} else {
|
||||
rfcomm->transport->codec = HFP_AUDIO_CODEC_CVSD;
|
||||
spa_bt_device_connect_profile(rfcomm->device, rfcomm->profile);
|
||||
}
|
||||
rfcomm->transport->codec = HFP_AUDIO_CODEC_CVSD;
|
||||
spa_bt_device_connect_profile(rfcomm->device, rfcomm->profile);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -351,6 +351,11 @@ static DBusHandlerResult ofono_audio_card_found(struct impl *backend, char *path
|
|||
close(fd);
|
||||
}
|
||||
|
||||
if (!remote_address || !local_address) {
|
||||
spa_log_error(backend->log, NAME": Missing addresses for %s", path);
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
d = spa_bt_device_find_by_address(backend->monitor, remote_address, local_address);
|
||||
if (!d) {
|
||||
spa_log_error(backend->log, NAME": Device doesn’t exist for %s", path);
|
||||
|
|
@ -449,8 +454,11 @@ static DBusHandlerResult ofono_new_audio_connection(DBusConnection *conn, DBusMe
|
|||
|
||||
fail:
|
||||
if (r) {
|
||||
dbus_connection_send(backend->conn, r, NULL);
|
||||
dbus_message_unref(r);
|
||||
DBusHandlerResult res = DBUS_HANDLER_RESULT_HANDLED;
|
||||
if (!dbus_connection_send(backend->conn, r, NULL))
|
||||
res = DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||
dbus_message_unref(r);
|
||||
return res;
|
||||
}
|
||||
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
|
|
|
|||
|
|
@ -1474,6 +1474,9 @@ static int impl_set_param(void *object,
|
|||
uint32_t profile;
|
||||
enum spa_bluetooth_audio_codec codec;
|
||||
|
||||
if (param == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if ((res = spa_pod_parse_object(param,
|
||||
SPA_TYPE_OBJECT_ParamProfile, NULL,
|
||||
SPA_PARAM_PROFILE_index, SPA_POD_Int(&id))) < 0) {
|
||||
|
|
@ -1496,6 +1499,9 @@ static int impl_set_param(void *object,
|
|||
struct spa_pod *props = NULL;
|
||||
struct node *node;
|
||||
|
||||
if (param == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if ((res = spa_pod_parse_object(param,
|
||||
SPA_TYPE_OBJECT_ParamRoute, NULL,
|
||||
SPA_PARAM_ROUTE_index, SPA_POD_Int(&id),
|
||||
|
|
|
|||
|
|
@ -692,7 +692,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman
|
|||
|
||||
static void emit_node_info(struct impl *this, bool full)
|
||||
{
|
||||
bool is_ag = (this->transport->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY);
|
||||
bool is_ag = this->transport && (this->transport->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY);
|
||||
struct spa_dict_item ag_node_info_items[] = {
|
||||
{ SPA_KEY_DEVICE_API, "bluez5" },
|
||||
{ SPA_KEY_MEDIA_CLASS, "Stream/Output/Audio" },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue