Re: [PATCH 1/3] avrcp: limit avrcp packet size to the MTU of AV/C

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Lucas,

On Tue, Sep 20, 2011 at 9:31 PM, Lucas De Marchi
<lucas.demarchi@xxxxxxxxxxxxxx> wrote:
> AVRCP is an extension of AV/C spec which has a limit of 512 bytes. The
> only place where it can exceed this value is in the response to
> GetElementAttributes command.
>
> Now we simply don't add the attributes that would overflow the available
> buffer space.
> ---
>  audio/avctp.c |    2 -
>  audio/avctp.h |    3 ++
>  audio/avrcp.c |   58 +++++++++++++++++++++++++++++++++-----------------------
>  3 files changed, 37 insertions(+), 26 deletions(-)
>
> diff --git a/audio/avctp.c b/audio/avctp.c
> index 2800a16..e9b8e40 100644
> --- a/audio/avctp.c
> +++ b/audio/avctp.c
> @@ -84,7 +84,6 @@ struct avc_header {
>        uint8_t subunit_type:5;
>        uint8_t opcode;
>  } __attribute__ ((packed));
> -#define AVC_HEADER_LENGTH 3
>
>  #elif __BYTE_ORDER == __BIG_ENDIAN
>
> @@ -104,7 +103,6 @@ struct avc_header {
>        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
> @@ -24,6 +24,9 @@
>
>  #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
> @@ -173,6 +173,9 @@ struct avrcp_header {
>  #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;
> @@ -649,7 +652,8 @@ static void mp_set_playback_status(struct media_player *mp, uint8_t status,
>  * 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;
> @@ -661,67 +665,72 @@ static int mp_get_media_attribute(struct media_player *mp,
>        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);
> @@ -905,8 +914,8 @@ static uint8_t avrcp_handle_get_element_attributes(struct media_player *mp,
>                 * 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++;
> @@ -922,7 +931,8 @@ static uint8_t avrcp_handle_get_element_attributes(struct media_player *mp,
>                        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++;
> --
> 1.7.6.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Ack

-- 
Luiz Augusto von Dentz
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux