aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;