aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Ranostay <matt.ranostay@konsulko.com>2018-12-04 00:39:21 -0800
committerMatt Ranostay <matt.ranostay@konsulko.com>2018-12-05 15:23:40 +0000
commitf2aaebf3f8c1f9e71586a9d5f5c370d3338c07cf (patch)
treec66b75f86d5beae38ff30de45eeb47c94efa3ef8
parent547a7b88de739d6cf12fdc951cac106250aaca25 (diff)
binding: bluetooth: add MediaTransport1 support
Bug-AGL: SPEC-1630 SPEC-1986 Change-Id: I6ad1f85d4edc00239f891edf6994db416e8a2dbd Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com>
-rw-r--r--README.md25
-rw-r--r--binding/bluetooth-api.c75
-rw-r--r--binding/bluetooth-api.h33
-rw-r--r--binding/bluetooth-bluez.c15
4 files changed, 134 insertions, 14 deletions
diff --git a/README.md b/README.md
index 13bd068..50870df 100644
--- a/README.md
+++ b/README.md
@@ -221,6 +221,7 @@ Playing audio reporting event (not all fields will be passed in every event):
{
"adapter": "hci0",
"device": "dev_D0_81_7A_5A_BC_5E",
+ "type": "playback",
"track": {
"title": "True Colors",
"duration": 228000,
@@ -236,6 +237,30 @@ Playing audio reporting event (not all fields will be passed in every event):
}
</pre>
+A2DP transport addition/removal (some fields are optional):
+
+<pre>
+{
+ "adapter": "hci0",
+ "device": "dev_D0_81_7A_5A_BC_5E",
+ "action": "added",
+ "type": "transport",
+ "endpoint": "fd0"
+ "properties": {
+ "uuid": "0000110B-0000-1000-8000-00805F9B34FB",
+ "state": "idle",
+ "volume": 127
+ },
+}
+...
+{
+ "adapter": "hci0",
+ "device": "dev_D0_81_7A_5A_BC_5E",
+ "action": "removed",
+ "type": "transport",
+ "endpoint": "fd0"
+}
+</pre>
### agent event
diff --git a/binding/bluetooth-api.c b/binding/bluetooth-api.c
index 23ce55d..8388695 100644
--- a/binding/bluetooth-api.c
+++ b/binding/bluetooth-api.c
@@ -300,18 +300,23 @@ static void bluez_devices_signal_callback(
const char *name = NULL;
GVariant *val = NULL;
- if (g_strcmp0(key, BLUEZ_DEVICE_INTERFACE) != 0)
+ if (g_strcmp0(key, BLUEZ_DEVICE_INTERFACE) &&
+ g_strcmp0(key, BLUEZ_MEDIATRANSPORT_INTERFACE))
continue;
array1 = g_variant_iter_new(var);
while (g_variant_iter_next(array1, "{&sv}", &name, &val)) {
- ret = device_property_dbus2json(jobj,
- name, val, &is_config, &error);
+ if (!g_strcmp0(key, BLUEZ_DEVICE_INTERFACE))
+ ret = device_property_dbus2json(jobj,
+ name, val, &is_config, &error);
+ else
+ ret = mediatransport_property_dbus2json(jobj,
+ name, val, &is_config, &error);
g_variant_unref(val);
if (!ret) {
- AFB_WARNING("%s property %s - %s",
- "devices",
+ AFB_DEBUG("%s property %s - %s",
+ path,
key, error->message);
g_clear_error(&error);
}
@@ -323,12 +328,25 @@ static void bluez_devices_signal_callback(
if (array1) {
json_object_object_add(jresp, "action",
json_object_new_string("added"));
+
+ if (is_mediatransport1_interface(path)) {
+ gchar *endpoint = find_index(path, 5);
+ json_object_object_add(jresp, "type",
+ json_object_new_string("transport"));
+ json_object_object_add(jresp, "endpoint",
+ json_object_new_string(endpoint));
+ g_free(endpoint);
+
+ event = ns->media_event;
+ }
json_object_object_add(jresp, "properties", jobj);
} else if (is_mediaplayer1_interface(path) &&
g_str_has_suffix(path, BLUEZ_DEFAULT_PLAYER)) {
json_object_object_add(jresp, "connected",
json_object_new_boolean(TRUE));
+ json_object_object_add(jresp, "type",
+ json_object_new_string("playback"));
mediaplayer1_set_path(ns, path);
event = ns->media_event;
} else {
@@ -344,10 +362,22 @@ static void bluez_devices_signal_callback(
jresp = json_object_new_object();
json_process_path(jresp, path);
- if (is_mediaplayer1_interface(path)) {
+ if (is_mediatransport1_interface(path)) {
+ gchar *endpoint = find_index(path, 5);
+ json_object_object_add(jresp, "type",
+ json_object_new_string("transport"));
+ json_object_object_add(jresp, "action",
+ json_object_new_string("removed"));
+ json_object_object_add(jresp, "endpoint",
+ json_object_new_string(endpoint));
+ g_free(endpoint);
+
+ event = ns->media_event;
+ } else if (is_mediaplayer1_interface(path)) {
json_object_object_add(jresp, "connected",
json_object_new_boolean(FALSE));
- //mediaplayer1_set_path(ns, NULL);
+ json_object_object_add(jresp, "type",
+ json_object_new_string("playback"));
event = ns->media_event;
} else if (split_length(path) == 5) {
json_object_object_add(jresp, "action",
@@ -377,7 +407,7 @@ static void bluez_devices_signal_callback(
key, var, &is_config, &error);
g_variant_unref(var);
if (!ret) {
- AFB_WARNING("%s property %s - %s",
+ AFB_DEBUG("%s property %s - %s",
"devices",
key, error->message);
g_clear_error(&error);
@@ -395,25 +425,44 @@ static void bluez_devices_signal_callback(
jresp = NULL;
}
- } else if (!g_strcmp0(path, BLUEZ_MEDIAPLAYER_INTERFACE)) {
+ } else if (!g_strcmp0(path, BLUEZ_MEDIAPLAYER_INTERFACE) ||
+ !g_strcmp0(path, BLUEZ_MEDIATRANSPORT_INTERFACE)) {
int cnt = 0;
jresp = json_object_new_object();
json_process_path(jresp, object_path);
while (g_variant_iter_next(array, "{&sv}", &key, &var)) {
- ret = mediaplayer_property_dbus2json(jresp,
+ if (!g_strcmp0(path, BLUEZ_MEDIAPLAYER_INTERFACE))
+ ret = mediaplayer_property_dbus2json(jresp,
+ key, var, &is_config, &error);
+ else
+ ret = mediatransport_property_dbus2json(jresp,
key, var, &is_config, &error);
g_variant_unref(var);
if (!ret) {
- //AFB_WARNING("%s property %s - %s",
- // "mediaplayer",
- // key, error->message);
+ AFB_DEBUG("%s property %s - %s",
+ path,
+ key, error->message);
g_clear_error(&error);
continue;
}
cnt++;
}
+ if (!g_strcmp0(path, BLUEZ_MEDIAPLAYER_INTERFACE)) {
+ json_object_object_add(jresp, "type",
+ json_object_new_string("playback"));
+ } else {
+ gchar *endpoint = find_index(object_path, 5);
+ json_object_object_add(jresp, "action",
+ json_object_new_string("changed"));
+ json_object_object_add(jresp, "type",
+ json_object_new_string("transport"));
+ json_object_object_add(jresp, "endpoint",
+ json_object_new_string(endpoint));
+ g_free(endpoint);
+ }
+
// NOTE: Possible to get a changed property for something we don't care about
if (!cnt) {
json_object_put(jresp);
diff --git a/binding/bluetooth-api.h b/binding/bluetooth-api.h
index 5fa417a..31418ae 100644
--- a/binding/bluetooth-api.h
+++ b/binding/bluetooth-api.h
@@ -34,6 +34,7 @@
#define BLUEZ_AGENTMANAGER_INTERFACE BLUEZ_SERVICE ".AgentManager1"
#define BLUEZ_DEVICE_INTERFACE BLUEZ_SERVICE ".Device1"
#define BLUEZ_MEDIAPLAYER_INTERFACE BLUEZ_SERVICE ".MediaPlayer1"
+#define BLUEZ_MEDIATRANSPORT_INTERFACE BLUEZ_SERVICE ".MediaTransport1"
#define BLUEZ_OBJECT_PATH "/"
#define BLUEZ_PATH "/org/bluez"
@@ -68,6 +69,7 @@
#define BLUEZ_AT_AGENT "agent"
#define BLUEZ_AT_AGENTMANAGER "agent-manager"
#define BLUEZ_AT_MEDIAPLAYER "mediaplayer"
+#define BLUEZ_AT_MEDIATRANSPORT "mediatransport"
#define BLUEZ_DEFAULT_ADAPTER "hci0"
#define BLUEZ_DEFAULT_PLAYER "player0"
@@ -122,6 +124,22 @@ static inline gboolean is_mediaplayer1_interface(const char *path)
return ret;
}
+static inline gboolean is_mediatransport1_interface(const char *path)
+{
+ gchar *data = NULL;
+ gboolean ret;
+
+ // Don't trigger on NowPlaying, Item, etc paths
+ if (split_length(path) != 6)
+ return FALSE;
+
+ data = find_index(path, 5);
+ ret = g_str_has_prefix(data, "fd");
+ g_free(data);
+
+ return ret;
+}
+
struct bluetooth_state *bluetooth_get_userdata(afb_req_t request);
struct call_work *call_work_create_unlocked(struct bluetooth_state *ns,
@@ -192,6 +210,14 @@ static inline gboolean mediaplayer_property_dbus2json(json_object *jprop,
jprop, key, var, is_config, error);
}
+static inline gboolean mediatransport_property_dbus2json(json_object *jprop,
+ const gchar *key, GVariant *var, gboolean *is_config,
+ GError **error)
+{
+ return bluez_property_dbus2json(BLUEZ_AT_MEDIATRANSPORT,
+ jprop, key, var, is_config, error);
+}
+
static inline GVariant *device_call(struct bluetooth_state *ns,
const char *device, const char *method,
GVariant *params, GError **error)
@@ -252,6 +278,13 @@ static inline json_object *mediaplayer_properties(struct bluetooth_state *ns,
BLUEZ_AT_MEDIAPLAYER, player, error);
}
+static inline json_object *mediatransport_properties(struct bluetooth_state *ns,
+ GError **error, const gchar *player)
+{
+ return bluez_get_properties(ns,
+ BLUEZ_AT_MEDIATRANSPORT, player, error);
+}
+
static inline json_object *object_properties(struct bluetooth_state *ns,
GError **error)
{
diff --git a/binding/bluetooth-bluez.c b/binding/bluetooth-bluez.c
index 1c46106..a52d225 100644
--- a/binding/bluetooth-bluez.c
+++ b/binding/bluetooth-bluez.c
@@ -68,7 +68,6 @@ static const struct property_info device_props[] = {
{ .name = "Connected", .fmt = "b", },
{ .name = "UUIDs", .fmt = "as", },
{ .name = "Adapter", .fmt = "s", },
- { .name = "ServicesResolved", .fmt = "b", },
{ },
};
@@ -92,6 +91,14 @@ static const struct property_info mediaplayer_props[] = {
{ },
};
+static const struct property_info mediatransport_props[] = {
+ { .name = "UUID", .fmt = "s", },
+ { .name = "State", .fmt = "s", },
+ { .name = "Delay", .fmt = "q", },
+ { .name = "Volume", .fmt = "q", },
+ { },
+};
+
const struct property_info *bluez_get_property_info(
const char *access_type, GError **error)
{
@@ -103,6 +110,8 @@ const struct property_info *bluez_get_property_info(
pi = device_props;
else if (!strcmp(access_type, BLUEZ_AT_MEDIAPLAYER))
pi = mediaplayer_props;
+ else if (!strcmp(access_type, BLUEZ_AT_MEDIATRANSPORT))
+ pi = mediatransport_props;
else
g_set_error(error, NB_ERROR, NB_ERROR_ILLEGAL_ARGUMENT,
"illegal %s argument", access_type);
@@ -347,6 +356,7 @@ json_object *bluez_get_properties(struct bluetooth_state *ns,
if (!strcmp(access_type, BLUEZ_AT_DEVICE) ||
!strcmp(access_type, BLUEZ_AT_MEDIAPLAYER) ||
+ !strcmp(access_type, BLUEZ_AT_MEDIATRANSPORT) ||
!strcmp(access_type, BLUEZ_AT_ADAPTER)) {
pi = bluez_get_property_info(access_type, error);
@@ -366,6 +376,8 @@ json_object *bluez_get_properties(struct bluetooth_state *ns,
interface2 = BLUEZ_DEVICE_INTERFACE;
else if (!strcmp(access_type, BLUEZ_AT_MEDIAPLAYER))
interface2 = BLUEZ_MEDIAPLAYER_INTERFACE;
+ else if (!strcmp(access_type, BLUEZ_AT_MEDIATRANSPORT))
+ interface2 = BLUEZ_MEDIATRANSPORT_INTERFACE;
else if (!strcmp(access_type, BLUEZ_AT_ADAPTER))
interface2 = BLUEZ_ADAPTER_INTERFACE;
else if (!strcmp(access_type, BLUEZ_AT_OBJECT))
@@ -391,6 +403,7 @@ json_object *bluez_get_properties(struct bluetooth_state *ns,
if (!strcmp(access_type, BLUEZ_AT_DEVICE) ||
!strcmp(access_type, BLUEZ_AT_MEDIAPLAYER) ||
+ !strcmp(access_type, BLUEZ_AT_MEDIATRANSPORT) ||
!strcmp(access_type, BLUEZ_AT_ADAPTER)) {
jprop = json_object_new_object();
g_variant_get(reply, "(a{sv})", &array);