aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTaylor Holberton <taylorcholberton@gmail.com>2017-01-10 08:04:04 -0500
committerGitHub <noreply@github.com>2017-01-10 08:04:04 -0500
commit3e9a64211e76529aae4ff08e7a661bcffdee02a5 (patch)
treec3a50bce2368bc86549907aa784e8b1b638de3a4 /src
parent6e8e6374e71d111ae2ee95dbc9e3e45a3bb22f9d (diff)
parent3f813e47784674a3909fe1277bc10b70d03791e2 (diff)
Merge pull request #92 from bpankajl/tvl_fix
Tvl fix
Diffstat (limited to 'src')
-rw-r--r--src/mixer.c43
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))