aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Wilson <simonrules@users.noreply.github.com>2020-09-21 10:13:57 -0600
committerGitHub <noreply@github.com>2020-09-21 10:13:57 -0600
commit618a7e28a86dcec74ce02580190f6ad173bf7719 (patch)
treeb8975014821f1169bc16444b82dfe8246438ce4f
parent6a4cab794ce3d8673242e982dd15805cf963126e (diff)
parent6125aaf4f7af3ba73c3b3695ccdccb6cf8e3dd82 (diff)
Merge pull request #173 from rohkkumar/mixer_fix
Fix mixer set/get for tlv based controls
-rw-r--r--src/mixer.c25
-rw-r--r--utils/tinymix.c30
2 files changed, 13 insertions, 42 deletions
diff --git a/src/mixer.c b/src/mixer.c
index 94aa019..6a104fe 100644
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -936,21 +936,13 @@ 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 || !array)
return -EINVAL;
grp = ctl->grp;
- 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)
+ if (count > ctl->info.count)
return -EINVAL;
memset(&ev, 0, sizeof(ev));
@@ -974,9 +966,11 @@ int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count)
if (count > SIZE_MAX - sizeof(*tlv))
return -EINVAL;
+
tlv = calloc(1, sizeof(*tlv) + count);
if (!tlv)
return -ENOMEM;
+
tlv->numid = ctl->info.id.numid;
tlv->length = count;
ret = grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_TLV_READ, tlv);
@@ -1076,21 +1070,13 @@ 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;
grp = ctl->grp;
- 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 (count > total_count)
+ if (count > ctl->info.count)
return -EINVAL;
memset(&ev, 0, sizeof(ev));
@@ -1108,11 +1094,14 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count)
if (mixer_ctl_is_access_tlv_rw(ctl)) {
struct snd_ctl_tlv *tlv;
int ret = 0;
+
if (count > SIZE_MAX - sizeof(*tlv))
return -EINVAL;
+
tlv = calloc(1, sizeof(*tlv) + count);
if (!tlv)
return -ENOMEM;
+
tlv->numid = ctl->info.id.numid;
tlv->length = count;
memcpy(tlv->tlv, array, count);
diff --git a/utils/tinymix.c b/utils/tinymix.c
index a47005c..fdb774c 100644
--- a/utils/tinymix.c
+++ b/utils/tinymix.c
@@ -200,7 +200,6 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control)
int min, max;
int ret;
char *buf = NULL;
- unsigned int tlv_header_size = 0;
if (isdigit(control[0]))
ctl = mixer_get_ctl(mixer, atoi(control));
@@ -216,16 +215,13 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control)
num_values = mixer_ctl_get_num_values(ctl);
if ((type == MIXER_CTL_TYPE_BYTE) && (num_values > 0)) {
- if (mixer_ctl_is_access_tlv_rw(ctl) != 0) {
- tlv_header_size = TLV_HEADER_SIZE;
- }
- buf = calloc(1, num_values + tlv_header_size);
+ buf = calloc(1, num_values);
if (buf == NULL) {
fprintf(stderr, "Failed to alloc mem for bytes %u\n", num_values);
return;
}
- ret = mixer_ctl_get_array(ctl, buf, num_values + tlv_header_size);
+ ret = mixer_ctl_get_array(ctl, buf, num_values);
if (ret < 0) {
fprintf(stderr, "Failed to mixer_ctl_get_array\n");
free(buf);
@@ -246,8 +242,7 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control)
tinymix_print_enum(ctl);
break;
case MIXER_CTL_TYPE_BYTE:
- /* skip printing TLV header if exists */
- printf(" %02x", buf[i + tlv_header_size]);
+ printf(" %02x", buf[i]);
break;
default:
printf("unknown");
@@ -275,25 +270,13 @@ static void tinymix_set_byte_ctl(struct mixer_ctl *ctl,
char *end;
unsigned int i;
long n;
- unsigned int *tlv, tlv_size;
- unsigned int tlv_header_size = 0;
-
- if (mixer_ctl_is_access_tlv_rw(ctl) != 0) {
- tlv_header_size = TLV_HEADER_SIZE;
- }
- tlv_size = num_values + tlv_header_size;
-
- buf = calloc(1, tlv_size);
+ buf = calloc(1, num_values);
if (buf == NULL) {
fprintf(stderr, "set_byte_ctl: Failed to alloc mem for bytes %u\n", num_values);
exit(EXIT_FAILURE);
}
- tlv = (unsigned int *)buf;
- tlv[0] = 0;
- tlv[1] = num_values;
-
for (i = 0; i < num_values; i++) {
errno = 0;
n = strtol(values[i], &end, 0);
@@ -311,11 +294,10 @@ static void tinymix_set_byte_ctl(struct mixer_ctl *ctl,
values[i]);
goto fail;
}
- /* start filling after tlv header */
- buf[i + tlv_header_size] = n;
+ buf[i] = n;
}
- ret = mixer_ctl_set_array(ctl, buf, tlv_size);
+ ret = mixer_ctl_set_array(ctl, buf, num_values);
if (ret < 0) {
fprintf(stderr, "Failed to set binary control\n");
goto fail;