From f4e8cddddc0675821de04bacdb36b0bb33daaceb Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Tue, 6 Nov 2018 23:02:11 -0800 Subject: binding: bluetooth: add new avrcp controls verb Since MediaPlayer1 controls are part of bluez it makes sense to keep them here for now Bug-AGL: SPEC-1630 Change-Id: Ia02341179a322082357b0e7eff07264e34197d57 Signed-off-by: Matt Ranostay --- binding/bluetooth-api.c | 43 +++++++++++++++++++++++++++++++++++++++++++ binding/bluetooth-api.h | 12 ++++++++++++ binding/bluetooth-bluez.c | 18 +++++++++++++++++- 3 files changed, 72 insertions(+), 1 deletion(-) (limited to 'binding') diff --git a/binding/bluetooth-api.c b/binding/bluetooth-api.c index 5d26f3a..7e3e1eb 100644 --- a/binding/bluetooth-api.c +++ b/binding/bluetooth-api.c @@ -1029,6 +1029,44 @@ out_free: } +static void bluetooth_avrcp_controls(afb_req_t request) +{ + struct bluetooth_state *ns = bluetooth_get_userdata(request); + const char *action = afb_req_value(request, "action"); + gchar *device, *player; + GVariant *reply; + GError *error = NULL; + + if (!action) { + afb_req_fail(request, "failed", "No action given"); + return; + } + + device = return_bluez_path(request); + if (!device) { + afb_req_fail(request, "failed", "No path given"); + return; + } + + /* TODO: handle multiple players per device */ + player = g_strconcat(device, "/player0", NULL); + g_free(device); + + reply = mediaplayer_call(ns, player, action, NULL, &error); + + if (!reply) { + afb_req_fail_f(request, "failed", + "mediaplayer %s method %s error %s", + player, action, BLUEZ_ERRMSG(error)); + g_free(player); + g_error_free(error); + return; + } + + g_free(player); + afb_req_success(request, NULL, "Bluetooth - AVRCP controls"); +} + static void bluetooth_version(afb_req_t request) { json_object *jresp = json_object_new_object(); @@ -1089,6 +1127,11 @@ static const struct afb_verb_v3 bluetooth_verbs[] = { .session = AFB_SESSION_NONE, .callback = bluetooth_remove_device, .info = "Removed paired device", + }, { + .verb = "avrcp_controls", + .session = AFB_SESSION_NONE, + .callback = bluetooth_avrcp_controls, + .info = "AVRCP controls" }, { .verb = "version", .session = AFB_SESSION_NONE, diff --git a/binding/bluetooth-api.h b/binding/bluetooth-api.h index f8ce9d8..0d72afc 100644 --- a/binding/bluetooth-api.h +++ b/binding/bluetooth-api.h @@ -33,6 +33,7 @@ #define BLUEZ_AGENT_INTERFACE BLUEZ_SERVICE ".Agent1" #define BLUEZ_AGENTMANAGER_INTERFACE BLUEZ_SERVICE ".AgentManager1" #define BLUEZ_DEVICE_INTERFACE BLUEZ_SERVICE ".Device1" +#define BLUEZ_MEDIAPLAYER_INTERFACE BLUEZ_SERVICE ".MediaPlayer1" #define BLUEZ_OBJECT_PATH "/" #define BLUEZ_PATH "/org/bluez" @@ -64,6 +65,7 @@ #define BLUEZ_AT_DEVICE "device" #define BLUEZ_AT_AGENT "agent" #define BLUEZ_AT_AGENTMANAGER "agent-manager" +#define BLUEZ_AT_MEDIAPLAYER "mediaplayer" #define BLUEZ_DEFAULT_ADAPTER "hci0" @@ -184,6 +186,14 @@ static inline GVariant *agentmanager_call(struct bluetooth_state *ns, method, params, error); } +static inline GVariant *mediaplayer_call(struct bluetooth_state *ns, + const char *player, const char *method, + GVariant *params, GError **error) +{ + return bluez_call(ns, BLUEZ_AT_MEDIAPLAYER, player, + method, params, error); +} + static inline gboolean adapter_set_property(struct bluetooth_state *ns, const char *adapter, gboolean is_json_name, const char *name, json_object *jval, GError **error) @@ -235,4 +245,6 @@ void bluez_decode_call_error(struct bluetooth_state *ns, const char *method, GError **error); + + #endif /* BLUETOOTH_API_H */ diff --git a/binding/bluetooth-bluez.c b/binding/bluetooth-bluez.c index 052ea7b..824843b 100644 --- a/binding/bluetooth-bluez.c +++ b/binding/bluetooth-bluez.c @@ -155,6 +155,19 @@ void bluez_decode_call_error(struct bluetooth_state *ns, NB_ERROR_UNKNOWN_SERVICE, "unknown service %s", type_arg); + } else if (!strcmp(method, "Play") || + !strcmp(method, "Pause") || + !strcmp(method, "Stop") || + !strcmp(method, "Next") || + !strcmp(method, "Previous") || + !strcmp(method, "FastForward") || + !strcmp(method, "Rewind")) { + + g_clear_error(error); + g_set_error(error, NB_ERROR, + NB_ERROR_UNKNOWN_PROPERTY, + "unknown method %s", + method); } } } @@ -167,7 +180,8 @@ GVariant *bluez_call(struct bluetooth_state *ns, GVariant *reply; if (!path && (!strcmp(access_type, BLUEZ_AT_DEVICE) || - !strcmp(access_type, BLUEZ_AT_ADAPTER))) { + !strcmp(access_type, BLUEZ_AT_ADAPTER) || + !strcmp(access_type, BLUEZ_AT_MEDIAPLAYER))) { g_set_error(error, NB_ERROR, NB_ERROR_MISSING_ARGUMENT, "missing %s argument", access_type); @@ -181,6 +195,8 @@ GVariant *bluez_call(struct bluetooth_state *ns, } else if (!strcmp(access_type, BLUEZ_AT_AGENTMANAGER)) { path = BLUEZ_PATH; interface = BLUEZ_AGENTMANAGER_INTERFACE; + } else if (!strcmp(access_type, BLUEZ_AT_MEDIAPLAYER)) { + interface = BLUEZ_MEDIAPLAYER_INTERFACE; } else { g_set_error(error, NB_ERROR, NB_ERROR_ILLEGAL_ARGUMENT, "illegal %s argument", -- cgit 1.2.3-korg