/* * 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 - Probed devices structure handling functions * ******************************************************************************/ enum ProbedDeviceClasses HalUtlGetProbedDeviceClassFromString(char *probedDeviceString) { if(! probedDeviceString) return INVALID_PROBED_DEVICE; if(! strcasecmp("static", probedDeviceString)) return STATIC_PROBED_DEVICE; if(! strcasecmp("dynamic", probedDeviceString)) return DYNAMIC_PROBED_DEVICE; if(! strcasecmp("mandatory", probedDeviceString)) return MANDATORY_PROBED_DEVICE; return INVALID_PROBED_DEVICE; } char *HalUtlGetProbedDeviceClassString(enum ProbedDeviceClasses deviceClass) { switch(deviceClass) { case STATIC_PROBED_DEVICE: return "static"; case DYNAMIC_PROBED_DEVICE: return "dynamic"; case MANDATORY_PROBED_DEVICE: return "mandatory"; case INVALID_PROBED_DEVICE: return "invalid"; default: return "unknown"; } return NULL; } struct InternalHalProbedDevice *HalUtlAddProbedDeviceToProbedDeviceList(struct InternalHalProbedDevice **probedDevicesList) { struct InternalHalProbedDevice *currentProbedDevice; if(! probedDevicesList) return NULL; currentProbedDevice = *probedDevicesList; if(! currentProbedDevice) { currentProbedDevice = (struct InternalHalProbedDevice *) calloc(1, sizeof(struct InternalHalProbedDevice)); if(! currentProbedDevice) return NULL; *probedDevicesList = currentProbedDevice; } else { while(currentProbedDevice->next) currentProbedDevice = currentProbedDevice->next; currentProbedDevice->next = calloc(1, sizeof(struct InternalHalProbedDevice)); if(! currentProbedDevice->next) return NULL; currentProbedDevice = currentProbedDevice->next; } return currentProbedDevice; } int HalUtlRemoveSelectedProbedDeviceFromList(struct InternalHalProbedDevice **probedDevicesList, struct InternalHalProbedDevice *probedDeviceToRemove) { struct InternalHalProbedDevice *currentProbedDevice, *matchingProbedDevice; if(! probedDevicesList || ! *probedDevicesList || ! probedDeviceToRemove) return -1; currentProbedDevice = *probedDevicesList; if(currentProbedDevice == probedDeviceToRemove) { *probedDevicesList = currentProbedDevice->next; matchingProbedDevice = currentProbedDevice; } else { while(currentProbedDevice && currentProbedDevice->next != probedDeviceToRemove) currentProbedDevice = currentProbedDevice->next; if(currentProbedDevice) { matchingProbedDevice = currentProbedDevice->next; currentProbedDevice->next = currentProbedDevice->next->next; } else { return -2; } } free(matchingProbedDevice->uid); if(matchingProbedDevice->deviceData) { free(matchingProbedDevice->deviceData->extendedCardNb); free(matchingProbedDevice->deviceData->cardId); free(matchingProbedDevice->deviceData->cardShortName); free(matchingProbedDevice->deviceData->cardLongName); free(matchingProbedDevice->deviceData->cardDriver); free(matchingProbedDevice->deviceData->cardMixerName); free(matchingProbedDevice->deviceData->cardComponents); free(matchingProbedDevice->deviceData->playbackDeviceId); free(matchingProbedDevice->deviceData->playbackDeviceName); free(matchingProbedDevice->deviceData); } if(matchingProbedDevice->requestedDeviceJ) json_object_put(matchingProbedDevice->requestedDeviceJ); free(matchingProbedDevice); return 0; } int HalUtlRemoveAllProbedDevicesFromList(struct InternalHalProbedDevice **probedDevicesList) { int probedDevicesRemoved = 0; if(! probedDevicesList) return -1; if(! *probedDevicesList) return 0; while(*probedDevicesList) { if(HalUtlRemoveSelectedProbedDeviceFromList(probedDevicesList, *probedDevicesList)) return -2; probedDevicesRemoved++; } return probedDevicesRemoved; } int HalUtlGetNumberOfProbedDevicesInList(struct InternalHalProbedDevice **probedDevicesList) { int numberOfProbedDevices = 0; struct InternalHalProbedDevice *currentProbedDevice; if(! probedDevicesList) return -1; currentProbedDevice = *probedDevicesList; while(currentProbedDevice) { currentProbedDevice = currentProbedDevice->next; numberOfProbedDevices++; } return numberOfProbedDevices; } struct InternalHalProbedDevice *HalUtlSearchProbedDeviceDataById(struct InternalHalProbedDevice **probedDevicesList, char *uid) { struct InternalHalProbedDevice *currentProbedDevice; if(! probedDevicesList || ! *probedDevicesList || ! uid) return NULL; currentProbedDevice = *probedDevicesList; while(currentProbedDevice) { if(! strcmp(uid, currentProbedDevice->uid)) return currentProbedDevice; currentProbedDevice = currentProbedDevice->next; } return NULL; } struct InternalHalDeviceData *HalUtlAllocateAndFillProbedDeviceDataUsingInfoGetResponse(json_object *responseJ) { struct InternalHalDeviceData *currentProbedDeviceData; if(! responseJ) return NULL; currentProbedDeviceData = calloc(1, sizeof(struct InternalHalDeviceData)); if(! currentProbedDeviceData) return NULL; currentProbedDeviceData->cardNb = HAL_UNKNOWN_DEVICE; currentProbedDeviceData->playbackDeviceNb = HAL_UNKNOWN_DEVICE; if(wrap_json_unpack(responseJ, "{s:i, s:s, s:s, s:s, s:s, s:s, s:s, s?:i, s?:s, s?:s !}", "cardNb", ¤tProbedDeviceData->cardNb, "cardId", ¤tProbedDeviceData->cardId, "cardShortName", ¤tProbedDeviceData->cardShortName, "cardLongName", ¤tProbedDeviceData->cardLongName, "cardDriver", ¤tProbedDeviceData->cardDriver, "cardMixerName", ¤tProbedDeviceData->cardMixerName, "cardComponents", ¤tProbedDeviceData->cardComponents, "playbackDeviceNb", ¤tProbedDeviceData->playbackDeviceNb, "playbackDeviceId", ¤tProbedDeviceData->playbackDeviceId, "playbackDeviceName", ¤tProbedDeviceData->playbackDeviceName) || currentProbedDeviceData->cardNb == HAL_UNKNOWN_DEVICE || (currentProbedDeviceData->playbackDeviceNb == HAL_UNKNOWN_DEVICE && asprintf(¤tProbedDeviceData->extendedCardNb, "hw:%i", currentProbedDeviceData->cardNb) < 0) || (currentProbedDeviceData->playbackDeviceNb != HAL_UNKNOWN_DEVICE && asprintf(¤tProbedDeviceData->extendedCardNb, "hw:%i,%i", currentProbedDeviceData->cardNb, currentProbedDeviceData->playbackDeviceNb) < 0)) { free(currentProbedDeviceData); return NULL; } return currentProbedDeviceData; } json_object *HalUtlGetCompactJsonForSpecificDependencies(afb_api_t apiHandle, struct InternalHalProbedDevice *requestedProbedDevice) { int wrapRet; char *cardNb; json_object *requestedProbedDeviceJ; if(! apiHandle) { AFB_API_ERROR(apiHandle, "Api handle is not valid"); return NULL; } if(! requestedProbedDevice) { AFB_API_ERROR(apiHandle, "Requested dependency is not valid"); return NULL; } if(! requestedProbedDevice->deviceData || requestedProbedDevice->deviceData->cardNb == HAL_UNKNOWN_DEVICE) cardNb = NULL; else cardNb = requestedProbedDevice->deviceData->extendedCardNb; wrapRet = wrap_json_pack(&requestedProbedDeviceJ, "{s:s s:s}", "uid", requestedProbedDevice->uid, "cardNb", cardNb ? cardNb : "none"); if(wrapRet) { AFB_API_ERROR(apiHandle, "Didn't succeed to allocate (uid: '%s') dependency compact json object", requestedProbedDevice->uid); return NULL; } return requestedProbedDeviceJ; } json_object *HalUtlGetFullJsonForSpecificDependencies(afb_api_t apiHandle, struct InternalHalProbedDevice *requestedProbedDevice) { int wrapRet; json_object *requestedProbedDeviceJ, *additionalInfoJ; if(! apiHandle) { AFB_API_ERROR(apiHandle, "Api handle is not valid"); return NULL; } if(! requestedProbedDevice) { AFB_API_ERROR(apiHandle, "Requested dependency is not valid"); return NULL; } wrapRet = wrap_json_pack(&requestedProbedDeviceJ, "{s:s s:s s:b}", "uid", requestedProbedDevice->uid, "class", HalUtlGetProbedDeviceClassString(requestedProbedDevice->deviceClass), "available", requestedProbedDevice->deviceData ? 1 : 0); if(wrapRet) { AFB_API_ERROR(apiHandle, "Didn't succeed to allocate first part of requested (uid: '%s') dependency full json object", requestedProbedDevice->uid); return NULL; } if(! requestedProbedDevice->deviceData || requestedProbedDevice->deviceData->cardNb == HAL_UNKNOWN_DEVICE) return requestedProbedDeviceJ; wrapRet = wrap_json_pack(&additionalInfoJ, "{s:i s:s s:s s:s s:s s:s s:s s:s}", "cardNb", requestedProbedDevice->deviceData->cardNb, "cardId", requestedProbedDevice->deviceData->cardId, "cardShortName", requestedProbedDevice->deviceData->cardShortName, "cardLongName", requestedProbedDevice->deviceData->cardLongName, "cardDriver", requestedProbedDevice->deviceData->cardDriver, "cardMixerName", requestedProbedDevice->deviceData->cardMixerName, "cardComponents", requestedProbedDevice->deviceData->cardComponents, "extendedCardNb", requestedProbedDevice->deviceData->extendedCardNb); if(wrapRet) { AFB_API_ERROR(apiHandle, "Didn't succeed to allocate second part of requested (uid: '%s') dependency full json object", requestedProbedDevice->uid); json_object_put(requestedProbedDeviceJ); return NULL; } wrap_json_object_add(requestedProbedDeviceJ, additionalInfoJ); if(requestedProbedDevice->deviceData->playbackDeviceNb == HAL_UNKNOWN_DEVICE) return requestedProbedDeviceJ; wrapRet = wrap_json_pack(&additionalInfoJ, "{s:i s:s s:s}", "playbackDeviceNb", requestedProbedDevice->deviceData->playbackDeviceNb, "playbackDeviceId", requestedProbedDevice->deviceData->playbackDeviceId, "playbackDeviceName", requestedProbedDevice->deviceData->playbackDeviceName); if(wrapRet) { AFB_API_ERROR(apiHandle, "Didn't succeed to allocate third part of requested (uid: '%s') dependency full json object", requestedProbedDevice->uid); json_object_put(requestedProbedDeviceJ); return NULL; } wrap_json_object_add(requestedProbedDeviceJ, additionalInfoJ); return requestedProbedDeviceJ; } json_object *HalUtlGetJsonForSpecificDependencies(afb_api_t apiHandle, struct InternalHalProbedDevice *requestedProbedDevice, enum DependencyInfoJsonFormat jsonFormat) { json_object *requestedProbedDeviceJ; if(! apiHandle) { AFB_API_ERROR(apiHandle, "Api handle is not valid"); return NULL; } if(! requestedProbedDevice) { AFB_API_ERROR(apiHandle, "Requested dependency is not valid"); return NULL; } switch(jsonFormat) { case DEPENDENCY_COMPACT_JSON: requestedProbedDeviceJ = HalUtlGetCompactJsonForSpecificDependencies(apiHandle,requestedProbedDevice); if(! requestedProbedDeviceJ) { AFB_API_ERROR(apiHandle, "An error happened when generating compact json for selected dependency (uid: '%s')", requestedProbedDevice->uid); return NULL; } return requestedProbedDeviceJ; case DEPENDENCY_FULL_JSON: requestedProbedDeviceJ = HalUtlGetFullJsonForSpecificDependencies(apiHandle,requestedProbedDevice); if(! requestedProbedDeviceJ) { AFB_API_ERROR(apiHandle, "An error happened when generating full json for selected dependency (uid: '%s')", requestedProbedDevice->uid); return NULL; } return requestedProbedDeviceJ; default: AFB_API_ERROR(apiHandle, "Unrecognized requested json format"); return NULL; } } json_object *HalUtlGetJsonForSpecificDependenciesUsingUid(afb_api_t apiHandle, struct InternalHalProbedDevice **probedDevicesList, char *uid, enum DependencyInfoJsonFormat jsonFormat) { json_object *requestedProbedDeviceJ; struct InternalHalProbedDevice *requestedProbedDevice; if(! apiHandle) { AFB_API_ERROR(apiHandle, "Api handle is not valid"); return NULL; } if(! probedDevicesList || ! *probedDevicesList) { AFB_API_ERROR(apiHandle, "Probed device list is empty"); return NULL; } if(! uid) { AFB_API_ERROR(apiHandle, "Requested dependency uid is not valid"); return NULL; } requestedProbedDevice = HalUtlSearchProbedDeviceDataById(probedDevicesList, uid); if(! requestedProbedDevice) { AFB_API_ERROR(apiHandle, "Requested dependency uid ('%s) was not found in probed device list", uid); return NULL; } requestedProbedDeviceJ = HalUtlGetJsonForSpecificDependencies(apiHandle, requestedProbedDevice, jsonFormat); if(! requestedProbedDeviceJ) { AFB_API_ERROR(apiHandle, "An error happened when generating json for selected dependency (uid: '%s')", requestedProbedDevice->uid); return NULL; } return requestedProbedDeviceJ; } int HalUtlIsDependencySelected(struct InternalHalProbedDevice *probedDevice, enum DependencyStatus requestedStatus) { if(! probedDevice) { return 0; } switch(requestedStatus) { case UNAVAILABLE_DEPENDENCY: if(! probedDevice->deviceData) return 1; else return 0; case AVAILABLE_DEPENDENCY: if(probedDevice->deviceData) return 1; else return 0; case ALL_DEPENDENCY: return 1; default: return 0; } } json_object *HalUtlGetJsonArrayForSelectedDependencies(afb_api_t apiHandle, struct InternalHalProbedDevice **probedDevicesList, enum DependencyInfoJsonFormat jsonFormat, enum DependencyStatus requestedStatus) { json_object *requestedProbedDeviceJ, *requestedDependenciesInfoJ; struct InternalHalProbedDevice *currentProbedDevice; if(! apiHandle) { AFB_API_ERROR(apiHandle, "Api handle is not valid"); return NULL; } if(! probedDevicesList || ! *probedDevicesList) { AFB_API_ERROR(apiHandle, "Probed device list is empty"); return NULL; } requestedDependenciesInfoJ = json_object_new_array(); if(! requestedDependenciesInfoJ) { AFB_API_ERROR(apiHandle, "Didn't succeed to allocate probed devices (dependencies) json array"); return NULL; } currentProbedDevice = *probedDevicesList; while(currentProbedDevice) { requestedProbedDeviceJ = NULL; if(HalUtlIsDependencySelected(currentProbedDevice, requestedStatus)) { requestedProbedDeviceJ = HalUtlGetJsonForSpecificDependencies(apiHandle, currentProbedDevice, jsonFormat); if(! requestedProbedDeviceJ) { AFB_API_ERROR(apiHandle, "Didn't succeed to get json for probed devices (dependencies) with uid : '%s'", currentProbedDevice->uid); json_object_put(requestedDependenciesInfoJ); return NULL; } } if(requestedProbedDeviceJ) json_object_array_add(requestedDependenciesInfoJ, requestedProbedDeviceJ); currentProbedDevice = currentProbedDevice->next; } return requestedDependenciesInfoJ; } json_object *HalUtlGetJsonArrayForAvailableDependencies(afb_api_t apiHandle, struct InternalHalProbedDevice **probedDevicesList, enum DependencyInfoJsonFormat jsonFormat) { json_object *requestedDependenciesInfoJ; if(! apiHandle) { AFB_API_ERROR(apiHandle, "Api handle is not valid"); return NULL; } if(! probedDevicesList || ! *probedDevicesList) { AFB_API_ERROR(apiHandle, "Probed device list is empty"); return NULL; } requestedDependenciesInfoJ = HalUtlGetJsonArrayForSelectedDependencies(apiHandle, probedDevicesList, jsonFormat, AVAILABLE_DEPENDENCY); if(! requestedDependenciesInfoJ) { AFB_API_ERROR(apiHandle, "Didn't succeed get available devices (dependencies) info"); return NULL; } return requestedDependenciesInfoJ; } json_object *HalUtlGetJsonArrayForAllDependencies(afb_api_t apiHandle, struct InternalHalProbedDevice **probedDevicesList, enum DependencyInfoJsonFormat jsonFormat) { json_object *requestedDependenciesInfoJ; if(! apiHandle) { AFB_API_ERROR(apiHandle, "Api handle is not valid"); return NULL; } if(! probedDevicesList || ! *probedDevicesList) { AFB_API_ERROR(apiHandle, "Probed device list is empty"); return NULL; } requestedDependenciesInfoJ = HalUtlGetJsonArrayForSelectedDependencies(apiHandle, probedDevicesList, jsonFormat, ALL_DEPENDENCY); if(! requestedDependenciesInfoJ) { AFB_API_ERROR(apiHandle, "Didn't succeed get available devices (dependencies) info"); return NULL; } return requestedDependenciesInfoJ; } /******************************************************************************* * 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; } int 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; } int HalUtlRemoveAllMixerData(struct InternalHalMixerData **mixerDataList) { int mixerDataRemoved = 0; if(! mixerDataList) return -1; while(*mixerDataList) { if(HalUtlRemoveSelectedMixerData(mixerDataList, *mixerDataList)) return -2; mixerDataRemoved++; } return mixerDataRemoved; } int HalUtlGetNumberOfMixerDataInList(struct InternalHalMixerData **mixerDataList) { int 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 || ! *mixerDataList || ! verb || ! verbToCall) return NULL; currentMixerData = *mixerDataList; while(currentMixerData) { if(! strcmp(verb, currentMixerData->verb) && ! strcmp(verbToCall, currentMixerData->verbToCall) && ((! streamCardId && ! currentMixerData->streamCardId) || (streamCardId && currentMixerData->streamCardId && ! strcmp(streamCardId, currentMixerData->streamCardId)))) return currentMixerData; currentMixerData = currentMixerData->next; } return NULL; } json_object *HalUtlGetJsonArrayForSpecificMixerData(afb_api_t apiHandle, struct InternalHalMixerData *mixerData) { int wrapRet; json_object *currentMixerDataJ; if(! apiHandle) { AFB_API_ERROR(apiHandle, "Api handle is not valid"); return NULL; } if(! mixerData) { AFB_API_ERROR(apiHandle, "Mixer data to use to generate json object are empty"); return NULL; } wrapRet = wrap_json_pack(¤tMixerDataJ, "{s:s s:s}", "name", mixerData->verb, "cardId", mixerData->streamCardId); if(wrapRet) { AFB_API_ERROR(apiHandle, "Didn't succeed to allocate current mixer json object"); return NULL; } return currentMixerDataJ; } json_object *HalUtlGetJsonArrayForAllMixersData(afb_api_t apiHandle, struct InternalHalMixerData **mixerDataList) { json_object *mixerDataArrayJ, *currentMixerDataJ; struct InternalHalMixerData *currentMixerData; if(! apiHandle) { AFB_API_ERROR(apiHandle, "Api handle is not valid"); return NULL; } mixerDataArrayJ = json_object_new_array(); if(! mixerDataArrayJ) { AFB_API_ERROR(apiHandle, "Didn't succeed to allocate requested mixer data json array"); return NULL; } currentMixerData = *mixerDataList; while(currentMixerData) { currentMixerDataJ = HalUtlGetJsonArrayForSpecificMixerData(apiHandle, currentMixerData); if(! currentMixerDataJ) { AFB_API_ERROR(apiHandle, "Didn't succeed to generate current mixer data json object"); json_object_put(mixerDataArrayJ); return NULL; } json_object_array_add(mixerDataArrayJ, currentMixerDataJ); currentMixerData = currentMixerData->next; } return mixerDataArrayJ; } /******************************************************************************* * 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; } int 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) { free(matchingHal->internalHalData->mixerApiName); free(matchingHal->internalHalData->prefix); HalUtlRemoveAllProbedDevicesFromList(&matchingHal->internalHalData->probedDevicesList); HalUtlRemoveAllMixerData(&matchingHal->internalHalData->streamsData); HalUtlFreeAlsaCtlsMap(matchingHal->internalHalData->alsaMapT); free(matchingHal->internalHalData); } free(matchingHal); return 0; } int HalUtlRemoveAllHalFromList(struct HalData **halDataList) { int halRemoved = 0; if(! halDataList) return -1; while(*halDataList) { if(HalUtlRemoveSelectedHalFromList(halDataList, *halDataList)) return -2; halRemoved++; } return halRemoved; } int HalUtlGetNumberOfHalInList(struct HalData **halDataList) { int 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 * ******************************************************************************/ int 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); }