aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Aillet <jonathan.aillet@iot.bzh>2019-06-24 14:38:39 +0200
committerJonathan Aillet <jonathan.aillet@iot.bzh>2019-06-26 16:52:39 +0200
commitc6cb9e4064c05ded2c52f833d5e26ab42a03d1de (patch)
tree1af5e72f45b631f4cfe534d2f70b323d81f8fafc
parente62be7bd8ee0ad8fcd0c5a9f7c1f5831d789c5b4 (diff)
Use haldependencies to process and handle halmap
Use haldependencies section definition to process and to handle halmap section. That means that each 'halmap' control can use its own probed audio device card number using a targeted dependencies. Also, change halmap section definition to be able to handle several halmap defined with the same dependencies. Update example hal to match new json file format. BUG-AGL: SPEC-2329 Change-Id: I31997a037ee8f0e727e0a67866d651b988b85260 Signed-off-by: Jonathan Aillet <jonathan.aillet@iot.bzh>
-rw-r--r--4a-hal-cfg-example/hal-4a-2ch-generic-usb.json75
-rw-r--r--lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h10
-rw-r--r--lib/4a-hal-utilities/4a-hal-utilities-data.c53
-rw-r--r--lib/4a-hal-utilities/4a-hal-utilities-data.h2
-rw-r--r--src/4a-internals-hal/4a-internals-hal-alsacore-link.c2
-rw-r--r--src/4a-internals-hal/4a-internals-hal-cb.c325
6 files changed, 337 insertions, 130 deletions
diff --git a/4a-hal-cfg-example/hal-4a-2ch-generic-usb.json b/4a-hal-cfg-example/hal-4a-2ch-generic-usb.json
index ea7c00f..9fe4c1d 100644
--- a/4a-hal-cfg-example/hal-4a-2ch-generic-usb.json
+++ b/4a-hal-cfg-example/hal-4a-2ch-generic-usb.json
@@ -1,13 +1,13 @@
{
"$schema": "http://iot.bzh/download/public/schema/json/ctl-schema.json",
"metadata": {
- "uid": "/dev/snd/by-id/usb-0d8c_USB_Sound_Device-00",
- "version": "0.9",
+ "uid": "GENERIC-USB-4A-HAL",
+ "version": "0.99",
"api": "4a-hal-2ch-generic-usb",
"require": [ "alsacore", "smixer" ],
"info": "4a hal for 2ch generic USB device",
"author": "Jonathan Aillet",
- "date": "2018-06-13"
+ "date": "2019-06-25"
},
"resources": [
{
@@ -15,13 +15,13 @@
"info": "Bluealsa hal plugin",
"params": {
"sco": {
- "mic": "2CH-GENERIC-USB",
+ "mic": "CSL-CM106-8CH-USB",
"zone": "full-stereo",
"delayms": 800
},
"a2dp": {
- "zone": "full-stereo",
- "delayms": 500
+ "zone": "full-stereo",
+ "delayms": 500
}
},
"libs": ["hal-bluealsa.ctlso"]
@@ -34,34 +34,45 @@
"action": "api://4a-hal-manager#ping"
}
],
+ "haldependencies" : {
+ "uid" : "generic-usb",
+ "class" : "mandatory",
+ "cardPath" : "/dev/snd/by-id/usb-0d8c_USB_Sound_Device-00"
+ },
"halmap": [
{
- "uid": "agl-master-playback-volume",
- "alsa": {
- "name": "Speaker Playback Volume",
- "value": 80
- }
- },
- {
- "uid": "agl-master-playback-switch",
- "alsa": {
- "name": "Speaker Playback Switch",
- "value": 1
- }
- },
- {
- "uid": "agl-mic-capture-volume",
- "alsa": {
- "name": "Mic Capture Volume",
- "value": 80
- }
- },
- {
- "uid": "agl-mic-capture-switch",
- "alsa": {
- "name": "Mic Capture Switch",
- "value": 1
- }
+ "uid" : "halmap-generic-usb",
+ "target" : "generic-usb",
+ "controls" : [
+ {
+ "uid": "agl-master-playback-volume",
+ "alsa": {
+ "name": "Speaker Playback Volume",
+ "value": 80
+ }
+ },
+ {
+ "uid": "agl-master-playback-switch",
+ "alsa": {
+ "name": "Speaker Playback Switch",
+ "value": 1
+ }
+ },
+ {
+ "uid": "agl-master-capture-volume",
+ "alsa": {
+ "name": "Mic Capture Volume",
+ "value": 80
+ }
+ },
+ {
+ "uid": "agl-mic-capture-switch",
+ "alsa": {
+ "name": "Mic Capture Switch",
+ "value": 1
+ }
+ }
+ ]
}
],
"halmixer": {
diff --git a/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h b/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h
index d548c73..b387468 100644
--- a/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h
+++ b/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h
@@ -30,6 +30,8 @@
#include <ctl-config.h>
+#define HAL_UNKNOWN_DEVICE -1
+
struct InternalHalAlsaDBScale {
int min;
int max;
@@ -44,7 +46,7 @@ struct InternalHalAlsaCtlProperties {
int maxval;
int step;
// TBD JAI : use them
- const char **enums;
+ char **enums;
struct InternalHalAlsaDBScale *dbscale;
};
@@ -58,6 +60,12 @@ struct InternalHalAlsaCtl {
};
struct InternalHalAlsaMap {
+ char *targetUid;
+ char *targetInfo;
+
+ char *targetedDependency;
+ int cardNb;
+
char *uid;
char *info;
diff --git a/lib/4a-hal-utilities/4a-hal-utilities-data.c b/lib/4a-hal-utilities/4a-hal-utilities-data.c
index cebc223..b6d8abb 100644
--- a/lib/4a-hal-utilities/4a-hal-utilities-data.c
+++ b/lib/4a-hal-utilities/4a-hal-utilities-data.c
@@ -68,6 +68,7 @@ void *HalUtlAddNodeInList(struct cds_list_head *listHead, enum LinkedListType li
if(! returned)
return NULL;
nodeToAdd = &((struct InternalHalAlsaMap *) returned)->node;
+ ((struct InternalHalAlsaMap *) returned)->cardNb = HAL_UNKNOWN_DEVICE;
break;
case LINKED_LIST_FOR_HAL_DATA:
@@ -871,12 +872,18 @@ json_object *HalUtlGetJsonArrayForAllMixersData(afb_api_t apiHandle, struct cds_
void HalUtlFreeSelectedHalMapDataAllocation(struct InternalHalAlsaMap *halMapDataToFree)
{
+ free(halMapDataToFree->targetUid);
+ free(halMapDataToFree->targetInfo);
+
+ free(halMapDataToFree->targetedDependency);
+
free(halMapDataToFree->uid);
free(halMapDataToFree->info);
free(halMapDataToFree->action);
- free(halMapDataToFree->ctl.name);
+ if(halMapDataToFree->ctl.name != halMapDataToFree->uid)
+ free(halMapDataToFree->ctl.name);
if(halMapDataToFree->ctl.alsaCtlCreation) {
free(halMapDataToFree->ctl.alsaCtlCreation->enums);
@@ -918,7 +925,7 @@ json_object *HalUtGetJsonArrayForSpecificHalMapControl(afb_api_t apiHandle,
{
int wrapRet;
- json_object *currentAlsaMapDataJ;
+ json_object *currentAlsaMapInfoJ, *additionalInfoJ;
if(! apiHandle) {
AFB_API_ERROR(apiHandle, "Can't get current internal hal api handle");
@@ -930,16 +937,48 @@ json_object *HalUtGetJsonArrayForSpecificHalMapControl(afb_api_t apiHandle,
return NULL;
}
- wrapRet = wrap_json_pack(&currentAlsaMapDataJ,
- "{s:s s:s}",
+ wrapRet = wrap_json_pack(&currentAlsaMapInfoJ,
+ "{s:s s:s s:s}",
"name", currentHalMapData->uid,
- "info", currentHalMapData->info ? currentHalMapData->info : "none");
+ "info", currentHalMapData->info ? currentHalMapData->info : "none",
+ "target", currentHalMapData->targetedDependency);
if(wrapRet) {
- AFB_API_ERROR(apiHandle, "Didn't succeed to allocate current streams json object");
+ AFB_API_ERROR(apiHandle, "Didn't succeed to allocate current halmap control first part of info json object");
return NULL;
}
- return currentAlsaMapDataJ;
+ if(currentHalMapData->cardNb == HAL_UNKNOWN_DEVICE ||
+ ! currentHalMapData->ctl.alsaCtlProperties) {
+ json_object_object_add(currentAlsaMapInfoJ, "available", json_object_new_boolean(0));
+ }
+ else {
+ wrapRet = wrap_json_pack(&additionalInfoJ,
+ "{s:b s:i s:s}",
+ "available", 1,
+ "cardNb", currentHalMapData->cardNb,
+ "cardControlName", currentHalMapData->ctl.name ? currentHalMapData->ctl.name : "'N/A'");
+ if(wrapRet) {
+ AFB_API_ERROR(apiHandle, "Didn't succeed to allocate current halmap control second part of info json object");
+ json_object_put(currentAlsaMapInfoJ);
+ return NULL;
+ }
+
+ wrap_json_object_add(currentAlsaMapInfoJ, additionalInfoJ);
+ }
+
+ wrapRet = wrap_json_pack(&additionalInfoJ,
+ "{s:s s:s}",
+ "halmap-uid", currentHalMapData->targetUid,
+ "halmap-info", currentHalMapData->targetInfo ? currentHalMapData->targetInfo : "none");
+ if(wrapRet) {
+ AFB_API_ERROR(apiHandle, "Didn't succeed to allocate current halmap control third part of info json object");
+ json_object_put(currentAlsaMapInfoJ);
+ return NULL;
+ }
+
+ wrap_json_object_add(currentAlsaMapInfoJ, additionalInfoJ);
+
+ return currentAlsaMapInfoJ;
}
json_object *HalUtGetJsonArrayForAllHalMapControls(afb_api_t apiHandle, struct cds_list_head *halMapListHead)
diff --git a/lib/4a-hal-utilities/4a-hal-utilities-data.h b/lib/4a-hal-utilities/4a-hal-utilities-data.h
index 1ecfe00..bea92dd 100644
--- a/lib/4a-hal-utilities/4a-hal-utilities-data.h
+++ b/lib/4a-hal-utilities/4a-hal-utilities-data.h
@@ -30,8 +30,6 @@
#include "4a-hal-utilities-alsa-data.h"
-#define HAL_UNKNOWN_DEVICE -1
-
#define HAL_STREAM_UPDATES_EVENT_NAME "stream-updates"
// Enum for linked list type
diff --git a/src/4a-internals-hal/4a-internals-hal-alsacore-link.c b/src/4a-internals-hal/4a-internals-hal-alsacore-link.c
index 0243a7b..6a56e78 100644
--- a/src/4a-internals-hal/4a-internals-hal-alsacore-link.c
+++ b/src/4a-internals-hal/4a-internals-hal-alsacore-link.c
@@ -582,7 +582,7 @@ void InternalHalActionOnAlsaCtl(afb_req_t request)
return;
}
- snprintf(cardIdString, 6, "hw:%i", currentHalData->sndCardId);
+ snprintf(cardIdString, 6, "hw:%i", currentAlsaCtl->cardNb);
if(InternalHalGetAlsaCtlValues(apiHandle, cardIdString, &currentAlsaCtl->ctl, &previousControlValuesJ)) {
afb_req_fail(request, "previous_values", "Error when trying to get unchanged alsa control values");
diff --git a/src/4a-internals-hal/4a-internals-hal-cb.c b/src/4a-internals-hal/4a-internals-hal-cb.c
index 19a1d4a..5dc0a2e 100644
--- a/src/4a-internals-hal/4a-internals-hal-cb.c
+++ b/src/4a-internals-hal/4a-internals-hal-cb.c
@@ -75,15 +75,6 @@ void InternalHalDispatchApiEvent(afb_api_t apiHandle, const char *evtLabel, json
return;
}
- if(currentHalData->sndCardId != cardidx) {
- AFB_API_NOTICE(apiHandle,
- "The received alsacore event does not concern "
- "current hal soundcard %i (it was about card %i)",
- currentHalData->sndCardId,
- cardidx);
- return;
- }
-
if(cds_list_empty(&currentHalData->internalHalData->halMapListHead)) {
AFB_API_ERROR(apiHandle, "No halmap data is available, cannot handle alsacore event");
return;
@@ -91,7 +82,8 @@ void InternalHalDispatchApiEvent(afb_api_t apiHandle, const char *evtLabel, json
// Search for corresponding numid in ALSA controls list, if found, launch callback (if available)
cds_list_for_each_entry(currentHalMapControl, &currentHalData->internalHalData->halMapListHead, node) {
- if(currentHalMapControl->ctl.alsaCtlProperties &&
+ if(currentHalMapControl->cardNb == cardidx &&
+ currentHalMapControl->ctl.alsaCtlProperties &&
currentHalMapControl->ctl.numid == numid) {
if(currentHalMapControl->action) {
memset(&source, 0, sizeof(CtlSourceT));
@@ -207,57 +199,64 @@ int InternalHalHalMixerConfig(afb_api_t apiHandle, CtlSectionT *section, json_ob
* Internals HAL - 'halmap' section parsing/handling functions *
******************************************************************************/
-int InternalHalProcessOneHalMapObject(afb_api_t apiHandle, struct InternalHalAlsaMap *halMapData, json_object *halMapJ)
+int InternalHalProcessOneHalMapControl(afb_api_t apiHandle,
+ struct InternalHalAlsaMap *halMapData,
+ json_object *halMapControlJ)
{
char *uid, *info = NULL, *action = NULL, *name = NULL, *typename = NULL;
json_object *alsaJ = NULL, *createAlsaCtlJ = NULL;
- AFB_API_DEBUG(apiHandle, "halMapJ=%s", json_object_get_string(halMapJ));
+ if(! apiHandle || ! halMapData || ! halMapControlJ) {
+ AFB_API_ERROR(apiHandle, "Invalid argument(s)");
+ return -1;
+ }
- if(wrap_json_unpack(halMapJ, "{s:s s?:s s:o s?:s !}",
- "uid", &uid,
- "info", &info,
- "alsa", &alsaJ,
- "action", &action)) {
+ if(wrap_json_unpack(halMapControlJ,
+ "{s:s s?:s s:o s?:s !}",
+ "uid", &uid,
+ "info", &info,
+ "alsa", &alsaJ,
+ "action", &action)) {
AFB_API_ERROR(apiHandle,
- "Parsing error, map should only contains "
- "[label]|[uid]|[tag]|[info]|[alsa]|[action] in : '%s'",
- json_object_get_string(halMapJ));
- return -1;
+ "Parsing error, control json should only contains "
+ "[uid]|[info]|[alsa] in : '%s'",
+ json_object_get_string(halMapControlJ));
+ return -2;
}
halMapData->uid = strdup(uid);
if(! halMapData->uid) {
AFB_API_ERROR(apiHandle, "Didn't succeed to store (allocate) control 'uid' string");
- return -2;
+ return -3;
}
if(info) {
halMapData->info = strdup(info);
if(! halMapData->info) {
AFB_API_ERROR(apiHandle, "Didn't succeed to store (allocate) control 'info' string");
- return -3;
+ return -4;
}
}
- if(wrap_json_unpack(alsaJ, "{s?:s s?:i s?:i s?:o !}",
- "name", &name,
- "numid", &halMapData->ctl.numid,
- "value", &halMapData->ctl.value,
- "create", &createAlsaCtlJ)) {
+ if(wrap_json_unpack(alsaJ,
+ "{s?:s s?:i s?:i s?:o !}",
+ "name", &name,
+ "numid", &halMapData->ctl.numid,
+ "value", &halMapData->ctl.value,
+ "create", &createAlsaCtlJ)) {
AFB_API_ERROR(apiHandle,
"Parsing error, alsa json should only contains "
"[name]|[numid]||[value]|[create] in : '%s'",
json_object_get_string(alsaJ));
- return -4;
+ return -5;
}
if(name) {
halMapData->ctl.name = strdup(name);
if(! halMapData->ctl.name) {
AFB_API_ERROR(apiHandle, "Didn't succeed to store (allocate) control 'info' string");
- return -5;
+ return -6;
}
}
@@ -266,7 +265,7 @@ int InternalHalProcessOneHalMapObject(afb_api_t apiHandle, struct InternalHalAls
if(! halMapData->ctl.alsaCtlCreation) {
AFB_API_ERROR(apiHandle,
"Didn't succeed to allocate alsa properties data structure for control to create");
- return -6;
+ return -7;
}
if(wrap_json_unpack(createAlsaCtlJ,
@@ -280,7 +279,7 @@ int InternalHalProcessOneHalMapObject(afb_api_t apiHandle, struct InternalHalAls
"Parsing error, alsa creation json should only contains "
"[type]|[count]|[minval]|[maxval]|[step] in : '%s'",
json_object_get_string(alsaJ));
- return -7;
+ return -8;
}
if(typename) {
@@ -290,12 +289,12 @@ int InternalHalProcessOneHalMapObject(afb_api_t apiHandle, struct InternalHalAls
"Couldn't get alsa type from string %s in : '%s'",
typename,
json_object_get_string(alsaJ));
- return -8;
+ return -9;
}
}
if(! halMapData->ctl.name)
- halMapData->ctl.name = (char *) halMapData->uid;
+ halMapData->ctl.name = halMapData->uid;
}
else if(halMapData->ctl.name && halMapData->ctl.numid > 0) {
AFB_API_ERROR(apiHandle,
@@ -303,58 +302,161 @@ int InternalHalProcessOneHalMapObject(afb_api_t apiHandle, struct InternalHalAls
halMapData->ctl.name,
halMapData->ctl.numid,
json_object_get_string(alsaJ));
- return -9;
+ return -10;
}
else if(! halMapData->ctl.name && halMapData->ctl.numid <= 0) {
AFB_API_ERROR(apiHandle,
"Need at least a control name or a control uid in alsa object : '%s'",
json_object_get_string(alsaJ));
- return -10;
+ return -11;
}
if(action)
- halMapData->actionJ = json_object_get(halMapJ);
+ halMapData->actionJ = json_object_get(halMapControlJ);
return 0;
}
-int InternalHalProcessAllHalMap(afb_api_t apiHandle, json_object *halMapJ, struct cds_list_head *halMapListHead)
+int InternalHalProcessOneHalMapObject(afb_api_t apiHandle,
+ json_object *halMapForTargetJ,
+ struct cds_list_head *halMapListHead,
+ struct cds_list_head *halDevicesToProbeListHead)
{
- int idx, count, err = 0, halMapJsonIsAnArray = 0;
+ int idx, controlsCount, err = 0, halMapControlsJsonIsAnArray = 0;
+
+ char *uid, *info = NULL, *target;
struct InternalHalAlsaMap *currentHalMapData;
- json_object *currentHalMapJ;
+ json_object *controlsJ, *currentHalMapControlJ;
+ json_type halMapControlsType;
+
+ AFB_API_DEBUG(apiHandle, "halMapForTargetJ='%s'", json_object_get_string(halMapForTargetJ));
+
+ if(wrap_json_unpack(halMapForTargetJ,
+ "{s:s s?:s s:s s:o !}",
+ "uid", &uid,
+ "info", &info,
+ "target", &target,
+ "controls", &controlsJ)) {
+ AFB_API_ERROR(apiHandle,
+ "Parsing error, map should only contains "
+ "[uid]|[info]|[target]|[controls] in : '%s'",
+ json_object_get_string(halMapForTargetJ));
+ return -1;
+ }
+
+ if(! HalUtlSearchProbedDeviceDataById(halDevicesToProbeListHead, target)) {
+ AFB_API_ERROR(apiHandle,
+ "Content of 'halmap' section is not valid because targeted dependency ('%s') is not present "
+ "in 'haldependencies' section, json configuration file correction is needed",
+ target);
+ return -2;
+ }
+
+ halMapControlsType = json_object_get_type(controlsJ);
+ switch(halMapControlsType) {
+ case json_type_array:
+ controlsCount = (int) json_object_array_length(controlsJ);
+ halMapControlsJsonIsAnArray = 1;
+ break;
+
+ case json_type_object:
+ controlsCount = 1;
+ break;
+
+ default:
+ AFB_API_ERROR(apiHandle,
+ "Content of 'halmap' controls section is not valid ('%s')",
+ json_object_get_string(controlsJ));
+ return -3;
+ }
+
+ for(idx = 0; idx < controlsCount; idx++) {
+ currentHalMapControlJ = halMapControlsJsonIsAnArray ? json_object_array_get_idx(controlsJ, idx) : controlsJ;
+
+ currentHalMapData = HalUtlAddHalMapDataToHalMapDataList(halMapListHead);
+
+ currentHalMapData->targetUid = strdup(uid);
+ if(! currentHalMapData->targetUid) {
+ AFB_API_ERROR(apiHandle, "Didn't succeed to store (allocate) 'targetUid' string");
+ return -4;
+ }
+
+ if(info) {
+ currentHalMapData->targetInfo = strdup(info);
+ if(! currentHalMapData->targetInfo) {
+ AFB_API_ERROR(apiHandle, "Didn't succeed to store (allocate) 'targetInfo' string");
+ return -5;
+ }
+ }
+
+ currentHalMapData->targetedDependency = strdup(target);
+ if(! currentHalMapData->targetedDependency) {
+ AFB_API_ERROR(apiHandle, "Didn't succeed to store (allocate) 'targetedDependency' string");
+ return -6;
+ }
+
+ err = InternalHalProcessOneHalMapControl(apiHandle,
+ currentHalMapData,
+ currentHalMapControlJ);
+ if(err) {
+ AFB_API_ERROR(apiHandle,
+ "Error %i was returned when tried to proccess halmap control %i ('%s')",
+ err,
+ idx,
+ json_object_get_string(currentHalMapControlJ));
+ HalUtlRemoveSelectedHalMapData(halMapListHead, currentHalMapData);
+ return -7;
+ }
+ }
+
+ return 0;
+}
+
+int InternalHalProcessAllHalMap(afb_api_t apiHandle,
+ json_object *halMapJ,
+ struct cds_list_head *halMapListHead,
+ struct cds_list_head *halDevicesToProbeListHead)
+{
+ int idx, targetCount, err = 0, halMapJsonIsAnArray = 0;
+
+ json_object *currentHalMapTargetJ;
json_type alsaMapType;
+ AFB_API_DEBUG(apiHandle, "halMapJ='%s'", json_object_get_string(halMapJ));
+
alsaMapType = json_object_get_type(halMapJ);
switch(alsaMapType) {
case json_type_array:
- count = (int) json_object_array_length(halMapJ);
+ targetCount = (int) json_object_array_length(halMapJ);
halMapJsonIsAnArray = 1;
break;
case json_type_object:
- count = 1;
+ targetCount = 1;
break;
default:
- AFB_API_ERROR(apiHandle, "Content of 'halmap' section is not valid ('%s')", json_object_get_string(halMapJ));
+ AFB_API_ERROR(apiHandle,
+ "Content of 'halmap' section is not valid ('%s')",
+ json_object_get_string(halMapJ));
return -1;
}
- for(idx = 0; idx < count; idx++) {
- currentHalMapJ = halMapJsonIsAnArray ? json_object_array_get_idx(halMapJ, idx) : halMapJ;
+ for(idx = 0; idx < targetCount; idx++) {
+ currentHalMapTargetJ = halMapJsonIsAnArray ? json_object_array_get_idx(halMapJ, idx) : halMapJ;
- currentHalMapData = HalUtlAddHalMapDataToHalMapDataList(halMapListHead);
-
- err = InternalHalProcessOneHalMapObject(apiHandle, currentHalMapData, currentHalMapJ);
+ err = InternalHalProcessOneHalMapObject(apiHandle,
+ currentHalMapTargetJ,
+ halMapListHead,
+ halDevicesToProbeListHead);
if(err) {
AFB_API_ERROR(apiHandle,
- "Error %i was returned when tried to proccess halmap object %i ('%s')",
+ "Error %i was returned when tried to proccess halmap target %i ('%s')",
err,
idx,
- json_object_get_string(currentHalMapJ));
+ json_object_get_string(currentHalMapTargetJ));
HalUtlRemoveAllHalMapData(halMapListHead);
return -2;
}
@@ -363,10 +465,12 @@ int InternalHalProcessAllHalMap(afb_api_t apiHandle, json_object *halMapJ, struc
return 0;
}
-int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct InternalHalAlsaMap *halMapData)
+int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, struct InternalHalAlsaMap *halMapData)
{
int err;
+ char cardNbString[6];
+
json_object *valueJ, *convertedValueJ = NULL;
CtlActionT *toLoadAction;
@@ -374,13 +478,15 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I
halMapData->alsaControlEvent = afb_api_make_event(apiHandle, halMapData->uid);
if(! halMapData->alsaControlEvent) {
AFB_API_ERROR(apiHandle,
- "Didn't succeed to create event for current alsa control to load action using alsa object : '%s'",
- json_object_get_string(halMapData->actionJ));
+ "Didn't succeed to create event for alsa control with uid %s",
+ halMapData->uid);
return -1;
}
+ snprintf(cardNbString, sizeof(cardNbString), "hw:%i", halMapData->cardNb);
+
if(halMapData->ctl.alsaCtlCreation) {
- if(InternalHalCreateAlsaCtl(apiHandle, cardId, &halMapData->ctl)) {
+ if(InternalHalCreateAlsaCtl(apiHandle, cardNbString, &halMapData->ctl)) {
AFB_API_ERROR(apiHandle, "An error happened when trying to create a new alsa control");
return -2;
}
@@ -394,7 +500,7 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I
return -3;
}
- if(InternalHalUpdateAlsaCtlProperties(apiHandle, cardId, &halMapData->ctl)) {
+ if(InternalHalUpdateAlsaCtlProperties(apiHandle, cardNbString, &halMapData->ctl)) {
AFB_API_ERROR(apiHandle, "An error happened when trying to get existing alsa control info");
free(halMapData->ctl.alsaCtlProperties);
halMapData->ctl.alsaCtlProperties = NULL;
@@ -422,8 +528,8 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I
halMapData->action = toLoadAction;
}
- if(InternalHalSubscribeToAlsaCardEvent(apiHandle, cardId)) {
- AFB_API_ERROR(apiHandle, "Error when trying to subscribe to alsacore event for audio card '%s'", cardId);
+ if(InternalHalSubscribeToAlsaCardEvent(apiHandle, cardNbString)) {
+ AFB_API_ERROR(apiHandle, "Error when trying to subscribe to alsacore event for audio card '%s'", cardNbString);
return -7;
}
@@ -445,11 +551,11 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I
AFB_API_ERROR(apiHandle, "Error when trying to convert initiate value json '%s'", json_object_get_string(valueJ));
err = -9;
}
- else if(InternalHalSetAlsaCtlValue(apiHandle, cardId, halMapData->ctl.numid, convertedValueJ)) {
+ else if(InternalHalSetAlsaCtlValue(apiHandle, cardNbString, halMapData->ctl.numid, convertedValueJ)) {
AFB_API_ERROR(apiHandle,
"Error while trying to set initial value on alsa control %i, device '%s', value '%s'",
halMapData->ctl.numid,
- cardId,
+ cardNbString,
json_object_get_string(valueJ));
err = -10;
}
@@ -463,45 +569,93 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I
return err;
}
- if(afb_api_add_verb(apiHandle, halMapData->uid, halMapData->info, InternalHalActionOnAlsaCtl, (void *) halMapData, NULL, 0, 0)) {
+ if(afb_api_add_verb(apiHandle, halMapData->uid, NULL, InternalHalActionOnAlsaCtl, (void *) halMapData, NULL, 0, 0)) {
AFB_API_ERROR(apiHandle,
- "Didn't succeed to create verb for current alsa control : '%s'",
- json_object_get_string(halMapData->actionJ));
+ "Didn't succeed to create verb %s for alsa control named %s on card %i",
+ halMapData->uid,
+ halMapData->ctl.name ? halMapData->ctl.name : "'N/A'",
+ halMapData->cardNb);
return -10;
}
return 0;
}
-int InternalHalHandleAllHalMap(afb_api_t apiHandle, int sndCardId, struct cds_list_head *halMapListHead)
+int InternalHalHandleSelectedHalMapWithValidatedDependency(afb_api_t apiHandle,
+ struct cds_list_head *halMapListHead,
+ struct cds_list_head *halDevicesToProbeListHead,
+ char *targetedDependency,
+ enum DependenciesHandlingType halMapHandlingType)
{
- int err = 0;
-
- char cardIdString[6];
+ int err = 0, validatedHalMap;
struct InternalHalAlsaMap *currentHalMapData;
- snprintf(cardIdString, 6, "hw:%i", sndCardId);
-
if(cds_list_empty(halMapListHead)) {
AFB_API_ERROR(apiHandle, "HalMap list is empty, nothing to handle");
return 0;
}
+ if(halMapHandlingType == UID_CORRESPONDING_DEPENDENCIES &&
+ ! targetedDependency) {
+ AFB_API_ERROR(apiHandle, "Invalid targeted dependency");
+ return -1;
+ }
+
cds_list_for_each_entry(currentHalMapData, halMapListHead, node) {
- err = InternalHalHandleOneHalMapObject(apiHandle, cardIdString, currentHalMapData);
- if(err) {
- AFB_API_ERROR(apiHandle,
- "Error %i was returned when tried to handle halmap object :' %s'",
- err,
- json_object_get_string(currentHalMapData->actionJ));
- return -1;
+ validatedHalMap = 0;
+ switch(halMapHandlingType) {
+ case ALL_DEPENDENCIES:
+ validatedHalMap = 1;
+ break;
+
+ case UID_CORRESPONDING_DEPENDENCIES:
+ if(! strcmp(targetedDependency, currentHalMapData->targetedDependency))
+ validatedHalMap = 1;
+ break;
+
+ default:
+ AFB_API_ERROR(apiHandle, "Invalid dependencies enum type");
+ return -2;
+ }
+
+ if(validatedHalMap) {
+ currentHalMapData->cardNb = HalUtlGetProbedDeviceCardNbUsingUid(halDevicesToProbeListHead,
+ currentHalMapData->targetedDependency);
+ if(currentHalMapData->cardNb == HAL_UNKNOWN_DEVICE) {
+ AFB_API_WARNING(apiHandle,
+ "Current halmap control %s can't be handled because corresponding "
+ "dependency ('%s') card is not available at the moment",
+ currentHalMapData->uid,
+ currentHalMapData->targetedDependency);
+ continue;
+ }
+
+ err = InternalHalHandleOneHalMapObject(apiHandle, currentHalMapData);
+ if(err) {
+ AFB_API_ERROR(apiHandle,
+ "Error %i was returned when tried to handle halmap control with uid %s",
+ err,
+ currentHalMapData->uid);
+ return -3;
+ }
}
}
return 0;
}
+int InternalHalHandleAllHalMapWithValidatedDependency(afb_api_t apiHandle,
+ struct cds_list_head *halMapListHead,
+ struct cds_list_head *halDevicesToProbeListHead)
+{
+ return InternalHalHandleSelectedHalMapWithValidatedDependency(apiHandle,
+ halMapListHead,
+ halDevicesToProbeListHead,
+ NULL,
+ ALL_DEPENDENCIES);
+}
+
int InternalHalHalMapConfig(afb_api_t apiHandle, CtlSectionT *section, json_object *AlsaMapJ)
{
CtlConfigT *ctrlConfig;
@@ -516,27 +670,24 @@ int InternalHalHalMapConfig(afb_api_t apiHandle, CtlSectionT *section, json_obje
return -2;
if(AlsaMapJ) {
- if(InternalHalProcessAllHalMap(apiHandle, AlsaMapJ, &currentHalData->internalHalData->halMapListHead)) {
+ if(InternalHalProcessAllHalMap(apiHandle,
+ AlsaMapJ,
+ &currentHalData->internalHalData->halMapListHead,
+ &currentHalData->internalHalData->probedDevicesListHead)) {
AFB_API_ERROR(apiHandle, "Failed to process 'halmap' section");
HalUtlRemoveAllHalMapData(&currentHalData->internalHalData->halMapListHead);
return -4;
}
}
- else if(currentHalData->status == HAL_STATUS_UNAVAILABLE) {
- AFB_API_WARNING(apiHandle, "Hal is unavailable, 'halmap' section data can't be handle");
- return 1;
- }
- else if(currentHalData->sndCardId < 0) {
- AFB_API_ERROR(apiHandle, "Hal alsa card id is not valid, 'halmap' section data can't be handle");
- return -5;
- }
else if(cds_list_empty(&currentHalData->internalHalData->halMapListHead)) {
AFB_API_WARNING(apiHandle, "No alsa controls defined in 'halmap' section");
- return 2;
+ return 1;
}
- else if(InternalHalHandleAllHalMap(apiHandle, currentHalData->sndCardId, &currentHalData->internalHalData->halMapListHead)) {
+ else if(InternalHalHandleAllHalMapWithValidatedDependency(apiHandle,
+ &currentHalData->internalHalData->halMapListHead,
+ &currentHalData->internalHalData->probedDevicesListHead)) {
AFB_API_ERROR(apiHandle, "Failed to handle 'halmap' section");
- return -6;
+ return -5;
}
return 0;