diff options
author | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2014-09-10 15:40:31 +0200 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2014-10-06 16:01:50 +0300 |
commit | 169cd958f04df2da954ae17cf7559b0b6afe35ff (patch) | |
tree | 02150bedcad580e95fcb32b61b13986f25c60cbb /android/avrcp-lib.c | |
parent | cd66530d8bd4d389c58166be81e413b5c9cc06fa (diff) | |
download | bluez-169cd958f04df2da954ae17cf7559b0b6afe35ff.tar.gz |
android/avrcp-lib: Add SetBrowsed structs
Diffstat (limited to 'android/avrcp-lib.c')
-rw-r--r-- | android/avrcp-lib.c | 80 |
1 files changed, 53 insertions, 27 deletions
diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c index b0a66d1fa..45dbe565b 100644 --- a/android/avrcp-lib.c +++ b/android/avrcp-lib.c @@ -205,6 +205,19 @@ struct set_addressed_rsp { uint8_t status; } __attribute__ ((packed)); +struct set_browsed_req { + uint16_t id; +} __attribute__ ((packed)); + +struct set_browsed_rsp { + uint8_t status; + uint16_t counter; + uint16_t charset; + uint32_t items; + uint8_t depth; + uint8_t data[0]; +} __attribute__ ((packed)); + struct avrcp_control_handler { uint8_t id; uint8_t code; @@ -2436,18 +2449,47 @@ int avrcp_set_addressed_player(struct avrcp *session, uint16_t player_id) set_addressed_rsp, session); } +static char *parse_folder_list(uint8_t *params, uint16_t params_len, + uint8_t depth) +{ + char **folders, *path; + uint8_t count; + size_t i; + + folders = g_new0(char *, depth + 2); + folders[0] = g_strdup("/Filesystem"); + + for (i = 0, count = 1; count <= depth && i < params_len; count++) { + uint8_t len; + + len = params[i++]; + + if (i + len > params_len || len == 0) { + g_strfreev(folders); + return NULL; + } + + folders[count] = g_memdup(¶ms[i], len); + i += len; + } + + path = g_build_pathv("/", folders); + g_strfreev(folders); + + return path; +} + static gboolean set_browsed_rsp(struct avctp *conn, uint8_t *operands, size_t operand_count, void *user_data) { struct avrcp *session = user_data; struct avrcp_player *player = session->player; struct avrcp_browsing_header *pdu; + struct set_browsed_rsp *rsp; uint16_t counter = 0; uint32_t items = 0; - uint8_t depth = 0, count; - char **folders, *path = NULL; + char *path = NULL; int err; - size_t i; DBG(""); @@ -2464,36 +2506,20 @@ static gboolean set_browsed_rsp(struct avctp *conn, uint8_t *operands, if (err < 0) goto done; - if (pdu->params_len < 10) { + if (pdu->params_len < sizeof(*rsp)) { err = -EPROTO; goto done; } - counter = get_be16(&pdu->params[1]); - items = get_be32(&pdu->params[3]); - depth = pdu->params[9]; - - folders = g_new0(char *, depth + 2); - folders[0] = g_strdup("/Filesystem"); - - for (i = 10, count = 1; count - 1 < depth && i < pdu->params_len; - count++) { - uint8_t len; - - len = pdu->params[i++]; - - if (i + len > pdu->params_len || len == 0) { - g_strfreev(folders); - err = -EPROTO; - goto done; - } + rsp = (void *) pdu->params; - folders[count] = g_memdup(&pdu->params[i], len); - i += len; - } + counter = get_be16(&rsp->counter); + items = get_be32(&rsp->items); - path = g_build_pathv("/", folders); - g_strfreev(folders); + path = parse_folder_list(rsp->data, pdu->params_len - sizeof(*rsp), + rsp->depth); + if (!path) + err = -EPROTO; done: player->cfm->set_browsed(session, err, counter, items, path, |