From 5283492076fa4a0e537c255337d4139ab33896f7 Mon Sep 17 00:00:00 2001 From: Jonathan Aillet Date: Wed, 19 Dec 2018 10:59:37 +0100 Subject: Improve ALSA controls volume values conversion Rework halmap ALSA controls volume conversion to be able to add new types of volume conversions easily. Bug-AGL: SPEC-1313 Change-Id: I0949f25c24a349e7409233f51b3d5738ebc43a8a Signed-off-by: Jonathan Aillet --- .../4a-hal-controllers-alsacore-link.c | 15 +- 4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c | 2 +- .../4a-hal-controllers-value-handler.c | 223 +++++++++++++++------ .../4a-hal-controllers-value-handler.h | 18 +- 4 files changed, 192 insertions(+), 66 deletions(-) (limited to '4a-hal') diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-alsacore-link.c b/4a-hal/4a-hal-controllers/4a-hal-controllers-alsacore-link.c index 00acd4f..d5cd81f 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-alsacore-link.c +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-alsacore-link.c @@ -425,7 +425,9 @@ void HalCtlsActionOnAlsaCtl(AFB_ReqT request) struct SpecificHalData *currentCtlHalData; struct CtlHalAlsaMap *currentAlsaCtl; - json_object *requestJson, *valueJ, *convertedJ; + json_object *requestJson, + *valueJ, + *convertedJ; apiHandle = (AFB_ApiT) afb_request_get_dynapi(request); if(! apiHandle) { @@ -481,8 +483,15 @@ void HalCtlsActionOnAlsaCtl(AFB_ReqT request) return; } - if(HalCtlsNormalizeJsonValues(apiHandle, ¤tAlsaCtl->ctl.alsaCtlProperties, valueJ, &convertedJ)) { - AFB_ReqFailF(request, "request_json", "Error when trying to convert request json '%s'", json_object_get_string(requestJson)); + if(HalCtlsConvertJsonValues(apiHandle, + ¤tAlsaCtl->ctl.alsaCtlProperties, + valueJ, + &convertedJ, + CONVERSION_NORMALIZED_TO_ALSACORE)) { + AFB_ReqFailF(request, + "request_json", + "Error when trying to convert request values '%s'", + json_object_get_string(valueJ)); return; } diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c index 22783d5..46fcabb 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c @@ -243,7 +243,7 @@ int HalCtlsHandleOneHalMapObject(AFB_ApiT apiHandle, char *cardId, struct CtlHal valueJ = json_object_new_int(alsaMap->ctl.value); err = 0; - if(HalCtlsNormalizeJsonValues(apiHandle, &alsaMap->ctl.alsaCtlProperties, valueJ, &convertedValueJ)) { + if(HalCtlsConvertJsonValues(apiHandle, &alsaMap->ctl.alsaCtlProperties, valueJ, &convertedValueJ, CONVERSION_NORMALIZED_TO_ALSACORE)) { AFB_ApiError(apiHandle, "Error when trying to convert initiate value json '%s'", json_object_get_string(valueJ)); err = -3; } diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c b/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c index f66c7ca..18c4113 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c @@ -60,31 +60,152 @@ int HalCtlsConvertPercentageToValue(int percentage, int min, int max) * Convert json object from percentage to value * ******************************************************************************/ -int HalCtlsNormalizeJsonValues(AFB_ApiT apiHandle, struct CtlHalAlsaCtlProperties *alsaCtlProperties, json_object *toConvertJ, json_object **ConvertedJ) +int HalCtlsConvertJsonValueForIntegerControl(AFB_ApiT apiHandle, + struct CtlHalAlsaCtlProperties *alsaCtlProperties, + json_object *toConvertJ, + json_object **ConvertedJ, + enum ConversionType requestedConversion) { - int err = 0, idx, count, initialValue, convertedValue; + int initialValue, convertedValue; - json_type toConvertType; - json_object *toConvertObjectJ, *convertedValueJ, *convertedArrayJ; + if(! json_object_is_type(toConvertJ, json_type_int)) { + AFB_ApiError(apiHandle, + "Can't convert json value, unrecognized json format (must be an integer) : '%s'", + json_object_get_string(toConvertJ)); + return -1; + } - toConvertType = json_object_get_type(toConvertJ); - switch(toConvertType) { - case json_type_array: - count = (int) json_object_array_length(toConvertJ); + initialValue = json_object_get_int(toConvertJ); + + switch(requestedConversion) { + case CONVERSION_NORMALIZED_TO_ALSACORE: + if(initialValue < 0 || initialValue > 100) { + AFB_ApiError(apiHandle, + "Cannot convert '%i' value, value should be between 0 and 100 ('%s')", + initialValue, + json_object_get_string(toConvertJ)); + return -2; + } + + convertedValue = HalCtlsConvertPercentageToValue(initialValue, + alsaCtlProperties->minval, + alsaCtlProperties->maxval); + + if(convertedValue == -INT_MAX) { + AFB_ApiError(apiHandle, + "Didn't succeed to convert %i (using min %i et max %i)", + initialValue, + alsaCtlProperties->minval, + alsaCtlProperties->maxval); + return -3; + } + + if(alsaCtlProperties->step) { + // Round value to the nearest step + convertedValue = (int) round((double) convertedValue / (double) alsaCtlProperties->step); + convertedValue *= alsaCtlProperties->step; + } break; - case json_type_null: - case json_type_object: - count = 0; - AFB_ApiWarning(apiHandle, "Can't normalize json values :\n-- %s", json_object_get_string(toConvertJ)); - *ConvertedJ = json_object_get(toConvertJ); - return -1; + case CONVERSION_ALSACORE_TO_NORMALIZED: + convertedValue = HalCtlsConvertValueToPercentage(initialValue, + alsaCtlProperties->minval, + alsaCtlProperties->maxval); + + if(convertedValue == -INT_MAX) { + AFB_ApiError(apiHandle, + "Didn't succeed to convert %i (using min %i et max %i)", + initialValue, + alsaCtlProperties->minval, + alsaCtlProperties->maxval); + return -4; + } + + break; + + default: + AFB_ApiError(apiHandle, + "Can't convert '%i' value, unrecognized conversion type : '%i'", + initialValue, + (int) requestedConversion); + *ConvertedJ = NULL; + return -5; + } + + *ConvertedJ = json_object_new_int(convertedValue); + + return 0; +} + +int HalCtlsConvertJsonValueForBooleanControl(AFB_ApiT apiHandle, + struct CtlHalAlsaCtlProperties *alsaCtlProperties, + json_object *toConvertJ, + json_object **ConvertedJ, + enum ConversionType requestedConversion) +{ + int initialValue; + + switch(json_object_get_type(toConvertJ)) { + case json_type_int: + initialValue = json_object_get_int(toConvertJ); + break; + + case json_type_boolean: + initialValue = json_object_get_boolean(toConvertJ); + break; default: - count = 1; + AFB_ApiError(apiHandle, + "Can't convert json value, unrecognized format (must be an integer or a boolean) : '%s'", + json_object_get_string(toConvertJ)); + return -1; + } + + if(initialValue < 0 || initialValue > 1) { + AFB_ApiError(apiHandle, + "Cannot convert '%i' value, value should be 0 or 1 ('%s')", + initialValue, + json_object_get_string(toConvertJ)); + return -2; + } + + switch(requestedConversion) { + case CONVERSION_NORMALIZED_TO_ALSACORE: + *ConvertedJ = json_object_new_int(initialValue); break; + + case CONVERSION_ALSACORE_TO_NORMALIZED: + *ConvertedJ = json_object_new_boolean(initialValue); + break; + + default: + AFB_ApiError(apiHandle, + "Can't convert '%i' value, unrecognized conversion type : '%i'", + initialValue, + (int) requestedConversion); + *ConvertedJ = NULL; + return -3; } + return 0; +} + +int HalCtlsConvertJsonValues(AFB_ApiT apiHandle, + struct CtlHalAlsaCtlProperties *alsaCtlProperties, + json_object *toConvertJ, + json_object **ConvertedJ, + enum ConversionType requestedConversion) +{ + int conversionError = 0, idx, count; + + json_type toConvertType; + json_object *toConvertObjectJ, *convertedValueJ, *convertedArrayJ; + + *ConvertedJ = NULL; + + toConvertType = json_object_get_type(toConvertJ); + count = (toConvertType == json_type_array) ? (int) json_object_array_length(toConvertJ) : 1; + convertedArrayJ = json_object_new_array(); for(idx = 0; idx < count; idx++) { @@ -96,57 +217,43 @@ int HalCtlsNormalizeJsonValues(AFB_ApiT apiHandle, struct CtlHalAlsaCtlPropertie switch(alsaCtlProperties->type) { case SND_CTL_ELEM_TYPE_INTEGER: case SND_CTL_ELEM_TYPE_INTEGER64: - if(! json_object_is_type(toConvertObjectJ, json_type_int)) { - err += -10*idx; - AFB_ApiWarning(apiHandle, - "Try normalize an integer control but value sent in json is not an integer : '%s'", - json_object_get_string(toConvertObjectJ)); - convertedValueJ = toConvertObjectJ; - break; + if((conversionError = HalCtlsConvertJsonValueForIntegerControl(apiHandle, + alsaCtlProperties, + toConvertObjectJ, + &convertedValueJ, + requestedConversion))) { + AFB_ApiError(apiHandle, + "Error %i happened in when trying to convert index %i for integer control ('%s')", + conversionError, + idx, + json_object_get_string(toConvertObjectJ)); + json_object_put(convertedArrayJ); + return -(idx + 1); } - - initialValue = json_object_get_int(toConvertObjectJ); - convertedValue = HalCtlsConvertPercentageToValue(initialValue, alsaCtlProperties->minval, alsaCtlProperties->maxval); - if(convertedValue == -INT_MAX) { - AFB_ApiWarning(apiHandle, - "Can't normalize %i (using min %i et max %i), value set to 0", - initialValue, - alsaCtlProperties->minval, - alsaCtlProperties->maxval); - convertedValue = 0; - } - - if(alsaCtlProperties->step) { - // Round value to the nearest step - convertedValue = (int) round((double) convertedValue / (double) alsaCtlProperties->step); - convertedValue *= alsaCtlProperties->step; - } - - convertedValueJ = json_object_new_int(convertedValue); break; case SND_CTL_ELEM_TYPE_BOOLEAN: - if(! (json_object_is_type(toConvertObjectJ, json_type_int) || - json_object_is_type(toConvertObjectJ, json_type_boolean))) { - err += -1000*idx; - AFB_ApiWarning(apiHandle, - "Try normalize a boolean control but value sent in json is not a boolean/integer : '%s'", - json_object_get_string(toConvertObjectJ)); - convertedValueJ = toConvertObjectJ; - break; + if((conversionError = HalCtlsConvertJsonValueForBooleanControl(apiHandle, + alsaCtlProperties, + toConvertObjectJ, + &convertedValueJ, + requestedConversion))) { + AFB_ApiError(apiHandle, + "Error %i happened in when trying to convert index %i for boolean control ('%s')", + conversionError, + idx, + json_object_get_string(toConvertObjectJ)); + json_object_put(convertedArrayJ); + return -(idx + 1); } - - initialValue = json_object_get_int(toConvertObjectJ); - convertedValueJ = json_object_new_int(initialValue ? 1 : 0); break; default: - AFB_ApiWarning(apiHandle, - "Normalization not handle for the alsa control type %i, sending back the object as it was '%s'", - (int) alsaCtlProperties->type, - json_object_get_string(toConvertJ)); - convertedValueJ = toConvertObjectJ; - break; + AFB_ApiError(apiHandle, + "Conversion not handle for the alsa control type %i", + (int) alsaCtlProperties->type); + json_object_put(convertedArrayJ); + return -(idx + 1); } json_object_array_put_idx(convertedArrayJ, idx, convertedValueJ); diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.h b/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.h index 5f91aaa..f976fe8 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.h +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.h @@ -15,8 +15,8 @@ * limitations under the License. */ -#ifndef _HAL_CTLS_VALUE_NORMALIZATION_INCLUDE_ -#define _HAL_CTLS_VALUE_NORMALIZATION_INCLUDE_ +#ifndef _HAL_CTLS_VALUE_CONVERSION_INCLUDE_ +#define _HAL_CTLS_VALUE_CONVERSION_INCLUDE_ #include @@ -24,11 +24,21 @@ #include "4a-hal-controllers-alsacore-link.h" +// Enum for the type of conversion requested +enum ConversionType { + CONVERSION_NORMALIZED_TO_ALSACORE = 1, + CONVERSION_ALSACORE_TO_NORMALIZED = 2 +}; + // Simple conversion value to/from percentage functions int HalCtlsConvertValueToPercentage(double val, double min, double max); int HalCtlsConvertPercentageToValue(int percentage, int min, int max); // Convert json object from percentage to value -int HalCtlsNormalizeJsonValues(AFB_ApiT apiHandle, struct CtlHalAlsaCtlProperties *alsaCtlProperties, json_object *toConvertJ, json_object ** ConvertedJ); +int HalCtlsConvertJsonValues(AFB_ApiT apiHandle, + struct CtlHalAlsaCtlProperties *alsaCtlProperties, + json_object *toConvertJ, + json_object **ConvertedJ, + enum ConversionType requestedConversion); -#endif /* _HAL_CTLS_VALUE_NORMALIZATION_INCLUDE_ */ \ No newline at end of file +#endif /* _HAL_CTLS_VALUE_CONVERSION_INCLUDE_ */ \ No newline at end of file -- cgit 1.2.3-korg