aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Aillet <jonathan.aillet@iot.bzh>2019-01-25 18:44:23 +0100
committerJonathan Aillet <jonathan.aillet@iot.bzh>2019-01-25 18:44:23 +0100
commit0219aa93778c8937059d4856ba8223236bbe8abd (patch)
tree31a45d983b283e99b9aa52622b9ffdcac5494a0f
parent980a8f01d081080b087a832570f617187093c619 (diff)
Improve ALSA control creation
Improve ALSA control creation by : - Checking supported controls type at function start. - Prevent segfault when a none INTEGER control is updated. Change-Id: Icbff18ec6fc6c35938bf2945edc27c36fecf99d1 Signed-off-by: Jonathan Aillet <jonathan.aillet@iot.bzh>
-rw-r--r--alsa-binding/Alsa-AddCtl.c90
1 files changed, 60 insertions, 30 deletions
diff --git a/alsa-binding/Alsa-AddCtl.c b/alsa-binding/Alsa-AddCtl.c
index 9c48914..a40112c 100644
--- a/alsa-binding/Alsa-AddCtl.c
+++ b/alsa-binding/Alsa-AddCtl.c
@@ -108,33 +108,46 @@ STATIC json_object * addOneSndCtl(afb_req_t request, snd_ctl_t *ctlDev, json_obj
if (done) ctlType = json_object_get_int(tmpJ);
else ctlType = SND_CTL_ELEM_TYPE_INTEGER;
- json_object_object_get_ex(ctlJ, "val", &tmpJ);
- ctlValue = json_object_get_int(tmpJ);
-
- // default for json_object_get_int is zero
- json_object_object_get_ex(ctlJ, "min", &tmpJ);
- ctlMin = json_object_get_int(tmpJ);
-
- done = json_object_object_get_ex(ctlJ, "max", &tmpJ);
- if (done) ctlMax = json_object_get_int(tmpJ);
- else {
- if (ctlType == SND_CTL_ELEM_TYPE_BOOLEAN) ctlMax = 1;
- else ctlMax = 100;
- }
-
- done = json_object_object_get_ex(ctlJ, "step", &tmpJ);
- if (!done) ctlStep = 1;
- else ctlStep = json_object_get_int(tmpJ);
-
done = json_object_object_get_ex(ctlJ, "count", &tmpJ);
if (!done) ctlCount = 1;
else ctlCount = json_object_get_int(tmpJ);
+ json_object_object_get_ex(ctlJ, "val", &tmpJ);
+ ctlValue = json_object_get_int(tmpJ);
+
json_object_object_get_ex(ctlJ, "snddev", &tmpJ);
ctlSndDev = json_object_get_int(tmpJ);
json_object_object_get_ex(ctlJ, "subdev", &tmpJ);
ctlSubDev = json_object_get_int(tmpJ);
+
+ switch(ctlType) {
+ case SND_CTL_ELEM_TYPE_INTEGER:
+ // default for json_object_get_int is zero
+ json_object_object_get_ex(ctlJ, "min", &tmpJ);
+ ctlMin = json_object_get_int(tmpJ);
+
+ done = json_object_object_get_ex(ctlJ, "max", &tmpJ);
+ if (done) ctlMax = json_object_get_int(tmpJ);
+ else ctlMax = 100;
+
+ done = json_object_object_get_ex(ctlJ, "step", &tmpJ);
+ if (!done) ctlStep = 1;
+ else ctlStep = json_object_get_int(tmpJ);
+ break;
+
+ case SND_CTL_ELEM_TYPE_BOOLEAN:
+ case SND_CTL_ELEM_TYPE_ENUMERATED:
+ AFB_NOTICE("addOneSndCtl: Requesting creation of a none INTEGER control. 'min', 'max, and 'step' won't be used");
+ break;
+
+ // Long Term Waiting ToDoList
+ case SND_CTL_ELEM_TYPE_INTEGER64:
+ case SND_CTL_ELEM_TYPE_BYTES:
+ default:
+ afb_req_fail_f(request, "ctl-invalid-type", "crl=%s unsupported type type=%d", json_object_get_string(ctlJ), ctlType);
+ goto OnErrorExit;
+ }
}
// Assert that this ctls is not used
@@ -163,18 +176,39 @@ STATIC json_object * addOneSndCtl(afb_req_t request, snd_ctl_t *ctlDev, json_obj
}
count = snd_ctl_elem_info_get_count(elemInfo);
- min = (int) snd_ctl_elem_info_get_min(elemInfo);
- max = (int) snd_ctl_elem_info_get_max(elemInfo);
type = snd_ctl_elem_info_get_type(elemInfo);
sndDev = (int) snd_ctl_elem_info_get_device(elemInfo);
subDev = (int) snd_ctl_elem_info_get_subdevice(elemInfo);
- if (count == ctlCount && min == ctlMin && max == ctlMax && type == ctlType && sndDev == ctlSndDev && subDev == ctlSubDev) {
- // Adjust value to best fit request
- shouldCreate = 0;
- } else {
+ switch(type) {
+ case SND_CTL_ELEM_TYPE_INTEGER:
+ min = (int) snd_ctl_elem_info_get_min(elemInfo);
+ max = (int) snd_ctl_elem_info_get_max(elemInfo);
+ if (count == ctlCount && min == ctlMin && max == ctlMax && type == ctlType && sndDev == ctlSndDev && subDev == ctlSubDev)
+ shouldCreate = 0; // Adjust value to best fit request
+ else
+ shouldCreate = 1;
+ break;
+
+ case SND_CTL_ELEM_TYPE_BOOLEAN:
+ if (count == ctlCount && type == ctlType && sndDev == ctlSndDev && subDev == ctlSubDev)
+ shouldCreate = 0; // Adjust value to best fit request
+ else
+ shouldCreate = 1;
+ break;
+
+ case SND_CTL_ELEM_TYPE_ENUMERATED:
+ shouldCreate = 1;
+ break;
+
+ default:
+ AFB_WARNING("addOneSndCtl: Removing an unmanaged control type, type=%i, ctlName=%s, numid=%d", (int) type, snd_ctl_elem_info_get_name(elemInfo), snd_ctl_elem_info_get_numid(elemInfo));
+ shouldCreate = 1;
+ break;
+ }
+
+ if(shouldCreate) {
err = snd_ctl_elem_remove(ctlDev, elemId);
- shouldCreate = 1;
if (err < 0) {
AFB_ERROR("addOneSndCtl: ctlName=%s numid=%d fail to reset", snd_ctl_elem_info_get_name(elemInfo), snd_ctl_elem_info_get_numid(elemInfo));
goto DoNotUpdate;
@@ -280,12 +314,8 @@ STATIC json_object * addOneSndCtl(afb_req_t request, snd_ctl_t *ctlDev, json_obj
}
break;
- // Long Term Waiting ToDoList
- case SND_CTL_ELEM_TYPE_INTEGER64:
- case SND_CTL_ELEM_TYPE_BYTES:
default:
- afb_req_fail_f(request, "ctl-invalid-type", "crl=%s unsupported type type=%d numid=%d", json_object_get_string(ctlJ), ctlType, ctlNumid);
- goto OnErrorExit;
+ break;
}
UpdateDefaultVal: