From: Luiz Augusto von Dentz <[email protected]>
This changes endpoint.presets command to take codec as parameter.
---
client/player.c | 240 +++++++++++++++++++++++++++++++++++-------------
1 file changed, 175 insertions(+), 65 deletions(-)
diff --git a/client/player.c b/client/player.c
index 58e14654ffb0..a9f56fb94b9b 100644
--- a/client/player.c
+++ b/client/player.c
@@ -78,6 +78,7 @@ struct endpoint {
uint8_t cis;
char *transport;
DBusMessage *msg;
+ struct preset *preset;
};
static DBusConnection *dbus_conn;
@@ -1166,7 +1167,7 @@ struct codec_qos {
};
struct codec_preset {
- const char *name;
+ char *name;
const struct iovec data;
const struct codec_qos qos;
uint8_t target_latency;
@@ -1410,9 +1411,10 @@ static struct codec_preset lc3_presets[] = {
LC3_10_UNFRAMED(155u, 13u, 100u, 40000u)),
};
-#define PRESET(_uuid, _presets, _default_index) \
+#define PRESET(_uuid, _codec, _presets, _default_index) \
{ \
.uuid = _uuid, \
+ .codec = _codec, \
.custom = { .name = "custom" }, \
.default_preset = &_presets[_default_index], \
.presets = _presets, \
@@ -1421,46 +1423,142 @@ static struct codec_preset lc3_presets[] = {
static struct preset {
const char *uuid;
+ uint8_t codec;
+ uint16_t cid;
+ uint16_t vid;
struct codec_preset custom;
struct codec_preset *default_preset;
struct codec_preset *presets;
size_t num_presets;
} presets[] = {
- PRESET(A2DP_SOURCE_UUID, sbc_presets, 6),
- PRESET(A2DP_SINK_UUID, sbc_presets, 6),
- PRESET(PAC_SINK_UUID, lc3_presets, 3),
- PRESET(PAC_SOURCE_UUID, lc3_presets, 3),
+ PRESET(A2DP_SOURCE_UUID, A2DP_CODEC_SBC, sbc_presets, 6),
+ PRESET(A2DP_SINK_UUID, A2DP_CODEC_SBC, sbc_presets, 6),
+ PRESET(PAC_SINK_UUID, LC3_ID, lc3_presets, 3),
+ PRESET(PAC_SOURCE_UUID, LC3_ID, lc3_presets, 3),
};
-static struct codec_preset *find_preset(const char *uuid, const char *name)
+static void parse_vendor_codec(const char *codec, uint16_t *vid, uint16_t *cid)
+{
+ char **list;
+ char *endptr = NULL;
+
+ if (!codec)
+ return;
+
+ list = g_strsplit(codec, ":", 2);
+
+ if (vid)
+ *vid = strtol(list[0], &endptr, 0);
+
+ if (cid)
+ *cid = strtol(list[1], &endptr, 0);
+
+ g_strfreev(list);
+}
+
+static struct preset *find_presets(const char *uuid, uint8_t codec,
+ uint16_t vid, uint16_t cid)
{
size_t i;
+ if (codec == 0xff) {
+ GList *l;
+
+ for (l = local_endpoints; l; l = g_list_next(l)) {
+ struct endpoint *ep = l->data;
+
+ if (strcasecmp(ep->uuid, uuid) || ep->codec != codec)
+ continue;
+
+ if (ep->codec == 0xff && (ep->vid != vid ||
+ ep->cid != cid))
+ continue;
+
+ return ep->preset;
+ }
+
+ return NULL;
+ }
+
for (i = 0; i < ARRAY_SIZE(presets); i++) {
struct preset *preset = &presets[i];
- if (!strcasecmp(preset->uuid, uuid)) {
- size_t j;
+ if (preset->codec != codec)
+ continue;
- if (!name)
- return preset->default_preset;
- else if (!strcmp(name, "custom"))
- return &preset->custom;
-
- for (j = 0; j < preset->num_presets; j++) {
- struct codec_preset *p;
-
- p = &preset->presets[j];
-
- if (!strcmp(p->name, name))
- return p;
- }
- }
+ if (!strcasecmp(preset->uuid, uuid))
+ return preset;
}
return NULL;
}
+static struct preset *find_vendor_presets(const char *uuid, const char *codec)
+{
+ uint16_t cid;
+ uint16_t vid;
+
+ if (!uuid || !codec)
+ return NULL;
+
+ parse_vendor_codec(codec, &vid, &cid);
+
+ return find_presets(uuid, 0xff, vid, cid);
+}
+
+static struct preset *find_presets_name(const char *uuid, const char *codec)
+{
+ uint8_t id;
+ char *endptr = NULL;
+
+ if (!uuid || !codec)
+ return NULL;
+
+ if (strrchr(codec, ':'))
+ return find_vendor_presets(uuid, codec);
+
+ id = strtol(codec, &endptr, 0);
+
+ return find_presets(uuid, id, 0x0000, 0x0000);
+}
+
+static struct codec_preset *preset_find_name(struct preset *preset,
+ const char *name)
+{
+ size_t i;
+
+ if (!preset)
+ return NULL;
+
+ if (!name)
+ return preset->default_preset;
+ else if (!strcmp(name, "custom"))
+ return &preset->custom;
+
+ for (i = 0; i < preset->num_presets; i++) {
+ struct codec_preset *p;
+
+ p = &preset->presets[i];
+
+ if (!strcmp(p->name, name))
+ return p;
+ }
+
+ return NULL;
+}
+
+static struct codec_preset *find_preset(const char *uuid, const char *codec,
+ const char *name)
+{
+ struct preset *preset;
+
+ preset = find_presets_name(uuid, codec);
+ if (!preset)
+ return NULL;
+
+ return preset_find_name(preset, name);
+}
+
static DBusMessage *endpoint_select_config_reply(DBusMessage *msg,
uint8_t *data, size_t len)
{
@@ -1525,7 +1623,7 @@ static void select_config_response(const char *input, void *user_data)
uint8_t *data;
size_t len;
- p = find_preset(ep->uuid, input);
+ p = preset_find_name(ep->preset, input);
if (p) {
data = p->data.iov_base;
len = p->data.iov_len;
@@ -1580,7 +1678,7 @@ static DBusMessage *endpoint_select_configuration(DBusConnection *conn,
return NULL;
}
- p = find_preset(ep->uuid, NULL);
+ p = preset_find_name(ep->preset, NULL);
if (!p) {
reply = g_dbus_create_error(msg, "org.bluez.Error.Rejected",
NULL);
@@ -1755,7 +1853,7 @@ static void select_properties_response(const char *input, void *user_data)
struct codec_preset *p;
DBusMessage *reply;
- p = find_preset(ep->uuid, input);
+ p = preset_find_name(ep->preset, input);
if (p) {
reply = endpoint_select_properties_reply(ep, ep->msg, p);
goto done;
@@ -1797,9 +1895,9 @@ static DBusMessage *endpoint_select_properties(DBusConnection *conn,
return NULL;
}
- p = find_preset(ep->uuid, NULL);
+ p = preset_find_name(ep->preset, NULL);
if (!p)
- NULL;
+ return NULL;
reply = endpoint_select_properties_reply(ep, msg, p);
if (!reply)
@@ -1903,6 +2001,11 @@ static void endpoint_free(void *data)
if (ep->msg)
dbus_message_unref(ep->msg);
+ if (ep->codec == 0xff) {
+ free(ep->preset->custom.name);
+ free(ep->preset);
+ }
+
g_free(ep->path);
g_free(ep->uuid);
g_free(ep);
@@ -2312,7 +2415,6 @@ static void cmd_register_endpoint(int argc, char *argv[])
{
struct endpoint *ep;
char *endptr = NULL;
- char **list;
ep = g_new0(struct endpoint, 1);
ep->uuid = g_strdup(argv[1]);
@@ -2324,12 +2426,13 @@ static void cmd_register_endpoint(int argc, char *argv[])
local_endpoints = g_list_append(local_endpoints, ep);
if (strrchr(argv[2], ':')) {
- list = g_strsplit(argv[2], ":", 2);
-
ep->codec = 0xff;
- ep->vid = strtol(list[0], &endptr, 0);
- endptr = NULL;
- ep->cid = strtol(list[1], &endptr, 0);
+ parse_vendor_codec(argv[2], &ep->cid, &ep->vid);
+ ep->preset = new0(struct preset, 1);
+ ep->preset->custom.name = strdup("custom");
+ ep->preset->default_preset = &ep->preset->custom;
+ } else {
+ ep->preset = find_presets_name(ep->uuid, argv[2]);
}
if (argc > 3)
@@ -2489,7 +2592,7 @@ static void cmd_config_endpoint(int argc, char *argv[])
}
if (argc > 3) {
- preset = find_preset(cfg->ep->uuid, argv[3]);
+ preset = preset_find_name(cfg->ep->preset, argv[3]);
if (!preset) {
bt_shell_printf("Preset %s not found\n", argv[3]);
goto fail;
@@ -2835,46 +2938,50 @@ static void custom_frequency(const char *input, void *user_data)
custom_duration, user_data);
}
-static void cmd_presets_endpoint(int argc, char *argv[])
+static void print_presets(struct preset *preset)
{
size_t i;
+ struct codec_preset *p;
+
+ p = &preset->custom;
+
+ bt_shell_printf("%s%s\n", p == preset->default_preset ? "*" : "",
+ p->name);
+
+ for (i = 0; i < preset->num_presets; i++) {
+ p = &preset->presets[i];
+ bt_shell_printf("%s%s\n", p == preset->default_preset ?
+ "*" : "", p->name);
+ }
+}
+
+static void cmd_presets_endpoint(int argc, char *argv[])
+{
+ struct preset *preset;
struct codec_preset *default_preset = NULL;
- if (argc > 2) {
- default_preset = find_preset(argv[1], argv[2]);
+ if (argc > 3) {
+ default_preset = find_preset(argv[1], argv[2], argv[3]);
if (!default_preset) {
- bt_shell_printf("Preset %s not found\n", argv[2]);
+ bt_shell_printf("Preset %s not found\n", argv[3]);
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
}
- for (i = 0; i < ARRAY_SIZE(presets); i++) {
- struct preset *preset = &presets[i];
-
- if (!strcasecmp(preset->uuid, argv[1])) {
- size_t j;
- struct codec_preset *p;
-
- if (default_preset) {
- preset->default_preset = default_preset;
- break;
- }
-
- p = &preset->custom;
-
- bt_shell_printf("%s%s\n", p == preset->default_preset ?
- "*" : "", p->name);
-
- for (j = 0; j < preset->num_presets; j++) {
- p = &preset->presets[j];
-
- bt_shell_printf("%s%s\n",
- p == preset->default_preset ?
- "*" : "", p->name);
- }
- }
+ preset = find_presets_name(argv[1], argv[2]);
+ if (!preset) {
+ bt_shell_printf("No preset found\n");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
+ if (default_preset) {
+ preset->default_preset = default_preset;
+ goto done;
+ }
+
+ print_presets(preset);
+
+done:
if (default_preset && !strcmp(default_preset->name, "custom")) {
bt_shell_prompt_input("Codec", "Enter frequency (Khz):",
custom_frequency, default_preset);
@@ -2904,7 +3011,8 @@ static const struct bt_shell_menu endpoint_menu = {
cmd_config_endpoint,
"Configure Endpoint",
endpoint_generator },
- { "presets", "<UUID> [default]", cmd_presets_endpoint,
+ { "presets", "<UUID> <codec[:company]> [default]",
+ cmd_presets_endpoint,
"List available presets",
uuid_generator },
{} },
@@ -2938,6 +3046,8 @@ static void register_endpoints(GDBusProxy *proxy)
continue;
ep = endpoint_new(cap);
+ ep->preset = find_presets(ep->uuid, ep->codec, ep->vid,
+ ep->cid);
ep->max_transports = UINT8_MAX;
ep->auto_accept = true;
ep->cig = BT_ISO_QOS_CIG_UNSET;
--
2.40.0
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=747185
---Test result---
Test Summary:
CheckPatch PASS 0.69 seconds
GitLint PASS 0.34 seconds
BuildEll PASS 26.35 seconds
BluezMake PASS 756.71 seconds
MakeCheck PASS 11.61 seconds
MakeDistcheck PASS 152.87 seconds
CheckValgrind PASS 245.82 seconds
CheckSmatch PASS 329.72 seconds
bluezmakeextell PASS 99.86 seconds
IncrementalBuild PASS 637.77 seconds
ScanBuild PASS 990.47 seconds
---
Regards,
Linux Bluetooth