summaryrefslogtreecommitdiffstats
path: root/4a-hal
diff options
context:
space:
mode:
Diffstat (limited to '4a-hal')
-rw-r--r--4a-hal/4a-hal-controllers/4a-hal-controllers-alsacore-link.c27
-rw-r--r--4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c32
-rw-r--r--4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c161
-rw-r--r--4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.h34
-rw-r--r--4a-hal/CMakeLists.txt1
5 files changed, 237 insertions, 18 deletions
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 230cddd..47cfcc7 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
@@ -31,6 +31,7 @@
#include "../4a-hal-utilities/4a-hal-utilities-appfw-responses-handler.h"
#include "4a-hal-controllers-alsacore-link.h"
+#include "4a-hal-controllers-value-handler.h"
/*******************************************************************************
* Map to alsa control types *
@@ -264,7 +265,7 @@ int HalCtlsSetAlsaCtlValue(AFB_ApiT apiHandle, char *cardId, int ctlId, json_obj
return -4;
}
- wrap_json_pack(&queryJ, "{s:s s:{s:i s:o}}", "devid", cardId, "ctl", "id", ctlId, "val", valuesJ);
+ wrap_json_pack(&queryJ, "{s:s s:{s:i s:o}}", "devid", cardId, "ctl", "id", ctlId, "val", json_object_get(valuesJ));
if(AFB_ServiceSync(apiHandle, ALSACORE_API, ALSACORE_CTLSET_VERB, queryJ, &returnedJ)) {
returnedError = HalUtlHandleAppFwCallError(apiHandle, ALSACORE_API, ALSACORE_CTLSET_VERB, returnedJ, &returnedStatus, &returnedInfo);
@@ -386,7 +387,7 @@ void HalCtlsActionOnAlsaCtl(AFB_ReqT request)
struct SpecificHalData *currentCtlHalData;
struct CtlHalAlsaMap *currentAlsaCtl;
- json_object *requestJson;
+ json_object *requestJson, *valueJ, *convertedJ;
apiHandle = (AFB_ApiT) afb_request_get_dynapi(request);
if(! apiHandle) {
@@ -440,17 +441,29 @@ void HalCtlsActionOnAlsaCtl(AFB_ReqT request)
snprintf(cardIdString, 6, "hw:%i", currentCtlHalData->sndCardId);
- // TODO JAI: add weighting passing values on currentAlsaCtl->value (and put them into valueJ json)
+ if(wrap_json_unpack(requestJson, "{s:o}", "val", &valueJ)) {
+ AFB_ReqFailF(request,
+ "request_json", "Error when trying to get request value object inside request '%s'",
+ json_object_get_string(requestJson));
+ return;
+ }
- // TODO JAI : test it
- if(HalCtlsSetAlsaCtlValue(apiHandle, cardIdString, currentAlsaCtl->ctl.numid, requestJson)) {
+ if(HalCtlsNormalizeJsonValues(apiHandle, &currentAlsaCtl->ctl.alsaCtlProperties, valueJ, &convertedJ)) {
+ AFB_ReqFailF(request, "request_json", "Error when trying to convert request json '%s'", json_object_get_string(requestJson));
+ return;
+ }
+
+ if(HalCtlsSetAlsaCtlValue(apiHandle, cardIdString, currentAlsaCtl->ctl.numid, convertedJ)) {
AFB_ReqFailF(request,
"alsa_control_call_error",
- "Error while trying to set value on alsa control %i, device '%s'",
+ "Error while trying to set value on alsa control %i, device '%s', message '%s'",
currentAlsaCtl->ctl.numid,
- cardIdString);
+ cardIdString,
+ json_object_get_string(requestJson));
return;
}
+ json_object_put(convertedJ);
+
AFB_ReqSucess(request, NULL, "Action on alsa control correclty done");
} \ No newline at end of file
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 e52639f..5b9f2a8 100644
--- a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c
+++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c
@@ -27,8 +27,9 @@
#include "../4a-hal-utilities/4a-hal-utilities-appfw-responses-handler.h"
#include "4a-hal-controllers-cb.h"
-#include "4a-hal-controllers-mixer-handler.h"
#include "4a-hal-controllers-alsacore-link.h"
+#include "4a-hal-controllers-mixer-handler.h"
+#include "4a-hal-controllers-value-handler.h"
/*******************************************************************************
* HAL controller event handler function *
@@ -81,10 +82,14 @@ void HalCtlsDispatchApiEvent(afb_dynapi *apiHandle, const char *evtLabel, json_o
source.api = currentHalAlsaCtlsT->ctls[idx].action->api;
source.request = NULL;
- // TODO JAI: add weighting passing values (new valueJ object)
-
(void) ActionExecOne(&source, currentHalAlsaCtlsT->ctls[idx].action, valuesJ);
}
+ else {
+ AFB_ApiNotice(apiHandle,
+ "%s: The alsa control id '%i' is corresponding to a known control but without any action registered",
+ __func__,
+ numid);
+ }
return;
}
@@ -219,7 +224,7 @@ int HalCtlsProcessOneHalMapObject(AFB_ApiT apiHandle, struct CtlHalAlsaMap *alsa
int HalCtlsHandleOneHalMapObject(AFB_ApiT apiHandle, char *cardId, struct CtlHalAlsaMap *alsaMap)
{
- json_object *valueJ;
+ json_object *valueJ, *convertedValueJ;
if(alsaMap->ctl.alsaCtlCreation) {
if(HalCtlsCreateAlsaCtl(apiHandle, cardId, &alsaMap->ctl)) {
@@ -237,16 +242,21 @@ int HalCtlsHandleOneHalMapObject(AFB_ApiT apiHandle, char *cardId, struct CtlHal
}
if(alsaMap->ctl.value) {
- // TODO JAI: add weighting passing values on currentAlsaCtl->value (and put them into valueJ json)
-
+ // TBD JAI : handle alsa controls type
valueJ = json_object_new_int(alsaMap->ctl.value);
- if(HalCtlsSetAlsaCtlValue(apiHandle, cardId, alsaMap->ctl.numid, valueJ)) {
+
+ if(HalCtlsNormalizeJsonValues(apiHandle, &alsaMap->ctl.alsaCtlProperties, valueJ, &convertedValueJ)) {
+ AFB_ApiError(apiHandle, "Error when trying to convert initiate value json '%s'", json_object_get_string(valueJ));
+ return -3;
+ }
+
+ if(HalCtlsSetAlsaCtlValue(apiHandle, cardId, alsaMap->ctl.numid, convertedValueJ)) {
AFB_ApiError(apiHandle,
"Error while trying to set initial value on alsa control %i, device '%s', value '%s'",
alsaMap->ctl.numid,
cardId,
json_object_get_string(valueJ));
- return -3;
+ return -4;
}
}
@@ -257,7 +267,7 @@ int HalCtlsHandleOneHalMapObject(AFB_ApiT apiHandle, char *cardId, struct CtlHal
"%s: Didn't succeed to load action using alsa object:\n-- %s",
__func__,
json_object_get_string(alsaMap->actionJ));
- return -4;
+ return -5;
}
}
@@ -266,7 +276,7 @@ int HalCtlsHandleOneHalMapObject(AFB_ApiT apiHandle, char *cardId, struct CtlHal
"%s: Didn't to create verb for current alsa control to load action using alsa object:\n-- %s",
__func__,
json_object_get_string(alsaMap->actionJ));
- return -5;
+ return -6;
}
return 0;
@@ -291,7 +301,7 @@ int HalCtlsProcessAllHalMap(AFB_ApiT apiHandle, json_object *AlsaMapJ, struct Ct
currentCtlHalAlsaMapT->ctlsCount = 0;
currentCtlHalAlsaMapT->ctls = NULL;
AFB_ApiWarning(apiHandle, "%s: couldn't get content of 'halmap' section in:\n-- %s", __func__, json_object_get_string(AlsaMapJ));
- return -3;
+ return -1;
}
ctlMaps = calloc(currentCtlHalAlsaMapT->ctlsCount, sizeof(struct CtlHalAlsaMap));
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
new file mode 100644
index 0000000..f749521
--- /dev/null
+++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2018 "IoT.bzh"
+ * Author Jonathan Aillet <jonathan.aillet@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <limits.h>
+#include <math.h>
+
+#include <wrap-json.h>
+
+#include "4a-hal-controllers-value-handler.h"
+#include "4a-hal-controllers-alsacore-link.h"
+
+/*******************************************************************************
+ * Simple conversion value to/from percentage functions *
+ ******************************************************************************/
+
+int HalCtlsConvertValueToPercentage(double val, double min, double max)
+{
+ double range;
+
+ range = max - min;
+ if(range <= 0)
+ return -INT_MAX;
+
+ val -= min;
+
+ return (int) round(val / range * 100);
+}
+
+int HalCtlsConvertPercentageToValue(int percentage, int min, int max)
+{
+ int range;
+
+ range = max - min;
+ if(range <= 0)
+ return -INT_MAX;
+
+ return (int) round((double) percentage * (double) range * 0.01 + (double) min);
+}
+
+/*******************************************************************************
+ * Convert json object from percentage to value *
+ ******************************************************************************/
+
+int HalCtlsNormalizeJsonValues(AFB_ApiT apiHandle, struct CtlHalAlsaCtlProperties *alsaCtlProperties, json_object *toConvertJ, json_object ** ConvertedJ)
+{
+ int err = 0, idx, count, initialValue, convertedValue;
+
+ json_object *toConvertObjectJ, *convertedValueJ, *convertedArrayJ;
+
+ switch(json_object_get_type(toConvertJ)) {
+ case json_type_array:
+ count = json_object_array_length(toConvertJ);
+ break;
+
+ case json_type_null:
+ case json_type_object:
+ count = 0;
+ AFB_ApiWarning(apiHandle, "%s: can't normalize json values :\n-- %s", __func__, json_object_get_string(toConvertJ));
+ *ConvertedJ = json_object_get(toConvertJ);
+ return -1;
+
+ default:
+ count = 1;
+ break;
+ }
+
+ convertedArrayJ = json_object_new_array();
+
+ for(idx = 0; idx < count; idx++) {
+ if(count > 1)
+ toConvertObjectJ = json_object_array_get_idx(toConvertJ, idx);
+ else
+ toConvertObjectJ = toConvertJ;
+
+ 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,
+ "%s: Try normalize an integer control but value sent in json is not an integer : '%s'",
+ __func__,
+ json_object_get_string(toConvertObjectJ));
+ convertedValueJ = toConvertObjectJ;
+ break;
+ }
+
+ initialValue = json_object_get_int(toConvertObjectJ);
+ convertedValue = HalCtlsConvertPercentageToValue(initialValue, alsaCtlProperties->minval, alsaCtlProperties->maxval);
+ if(convertedValue == -INT_MAX) {
+ AFB_ApiWarning(apiHandle,
+ "%s: Can't normalize %i (using min %i et max %i), value set to 0",
+ __func__,
+ 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,
+ "%s: Try normalize a boolean control but value sent in json is not a boolean/integer : '%s'",
+ __func__,
+ json_object_get_string(toConvertObjectJ));
+ convertedValueJ = toConvertObjectJ;
+ break;
+ }
+
+ initialValue = json_object_get_int(toConvertObjectJ);
+ convertedValueJ = json_object_new_int(initialValue ? 1 : 0);
+ break;
+
+ default:
+ AFB_ApiWarning(apiHandle,
+ "%s: Normalization not handle for the alsa control type %i, sending back the object as it was '%s'",
+ __func__,
+ (int) alsaCtlProperties->type,
+ json_object_get_string(toConvertJ));
+ convertedValueJ = toConvertObjectJ;
+ break;
+ }
+
+ json_object_array_put_idx(convertedArrayJ, idx, convertedValueJ);
+ }
+
+ *ConvertedJ = convertedArrayJ;
+
+ return 0;
+} \ No newline at end of file
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
new file mode 100644
index 0000000..5f91aaa
--- /dev/null
+++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-value-handler.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 "IoT.bzh"
+ * Author Jonathan Aillet <jonathan.aillet@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _HAL_CTLS_VALUE_NORMALIZATION_INCLUDE_
+#define _HAL_CTLS_VALUE_NORMALIZATION_INCLUDE_
+
+#include <stdio.h>
+
+#include <wrap-json.h>
+
+#include "4a-hal-controllers-alsacore-link.h"
+
+// 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);
+
+#endif /* _HAL_CTLS_VALUE_NORMALIZATION_INCLUDE_ */ \ No newline at end of file
diff --git a/4a-hal/CMakeLists.txt b/4a-hal/CMakeLists.txt
index cf485fd..ded6c8c 100644
--- a/4a-hal/CMakeLists.txt
+++ b/4a-hal/CMakeLists.txt
@@ -33,6 +33,7 @@ PROJECT_TARGET_ADD(4a-hal)
${TARGET_NAME}-controllers/${TARGET_NAME}-controllers-api-loader.c
${TARGET_NAME}-controllers/${TARGET_NAME}-controllers-cb.c
${TARGET_NAME}-controllers/${TARGET_NAME}-controllers-mixer-handler.c
+ ${TARGET_NAME}-controllers/${TARGET_NAME}-controllers-value-handler.c
)
# Binder exposes a unique public entry point