/* * Copyright (C) 2018 "IoT.bzh" * Author Jonathan Aillet * * 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 #include #include #include #include "4a-hal-utilities-data.h" #include "4a-hal-utilities-alsa-data.h" /******************************************************************************* * Internal Hal - Streams data handling functions * ******************************************************************************/ struct InternalHalMixerData *HalUtlAddMixerDataToMixerDataList(struct InternalHalMixerData **mixerDataList) { struct InternalHalMixerData *currentMixerData; if(! mixerDataList) return NULL; currentMixerData = *mixerDataList; if(! currentMixerData) { currentMixerData = (struct InternalHalMixerData *) calloc(1, sizeof(struct InternalHalMixerData)); if(! currentMixerData) return NULL; *mixerDataList = currentMixerData; } else { while(currentMixerData->next) currentMixerData = currentMixerData->next; currentMixerData->next = calloc(1, sizeof(struct InternalHalMixerData)); if(! currentMixerData->next) return NULL; currentMixerData = currentMixerData->next; } return currentMixerData; } int8_t HalUtlRemoveSelectedMixerData(struct InternalHalMixerData **mixerDataList, struct InternalHalMixerData *mixerDataToRemove) { struct InternalHalMixerData *currentMixerData, *matchingMixerData; if(! mixerDataList || ! *mixerDataList || ! mixerDataToRemove) return -1; currentMixerData = *mixerDataList; if(currentMixerData == mixerDataToRemove) { *mixerDataList = currentMixerData->next; matchingMixerData = currentMixerData; } else { while(currentMixerData && currentMixerData->next != mixerDataToRemove) currentMixerData = currentMixerData->next; if(currentMixerData) { matchingMixerData = currentMixerData->next; currentMixerData->next = currentMixerData->next->next; } else { return -2; } } free(matchingMixerData->verb); free(matchingMixerData->verbToCall); free(matchingMixerData->streamCardId); free(matchingMixerData); return 0; } int64_t HalUtlRemoveAllMixerData(struct InternalHalMixerData **mixerDataList) { int8_t ret; int64_t mixerDataRemoved = 0; if(! mixerDataList) return -1; while(*mixerDataList) { ret = HalUtlRemoveSelectedMixerData(mixerDataList, *mixerDataList); if(ret) return (int64_t) ret; mixerDataRemoved++; } return mixerDataRemoved; } int64_t HalUtlGetNumberOfMixerDataInList(struct InternalHalMixerData **mixerDataList) { int64_t numberOfMixerData = 0; struct InternalHalMixerData *currentMixerData; if(! mixerDataList) return -1; currentMixerData = *mixerDataList; while(currentMixerData) { currentMixerData = currentMixerData->next; numberOfMixerData++; } return numberOfMixerData; } struct InternalHalMixerData *HalUtlSearchMixerDataByProperties(struct InternalHalMixerData **mixerDataList, char *verb, char *verbToCall, char *streamCardId) { struct InternalHalMixerData *currentMixerData; if(! mixerDataList || ! verb) return NULL; currentMixerData = *mixerDataList; while(currentMixerData) { if((! strcmp(verb, currentMixerData->verb)) && (! strcmp(verbToCall, currentMixerData->verbToCall)) && (! strcmp(streamCardId, currentMixerData->streamCardId))) return currentMixerData; currentMixerData = currentMixerData->next; } return NULL; } /******************************************************************************* * Hal data handling functions * ******************************************************************************/ struct HalData *HalUtlAddHalToHalList(struct HalData **halDataList) { struct HalData *currentHalData; if(! halDataList) return NULL; currentHalData = *halDataList; if(! currentHalData) { currentHalData = (struct HalData *) calloc(1, sizeof(struct HalData)); if(! currentHalData) return NULL; *halDataList = currentHalData; } else { while(currentHalData->next) currentHalData = currentHalData->next; currentHalData->next = calloc(1, sizeof(struct HalData)); if(! currentHalData->next) return NULL; currentHalData = currentHalData->next; } return currentHalData; } int8_t HalUtlRemoveSelectedHalFromList(struct HalData **halDataList, struct HalData *halToRemove) { struct HalData *currentHalData, *matchingHal; if(! halDataList || ! *halDataList || ! halToRemove) return -1; currentHalData = *halDataList; if(currentHalData == halToRemove) { *halDataList = currentHalData->next; matchingHal = currentHalData; } else { while(currentHalData && currentHalData->next != halToRemove) currentHalData = currentHalData->next; if(currentHalData) { matchingHal = currentHalData->next; currentHalData->next = currentHalData->next->next; } else { return -2; } } free(matchingHal->apiName); free(matchingHal->sndCardPath); free(matchingHal->info); free(matchingHal->author); free(matchingHal->version); free(matchingHal->date); if(matchingHal->internal) { HalUtlRemoveAllMixerData(&matchingHal->internalHalData->streamsData); HalUtlRemoveAllMixerData(&matchingHal->internalHalData->playbacksData); HalUtlRemoveAllMixerData(&matchingHal->internalHalData->capturesData); HalUtlFreeAlsaCtlsMap(matchingHal->internalHalData->alsaMapT); free(matchingHal->internalHalData); } free(matchingHal); return 0; } int64_t HalUtlRemoveAllHalFromList(struct HalData **halDataList) { int8_t ret; int64_t halRemoved = 0; if(! halDataList) return -1; while(*halDataList) { ret = HalUtlRemoveSelectedHalFromList(halDataList, *halDataList); if(ret) return (int64_t) ret; halRemoved++; } return halRemoved; } int64_t HalUtlGetNumberOfHalInList(struct HalData **halDataList) { int64_t numberOfHal = 0; struct HalData *currentHalData; if(! halDataList) return -1; currentHalData = *halDataList; while(currentHalData) { currentHalData = currentHalData->next; numberOfHal++; } return numberOfHal; } struct HalData *HalUtlSearchHalDataByApiName(struct HalData **halDataList, char *apiName) { struct HalData *currentHalData; if(! halDataList || ! *halDataList || ! apiName) return NULL; currentHalData = *halDataList; while(currentHalData) { if(! strcmp(apiName, currentHalData->apiName)) return currentHalData; currentHalData = currentHalData->next; } return NULL; } struct HalData *HalUtlSearchReadyHalDataByCardId(struct HalData **halDataList, int cardId) { struct HalData *currentHalData; if(! halDataList || ! *halDataList) return NULL; currentHalData = *halDataList; while(currentHalData) { if(currentHalData->status == HAL_STATUS_READY && currentHalData->sndCardId == cardId) return currentHalData; currentHalData = currentHalData->next; } return NULL; } /******************************************************************************* * Hal Manager data handling functions * ******************************************************************************/ uint8_t HalUtlInitializeHalMgrData(afb_api_t apiHandle, struct HalMgrData *halMgrData, char *apiName, char *info) { if(! apiHandle || ! halMgrData || ! apiName || ! info) return -1; // Allocate and fill apiName and info strings halMgrData->apiName = strdup(apiName); if(! halMgrData->apiName) return -2; halMgrData->info = strdup(info); if(! halMgrData->info) return -3; halMgrData->apiHandle = apiHandle; return 0; } void HalUtlRemoveHalMgrData(struct HalMgrData *halMgrData) { if(! halMgrData) return; if(halMgrData->halDataList) HalUtlRemoveAllHalFromList(&halMgrData->halDataList); free(halMgrData->apiName); free(halMgrData->info); free(halMgrData); }