diff options
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c | 117 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h | 19 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-data.c | 133 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-data.h | 15 | ||||
-rw-r--r-- | lib/4a-hal-utilities/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/4a-internals-hal/4a-internals-hal-api-loader.c | 1 | ||||
-rw-r--r-- | src/4a-internals-hal/4a-internals-hal-cb.c | 253 | ||||
-rw-r--r-- | src/4a-internals-hal/4a-internals-hal-cb.h | 2 |
8 files changed, 276 insertions, 265 deletions
diff --git a/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c b/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c deleted file mode 100644 index 5d37c0a..0000000 --- a/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2019 "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 <wrap-json.h> - -#include <afb/afb-binding.h> - -#include "4a-hal-utilities-alsa-data.h" - -/******************************************************************************* - * Internal Hal - ALSA controls data handling functions * - ******************************************************************************/ - -json_object *HalUtGetJsonArrayForSpecificControl(afb_api_t apiHandle, struct InternalHalAlsaMap *currentAlsaMapData) -{ - int wrapRet; - - json_object *currentAlsaMapDataJ; - - if(! apiHandle) { - AFB_API_ERROR(apiHandle, "Can't get current internal hal api handle"); - return NULL; - } - - if(! currentAlsaMapData) { - AFB_API_ERROR(apiHandle, "ALSA control data to use to generate json object are empty"); - return NULL; - } - - wrapRet = wrap_json_pack(¤tAlsaMapDataJ, - "{s:s s:s}", - "name", currentAlsaMapData->uid, - "info", currentAlsaMapData->info ? currentAlsaMapData->info : "none"); - if(wrapRet) { - AFB_API_ERROR(apiHandle, "Didn't succeed to allocate current streams json object"); - return NULL; - } - - return currentAlsaMapDataJ; -} - -json_object *HalUtGetJsonArrayForAllControls(afb_api_t apiHandle, struct InternalHalAlsaMapT *currentAlsaMapDataT) -{ - unsigned int idx; - - json_object *alsaMapDataArrayJ, *currentAlsaMapDataJ; - - if(! apiHandle) { - AFB_API_ERROR(apiHandle, "Can't get current internal hal api handle"); - return NULL; - } - - if(! currentAlsaMapDataT) { - AFB_API_ERROR(apiHandle, "Can't get Alsa map data table to handle"); - return NULL; - } - - alsaMapDataArrayJ = json_object_new_array(); - if(! alsaMapDataArrayJ) { - AFB_API_ERROR(apiHandle, "Didn't succeed to allocate ALSA controls data json array"); - return NULL; - } - - for(idx = 0; idx < currentAlsaMapDataT->ctlsCount; idx++) { - currentAlsaMapDataJ = HalUtGetJsonArrayForSpecificControl(apiHandle, ¤tAlsaMapDataT->ctls[idx]); - if(! currentAlsaMapDataJ) { - AFB_API_ERROR(apiHandle, "Didn't succeed to generate current ALSA control data json object"); - json_object_put(alsaMapDataArrayJ); - return NULL; - } - - json_object_array_add(alsaMapDataArrayJ, currentAlsaMapDataJ); - } - - return alsaMapDataArrayJ; -} - -int HalUtlFreeAlsaCtlsMap(struct InternalHalAlsaMapT *alsaCtlsMap) -{ - int idx; - - if(! alsaCtlsMap) - return -1; - - if(alsaCtlsMap->ctlsCount > 0 && ! alsaCtlsMap->ctls) - return -2; - - for(idx = 0; idx < alsaCtlsMap->ctlsCount; idx++) { - free(alsaCtlsMap->ctls[idx].action); - free(alsaCtlsMap->ctls[idx].ctl.alsaCtlProperties.enums); - free(alsaCtlsMap->ctls[idx].ctl.alsaCtlProperties.dbscale); - } - - free(alsaCtlsMap->ctls); - - free(alsaCtlsMap); - - return 0; -}
\ No newline at end of file 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 3a4c885..88b3e44 100644 --- a/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h +++ b/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h @@ -20,6 +20,8 @@ #include <stdio.h> +#include <urcu/list.h> + #include <json-c/json.h> #include <alsa/asoundlib.h> @@ -50,27 +52,24 @@ struct InternalHalAlsaCtl { char *name; int numid; int value; + struct InternalHalAlsaCtlProperties alsaCtlProperties; struct InternalHalAlsaCtlProperties *alsaCtlCreation; }; struct InternalHalAlsaMap { - const char *uid; + char *uid; char *info; + afb_event_t alsaControlEvent; + struct InternalHalAlsaCtl ctl; + json_object *actionJ; + CtlActionT *action; -}; -struct InternalHalAlsaMapT { - struct InternalHalAlsaMap *ctls; - unsigned int ctlsCount; + struct cds_list_head node; }; -// Internal Hal - ALSA controls data handling functions -json_object *HalUtGetJsonArrayForSpecificControl(afb_api_t apiHandle, struct InternalHalAlsaMap *currentAlsaMapData); -json_object *HalUtGetJsonArrayForAllControls(afb_api_t apiHandle, struct InternalHalAlsaMapT *currentAlsaMapDataT); -int HalUtlFreeAlsaCtlsMap(struct InternalHalAlsaMapT *alsaCtlsMap); - #endif /* _HAL_UTILITIES_ALSA_DATA_INCLUDE_ */
\ No newline at end of file diff --git a/lib/4a-hal-utilities/4a-hal-utilities-data.c b/lib/4a-hal-utilities/4a-hal-utilities-data.c index 6121b33..d7ae1f6 100644 --- a/lib/4a-hal-utilities/4a-hal-utilities-data.c +++ b/lib/4a-hal-utilities/4a-hal-utilities-data.c @@ -33,6 +33,7 @@ void HalUtlFreeSelectedProbedDeviceAllocation(struct InternalHalProbedDevice *probedDeviceToFree); void HalUtlFreeSelectedMixerDataAllocation(struct InternalHalMixerData *mixerDataToFree); +void HalUtlFreeSelectedHalMapDataAllocation(struct InternalHalAlsaMap *halMapDataToFree); void HalUtlFreeSelectedHalAllocation(struct HalData *halDataToFree); /******************************************************************************* @@ -62,6 +63,13 @@ void *HalUtlAddNodeInList(struct cds_list_head *listHead, enum LinkedListType li nodeToAdd = &((struct InternalHalMixerData *) returned)->node; break; + case LINKED_LIST_FOR_HALMAP_DATA: + returned = calloc(1, sizeof(struct InternalHalAlsaMap)); + if(! returned) + return NULL; + nodeToAdd = &((struct InternalHalAlsaMap *) returned)->node; + break; + case LINKED_LIST_FOR_HAL_DATA: returned = calloc(1, sizeof(struct HalData)); if(! returned) @@ -96,6 +104,12 @@ int HalUtlRemoveNodeFromList(struct cds_list_head *listHead, void *dataToRemove, HalUtlFreeSelectedMixerDataAllocation((struct InternalHalMixerData *) dataToRemove); break; + case LINKED_LIST_FOR_HALMAP_DATA: + cds_list_del(&((struct InternalHalAlsaMap *) dataToRemove)->node); + + HalUtlFreeSelectedHalMapDataAllocation((struct InternalHalAlsaMap *) dataToRemove); + break; + case LINKED_LIST_FOR_HAL_DATA: cds_list_del(&((struct HalData *) dataToRemove)->node); @@ -135,14 +149,20 @@ int HalUtlRemoveAllNodeFromList(struct cds_list_head *listHead, enum LinkedListT return -3; break; + case LINKED_LIST_FOR_HALMAP_DATA: + if(HalUtlRemoveSelectedHalMapData(listHead, + cds_list_entry(nodeToRemove, struct InternalHalAlsaMap, node))) + return -4; + break; + case LINKED_LIST_FOR_HAL_DATA: if(HalUtlRemoveSelectedHalFromList(listHead, cds_list_entry(nodeToRemove, struct HalData, node))) - return -4; + return -5; break; default: - return -5; + return -6; } nodesRemoved++; @@ -820,6 +840,11 @@ json_object *HalUtlGetJsonArrayForAllMixersData(afb_api_t apiHandle, struct cds_ return NULL; } + if(cds_list_empty(mixerDataListHead)) { + AFB_API_ERROR(apiHandle, "Mixer data list is empty"); + return NULL; + } + mixerDataArrayJ = json_object_new_array(); if(! mixerDataArrayJ) { AFB_API_ERROR(apiHandle, "Didn't succeed to allocate requested mixer data json array"); @@ -841,6 +866,108 @@ json_object *HalUtlGetJsonArrayForAllMixersData(afb_api_t apiHandle, struct cds_ } /******************************************************************************* + * Internal Hal - Alsa Map data handling functions * + ******************************************************************************/ + +void HalUtlFreeSelectedHalMapDataAllocation(struct InternalHalAlsaMap *halMapDataToFree) +{ + free(halMapDataToFree->uid); + free(halMapDataToFree->info); + + free(halMapDataToFree->action); + + free(halMapDataToFree->ctl.name); + + free(halMapDataToFree); +} + +struct InternalHalAlsaMap *HalUtlAddHalMapDataToHalMapDataList(struct cds_list_head *halMapListHead) +{ + return (struct InternalHalAlsaMap *) HalUtlAddNodeInList(halMapListHead, LINKED_LIST_FOR_HALMAP_DATA); +} + +int HalUtlRemoveSelectedHalMapData(struct cds_list_head *halMapListHead, + struct InternalHalAlsaMap *halMapDataToRemove) +{ + return HalUtlRemoveNodeFromList(halMapListHead, (void *) halMapDataToRemove, LINKED_LIST_FOR_HALMAP_DATA); +} + +int HalUtlRemoveAllHalMapData(struct cds_list_head *halMapListHead) +{ + return HalUtlRemoveAllNodeFromList(halMapListHead, LINKED_LIST_FOR_HALMAP_DATA); +} + +int HalUtlGetNumberOfHalMapDataInList(struct cds_list_head *halMapListHead) +{ + return HalUtlGetNumberOfNodesInList(halMapListHead); +} + +json_object *HalUtGetJsonArrayForSpecificHalMapControl(afb_api_t apiHandle, + struct InternalHalAlsaMap *currentHalMapData) +{ + int wrapRet; + + json_object *currentAlsaMapDataJ; + + if(! apiHandle) { + AFB_API_ERROR(apiHandle, "Can't get current internal hal api handle"); + return NULL; + } + + if(! currentHalMapData) { + AFB_API_ERROR(apiHandle, "ALSA control data to use to generate json object are empty"); + return NULL; + } + + wrapRet = wrap_json_pack(¤tAlsaMapDataJ, + "{s:s s:s}", + "name", currentHalMapData->uid, + "info", currentHalMapData->info ? currentHalMapData->info : "none"); + if(wrapRet) { + AFB_API_ERROR(apiHandle, "Didn't succeed to allocate current streams json object"); + return NULL; + } + + return currentAlsaMapDataJ; +} + +json_object *HalUtGetJsonArrayForAllHalMapControls(afb_api_t apiHandle, struct cds_list_head *halMapListHead) +{ + struct InternalHalAlsaMap *currentHalMapData; + + json_object *halMapDataArrayJ, *currentHalMapDataJ; + + if(! apiHandle) { + AFB_API_ERROR(apiHandle, "Can't get current internal hal api handle"); + return NULL; + } + + if(! halMapListHead || cds_list_empty(halMapListHead)) { + AFB_API_ERROR(apiHandle, "HalMap data list is empty"); + return NULL; + } + + halMapDataArrayJ = json_object_new_array(); + if(! halMapDataArrayJ) { + AFB_API_ERROR(apiHandle, "Didn't succeed to allocate ALSA controls data json array"); + return NULL; + } + + cds_list_for_each_entry(currentHalMapData, halMapListHead, node) { + currentHalMapDataJ = HalUtGetJsonArrayForSpecificHalMapControl(apiHandle, currentHalMapData); + if(! currentHalMapDataJ) { + AFB_API_ERROR(apiHandle, "Didn't succeed to generate current HalMap data json object"); + json_object_put(halMapDataArrayJ); + return NULL; + } + + json_object_array_add(halMapDataArrayJ, currentHalMapDataJ); + } + + return halMapDataArrayJ; +} + +/******************************************************************************* * Hal data handling functions * ******************************************************************************/ @@ -857,7 +984,7 @@ void HalUtlFreeSelectedHalAllocation(struct HalData *halDataToFree) HalUtlRemoveAllMixerData(&halDataToFree->internalHalData->streamsDataListHead); - HalUtlFreeAlsaCtlsMap(halDataToFree->internalHalData->alsaMapT); + HalUtlRemoveAllHalMapData(&halDataToFree->internalHalData->halMapListHead); free(halDataToFree->internalHalData); } diff --git a/lib/4a-hal-utilities/4a-hal-utilities-data.h b/lib/4a-hal-utilities/4a-hal-utilities-data.h index 1571485..1ecfe00 100644 --- a/lib/4a-hal-utilities/4a-hal-utilities-data.h +++ b/lib/4a-hal-utilities/4a-hal-utilities-data.h @@ -38,7 +38,8 @@ enum LinkedListType { LINKED_LIST_FOR_DEPENDENCIES_DATA = 0, LINKED_LIST_FOR_MIXER_DATA = 1, - LINKED_LIST_FOR_HAL_DATA = 2 + LINKED_LIST_FOR_HALMAP_DATA = 2, + LINKED_LIST_FOR_HAL_DATA = 3 }; // Enum for hal status @@ -116,7 +117,7 @@ struct InternalHalData { struct cds_list_head streamsDataListHead; afb_event_t streamUpdates; - struct InternalHalAlsaMapT *alsaMapT; + struct cds_list_head halMapListHead; afb_api_t apiHandle; CtlConfigT *ctrlConfig; @@ -191,6 +192,16 @@ struct InternalHalMixerData *HalUtlSearchMixerDataByProperties(struct cds_list_h json_object *HalUtlGetJsonArrayForSpecificMixerData(afb_api_t apiHandle, struct InternalHalMixerData *mixerData); json_object *HalUtlGetJsonArrayForAllMixersData(afb_api_t apiHandle, struct cds_list_head *mixerDataListHead); +// Internal Hal - Alsa Map data handling functions +struct InternalHalAlsaMap *HalUtlAddHalMapDataToHalMapDataList(struct cds_list_head *halMapListHead); +int HalUtlRemoveSelectedHalMapData(struct cds_list_head *halMapListHead, + struct InternalHalAlsaMap *halMapDataToRemove); +int HalUtlRemoveAllHalMapData(struct cds_list_head *halMapListHead); +int HalUtlGetNumberOfHalMapDataInList(struct cds_list_head *halMapListHead); +json_object *HalUtGetJsonArrayForSpecificHalMapControl(afb_api_t apiHandle, + struct InternalHalAlsaMap *currentHalMapData); +json_object *HalUtGetJsonArrayForAllHalMapControls(afb_api_t apiHandle, struct cds_list_head *halMapListHead); + // Hal data handling functions struct HalData *HalUtlAddHalToHalList(struct cds_list_head *halDataListHead); int HalUtlRemoveSelectedHalFromList(struct cds_list_head *halDataListHead, struct HalData *halToRemove); diff --git a/lib/4a-hal-utilities/CMakeLists.txt b/lib/4a-hal-utilities/CMakeLists.txt index 8eb2c62..9689565 100644 --- a/lib/4a-hal-utilities/CMakeLists.txt +++ b/lib/4a-hal-utilities/CMakeLists.txt @@ -22,7 +22,6 @@ PROJECT_TARGET_ADD(4a-hal-utilities) # Define project Targets ADD_LIBRARY(${TARGET_NAME} STATIC - 4a-hal-utilities-alsa-data.c 4a-hal-utilities-data.c 4a-hal-utilities-hal-streams-handler.c) diff --git a/src/4a-internals-hal/4a-internals-hal-api-loader.c b/src/4a-internals-hal/4a-internals-hal-api-loader.c index 6f09d4a..4fffe01 100644 --- a/src/4a-internals-hal/4a-internals-hal-api-loader.c +++ b/src/4a-internals-hal/4a-internals-hal-api-loader.c @@ -213,6 +213,7 @@ int InternalHalCreateApi(afb_api_t apiHandle, char *path, struct HalMgrData *hal CDS_INIT_LIST_HEAD(¤tHalData->internalHalData->probedDevicesListHead); CDS_INIT_LIST_HEAD(¤tHalData->internalHalData->streamsDataListHead); + CDS_INIT_LIST_HEAD(¤tHalData->internalHalData->halMapListHead); // Create one API if(! afb_api_new_api(apiHandle, ctrlConfig->api, ctrlConfig->info, 1, InternalHalLoadOneApi, ctrlConfig)) { diff --git a/src/4a-internals-hal/4a-internals-hal-cb.c b/src/4a-internals-hal/4a-internals-hal-cb.c index 1749131..0050f11 100644 --- a/src/4a-internals-hal/4a-internals-hal-cb.c +++ b/src/4a-internals-hal/4a-internals-hal-cb.c @@ -43,7 +43,7 @@ void InternalHalDispatchApiEvent(afb_api_t apiHandle, const char *evtLabel, json CtlSourceT source; struct HalData *currentHalData; - struct InternalHalAlsaMapT *currentHalAlsaCtlsT; + struct InternalHalAlsaMap *currentHalMapControl; json_object *valuesJ, *normalizedValuesJ; @@ -66,8 +66,7 @@ void InternalHalDispatchApiEvent(afb_api_t apiHandle, const char *evtLabel, json idx++; if(evtLabel[idx] != '\0' && - (sscanf(&evtLabel[idx + 1], "%d", &cardidx) == 1) && - currentHalData->sndCardId == cardidx) { + (sscanf(&evtLabel[idx + 1], "%d", &cardidx) == 1)) { if(wrap_json_unpack(eventJ, "{s:i s:o !}", "id", &numid, "val", &valuesJ)) { AFB_API_ERROR(apiHandle, "Invalid alsacore event received label=%s value=%s", @@ -76,26 +75,31 @@ void InternalHalDispatchApiEvent(afb_api_t apiHandle, const char *evtLabel, json return; } - if(! currentHalData->internalHalData->alsaMapT || - currentHalData->internalHalData->alsaMapT->ctlsCount <= 0 || - ! currentHalData->internalHalData->alsaMapT->ctls) { - AFB_API_ERROR(apiHandle, "No halmap data is available, cannot handle alsacore event"); + 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; } - currentHalAlsaCtlsT = currentHalData->internalHalData->alsaMapT; + if(cds_list_empty(¤tHalData->internalHalData->halMapListHead)) { + AFB_API_ERROR(apiHandle, "No halmap data is available, cannot handle alsacore event"); + return; + } // Search for corresponding numid in ALSA controls list, if found, launch callback (if available) - for(idx = 0; idx < currentHalAlsaCtlsT->ctlsCount; idx++) { - if(currentHalAlsaCtlsT->ctls[idx].ctl.numid == numid) { - if(currentHalAlsaCtlsT->ctls[idx].action) { + cds_list_for_each_entry(currentHalMapControl, ¤tHalData->internalHalData->halMapListHead, node) { + if(currentHalMapControl->ctl.numid == numid) { + if(currentHalMapControl->action) { memset(&source, 0, sizeof(CtlSourceT)); - source.uid = currentHalAlsaCtlsT->ctls[idx].action->uid; - source.api = currentHalAlsaCtlsT->ctls[idx].action->api; + source.uid = currentHalMapControl->action->uid; + source.api = currentHalMapControl->action->api; - (void) ActionExecOne(&source, currentHalAlsaCtlsT->ctls[idx].action, valuesJ); + (void) ActionExecOne(&source, currentHalMapControl->action, valuesJ); } - else if(currentHalAlsaCtlsT->ctls[idx].actionJ) { + else if(currentHalMapControl->actionJ) { AFB_API_WARNING(apiHandle, "The alsa control id '%i' is corresponding to a known control which " "has a registered action, but action is not ready to be executed", @@ -109,17 +113,17 @@ void InternalHalDispatchApiEvent(afb_api_t apiHandle, const char *evtLabel, json numid); } - if(! currentHalAlsaCtlsT->ctls[idx].alsaControlEvent || + if(! currentHalMapControl->alsaControlEvent || InternalHalConvertJsonValues(apiHandle, - ¤tHalAlsaCtlsT->ctls[idx].ctl.alsaCtlProperties, + ¤tHalMapControl->ctl.alsaCtlProperties, valuesJ, &normalizedValuesJ, CONVERSION_ALSACORE_TO_NORMALIZED) || - (afb_event_push(currentHalAlsaCtlsT->ctls[idx].alsaControlEvent, normalizedValuesJ) < 0)) { + (afb_event_push(currentHalMapControl->alsaControlEvent, normalizedValuesJ) < 0)) { AFB_API_ERROR(apiHandle, "Couldn't generate an event for known halmap %s (alsa control id %i)", - currentHalAlsaCtlsT->ctls[idx].uid, - currentHalAlsaCtlsT->ctls[idx].ctl.numid); + currentHalMapControl->uid, + currentHalMapControl->ctl.numid); } return; @@ -202,32 +206,32 @@ 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 *alsaMap, json_object *AlsaMapJ) +int InternalHalProcessOneHalMapObject(afb_api_t apiHandle, struct InternalHalAlsaMap *halMapData, json_object *halMapJ) { char *uid, *info = NULL, *action = NULL, *name = NULL, *typename = NULL; json_object *alsaJ = NULL, *createAlsaCtlJ = NULL; - AFB_API_DEBUG(apiHandle, "AlsaMapJ=%s", json_object_get_string(AlsaMapJ)); + AFB_API_DEBUG(apiHandle, "halMapJ=%s", json_object_get_string(halMapJ)); - if(wrap_json_unpack(AlsaMapJ, "{s:s s?:s s:o s?:s !}", + if(wrap_json_unpack(halMapJ, "{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(AlsaMapJ)); + 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; } - alsaMap->uid = strdup(uid); - if(! alsaMap->uid) { + halMapData->uid = strdup(uid); + if(! halMapData->uid) { AFB_API_ERROR(apiHandle, "Didn't succeed to store (allocate) control 'uid' string"); return -2; } if(info) { - alsaMap->info = strdup(info); - if(! alsaMap->info) { + halMapData->info = strdup(info); + if(! halMapData->info) { AFB_API_ERROR(apiHandle, "Didn't succeed to store (allocate) control 'info' string"); return -3; } @@ -235,38 +239,38 @@ int InternalHalProcessOneHalMapObject(afb_api_t apiHandle, struct InternalHalAls if(wrap_json_unpack(alsaJ, "{s?:s s?:i s?:i s?:o !}", "name", &name, - "numid", &alsaMap->ctl.numid, - "value", &alsaMap->ctl.value, + "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; } if(name) { - alsaMap->ctl.name = strdup(name); - if(! alsaMap->ctl.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; } } if(createAlsaCtlJ) { - alsaMap->ctl.alsaCtlCreation = &alsaMap->ctl.alsaCtlProperties; + halMapData->ctl.alsaCtlCreation = &halMapData->ctl.alsaCtlProperties; if(wrap_json_unpack(createAlsaCtlJ, "{s:s s:i s:i s:i s:i !}", "type", &typename, - "count", &alsaMap->ctl.alsaCtlCreation->count, - "minval", &alsaMap->ctl.alsaCtlCreation->minval, - "maxval", &alsaMap->ctl.alsaCtlCreation->maxval, - "step", &alsaMap->ctl.alsaCtlCreation->step)) { + "count", &halMapData->ctl.alsaCtlCreation->count, + "minval", &halMapData->ctl.alsaCtlCreation->minval, + "maxval", &halMapData->ctl.alsaCtlCreation->maxval, + "step", &halMapData->ctl.alsaCtlCreation->step)) { AFB_API_ERROR(apiHandle, "Parsing error, alsa creation json should only contains [type]|[count]|[minval]|[maxval]|[step] in : '%s'", json_object_get_string(alsaJ)); return -6; } if(typename) { - alsaMap->ctl.alsaCtlCreation->type = InternalHalMapsAlsaTypeToEnum(typename); - if(alsaMap->ctl.alsaCtlCreation->type == SND_CTL_ELEM_TYPE_NONE) { + halMapData->ctl.alsaCtlCreation->type = InternalHalMapsAlsaTypeToEnum(typename); + if(halMapData->ctl.alsaCtlCreation->type == SND_CTL_ELEM_TYPE_NONE) { AFB_API_ERROR(apiHandle, "Couldn't get alsa type from string %s in : '%s'", typename, @@ -275,18 +279,18 @@ int InternalHalProcessOneHalMapObject(afb_api_t apiHandle, struct InternalHalAls } } - if(! alsaMap->ctl.name) - alsaMap->ctl.name = (char *) alsaMap->uid; + if(! halMapData->ctl.name) + halMapData->ctl.name = (char *) halMapData->uid; } - else if(alsaMap->ctl.name && alsaMap->ctl.numid > 0) { + else if(halMapData->ctl.name && halMapData->ctl.numid > 0) { AFB_API_ERROR(apiHandle, "Can't have both a control name (%s) and a control uid (%i) in alsa object : '%s'", - alsaMap->ctl.name, - alsaMap->ctl.numid, + halMapData->ctl.name, + halMapData->ctl.numid, json_object_get_string(alsaJ)); return -8; } - else if(! alsaMap->ctl.name && alsaMap->ctl.numid <= 0) { + 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)); @@ -294,62 +298,57 @@ int InternalHalProcessOneHalMapObject(afb_api_t apiHandle, struct InternalHalAls } if(action) - alsaMap->actionJ = json_object_get(AlsaMapJ); + halMapData->actionJ = json_object_get(halMapJ); return 0; } -int InternalHalProcessAllHalMap(afb_api_t apiHandle, json_object *AlsaMapJ, struct InternalHalAlsaMapT *currentInternalHalAlsaMapT) +int InternalHalProcessAllHalMap(afb_api_t apiHandle, json_object *halMapJ, struct cds_list_head *halMapListHead) { - int idx, err = 0; + int idx, count, err = 0, halMapJsonIsAnArray = 0; - struct InternalHalAlsaMap *ctlMaps; + struct InternalHalAlsaMap *currentHalMapData; - json_object *currentAlsaMapJ; + json_object *currentHalMapJ; json_type alsaMapType; - alsaMapType = json_object_get_type(AlsaMapJ); + alsaMapType = json_object_get_type(halMapJ); switch(alsaMapType) { case json_type_array: - currentInternalHalAlsaMapT->ctlsCount = (unsigned int) json_object_array_length(AlsaMapJ); + count = (int) json_object_array_length(halMapJ); + halMapJsonIsAnArray = 1; break; case json_type_object: - currentInternalHalAlsaMapT->ctlsCount = 1; + count = 1; break; default: - currentInternalHalAlsaMapT->ctlsCount = 0; - currentInternalHalAlsaMapT->ctls = NULL; - AFB_API_ERROR(apiHandle, "Content of 'halmap' section is not valid ('%s')", json_object_get_string(AlsaMapJ)); + AFB_API_ERROR(apiHandle, "Content of 'halmap' section is not valid ('%s')", json_object_get_string(halMapJ)); return -1; } - ctlMaps = calloc(currentInternalHalAlsaMapT->ctlsCount, sizeof(struct InternalHalAlsaMap)); - if(! ctlMaps) { - AFB_API_ERROR(apiHandle, "Didn't succeed to allocate halmap data table"); - return -2; - } + for(idx = 0; idx < count; idx++) { + currentHalMapJ = halMapJsonIsAnArray ? json_object_array_get_idx(halMapJ, idx) : halMapJ; + + currentHalMapData = HalUtlAddHalMapDataToHalMapDataList(halMapListHead); - for(idx = 0; idx < currentInternalHalAlsaMapT->ctlsCount; idx++) { - currentAlsaMapJ = (alsaMapType == json_type_array) ? json_object_array_get_idx(AlsaMapJ, idx) : AlsaMapJ; - err = InternalHalProcessOneHalMapObject(apiHandle, &ctlMaps[idx], currentAlsaMapJ); + err = InternalHalProcessOneHalMapObject(apiHandle, currentHalMapData, currentHalMapJ); if(err) { AFB_API_ERROR(apiHandle, - "Didn't succeed to proccess halmap object %i ('%s')", + "Error %i was returned when tried to proccess halmap object %i ('%s')", + err, idx, - json_object_get_string(currentAlsaMapJ)); - HalUtlFreeAlsaCtlsMap(currentInternalHalAlsaMapT); - return -3; + json_object_get_string(currentHalMapJ)); + HalUtlRemoveAllHalMapData(halMapListHead); + return -2; } } - currentInternalHalAlsaMapT->ctls = ctlMaps; - - return err; + return 0; } -int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct InternalHalAlsaMap *alsaMap) +int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct InternalHalAlsaMap *halMapData) { int err; @@ -357,26 +356,26 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I CtlActionT *toLoadAction; - alsaMap->alsaControlEvent = afb_api_make_event(apiHandle, alsaMap->uid); - if(! alsaMap->alsaControlEvent) { + 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(alsaMap->actionJ)); + json_object_get_string(halMapData->actionJ)); return -1; } - if(alsaMap->ctl.alsaCtlCreation) { - if(InternalHalCreateAlsaCtl(apiHandle, cardId, &alsaMap->ctl)) { + if(halMapData->ctl.alsaCtlCreation) { + if(InternalHalCreateAlsaCtl(apiHandle, cardId, &halMapData->ctl)) { AFB_API_ERROR(apiHandle, "An error happened when trying to create a new alsa control"); return -2; } } - else if(InternalHalUpdateAlsaCtlProperties(apiHandle, cardId, &alsaMap->ctl)) { + else if(InternalHalUpdateAlsaCtlProperties(apiHandle, cardId, &halMapData->ctl)) { AFB_API_ERROR(apiHandle, "An error happened when trying to get existing alsa control info"); return -3; } - if(alsaMap->actionJ) { + if(halMapData->actionJ) { toLoadAction = calloc(1, sizeof(CtlActionT)); if(! toLoadAction) { AFB_API_ERROR(apiHandle, @@ -385,15 +384,15 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I return -4; } - if(ActionLoadOne(apiHandle, toLoadAction, alsaMap->actionJ, 0)) { + if(ActionLoadOne(apiHandle, toLoadAction, halMapData->actionJ, 0)) { AFB_API_ERROR(apiHandle, "Didn't succeed to load action using alsa object : '%s'", - json_object_get_string(alsaMap->actionJ)); + json_object_get_string(halMapData->actionJ)); free(toLoadAction); return -5; } - alsaMap->action = toLoadAction; + halMapData->action = toLoadAction; } if(InternalHalSubscribeToAlsaCardEvent(apiHandle, cardId)) { @@ -401,9 +400,9 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I return -6; } - if(alsaMap->ctl.value) { + if(halMapData->ctl.value) { // TBD JAI : handle alsa controls type - valueJ = json_object_new_int(alsaMap->ctl.value); + valueJ = json_object_new_int(halMapData->ctl.value); if(! valueJ) { AFB_API_ERROR(apiHandle, "Didn't succeed to allocate ALSA control value json string"); return -7; @@ -411,14 +410,14 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I err = 0; - if(InternalHalConvertJsonValues(apiHandle, &alsaMap->ctl.alsaCtlProperties, valueJ, &convertedValueJ, CONVERSION_NORMALIZED_TO_ALSACORE)) { + if(InternalHalConvertJsonValues(apiHandle, &halMapData->ctl.alsaCtlProperties, valueJ, &convertedValueJ, CONVERSION_NORMALIZED_TO_ALSACORE)) { AFB_API_ERROR(apiHandle, "Error when trying to convert initiate value json '%s'", json_object_get_string(valueJ)); err = -8; } - else if(InternalHalSetAlsaCtlValue(apiHandle, cardId, alsaMap->ctl.numid, convertedValueJ)) { + else if(InternalHalSetAlsaCtlValue(apiHandle, cardId, halMapData->ctl.numid, convertedValueJ)) { AFB_API_ERROR(apiHandle, "Error while trying to set initial value on alsa control %i, device '%s', value '%s'", - alsaMap->ctl.numid, + halMapData->ctl.numid, cardId, json_object_get_string(valueJ)); err = -9; @@ -433,36 +432,43 @@ int InternalHalHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct I return err; } - if(afb_api_add_verb(apiHandle, alsaMap->uid, alsaMap->info, InternalHalActionOnAlsaCtl, (void *) alsaMap, NULL, 0, 0)) { + if(afb_api_add_verb(apiHandle, halMapData->uid, halMapData->info, 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(alsaMap->actionJ)); + json_object_get_string(halMapData->actionJ)); return -10; } return 0; } -int InternalHalHandleAllHalMap(afb_api_t apiHandle, int sndCardId, struct InternalHalAlsaMapT *currentInternalHalAlsaMapT) +int InternalHalHandleAllHalMap(afb_api_t apiHandle, int sndCardId, struct cds_list_head *halMapListHead) { - int idx, err = 0; + int err = 0; char cardIdString[6]; + struct InternalHalAlsaMap *currentHalMapData; + snprintf(cardIdString, 6, "hw:%i", sndCardId); - for(idx = 0; idx < currentInternalHalAlsaMapT->ctlsCount; idx++) { - err = InternalHalHandleOneHalMapObject(apiHandle, cardIdString, ¤tInternalHalAlsaMapT->ctls[idx]); + if(cds_list_empty(halMapListHead)) { + AFB_API_ERROR(apiHandle, "HalMap list is empty, nothing to handle"); + return 0; + } + + cds_list_for_each_entry(currentHalMapData, halMapListHead, node) { + err = InternalHalHandleOneHalMapObject(apiHandle, cardIdString, currentHalMapData); if(err) { AFB_API_ERROR(apiHandle, - "Didn't succeed to handle halmap object %i ('%s')", - idx, - json_object_get_string(currentInternalHalAlsaMapT->ctls[idx].actionJ)); - return -3; + "Error %i was returned when tried to handle halmap object :' %s'", + err, + json_object_get_string(currentHalMapData->actionJ)); + return -1; } } - return err; + return 0; } int InternalHalHalMapConfig(afb_api_t apiHandle, CtlSectionT *section, json_object *AlsaMapJ) @@ -479,15 +485,9 @@ int InternalHalHalMapConfig(afb_api_t apiHandle, CtlSectionT *section, json_obje return -2; if(AlsaMapJ) { - currentHalData->internalHalData->alsaMapT = calloc(1, sizeof(struct InternalHalAlsaMapT)); - if(! currentHalData->internalHalData->alsaMapT) { - AFB_API_ERROR(apiHandle, "Didn't succeed to allocate data structure used to store halmap data table"); - return -3; - } - - if(InternalHalProcessAllHalMap(apiHandle, AlsaMapJ, currentHalData->internalHalData->alsaMapT)) { + if(InternalHalProcessAllHalMap(apiHandle, AlsaMapJ, ¤tHalData->internalHalData->halMapListHead)) { AFB_API_ERROR(apiHandle, "Failed to process 'halmap' section"); - HalUtlFreeAlsaCtlsMap(currentHalData->internalHalData->alsaMapT); + HalUtlRemoveAllHalMapData(¤tHalData->internalHalData->halMapListHead); return -4; } } @@ -499,15 +499,11 @@ int InternalHalHalMapConfig(afb_api_t apiHandle, CtlSectionT *section, json_obje AFB_API_ERROR(apiHandle, "Hal alsa card id is not valid, 'halmap' section data can't be handle"); return -5; } - else if(! currentHalData->internalHalData->alsaMapT) { - AFB_API_WARNING(apiHandle, "'halmap' section data is empty"); - return 2; - } - else if(! (currentHalData->internalHalData->alsaMapT->ctlsCount > 0)) { + else if(cds_list_empty(¤tHalData->internalHalData->halMapListHead)) { AFB_API_WARNING(apiHandle, "No alsa controls defined in 'halmap' section"); - return 3; + return 2; } - else if(InternalHalHandleAllHalMap(apiHandle, currentHalData->sndCardId, currentHalData->internalHalData->alsaMapT)) { + else if(InternalHalHandleAllHalMap(apiHandle, currentHalData->sndCardId, ¤tHalData->internalHalData->halMapListHead)) { AFB_API_ERROR(apiHandle, "Failed to handle 'halmap' section"); return -6; } @@ -1153,8 +1149,8 @@ void InternalHalInfo(afb_req_t request) return; } - controlsArray = HalUtGetJsonArrayForAllControls(apiHandle, - currentHalData->internalHalData->alsaMapT); + controlsArray = HalUtGetJsonArrayForAllHalMapControls(apiHandle, + ¤tHalData->internalHalData->halMapListHead); if(! controlsArray) { afb_req_fail(request, "controls_data", "Didn't succeed to generate controls data array"); return; @@ -1179,7 +1175,7 @@ void InternalHalInfo(afb_req_t request) void InternalHalSubscribeUnsubscribe(afb_req_t request, enum SubscribeUnsubscribeType subscribeUnsubscribeType) { - int arrayIdx, searchIdx, count, subscriptionFound, subscriptionDoneNb = 0; + int arrayIdx, count, subscriptionFound, subscriptionDoneNb = 0; char *currentSubscriptionString; @@ -1188,7 +1184,7 @@ void InternalHalSubscribeUnsubscribe(afb_req_t request, enum SubscribeUnsubscrib struct HalData *currentHalData; struct InternalHalMixerData *currentStreamData; - struct InternalHalAlsaMapT *InternalHalAlsaMapT; + struct InternalHalAlsaMap *currentHalMapData; json_object *requestJson, *requestedSubscriptionsJ, @@ -1219,8 +1215,6 @@ void InternalHalSubscribeUnsubscribe(afb_req_t request, enum SubscribeUnsubscrib return; } - InternalHalAlsaMapT = currentHalData->internalHalData->alsaMapT; - requestJson = afb_req_json(request); if(! requestJson) { afb_req_fail(request, "request_json", "Can't get request json"); @@ -1310,26 +1304,25 @@ void InternalHalSubscribeUnsubscribe(afb_req_t request, enum SubscribeUnsubscrib } } - searchIdx = 0; - while((searchIdx < (InternalHalAlsaMapT ? InternalHalAlsaMapT->ctlsCount : 0)) && - ! subscriptionFound) { - if(! strcasecmp(currentSubscriptionString, InternalHalAlsaMapT->ctls[searchIdx].uid)) { - if(InternalHalAlsaMapT->ctls[searchIdx].alsaControlEvent && + cds_list_for_each_entry(currentHalMapData, ¤tHalData->internalHalData->halMapListHead, node) { + if(! subscriptionFound && + ! strcasecmp(currentSubscriptionString, currentHalMapData->uid)) { + if(currentHalMapData->alsaControlEvent && subscribeUnsubscribeType == SUBSCRIPTION && - afb_req_subscribe(request, InternalHalAlsaMapT->ctls[searchIdx].alsaControlEvent)) { + afb_req_subscribe(request, currentHalMapData->alsaControlEvent)) { afb_req_fail_f(request, "request_control_event", "Error while trying to subscribe to %s halmap controls events", - InternalHalAlsaMapT->ctls[searchIdx].uid); + currentHalMapData->uid); return; } - else if(InternalHalAlsaMapT->ctls[searchIdx].alsaControlEvent && + else if(currentHalMapData->alsaControlEvent && subscribeUnsubscribeType == UNSUBSCRIPTION && - afb_req_unsubscribe(request, InternalHalAlsaMapT->ctls[searchIdx].alsaControlEvent)) { + afb_req_unsubscribe(request, currentHalMapData->alsaControlEvent)) { afb_req_fail_f(request, "request_stream_event", "Error while trying to unsubscribe to %s halmap controls events", - InternalHalAlsaMapT->ctls[searchIdx].uid); + currentHalMapData->uid); return; } @@ -1337,8 +1330,6 @@ void InternalHalSubscribeUnsubscribe(afb_req_t request, enum SubscribeUnsubscrib subscriptionDoneNb++; break; } - - searchIdx++; } } diff --git a/src/4a-internals-hal/4a-internals-hal-cb.h b/src/4a-internals-hal/4a-internals-hal-cb.h index ac09ef1..671abbb 100644 --- a/src/4a-internals-hal/4a-internals-hal-cb.h +++ b/src/4a-internals-hal/4a-internals-hal-cb.h @@ -43,7 +43,7 @@ void InternalHalDispatchApiEvent(afb_api_t apiHandle, const char *evtLabel, json int InternalHalHalMixerConfig(afb_api_t apiHandle, CtlSectionT *section, json_object *MixerJ); // Internals HAL - 'halmap' section parsing/handling functions -int InternalHalHalMapConfig(afb_api_t apiHandle, CtlSectionT *section, json_object *AlsaMapJ); +int InternalHalHalMapConfig(afb_api_t apiHandle, CtlSectionT *section, json_object *halMapJ); // Internals HAL - 'haldependencies' section parsing/handling functions int InternalHalHandleHalDependencies(afb_api_t apiHandle, |