diff --git a/audio/control.c b/audio/control.c
index 300d0f3..f090566 100644
--- a/audio/control.c
+++ b/audio/control.c
#define AVRCP_GET_CAPABILITIES 0x10
#define AVRCP_LIST_PLAYER_ATTRIBUTES 0X11
#define AVRCP_LIST_PLAYER_VALUES 0x12
+#define AVRCP_GET_CURRENT_PLAYER_VALUE 0x13
/* Capabilities for AVRCP_GET_CAPABILITIES pdu */
#define CAP_COMPANY_ID 0x02
return -EINVAL;
}
+static int avrcp_handle_get_current_player_value(struct control *control,
+ struct avrcp_spec_avc_pdu *pdu)
+{
+ uint16_t len = ntohs(pdu->params_len);
+ struct media_player *mp = control->mp;
+ uint8_t *settings;
+ unsigned int i;
+
+ if (mp == NULL || len <= 1 || pdu->params[0] != len - 1)
+ goto err;
+
+ /*
+ * Save a copy of requested settings because we can override them
+ * while responding
+ */
+ settings = g_malloc(pdu->params[0]);
+ memcpy(settings, &pdu->params[1], pdu->params[0]);
+ len = 0;
+
+ /*
+ * From sec. 5.7 of AVRCP 1.3 spec, we should igore non-existent IDs
+ * and send a response with the existent ones. Only if all IDs are
+ * non-existent we should send an error.
+ */
+ for (i = 0; i < pdu->params[0]; i++) {
+ uint8_t val;
+
+ if (settings[i] < PLAYER_SETTING_EQUALIZER ||
+ settings[i] > PLAYER_SETTING_SCAN) {
+ DBG("Ignoring %u", settings[i]);
+ continue;
+ }
+
+ val = mp_get_attribute(mp, settings[i]);
+ if (!val) {
+ DBG("Ignoring %u: not supported by player",
+ settings[i]);
+ continue;
+ }
+
+ pdu->params[len] = settings[i];
+ pdu->params[len + 1] = val;
+ len += 2;
+ }
+
+ g_free(settings);
+
+ if (len) {
+ pdu->params[0] = len;
+ pdu->params_len = htons(2 * len + 1);
+
+ return 2 * len + 1;
+ }
+
+ error("No valid attributes in request");
+
+err:
+ pdu->params[0] = E_INVALID_PARAM;
+
+ return -EINVAL;
+}
+
/* handle vendordep pdu inside an avctp packet */
static int handle_vendordep_pdu(struct control *control,
struct avrcp_header *avrcp,
avrcp->code = CTYPE_STABLE;
break;
+ case AVRCP_GET_CURRENT_PLAYER_VALUE:
+ if (avrcp->code != CTYPE_STATUS) {
+ pdu->params[0] = E_INVALID_COMMAND;
+ goto err_metadata;
+ }
+
+ len = avrcp_handle_get_current_player_value(control, pdu);
+ if (len < 0)
+ goto err_metadata;
+
+ avrcp->code = CTYPE_STABLE;
+
+ break;
default:
/* Invalid pdu_id */
pdu->params[0] = E_INVALID_COMMAND;