@@ -66,6 +66,8 @@ struct endpoint {
char *path;
char *uuid;
uint8_t codec;
+ uint16_t cid;
+ uint16_t vid;
struct iovec *caps;
bool auto_accept;
bool acquiring;
@@ -85,6 +87,7 @@ static GList *endpoints = NULL;
static GList *local_endpoints = NULL;
static GList *transports = NULL;
static struct queue *ios = NULL;
+static bool is_cid_available = FALSE;
struct transport {
GDBusProxy *proxy;
@@ -1815,7 +1818,8 @@ static void endpoint_free(void *data)
struct endpoint *ep = data;
if (ep->caps) {
- g_free(ep->caps->iov_base);
+ if (ep->caps->iov_base)
+ g_free(ep->caps->iov_base);
g_free(ep->caps);
}
@@ -1865,10 +1869,32 @@ static gboolean endpoint_get_capabilities(const GDBusPropertyTable *property,
return TRUE;
}
+static gboolean endpoint_get_cid(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct endpoint *ep = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &ep->cid);
+
+ return TRUE;
+}
+
+static gboolean endpoint_get_vid(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct endpoint *ep = data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &ep->vid);
+
+ return TRUE;
+}
+
static const GDBusPropertyTable endpoint_properties[] = {
{ "UUID", "s", endpoint_get_uuid, NULL, NULL },
{ "Codec", "y", endpoint_get_codec, NULL, NULL },
{ "Capabilities", "ay", endpoint_get_capabilities, NULL, NULL },
+ { "CompanyID", "q", endpoint_get_cid, NULL, NULL },
+ { "VendorCodecID", "q", endpoint_get_vid, NULL, NULL },
{ }
};
@@ -1886,12 +1912,20 @@ static void register_endpoint_setup(DBusMessageIter *iter, void *user_data)
g_dbus_dict_append_entry(&dict, "Codec", DBUS_TYPE_BYTE, &ep->codec);
- g_dbus_dict_append_basic_array(&dict, DBUS_TYPE_STRING, &key,
+ g_dbus_dict_append_entry(&dict, "CompanyID", DBUS_TYPE_UINT16,
+ &ep->cid);
+
+ g_dbus_dict_append_entry(&dict, "VendorCodecID", DBUS_TYPE_UINT16,
+ &ep->vid);
+
+ if (ep->caps->iov_len) {
+ g_dbus_dict_append_basic_array(&dict, DBUS_TYPE_STRING, &key,
DBUS_TYPE_BYTE, &ep->caps->iov_base,
ep->caps->iov_len);
- bt_shell_printf("Capabilities:\n");
- bt_shell_hexdump(ep->caps->iov_base, ep->caps->iov_len);
+ bt_shell_printf("Capabilities:\n");
+ bt_shell_hexdump(ep->caps->iov_base, ep->caps->iov_len);
+ }
dbus_message_iter_close_container(iter, &dict);
}
@@ -1950,6 +1984,21 @@ fail:
}
+static void get_cid_vid(const char *input, uint32_t *id)
+{
+ char *endptr = NULL;
+ int value;
+
+ value = strtol(input, &endptr, 0);
+
+ if (!endptr || *endptr != '\0' || value > UINT32_MAX) {
+ bt_shell_printf("Invalid argument: %s\n", input);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ *id = (uint32_t)value;
+}
+
static void endpoint_cis(const char *input, void *user_data)
{
struct endpoint *ep = user_data;
@@ -2010,19 +2059,55 @@ static void endpoint_auto_accept(const char *input, void *user_data)
bt_shell_prompt_input(ep->path, "CIG (auto/value):", endpoint_cig, ep);
}
+static void endpoint_set_id(const char *input, void *user_data)
+{
+ struct endpoint *ep = user_data;
+ uint32_t val;
+
+ get_cid_vid(input, &val);
+ ep->cid = (uint16_t)(val & 0x0000ffff);
+ ep->vid = (uint16_t)((val & 0xffff0000) >> 16);
+
+ bt_shell_prompt_input(ep->path, "Auto Accept (yes/no):",
+ endpoint_auto_accept, ep);
+}
+
+void endpoint_set_parameters(struct endpoint *ep)
+{
+ if (!(strcasecmp(ep->uuid, PAC_SINK_UUID)) ||
+ !(strcasecmp(ep->uuid, PAC_SOURCE_UUID))) {
+ if ((ep->codec == 0xff) && (is_cid_available == FALSE))
+ bt_shell_prompt_input(ep->path,
+ "Enter Company ID & Vendor ID:",
+ endpoint_set_id, ep);
+ else
+ bt_shell_prompt_input(ep->path, "Auto Accept (yes/no):",
+ endpoint_auto_accept, ep);
+ } else
+ bt_shell_prompt_input(ep->path, "Auto Accept (yes/no):",
+ endpoint_auto_accept, ep);
+}
+
static void endpoint_set_capabilities(const char *input, void *user_data)
{
struct endpoint *ep = user_data;
- if (ep->caps)
+ if (ep->caps && ep->caps->iov_base) {
g_free(ep->caps->iov_base);
- else
+ ep->caps = g_new0(struct iovec, 1);
+ } else
ep->caps = g_new0(struct iovec, 1);
ep->caps->iov_base = str2bytearray((char *) input, &ep->caps->iov_len);
- bt_shell_prompt_input(ep->path, "Auto Accept (yes/no):",
- endpoint_auto_accept, ep);
+ if (ep->caps->iov_len == 0x01 &&
+ (*(uint8_t *)(ep->caps->iov_base)) == 0x00) {
+ g_free(ep->caps->iov_base);
+ ep->caps->iov_base = NULL;
+ ep->caps->iov_len = 0x00;
+ }
+
+ endpoint_set_parameters(ep);
}
static char *uuid_generator(const char *text, int state)
@@ -2073,13 +2158,13 @@ static void cmd_register_endpoint(int argc, char *argv[])
ep = g_new0(struct endpoint, 1);
ep->uuid = g_strdup(argv[1]);
ep->codec = strtol(argv[2], &endptr, 0);
+ ep->cid = 0x0000;
+ ep->vid = 0x0000;
ep->path = g_strdup_printf("%s/ep%u", BLUEZ_MEDIA_ENDPOINT_PATH,
g_list_length(local_endpoints));
local_endpoints = g_list_append(local_endpoints, ep);
- if (argc > 3)
- endpoint_set_capabilities(argv[3], ep);
- else {
+ if (argc == 3) {
const struct capabilities *cap;
cap = find_capabilities(ep->uuid, ep->codec);
@@ -2089,13 +2174,25 @@ static void cmd_register_endpoint(int argc, char *argv[])
/* Copy capabilities */
iov_append(&ep->caps, cap->data.iov_base,
- cap->data.iov_len);
+ cap->data.iov_len);
- bt_shell_prompt_input(ep->path, "Auto Accept (yes/no):",
- endpoint_auto_accept, ep);
+ endpoint_set_parameters(ep);
} else
- bt_shell_prompt_input(ep->path, "Enter capabilities:",
- endpoint_set_capabilities, ep);
+ bt_shell_prompt_input(ep->path, "Enter Capabilities:",
+ endpoint_set_capabilities, ep);
+ } else if (argc == 4) {
+ endpoint_set_capabilities(argv[3], ep);
+ } else if (argc == 5) {
+ uint32_t val = 0;
+
+ get_cid_vid(argv[4], &val);
+ ep->cid = (uint16_t)(val & 0x0000ffff);
+ ep->vid = (uint16_t)((val & 0xffff0000) >> 16);
+ is_cid_available = TRUE;
+
+ endpoint_set_capabilities(argv[3], ep);
+
+ is_cid_available = FALSE;
}
}
@@ -2638,7 +2735,7 @@ static const struct bt_shell_menu endpoint_menu = {
{ "show", "<endpoint>", cmd_show_endpoint,
"Endpoint information",
endpoint_generator },
- { "register", "<UUID> <codec> [capabilities...]",
+ { "register", "<UUID> <codec> [capabilities...] [Company ID]",
cmd_register_endpoint,
"Register Endpoint",
uuid_generator },