diff options
Diffstat (limited to 'lib/4a-hal-utilities')
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c | 51 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h | 74 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-data.c | 344 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-data.h | 116 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-hal-streams-handler.c | 355 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-hal-streams-handler.h | 51 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-verbs-loader.c | 50 | ||||
-rw-r--r-- | lib/4a-hal-utilities/4a-hal-utilities-verbs-loader.h | 28 | ||||
-rw-r--r-- | lib/4a-hal-utilities/CMakeLists.txt | 33 |
9 files changed, 1102 insertions, 0 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 new file mode 100644 index 0000000..6409253 --- /dev/null +++ b/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c @@ -0,0 +1,51 @@ +/* + * 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 <afb/afb-binding.h> + +#include "4a-hal-utilities-alsa-data.h" + +/******************************************************************************* + * Free contents of 'InternalHalAlsaMapT' data structure * + ******************************************************************************/ + +uint8_t 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 new file mode 100644 index 0000000..fe70210 --- /dev/null +++ b/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h @@ -0,0 +1,74 @@ +/* +* 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. +*/ + +#ifndef _HAL_UTILITIES_ALSA_DATA_INCLUDE_ +#define _HAL_UTILITIES_ALSA_DATA_INCLUDE_ + +#include <stdio.h> + +#include <json-c/json.h> + +#include <alsa/asoundlib.h> + +#include <afb/afb-binding.h> + +#include <ctl-config.h> + +struct InternalHalAlsaDBScale { + int min; + int max; + int step; + int mute; +}; + +struct InternalHalAlsaCtlProperties { + snd_ctl_elem_type_t type; + int count; + int minval; + int maxval; + int step; + // TBD JAI : use them + const char **enums; + struct InternalHalAlsaDBScale *dbscale; +}; + +struct InternalHalAlsaCtl { + char *name; + int numid; + int value; + struct InternalHalAlsaCtlProperties alsaCtlProperties; + struct InternalHalAlsaCtlProperties *alsaCtlCreation; +}; + +struct InternalHalAlsaMap { + const char *uid; + char *info; + afb_event_t alsaControlEvent; + struct InternalHalAlsaCtl ctl; + json_object *actionJ; + CtlActionT *action; +}; + +struct InternalHalAlsaMapT { + struct InternalHalAlsaMap *ctls; + unsigned int ctlsCount; +}; + +// Free contents of 'CtlHalAlsaMapT' data structure +uint8_t 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 new file mode 100644 index 0000000..314190f --- /dev/null +++ b/lib/4a-hal-utilities/4a-hal-utilities-data.c @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2018 "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 <string.h> + +#include <wrap-json.h> + +#include <afb/afb-binding.h> + +#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); +}
\ No newline at end of file diff --git a/lib/4a-hal-utilities/4a-hal-utilities-data.h b/lib/4a-hal-utilities/4a-hal-utilities-data.h new file mode 100644 index 0000000..f3de1a6 --- /dev/null +++ b/lib/4a-hal-utilities/4a-hal-utilities-data.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2018 "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. + */ + +#ifndef _HAL_UTILITIES_DATA_INCLUDE_ +#define _HAL_UTILITIES_DATA_INCLUDE_ + +#include <stdio.h> + +#include <wrap-json.h> + +#include <afb/afb-binding.h> + +#include <ctl-config.h> + +#include "4a-hal-utilities-alsa-data.h" + +#define HAL_STREAM_UPDATES_EVENT_NAME "stream-updates" + +// Enum for hal status +enum HalStatus { + HAL_STATUS_UNAVAILABLE=0, + HAL_STATUS_AVAILABLE=1, + HAL_STATUS_READY=2 +}; + +// Structure to store stream data +struct InternalHalMixerData { + char *verb; + char *verbToCall; + char *streamCardId; + afb_event_t event; + + struct InternalHalMixerData *next; +}; + +// Structure to store specific internal hal data +struct InternalHalData { + char *mixerApiName; + char *prefix; + json_object *halMixerJ; + + struct InternalHalMixerData *streamsData; + afb_event_t streamUpdates; + + struct InternalHalMixerData *playbacksData; + struct InternalHalMixerData *capturesData; + + struct InternalHalAlsaMapT *alsaMapT; + + afb_api_t apiHandle; + CtlConfigT *ctrlConfig; +}; + +// Structure to store specific hal (internal or external) data +struct HalData { + char *apiName; + enum HalStatus status; + char *sndCardPath; + int sndCardId; + char *info; + unsigned int internal; + + char *author; + char *version; + char *date; + // Can be beefed up if needed + + struct InternalHalData *internalHalData; // Can be NULL if external api + + struct HalData *next; +}; + +// Structure to store hal manager data +struct HalMgrData { + char *apiName; + char *info; + + afb_api_t apiHandle; + + struct HalData *halDataList; +}; + +// Internal Hal - Streams data handling functions +struct InternalHalMixerData *HalUtlAddMixerDataToMixerDataList(struct InternalHalMixerData **mixerDataList); +int8_t HalUtlRemoveSelectedMixerData(struct InternalHalMixerData **mixerDataList, struct InternalHalMixerData *mixerDataToRemove); +int64_t HalUtlRemoveAllMixerData(struct InternalHalMixerData **mixerDataList); +int64_t HalUtlGetNumberOfMixerDataInList(struct InternalHalMixerData **mixerDataList); +struct InternalHalMixerData *HalUtlSearchMixerDataByProperties(struct InternalHalMixerData **mixerDataList, char *verb, char *verbToCall, char *streamCardId); + +// Hal data handling functions +struct HalData *HalUtlAddHalToHalList(struct HalData **halDataList); +int8_t HalUtlRemoveSelectedHalFromList(struct HalData **halDataList, struct HalData *halToRemove); +int64_t HalUtlRemoveAllHalFromList(struct HalData **halDataList); +int64_t HalUtlGetNumberOfHalInList(struct HalData **halDataList); +struct HalData *HalUtlSearchHalDataByApiName(struct HalData **halDataList, char *apiName); +struct HalData *HalUtlSearchReadyHalDataByCardId(struct HalData **halDataList, int cardId); + +// Hal Manager data handling functions +uint8_t HalUtlInitializeHalMgrData(afb_api_t apiHandle, struct HalMgrData *halMgrData, char *apiName, char *info); +void HalUtlRemoveHalMgrData(struct HalMgrData *halMgrData); + +#endif /* _HAL_UTILITIES_DATA_INCLUDE_ */
\ No newline at end of file diff --git a/lib/4a-hal-utilities/4a-hal-utilities-hal-streams-handler.c b/lib/4a-hal-utilities/4a-hal-utilities-hal-streams-handler.c new file mode 100644 index 0000000..ed06b27 --- /dev/null +++ b/lib/4a-hal-utilities/4a-hal-utilities-hal-streams-handler.c @@ -0,0 +1,355 @@ +/* + * 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 <json-c/json.h> + +#include <afb/afb-binding.h> + +#include <ctl-config.h> + +#include "4a-hal-utilities-data.h" +#include "4a-hal-utilities-hal-streams-handler.h" + +/******************************************************************************* + * Actions to be call when a stream verb is called * + ******************************************************************************/ + +void HalUtlActionOnMixer(afb_req_t request, enum ActionOnMixerType actionType) +{ + int idx, count; + + char *apiToCall, *returnedError = NULL, *returnedInfo = NULL; + + afb_api_t apiHandle; + CtlConfigT *ctrlConfig; + + struct HalData *currentHalData; + struct InternalHalMixerData *currentMixerData = NULL; + + json_object *requestJson, *responseJ = NULL, *toReturnJ = NULL; + + if(! (apiHandle = afb_req_get_api(request))) { + afb_req_fail(request, "api_handle", "Can't get current hal controller api handle"); + return; + } + + if(! (ctrlConfig = (CtlConfigT *) afb_api_get_userdata(apiHandle))) { + afb_req_fail(request, "hal_controller_config", "Can't get current hal controller config"); + return; + } + + currentHalData = (struct HalData *) getExternalData(ctrlConfig); + if(! currentHalData) { + afb_req_fail(request, "hal_controller_data", "Can't get current hal controller data"); + return; + } + + if(! (requestJson = afb_req_json(request))) { + afb_req_fail(request, "request_json", "Can't get request json"); + return; + } + + if(json_object_is_type(requestJson, json_type_object) && json_object_get_object(requestJson)->count > 0) + json_object_object_add(requestJson, "verbose", json_object_new_boolean(1)); + + apiToCall = currentHalData->internalHalData->mixerApiName; + if(! apiToCall) { + afb_req_fail(request, "mixer_api", "Can't get mixer api"); + return; + } + + if(currentHalData->status != HAL_STATUS_READY) { + afb_req_fail(request, "hal_not_ready", "Seems that hal is not ready"); + return; + } + + currentMixerData = (struct InternalHalMixerData *) afb_req_get_vcbdata(request); + if(! currentMixerData) { + afb_req_fail(request, "hal_call_data", "Can't get current call data"); + return; + } + + switch(actionType) { + case ACTION_ON_MIXER_STREAM: + count = 1; + break; + + case ACTION_ON_MIXER_PLAYBACK: + case ACTION_ON_MIXER_CAPTURE: + case ACTION_ON_MIXER_ALL_STREAM: + count = (int) HalUtlGetNumberOfMixerDataInList(¤tMixerData); + toReturnJ = json_object_new_object(); + break; + + default: + afb_req_fail(request, "mixer_action_type", "Action type is unknown"); + return; + } + + for(idx = 0; idx < count; idx++) { + if(afb_api_call_sync(apiHandle, + apiToCall, + currentMixerData->verbToCall, + json_object_get(requestJson), + &responseJ, + &returnedError, + &returnedInfo)) { + if(responseJ) + json_object_put(responseJ); + if(toReturnJ) + json_object_put(toReturnJ); + afb_req_fail_f(request, + "mixer_call", + "Something went wrong during call to verb '%s' of api '%s' with error '%s' and info '%s' (call to mixer %i out of %i)", + currentMixerData->verbToCall, + apiToCall, + returnedError ? returnedError : "not returned", + returnedInfo ? returnedInfo : "not returned", + idx, + count); + free(returnedError); + free(returnedInfo); + return; + } + + if(! responseJ) { + if(toReturnJ) + json_object_put(toReturnJ); + afb_req_fail_f(request, + "mixer_call", + "Seems that %s call to api %s succeed but no response was returned (call to mixer %i out of %i)", + currentMixerData->verbToCall, + apiToCall, + idx, + count); + free(returnedError); + free(returnedInfo); + return; + } + + // TBD JAI : When mixer events will be available, use them instead of generating events at calls + if((actionType == ACTION_ON_MIXER_STREAM || + actionType == ACTION_ON_MIXER_ALL_STREAM) && + ((! currentMixerData->event) || + (afb_event_push(currentMixerData->event, json_object_get(responseJ)) < 0))) { + AFB_API_ERROR(apiHandle, "Could not generate an event for stream %s", currentMixerData->verb); + } + + switch(actionType) { + case ACTION_ON_MIXER_STREAM: + toReturnJ = responseJ; + break; + + case ACTION_ON_MIXER_PLAYBACK: + case ACTION_ON_MIXER_CAPTURE: + json_object_object_add(toReturnJ, currentMixerData->verbToCall, responseJ); + currentMixerData = currentMixerData->next; + break; + + case ACTION_ON_MIXER_ALL_STREAM: + json_object_object_add(toReturnJ, currentMixerData->verb, responseJ); + currentMixerData = currentMixerData->next; + break; + + default: + break; + } + } + + switch(actionType) { + case ACTION_ON_MIXER_STREAM: + afb_req_success_f(request, + toReturnJ, + "Action %s correctly transferred to %s without any error raised", + currentMixerData->verbToCall, + apiToCall); + break; + + case ACTION_ON_MIXER_PLAYBACK: + afb_req_success(request, + toReturnJ, + "Actions correctly transferred to all playbacks without any error raised"); + break; + + case ACTION_ON_MIXER_CAPTURE: + afb_req_success(request, + toReturnJ, + "Actions correctly transferred to all captures without any error raised"); + break; + + case ACTION_ON_MIXER_ALL_STREAM: + afb_req_success(request, + toReturnJ, + "Actions correctly transferred to all streams without any error raised"); + break; + + default: + break; + } +} + +void HalUtlActionOnStream(afb_req_t request) +{ + HalUtlActionOnMixer(request, ACTION_ON_MIXER_STREAM); +} + +void HalUtlActionOnPlayback(afb_req_t request) +{ + HalUtlActionOnMixer(request, ACTION_ON_MIXER_PLAYBACK); +} + +void HalUtlActionOnCapture(afb_req_t request) +{ + HalUtlActionOnMixer(request, ACTION_ON_MIXER_CAPTURE); +} + +void HalUtlActionOnAllStream(afb_req_t request) +{ + HalUtlActionOnMixer(request, ACTION_ON_MIXER_ALL_STREAM); +} + +/******************************************************************************* + * Add stream data and verb function * + ******************************************************************************/ + +struct InternalHalMixerData *HalUtlAddStreamDataAndCreateStreamVerb(afb_api_t apiHandle, + char *verb, + char *verbToCall, + char *streamCardId) +{ + json_object *streamAddedEventJ; + + CtlConfigT *ctrlConfig; + + struct HalData *currentHalData; + struct InternalHalMixerData *createdStreamData; + + if(! apiHandle || ! verb || ! verbToCall || ! streamCardId) + return NULL; + + ctrlConfig = (CtlConfigT *) afb_api_get_userdata(apiHandle); + if(! ctrlConfig) + return NULL; + + currentHalData = (struct HalData *) getExternalData(ctrlConfig); + if(! currentHalData || + ! currentHalData->internalHalData) + return NULL; + + createdStreamData = HalUtlAddMixerDataToMixerDataList(¤tHalData->internalHalData->streamsData); + if(! createdStreamData) + return NULL; + + createdStreamData->verb = strdup(verb); + createdStreamData->verbToCall = strdup(verbToCall); + createdStreamData->streamCardId = strdup(streamCardId); + + if((! createdStreamData->verb) || + (! createdStreamData->verbToCall) || + (! createdStreamData->streamCardId)) { + HalUtlRemoveSelectedMixerData(¤tHalData->internalHalData->streamsData, createdStreamData); + return NULL; + } + + if(! (createdStreamData->event = afb_api_make_event(apiHandle, createdStreamData->verb))) { + HalUtlRemoveSelectedMixerData(¤tHalData->internalHalData->streamsData, createdStreamData); + return NULL; + } + + if(afb_api_add_verb(apiHandle, + createdStreamData->verb, + "Stream action transferred to mixer", + HalUtlActionOnStream, + (void *) createdStreamData, + NULL, + 0, + 0)) { + AFB_API_ERROR(apiHandle,"Error while creating verb for stream : '%s'", createdStreamData->verb); + HalUtlRemoveSelectedMixerData(¤tHalData->internalHalData->streamsData, createdStreamData); + return NULL; + } + + wrap_json_pack(&streamAddedEventJ, + "{s:s, s:s, s:s}", + "action", "added", + "name", createdStreamData->verb, + "cardId", createdStreamData->streamCardId); + + afb_event_push(currentHalData->internalHalData->streamUpdates, streamAddedEventJ); + + return createdStreamData; +} + +int8_t HalUtlRemoveStreamDataAndDeleteStreamVerb(afb_api_t apiHandle, + char *verb, + char *verbToCall, + char *streamCardId) +{ + int8_t returnedErr = 0; + + json_object *streamRemovedEventJ; + + CtlConfigT *ctrlConfig; + + struct HalData *currentHalData; + struct InternalHalMixerData *toRemoveStreamData; + + if(! apiHandle || ! verb || ! verbToCall || ! streamCardId) + return -1; + + ctrlConfig = (CtlConfigT *) afb_api_get_userdata(apiHandle); + if(! ctrlConfig) + return -2; + + currentHalData = (struct HalData *) getExternalData(ctrlConfig); + if(! currentHalData || + ! currentHalData->internalHalData) + return -3; + + toRemoveStreamData = HalUtlSearchMixerDataByProperties(¤tHalData->internalHalData->streamsData, + verb, + verbToCall, + streamCardId); + if(! toRemoveStreamData) + return -4; + + wrap_json_pack(&streamRemovedEventJ, + "{s:s, s:s, s:s}", + "action", "removed", + "name", toRemoveStreamData->verb, + "cardId", toRemoveStreamData->streamCardId); + + if(afb_api_del_verb(apiHandle, verb, NULL)) { + AFB_API_ERROR(apiHandle,"Error while deleting verb for stream : '%s'", verb); + json_object_put(streamRemovedEventJ); + return -5; + } + + returnedErr = HalUtlRemoveSelectedMixerData(¤tHalData->internalHalData->streamsData, toRemoveStreamData); + if(returnedErr) { + AFB_API_ERROR(apiHandle,"Error %i while removing data for stream : '%s'", returnedErr, verb); + json_object_put(streamRemovedEventJ); + return -6; + } + + afb_event_push(currentHalData->internalHalData->streamUpdates, streamRemovedEventJ); + + return 0; +}
\ No newline at end of file diff --git a/lib/4a-hal-utilities/4a-hal-utilities-hal-streams-handler.h b/lib/4a-hal-utilities/4a-hal-utilities-hal-streams-handler.h new file mode 100644 index 0000000..028dd1f --- /dev/null +++ b/lib/4a-hal-utilities/4a-hal-utilities-hal-streams-handler.h @@ -0,0 +1,51 @@ +/* +* 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. +*/ + +#ifndef _HAL_UTILITIES_HAL_STREAMS_CREATION_INCLUDE_ +#define _HAL_UTILITIES_HAL_STREAMS_CREATION_INCLUDE_ + +#include <stdio.h> + +#include <afb/afb-binding.h> + +#include <ctl-config.h> + +// Enum for the type of action on mixer +enum ActionOnMixerType { + ACTION_ON_MIXER_STREAM = 1, + ACTION_ON_MIXER_PLAYBACK = 2, + ACTION_ON_MIXER_CAPTURE = 3, + ACTION_ON_MIXER_ALL_STREAM = 4 +}; + +// Actions to be call when a stream verb is called +void HalUtlActionOnStream(afb_req_t request); +void HalUtlActionOnPlayback(afb_req_t request); +void HalUtlActionOnCapture(afb_req_t request); +void HalUtlActionOnAllStream(afb_req_t request); + +// Add/Remove stream data and verb functions +struct InternalHalMixerData *HalUtlAddStreamDataAndCreateStreamVerb(afb_api_t apiHandle, + char *verb, + char *verbToCall, + char *streamCardId); +int8_t HalUtlRemoveStreamDataAndDeleteStreamVerb(afb_api_t apiHandle, + char *verb, + char *verbToCall, + char *streamCardId); + +#endif /* _HAL_UTILITIES_HAL_STREAMS_CREATION_INCLUDE_ */
\ No newline at end of file diff --git a/lib/4a-hal-utilities/4a-hal-utilities-verbs-loader.c b/lib/4a-hal-utilities/4a-hal-utilities-verbs-loader.c new file mode 100644 index 0000000..16c28c4 --- /dev/null +++ b/lib/4a-hal-utilities/4a-hal-utilities-verbs-loader.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 "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 <string.h> + +#include <afb/afb-binding.h> + +#include "4a-hal-utilities-verbs-loader.h" + +/******************************************************************************* + * Dynamic API common functions * + ******************************************************************************/ + +int HalUtlLoadVerbs(afb_api_t apiHandle, afb_verb_t *verbs) +{ + int idx, errCount = 0; + + if(! apiHandle || ! verbs) + return -1; + + for (idx = 0; verbs[idx].verb; idx++) { + errCount+= afb_api_add_verb(apiHandle, + verbs[idx].verb, + NULL, + verbs[idx].callback, + (void *) &verbs[idx], + verbs[idx].auth, + 0, + 0); + } + + return errCount; +}
\ No newline at end of file diff --git a/lib/4a-hal-utilities/4a-hal-utilities-verbs-loader.h b/lib/4a-hal-utilities/4a-hal-utilities-verbs-loader.h new file mode 100644 index 0000000..9084595 --- /dev/null +++ b/lib/4a-hal-utilities/4a-hal-utilities-verbs-loader.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2018 "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. + */ + +#ifndef _HAL_UTILITIES_VERBS_LOADER_INCLUDE_ +#define _HAL_UTILITIES_VERBS_LOADER_INCLUDE_ + +#include <stdio.h> + +#include <afb/afb-binding.h> + +// Verb that allows to add verb to a dynamic api +int HalUtlLoadVerbs(afb_api_t apiHandle, afb_verb_t *verbs); + +#endif /* _HAL_UTILITIES_VERBS_LOADER_INCLUDE_ */
\ No newline at end of file diff --git a/lib/4a-hal-utilities/CMakeLists.txt b/lib/4a-hal-utilities/CMakeLists.txt new file mode 100644 index 0000000..d90dd11 --- /dev/null +++ b/lib/4a-hal-utilities/CMakeLists.txt @@ -0,0 +1,33 @@ +########################################################################### +# Copyright 2015, 2016, 2017, 2018, 2019 IoT.bzh +# +# author: Fulup Ar Foll <fulup@iot.bzh> +# contrib: 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. +########################################################################### + +# Add target to project dependency list +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 + 4a-hal-utilities-verbs-loader.c) + + # Define target includes for this target client + TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ) |