summaryrefslogtreecommitdiffstats
path: root/HAL-afb/HAL-interface
diff options
context:
space:
mode:
authorfulup <fulup.arfoll@iot.bzh>2017-07-21 23:46:49 +0200
committerfulup <fulup.arfoll@iot.bzh>2017-07-21 23:46:49 +0200
commit044828c43097362973c82088a7afee760eab06ec (patch)
tree140522d19e9adea8286f377a53098566c0ee7b89 /HAL-afb/HAL-interface
parentdb4d63597b22b63eb73b5c0558476652ed4988bb (diff)
Added HAL selection in HTML page
Started SetCtl implementation WIP Only
Diffstat (limited to 'HAL-afb/HAL-interface')
-rw-r--r--HAL-afb/HAL-interface/CMakeLists.txt8
-rw-r--r--HAL-afb/HAL-interface/hal-interface.c233
2 files changed, 177 insertions, 64 deletions
diff --git a/HAL-afb/HAL-interface/CMakeLists.txt b/HAL-afb/HAL-interface/CMakeLists.txt
index 0ea298f..d4dba4b 100644
--- a/HAL-afb/HAL-interface/CMakeLists.txt
+++ b/HAL-afb/HAL-interface/CMakeLists.txt
@@ -21,17 +21,17 @@
PROJECT_TARGET_ADD(hal-interface)
# Define targets
- ADD_LIBRARY(hal-interface STATIC hal-interface.c)
+ ADD_LIBRARY(${TARGET_NAME} STATIC hal-interface.c)
# Library properties
- SET_TARGET_PROPERTIES(hal-interface PROPERTIES OUTPUT_NAME halinterface)
+ SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES OUTPUT_NAME halinterface)
# Library dependencies (include updates automatically)
- TARGET_LINK_LIBRARIES(hal-interface
+ TARGET_LINK_LIBRARIES(${TARGET_NAME}
audio-interface
)
# Define target includes
- TARGET_INCLUDE_DIRECTORIES(hal-interface
+ TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME}
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
)
diff --git a/HAL-afb/HAL-interface/hal-interface.c b/HAL-afb/HAL-interface/hal-interface.c
index 19fe191..dd00d1c 100644
--- a/HAL-afb/HAL-interface/hal-interface.c
+++ b/HAL-afb/HAL-interface/hal-interface.c
@@ -61,15 +61,14 @@ STATIC void halSubscribe(afb_req request) {
}
}
-
// HAL normalise volume values to 0-100%
-STATIC struct json_object *NormaliseValue(const alsaHalCtlMapT *halCtls, struct json_object *valuesJ) {
+STATIC struct json_object *UnNormaliseValue(const alsaHalCtlMapT *halCtls, struct json_object *valuesJ) {
int length;
// assert response as the right length
length = json_object_array_length(valuesJ);
if (length != halCtls->count) {
- AFB_WARNING ("NormaliseValue invalid ctl=%s values count=%d len=%d", halCtls->name, halCtls->count, length);
+ AFB_WARNING ("NormaliseValue invalid ctl='%s' values count=%d len=%d", halCtls->name, halCtls->count, length);
return NULL;
}
@@ -93,56 +92,41 @@ STATIC struct json_object *NormaliseValue(const alsaHalCtlMapT *halCtls, struct
return (normalisedJ);
}
-// Remap low level controls into HAL hight level ones
-STATIC json_object *CtlGetPrepareResponse(afb_req request, struct json_object *ctlsJ) {
- struct json_object *halResponseJ;
- // make sure return controls have a valid type
- if (json_object_get_type(ctlsJ) != json_type_array) {
- afb_req_fail_f(request, "ctls-notarray", "Invalid Controls return from alsa/getcontrol ctlsJ=%s", json_object_get_string(ctlsJ));
- goto OnErrorExit;
- }
-
- // responseJ is a JSON array
- halResponseJ = json_object_new_array();
- // loop on array and store values into client context
- for (int idx = 0; idx < json_object_array_length(ctlsJ); idx++) {
- struct json_object *sndCtlJ, *valJ, *numidJ;
- int numid;
+// HAL normalise volume values to 0-100%
+STATIC struct json_object *NormaliseValue(const alsaHalCtlMapT *halCtls, struct json_object *valuesJ) {
+ int length;
- sndCtlJ = json_object_array_get_idx(ctlsJ, idx);
- if (!json_object_object_get_ex(sndCtlJ, "numid", &numidJ) || !json_object_object_get_ex(sndCtlJ, "val", &valJ)) {
- afb_req_fail_f(request, "ctl-invalid", "Invalid Control return from alsa/getcontrol ctl=%s", json_object_get_string(sndCtlJ));
- goto OnErrorExit;
- }
+ // assert response as the right length
+ length = json_object_array_length(valuesJ);
+ if (length != halCtls->count) {
+ AFB_WARNING ("NormaliseValue invalid ctl=%s values count=%d len=%d", halCtls->name, halCtls->count, length);
+ return NULL;
+ }
+
+ json_object *normalisedJ= json_object_new_array();
+ for (int idx=0; idx <length; idx++) {
+ json_object *valueJ = json_object_array_get_idx (valuesJ, idx);
+ int value = json_object_get_int(valueJ);
- // HAL and Business logic use the same AlsaMixerHal.h direct conversion
- numid= (halCtlsEnumT) json_object_get_int(numidJ);
-
- for (int idx = 0; halCtls[idx].ctl.numid; idx++) {
- if (halCtls[idx].ctl.numid == numid) {
-
- // translate low level numid to HAL one and normalise values
- struct json_object *halCtlJ = json_object_new_object();
- json_object_object_add(halCtlJ, "label", json_object_new_string(halCtls[idx].label)); // idx+1 == HAL/NUMID
- json_object_object_add(halCtlJ, "tag" , json_object_new_int(halCtls[idx].tag)); // idx+1 == HAL/NUMID
- json_object_object_add(halCtlJ, "val" , NormaliseValue(&halCtls[idx].ctl, valJ));
- json_object_array_add(halResponseJ, halCtlJ);
- break;
- }
- }
- if ( halCtls[idx].ctl.numid == 0) {
- afb_req_fail_f(request, "ctl-invalid", "Invalid Control numid=%d from alsa/getcontrol ctlJ=%s", numid, json_object_get_string(sndCtlJ));
- goto OnErrorExit;
- }
+ // cleanup and normalise value
+ if (value > halCtls->maxval) value= halCtls->maxval;
+ if (value < halCtls->minval) value= halCtls->minval;
+
+ // If Integer scale to 0/100
+ if (halCtls->type == SND_CTL_ELEM_TYPE_INTEGER) {
+ value = (value * 100) / (halCtls->maxval - halCtls->minval);
+ }
+
+ json_object_array_add(normalisedJ, json_object_new_int(value));
}
- return halResponseJ;
- OnErrorExit:
- return NULL;
+ return (normalisedJ);
}
+
+
// Return ALL HAL snd controls
PUBLIC void halListCtls(afb_req request) {
struct json_object *ctlsHalJ = json_object_new_array();
@@ -181,7 +165,7 @@ STATIC int halCtlTagToIndex (halCtlsEnumT tag) {
return -1;
}
-STATIC int halGetOneCtls (afb_req request, struct json_object*ctlInJ) {
+STATIC int halGetCtlIndex (afb_req request, struct json_object*ctlInJ) {
struct json_object *tmpJ;
int tag, index;
@@ -205,20 +189,149 @@ STATIC int halGetOneCtls (afb_req request, struct json_object*ctlInJ) {
}
if (index < 0) {
- afb_req_fail_f(request, "ctl-invalid", "No Label/Tag given ctl=[%s]", json_object_get_string(ctlInJ));
+ afb_req_fail_f(request, "ctl-invalid", "No Label/Tag given ctl='%s'", json_object_get_string(ctlInJ));
goto OnErrorExit;
}
// return corresponding lowlevel numid to querylist
- return halCtls[index].ctl.numid;
+ return index;
OnErrorExit:
return -1;
}
+
+// Translate high level control to low level and call lower layer
+PUBLIC void halSetCtls(afb_req request) {
+ int err, index;
+ struct json_object *ctlsInJ, *ctlsOutJ, *queryJ, *valuesJ, *responseJ;
+
+ // get query from request
+ ctlsInJ = afb_req_json(request);
+ ctlsOutJ = json_object_new_array();
+
+ switch (json_object_get_type(ctlsInJ)) {
+ case json_type_object: {
+ // control is in literal form {tag=xxx, label=xxx, val=xxxx}
+ index = halGetCtlIndex (request, ctlsInJ);
+ if (index <=0) goto OnErrorExit;
+
+ err= json_object_object_get_ex (ctlsInJ, "val" , &valuesJ);
+ if (err) {
+ afb_req_fail_f(request, "ctl-invalid", "No val=[val1, ...] ctl='%s'", json_object_get_string(ctlsInJ));
+ goto OnErrorExit;
+ }
+
+ json_object_array_add (ctlsOutJ, json_object_new_int(halCtls[index].ctl.numid));
+ json_object_array_add (ctlsOutJ, UnNormaliseValue (&halCtls[index].ctl, valuesJ));
+ break;
+ }
+
+ case json_type_array: {
+
+ for (int idx= 0; idx < json_object_array_length (ctlsInJ); idx++) {
+ struct json_object *ctlInJ = json_object_array_get_idx (ctlsInJ, idx);
+ index= halGetCtlIndex (request, ctlInJ);
+ if (index<=0) goto OnErrorExit;
+
+ err= json_object_object_get_ex (ctlInJ, "val" , &valuesJ);
+ if (err) {
+ afb_req_fail_f(request, "ctl-invalid", "No val=[val1, ...] ctl='%s'", json_object_get_string(ctlsInJ));
+ goto OnErrorExit;
+ }
+ // let's create alsa low level set control request
+ struct json_object *ctlOutJ = json_object_new_array();
+ json_object_array_add (ctlOutJ, json_object_new_int(halCtls[index].ctl.numid));
+ json_object_array_add (ctlOutJ, UnNormaliseValue (&halCtls[index].ctl, valuesJ));
+
+ json_object_array_add (ctlsOutJ, ctlOutJ);
+ }
+ break;
+ }
+
+ default:
+ afb_req_fail_f(request, "ctl-invalid", "Not a valid JSON ctl='%s'", json_object_get_string(ctlsInJ));
+ goto OnErrorExit;
+ }
+
+ // Call now level CTL
+ queryJ = json_object_new_object();
+ json_object_object_add(queryJ, "devid", json_object_new_string (halDevid));
+ json_object_object_add(queryJ, "numids", ctlsOutJ);
+
+ err= afb_service_call_sync("alsacore", "setctls", queryJ, &responseJ);
+ if (err) {
+ afb_req_fail_f(request, "subcall:alsacore/setctl", "%s", json_object_get_string(responseJ));
+ goto OnErrorExit;
+ }
+
+ // Let ignore info data if any and keep on response
+ json_object_object_get_ex (responseJ, "response", &responseJ);
+
+ // map back low level response to HAL ctl with normalised values
+ //struct json_object *halResponse = CtlSetPrepareResponse(request, responseJ);
+ //if (!halResponse) goto OnErrorExit;
+
+ afb_req_success (request, NULL, NULL);
+ return;
+
+OnErrorExit:
+ return;
+};
+
+// Remap low level controls into HAL hight level ones
+STATIC json_object *CtlGetPrepareResponse(afb_req request, struct json_object *ctlsJ) {
+ struct json_object *halResponseJ;
+
+ // make sure return controls have a valid type
+ if (json_object_get_type(ctlsJ) != json_type_array) {
+ afb_req_fail_f(request, "ctls-notarray", "Invalid Controls return from alsa/getcontrol ctlsJ=%s", json_object_get_string(ctlsJ));
+ goto OnErrorExit;
+ }
+
+ // responseJ is a JSON array
+ halResponseJ = json_object_new_array();
+
+ // loop on array and store values into client context
+ for (int idx = 0; idx < json_object_array_length(ctlsJ); idx++) {
+ struct json_object *sndCtlJ, *valJ, *numidJ;
+ int numid;
+
+ sndCtlJ = json_object_array_get_idx(ctlsJ, idx);
+ if (!json_object_object_get_ex(sndCtlJ, "numid", &numidJ) || !json_object_object_get_ex(sndCtlJ, "val", &valJ)) {
+ afb_req_fail_f(request, "ctl-invalid", "Invalid Control return from alsa/getcontrol ctl=%s", json_object_get_string(sndCtlJ));
+ goto OnErrorExit;
+ }
+
+ // HAL and Business logic use the same AlsaMixerHal.h direct conversion
+ numid= (halCtlsEnumT) json_object_get_int(numidJ);
+
+ for (int idx = 0; halCtls[idx].ctl.numid; idx++) {
+ if (halCtls[idx].ctl.numid == numid) {
+
+ // translate low level numid to HAL one and normalise values
+ struct json_object *halCtlJ = json_object_new_object();
+ json_object_object_add(halCtlJ, "label", json_object_new_string(halCtls[idx].label)); // idx+1 == HAL/NUMID
+ json_object_object_add(halCtlJ, "tag" , json_object_new_int(halCtls[idx].tag)); // idx+1 == HAL/NUMID
+ json_object_object_add(halCtlJ, "val" , NormaliseValue(&halCtls[idx].ctl, valJ));
+ json_object_array_add(halResponseJ, halCtlJ);
+ break;
+ }
+ }
+ if ( halCtls[idx].ctl.numid == 0) {
+ afb_req_fail_f(request, "ctl-invalid", "Invalid Control numid=%d from alsa/getcontrol ctlJ=%s", numid, json_object_get_string(sndCtlJ));
+ goto OnErrorExit;
+ }
+ }
+ return halResponseJ;
+
+ OnErrorExit:
+ return NULL;
+}
+
// Translate high level control to low level and call lower layer
PUBLIC void halGetCtls(afb_req request) {
- int err, numid;
+ int err, index;
struct json_object *ctlsInJ, *ctlsOutJ, *queryJ, *responseJ;
// get query from request
@@ -228,9 +341,9 @@ PUBLIC void halGetCtls(afb_req request) {
switch (json_object_get_type(ctlsInJ)) {
case json_type_object: {
- numid = halGetOneCtls (request, ctlsInJ);
- if (numid <=0) goto OnErrorExit;
- json_object_array_add (ctlsOutJ, json_object_new_int(numid));
+ index = halGetCtlIndex (request, ctlsInJ);
+ if (index <=0) goto OnErrorExit;
+ json_object_array_add (ctlsOutJ, json_object_new_int(halCtls[index].ctl.numid));
break;
}
@@ -238,15 +351,15 @@ PUBLIC void halGetCtls(afb_req request) {
for (int idx= 0; idx < json_object_array_length (ctlsInJ); idx++) {
struct json_object *ctlInJ = json_object_array_get_idx (ctlsInJ, idx);
- numid= halGetOneCtls (request, ctlInJ);
- if (numid<=0) goto OnErrorExit;
- json_object_array_add (ctlsOutJ, json_object_new_int(numid));
+ index= halGetCtlIndex (request, ctlInJ);
+ if (index<=0) goto OnErrorExit;
+ json_object_array_add (ctlsOutJ, json_object_new_int(halCtls[index].ctl.numid));
}
break;
}
default:
- afb_req_fail_f(request, "ctl-invalid", "Not a valid JSON ctl=[%s]", json_object_get_string(ctlsInJ));
+ afb_req_fail_f(request, "ctl-invalid", "Not a valid JSON ctl='%s'", json_object_get_string(ctlsInJ));
goto OnErrorExit;
}
@@ -355,13 +468,13 @@ PUBLIC int halServiceInit (const char *apiPrefix, alsaHalSndCardT *alsaHalSndCar
err= afb_service_call_sync ("alsacore", "halregister", queryurl, &responseJ);
json_object_put(queryurl);
if (err) {
- AFB_NOTICE ("Fail to register HAL to ALSA lowlevel binding Response=[%s]", json_object_get_string(responseJ));
+ AFB_NOTICE ("Fail to register HAL to ALSA lowlevel binding Response='%s'", json_object_get_string(responseJ));
goto OnErrorExit;
}
// extract sound devidJ from HAL registration
if (!json_object_object_get_ex(responseJ, "response", &tmpJ) || !json_object_object_get_ex(tmpJ, "devid", &devidJ)) {
- AFB_ERROR ("Ooops: Internal error no devidJ return from HAL registration Response=[%s]", json_object_get_string(responseJ));
+ AFB_ERROR ("Ooops: Internal error no devidJ return from HAL registration Response='%s'", json_object_get_string(responseJ));
goto OnErrorExit;
}
@@ -400,7 +513,7 @@ PUBLIC int halServiceInit (const char *apiPrefix, alsaHalSndCardT *alsaHalSndCar
json_object_object_add(queryurl, "ctls",ctlsJ);
err= afb_service_call_sync ("alsacore", "addcustomctl", queryurl, &responseJ);
if (err) {
- AFB_ERROR ("Fail creating HAL Custom ALSA ctls Response=[%s]", json_object_get_string(responseJ));
+ AFB_ERROR ("Fail creating HAL Custom ALSA ctls Response='%s'", json_object_get_string(responseJ));
goto OnErrorExit;
}
}
@@ -408,7 +521,7 @@ PUBLIC int halServiceInit (const char *apiPrefix, alsaHalSndCardT *alsaHalSndCar
// Make sure response is valid
json_object_object_get_ex (responseJ, "response" , &ctlsJ);
if (json_object_get_type(ctlsJ) != json_type_array) {
- AFB_ERROR ("Response Invalid JSON array ctls Response=[%s]", json_object_get_string(responseJ));
+ AFB_ERROR ("Response Invalid JSON array ctls Response='%s'", json_object_get_string(responseJ));
goto OnErrorExit;
}