From 0219aa93778c8937059d4856ba8223236bbe8abd Mon Sep 17 00:00:00 2001 From: Jonathan Aillet Date: Fri, 25 Jan 2019 18:44:23 +0100 Subject: 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 --- alsa-binding/Alsa-AddCtl.c | 90 ++++++++++++++++++++++++++++++---------------- 1 file 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: -- cgit 1.2.3-korg