diff --git a/audio/avctp.c b/audio/avctp.c
index 2800a16..e9b8e40 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
uint8_t subunit_type:5;
uint8_t opcode;
} __attribute__ ((packed));
-#define AVC_HEADER_LENGTH 3
#elif __BYTE_ORDER == __BIG_ENDIAN
uint8_t subunit_id:3;
uint8_t opcode;
} __attribute__ ((packed));
-#define AVC_HEADER_LENGTH 3
#else
#error "Unknown byte order"
diff --git a/audio/avctp.h b/audio/avctp.h
index 2dab8fa..9727485 100644
--- a/audio/avctp.h
+++ b/audio/avctp.h
#define AVCTP_PSM 23
+#define AVC_MTU 512
+#define AVC_HEADER_LENGTH 3
+
/* ctype entries */
#define AVC_CTYPE_CONTROL 0x0
#define AVC_CTYPE_STATUS 0x1
diff --git a/audio/avrcp.c b/audio/avrcp.c
index f962946..ba04a12 100644
--- a/audio/avrcp.c
+++ b/audio/avrcp.c
#error "Unknown byte order"
#endif
+#define AVRCP_MTU (AVC_MTU - AVC_HEADER_LENGTH)
+#define AVRCP_PDU_MTU (AVRCP_MTU - AVRCP_HEADER_LENGTH)
+
struct avrcp_server {
bdaddr_t src;
uint32_t tg_record_id;
* attribute, -ENOENT is returned.
*/
static int mp_get_media_attribute(struct media_player *mp,
- uint32_t id, uint8_t *buf)
+ uint32_t id, uint8_t *buf,
+ uint16_t maxlen)
{
struct media_info_elem {
uint32_t id;
struct media_info_elem *elem = (void *)buf;
uint16_t len;
char valstr[20];
+ char *valp;
+
+ if (maxlen < sizeof(struct media_info_elem))
+ return -ENOBUFS;
+
+ /* Subtract the size of elem header from the available space */
+ maxlen -= sizeof(struct media_info_elem);
switch (id) {
case MEDIA_INFO_TITLE:
- if (mi->title) {
- len = strlen(mi->title);
- memcpy(elem->val, mi->title, len);
- } else {
- len = 0;
- }
-
+ valp = mi->title;
break;
case MEDIA_INFO_ARTIST:
if (mi->artist == NULL)
return -ENOENT;
- len = strlen(mi->artist);
- memcpy(elem->val, mi->artist, len);
+ valp = mi->artist;
break;
case MEDIA_INFO_ALBUM:
if (mi->album == NULL)
return -ENOENT;
- len = strlen(mi->album);
- memcpy(elem->val, mi->album, len);
+ valp = mi->album;
break;
case MEDIA_INFO_GENRE:
if (mi->genre == NULL)
return -ENOENT;
- len = strlen(mi->genre);
- memcpy(elem->val, mi->genre, len);
+ valp = mi->genre;
break;
-
case MEDIA_INFO_TRACK:
if (!mi->track)
return -ENOENT;
snprintf(valstr, 20, "%u", mi->track);
- len = strlen(valstr);
- memcpy(elem->val, valstr, len);
+ valp = valstr;
break;
case MEDIA_INFO_N_TRACKS:
if (!mi->ntracks)
return -ENOENT;
snprintf(valstr, 20, "%u", mi->ntracks);
- len = strlen(valstr);
- memcpy(elem->val, valstr, len);
+ valp = valstr;
break;
case MEDIA_INFO_PLAYING_TIME:
if (mi->track_len == 0xFFFFFFFF)
return -ENOENT;
snprintf(valstr, 20, "%u", mi->track_len);
- len = strlen(valstr);
- memcpy(elem->val, valstr, len);
+ valp = valstr;
break;
default:
return -EINVAL;
}
+ if (valp) {
+ len = strlen(valp);
+
+ if (len > maxlen)
+ return -ENOBUFS;
+
+ memcpy(elem->val, valp, len);
+ } else {
+ len = 0;
+ }
+
elem->id = htonl(id);
elem->charset = htons(0x6A); /* Always use UTF-8 */
elem->len = htons(len);
* title must be returned.
*/
for (i = 1; i < MEDIA_INFO_LAST; i++) {
- size = mp_get_media_attribute(mp, i,
- &pdu->params[pos]);
+ size = mp_get_media_attribute(mp, i, &pdu->params[pos],
+ AVRCP_PDU_MTU - pos);
if (size > 0) {
len++;
uint32_t attr = ntohl(attr_ids[i]);
size = mp_get_media_attribute(mp, attr,
- &pdu->params[pos]);
+ &pdu->params[pos],
+ AVRCP_PDU_MTU - pos);
if (size > 0) {
len++;