diff options
author | Taylor Holberton <taylorcholberton@gmail.com> | 2017-01-10 08:04:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-10 08:04:04 -0500 |
commit | 3e9a64211e76529aae4ff08e7a661bcffdee02a5 (patch) | |
tree | c3a50bce2368bc86549907aa784e8b1b638de3a4 /src | |
parent | 6e8e6374e71d111ae2ee95dbc9e3e45a3bb22f9d (diff) | |
parent | 3f813e47784674a3909fe1277bc10b70d03791e2 (diff) |
Merge pull request #92 from bpankajl/tvl_fix
Tvl fix
Diffstat (limited to 'src')
-rw-r--r-- | src/mixer.c | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/src/mixer.c b/src/mixer.c index 66881e9..b7239fd 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -381,6 +381,17 @@ void mixer_ctl_update(struct mixer_ctl *ctl) ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, ctl->info); } +/** Checks the control for TLV Read/Write access. + * @param ctl An initialized control handle. + * @returns On success, non-zero. + * On failure, zero. + * @ingroup libtinyalsa-mixer + */ +int mixer_ctl_is_access_tlv_rw(const struct mixer_ctl *ctl) +{ + return (ctl->info.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE); +} + /** Gets the control's ID. * @param ctl An initialized control handle. * @returns On success, the control's ID is returned. @@ -579,8 +590,20 @@ int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count) int ret = 0; size_t size; void *source; + size_t total_count; - if (!ctl || (count > ctl->info.count) || !count || !array) + if ((!ctl) || !count || !array) + return -EINVAL; + + total_count = ctl->info.count; + + if ((ctl->info.type == SNDRV_CTL_ELEM_TYPE_BYTES) && + (mixer_ctl_is_access_tlv_rw(ctl))) { + /* Additional two words is for the TLV header */ + total_count += TLV_HEADER_SIZE; + } + + if (count > total_count) return -EINVAL; memset(&ev, 0, sizeof(ev)); @@ -598,7 +621,7 @@ int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count) case SNDRV_CTL_ELEM_TYPE_BYTES: /* check if this is new bytes TLV */ - if (ctl->info.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) { + if (mixer_ctl_is_access_tlv_rw(ctl)) { struct snd_ctl_tlv *tlv; int ret; @@ -703,8 +726,20 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) struct snd_ctl_elem_value ev; size_t size; void *dest; + size_t total_count; + + if ((!ctl) || !count || !array) + return -EINVAL; + + total_count = ctl->info.count; + + if ((ctl->info.type == SNDRV_CTL_ELEM_TYPE_BYTES) && + (mixer_ctl_is_access_tlv_rw(ctl))) { + /* Additional TLV header */ + total_count += TLV_HEADER_SIZE; + } - if (!ctl || (count > ctl->info.count) || !count || !array) + if (count > total_count) return -EINVAL; memset(&ev, 0, sizeof(ev)); @@ -719,7 +754,7 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) case SNDRV_CTL_ELEM_TYPE_BYTES: /* check if this is new bytes TLV */ - if (ctl->info.access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE) { + if (mixer_ctl_is_access_tlv_rw(ctl)) { struct snd_ctl_tlv *tlv; int ret = 0; if (count > SIZE_MAX - sizeof(*tlv)) |