From 757c9b407938b65b1e31ccc62217910d4f942dcb Mon Sep 17 00:00:00 2001 From: Jonathan Aillet Date: Mon, 11 Jun 2018 01:45:57 +0200 Subject: Update 4a-hal to work with new 4a-softmixer Update 4a-hal to work with new 4a-softmixer version : - Update audio configuration files to match the configuration format expected by the mixer. - Parse mixer attach response to get information about 'streams', 'playbacks', and 'captures'. store them in new field of controller hal data structure. - Create verb for each returned stream, but only one playback/capture verb even if threre are multiple playbacks/captures returned by the mixer attch verb. - Return 'streams', 'playbacks', and 'captures' when info verb is called. - If info verb is called with a json request, the request is transfered to the mixer. Change-Id: I65593281c34aa91ad87afbf8bebff755cc5cc6d0 Signed-off-by: Jonathan Aillet --- 4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c | 139 +++++++---- 4a-hal/4a-hal-controllers/4a-hal-controllers-cb.h | 2 +- .../4a-hal-controllers-mixer-handler.c | 266 +++++++++++++++------ .../4a-hal-controllers-mixer-handler.h | 25 +- 4a-hal/4a-hal-utilities/4a-hal-utilities-data.c | 3 +- 4a-hal/4a-hal-utilities/4a-hal-utilities-data.h | 7 +- 6 files changed, 315 insertions(+), 127 deletions(-) (limited to '4a-hal') diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c index ded6118..bf676bb 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c @@ -144,8 +144,7 @@ int HalCtlsHalMixerConfig(AFB_ApiT apiHandle, CtlSectionT *section, json_object if(wrap_json_unpack(MixerJ, "{s:s}", "mixerapi", ¤tHalData->ctlHalSpecificData->mixerApiName)) return -5; - if(wrap_json_unpack(MixerJ, "{s:s}", "uid", ¤tHalData->ctlHalSpecificData->mixerVerbName)) - return -6; + wrap_json_unpack(MixerJ, "{s?:s}", "prefix", ¤tHalData->ctlHalSpecificData->prefix); } return 0; @@ -379,18 +378,17 @@ int HalCtlsHalMapConfig(AFB_ApiT apiHandle, CtlSectionT *section, json_object *A * HAL controllers verbs functions * ******************************************************************************/ -void HalCtlsActionOnStream(AFB_ReqT request) +void HalCtlsActionOnCall(AFB_ReqT request) { - int verbToCallSize; - - char *apiToCall, *mixerVerbName, *verbToCall; + char *apiToCall; AFB_ApiT apiHandle; CtlConfigT *ctrlConfig; struct SpecificHalData *currentCtlHalData; + struct CtlHalMixerData *currentMixerData; - json_object *requestJson, *returnJ, *toReturnJ; + json_object *requestJson, *returnJ; apiHandle = (AFB_ApiT) afb_request_get_dynapi(request); if(! apiHandle) { @@ -404,6 +402,12 @@ void HalCtlsActionOnStream(AFB_ReqT request) return; } + currentMixerData = (struct CtlHalMixerData *) afb_request_get_vcbdata(request); + if(! currentMixerData) { + AFB_ReqFail(request, "hal_call_data", "Can't get current call data"); + return; + } + currentCtlHalData = (struct SpecificHalData *) ctrlConfig->external; if(! currentCtlHalData) { AFB_ReqFail(request, "hal_controller_data", "Can't get current hal controller data"); @@ -422,54 +426,76 @@ void HalCtlsActionOnStream(AFB_ReqT request) return; } - mixerVerbName = currentCtlHalData->ctlHalSpecificData->mixerVerbName; - if(! mixerVerbName) { - AFB_ReqFail(request, "hal_softmixer_verb", "Can't get hal mixer verb prefix"); - return; - } - if(currentCtlHalData->status != HAL_STATUS_READY) { AFB_ReqFail(request, "hal_not_ready", "Seems that hal is not ready"); return; } - // TODO JAI : remove verb to call prefix, each hal should have its own api in softmixer, and each streams should be created as verb by mixer - verbToCallSize = (int) strlen(mixerVerbName) + (int) strlen(request->verb) + 2; - verbToCall = (char *) alloca(verbToCallSize * sizeof(char)); - verbToCall[0] = '\0'; - verbToCall[verbToCallSize - 1] = '\0'; + // TBD JAI : handle the case of there is multiple 'playbacks' or 'captures' entries (call them all) + + if(AFB_ServiceSync(apiHandle, apiToCall, currentMixerData->verbToCall, json_object_get(requestJson), &returnJ)) { + HalUtlHandleAppFwCallErrorInRequest(request, apiToCall, currentMixerData->verbToCall, returnJ, "call_action"); + } + + AFB_ReqSuccessF(request, + NULL, + "Action %s correctly transferred to %s without any error raised", + currentMixerData->verbToCall, + apiToCall); +} + +json_object *HalCtlsGetJsonArrayForMixerDataTable(AFB_ApiT apiHandle, struct CtlHalMixerDataT *currentMixerDataT, enum MixerDataType dataType) +{ + unsigned int idx; - strcat(verbToCall, mixerVerbName); - strcat(verbToCall, "/"); - strcat(verbToCall, request->verb); + json_object *mixerDataArray, *currentMixerData; - if(AFB_ServiceSync(apiHandle, apiToCall, verbToCall, json_object_get(requestJson), &returnJ)) { - HalUtlHandleAppFwCallErrorInRequest(request, apiToCall, verbToCall, returnJ, "stream_action"); + if(! apiHandle) { + AFB_ApiError(apiHandle, "Can't get current hal controller api handle"); + return NULL; } - else if(json_object_object_get_ex(returnJ, "response", &toReturnJ)){ - AFB_ReqSuccessF(request, - toReturnJ, - "Action %s correctly transferred to %s without any error raised", - verbToCall, - apiToCall); + + if(! currentMixerDataT) { + AFB_ApiError(apiHandle, "Can't get mixer data table to handle"); + return NULL; } - else { - AFB_ReqFailF(request, "invalid_response", "Action %s correctly transferred to %s, but response is not valid", - verbToCall, - apiToCall); + + mixerDataArray = json_object_new_array(); + if(! mixerDataArray) { + AFB_ApiError(apiHandle, "Can't generate json mixer data array"); + return NULL; } + + for(idx = 0; idx < currentMixerDataT->count; idx++) { + if(dataType == MIXER_DATA_STREAMS) { + wrap_json_pack(¤tMixerData, + "{s:s s:s}", + "name", currentMixerDataT->data[idx].verb, + "cardId", currentMixerDataT->data[idx].streamCardId); + } + else { + wrap_json_pack(¤tMixerData, + "{s:s s:s}", + "name", currentMixerDataT->data[idx].verb, + "mixer-name", currentMixerDataT->data[idx].verbToCall, + "uid", currentMixerDataT->data[idx].streamCardId ? currentMixerDataT->data[idx].streamCardId : "none"); + } + json_object_array_add(mixerDataArray, currentMixerData); + } + + return mixerDataArray; } void HalCtlsInfo(AFB_ReqT request) { - unsigned int idx; + char *apiToCall; AFB_ApiT apiHandle; CtlConfigT *ctrlConfig; struct SpecificHalData *currentCtlHalData; - json_object *requestJson, *requestAnswer, *streamsArray, *currentStream; + json_object *requestJson, *toReturnJ = NULL, *requestAnswer, *streamsArray, *playbacksArray, *capturesArray; apiHandle = (AFB_ApiT) afb_request_get_dynapi(request); if(! apiHandle) { @@ -489,34 +515,47 @@ void HalCtlsInfo(AFB_ReqT request) return; } - if(! currentCtlHalData->ctlHalSpecificData->ctlHalStreamsData.count) { - AFB_ReqSuccess(request, NULL, "No data to answer, no streams found"); + requestJson = AFB_ReqJson(request); + if(! requestJson) { + AFB_ReqFail(request, "info_data", "Can't get request json"); return; } - requestJson = AFB_ReqJson(request); - if(! requestJson) { - AFB_ReqFail(request, "request_json", "Can't get request json"); + if(json_object_is_type(requestJson, json_type_object)) { + apiToCall = currentCtlHalData->ctlHalSpecificData->mixerApiName; + if(! apiToCall) { + AFB_ReqFail(request, "mixer_api", "Can't get mixer api"); + return; + } + + if(HalCtlsGetInfoFromMixer(apiHandle, apiToCall, requestJson, &toReturnJ)) { + AFB_ReqFail(request, "mixer_info", "Call to mixer info verb didn't succeed"); + return; + } + + AFB_ReqSuccess(request, toReturnJ, "Mixer requested data"); return; } - streamsArray = json_object_new_array(); + streamsArray = HalCtlsGetJsonArrayForMixerDataTable(apiHandle, ¤tCtlHalData->ctlHalSpecificData->ctlHalStreamsData, MIXER_DATA_STREAMS); if(! streamsArray) { - AFB_ReqFail(request, "json_answer", "Can't generate par of json answer"); + AFB_ReqFail(request, "streams_data", "Didn't succeed to generate streams data array"); return; } - for(idx = 0; idx < currentCtlHalData->ctlHalSpecificData->ctlHalStreamsData.count; idx++) { - wrap_json_pack(¤tStream, - "{s:s s:s}", - "name", currentCtlHalData->ctlHalSpecificData->ctlHalStreamsData.data[idx].name, - "cardId", currentCtlHalData->ctlHalSpecificData->ctlHalStreamsData.data[idx].streamCardId); - json_object_array_add(streamsArray, currentStream); + playbacksArray = HalCtlsGetJsonArrayForMixerDataTable(apiHandle, ¤tCtlHalData->ctlHalSpecificData->ctlHalPlaybacksData, MIXER_DATA_PLAYBACKS); + if(! playbacksArray) { + AFB_ReqFail(request, "playbacks_data", "Didn't succeed to generate playbacks data array"); + return; } - // TODO JAI : Add playback and capture with their card id to the response + capturesArray = HalCtlsGetJsonArrayForMixerDataTable(apiHandle, ¤tCtlHalData->ctlHalSpecificData->ctlHalCapturesData, MIXER_DATA_CAPTURES); + if(! capturesArray) { + AFB_ReqFail(request, "captures_data", "Didn't succeed to generate captures data array"); + return; + } - wrap_json_pack(&requestAnswer, "{s:o}", "streams", streamsArray); + wrap_json_pack(&requestAnswer, "{s:o s:o s:o}", "streams", streamsArray, "playbacks", playbacksArray, "captures", capturesArray); AFB_ReqSuccess(request, requestAnswer, "Requested data"); } \ No newline at end of file diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.h b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.h index 2db6186..cfb72b4 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.h +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.h @@ -32,7 +32,7 @@ int HalCtlsHalMixerConfig(AFB_ApiT apiHandle, CtlSectionT *section, json_object int HalCtlsHalMapConfig(AFB_ApiT apiHandle, CtlSectionT *section, json_object *StreamControlsJ); // HAL controllers verbs functions -void HalCtlsActionOnStream(AFB_ReqT request); +void HalCtlsActionOnCall(AFB_ReqT request); void HalCtlsInfo(AFB_ReqT request); #endif /* _HALMGR_CB_INCLUDE_ */ \ No newline at end of file diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.c b/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.c index cb4ea93..ffb1bf2 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.c +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.c @@ -21,6 +21,8 @@ #include #include +#include + #include "../4a-hal-utilities/4a-hal-utilities-appfw-responses-handler.h" #include "../4a-hal-utilities/4a-hal-utilities-data.h" #include "../4a-hal-utilities/4a-hal-utilities-verbs-loader.h" @@ -34,70 +36,137 @@ * HAL controllers handle mixer calls functions * ******************************************************************************/ -int HalCtlsHandleMixerAttachResponse(AFB_ApiT apiHandle, struct CtlHalMixerDataT *currentHalStreamsData, json_object *mixerResponseJ) +int HalCtlsHandleMixerData(AFB_ApiT apiHandle, struct CtlHalMixerDataT *currentMixerDataT, json_object *currentDataJ, enum MixerDataType dataType) { + int idx, verbStart, size; int err = (int) MIXER_NO_ERROR; - unsigned int idx; - - char *currentStreamName, *currentStreamCardId; - struct HalUtlApiVerb *CtlHalDynApiStreamVerbs; + char *currentDataVerbName, *currentStreamCardId; - json_object *currentStreamJ; - - if(! apiHandle) { - AFB_ApiError(apiHandle, "%s: Can't get current hal api handle", __func__); - return (int) MIXER_ERROR_API_UNAVAILABLE; - } + json_object *currentJ; - switch(json_object_get_type(mixerResponseJ)) { + switch(json_object_get_type(currentDataJ)) { case json_type_object: - currentHalStreamsData->count = 1; + currentMixerDataT->count = 1; break; case json_type_array: - currentHalStreamsData->count = json_object_array_length(mixerResponseJ); + currentMixerDataT->count = json_object_array_length(currentDataJ); break; default: - currentHalStreamsData->count = 0; - AFB_ApiWarning(apiHandle, "%s: no streams returned", __func__); - return (int) MIXER_ERROR_NO_STREAMS; + currentMixerDataT->count = 0; + AFB_ApiError(apiHandle, "%s: no data returned", __func__); + return (int) MIXER_ERROR_DATA_EMPTY; } - currentHalStreamsData->data = (struct CtlHalMixerData *) calloc(currentHalStreamsData->count, sizeof(struct CtlHalMixerData)); + currentMixerDataT->data = (struct CtlHalMixerData *) calloc(currentMixerDataT->count, sizeof(struct CtlHalMixerData)); - CtlHalDynApiStreamVerbs = alloca((currentHalStreamsData->count + 1) * sizeof(struct HalUtlApiVerb)); - memset(CtlHalDynApiStreamVerbs, '\0', (currentHalStreamsData->count + 1) * sizeof(struct HalUtlApiVerb)); - CtlHalDynApiStreamVerbs[currentHalStreamsData->count].verb = NULL; - - for(idx = 0; idx < currentHalStreamsData->count; idx++) { - if(currentHalStreamsData->count > 1) - currentStreamJ = json_object_array_get_idx(mixerResponseJ, (int) idx); + for(idx = 0; idx < currentMixerDataT->count; idx++) { + if(currentMixerDataT->count > 1) + currentJ = json_object_array_get_idx(currentDataJ, (int) idx); else - currentStreamJ = mixerResponseJ; + currentJ = currentDataJ; - if(wrap_json_unpack(currentStreamJ, "{s:s}", "uid", ¤tStreamName)) { - AFB_ApiError(apiHandle, "%s: can't find name in current stream object", __func__); - err += (int) MIXER_ERROR_STREAM_NAME_UNAVAILABLE; + if(wrap_json_unpack(currentJ, "{s:s}", "verb", ¤tDataVerbName)) { + AFB_ApiError(apiHandle, "%s: can't find verb in current data object", __func__); + err += (int) MIXER_ERROR_DATA_NAME_UNAVAILABLE; } - else if(wrap_json_unpack(currentStreamJ, "{s:s}", "alsa", ¤tStreamCardId)) { - AFB_ApiError(apiHandle, "%s: can't find card id in current stream object", __func__); - err += (int) MIXER_ERROR_STREAM_CARDID_UNAVAILABLE; + else if(dataType == MIXER_DATA_STREAMS && wrap_json_unpack(currentJ, "{s:s}", "alsa", ¤tStreamCardId)) { + AFB_ApiError(apiHandle, "%s: can't find card id in current data object", __func__); + err += (int) MIXER_ERROR_DATA_CARDID_UNAVAILABLE; } else { - currentHalStreamsData->data[idx].name = strdup(currentStreamName); - currentHalStreamsData->data[idx].streamCardId = strdup(currentStreamCardId); + currentMixerDataT->data[idx].verbToCall = strdup(currentDataVerbName); + + if(dataType == MIXER_DATA_STREAMS) { + currentMixerDataT->data[idx].streamCardId = strdup(currentStreamCardId); + + size = (int) strlen(currentDataVerbName); + for(verbStart = 0; verbStart < size; verbStart++) { + if(currentDataVerbName[verbStart] == ':') + break; + } + + if(verbStart == size) + verbStart = 0; + else + verbStart++; + + currentMixerDataT->data[idx].verb = strdup(¤tDataVerbName[verbStart]); + + if(afb_dynapi_add_verb(apiHandle, + currentMixerDataT->data[idx].verb, + "Stream action transferred to mixer", + HalCtlsActionOnCall, + (void *) ¤tMixerDataT->data[idx], + NULL, + 0)) { + AFB_ApiError(apiHandle, "%s: error while creating verbs for stream : '%s'", __func__, currentMixerDataT->data[idx].verb); + err += (int) MIXER_ERROR_STREAM_VERB_NOT_CREATED; + } + } + else if(dataType == MIXER_DATA_PLAYBACKS) { + currentMixerDataT->data[idx].verb = strdup(HAL_PLAYBACK_VERB); + } + else if(dataType == MIXER_DATA_CAPTURES) { + currentMixerDataT->data[idx].verb = strdup(HAL_CAPTURE_VERB); + } + } + } + + if(dataType == MIXER_DATA_PLAYBACKS) { + if(afb_dynapi_add_verb(apiHandle, + HAL_PLAYBACK_VERB, + "Playback action transferred to mixer", + HalCtlsActionOnCall, + (void *) currentMixerDataT->data, + NULL, + 0)) { + AFB_ApiError(apiHandle, "%s: error while creating verb for playbacks : '%s'", __func__, HAL_PLAYBACK_VERB); + err += (int) MIXER_ERROR_PLAYBACK_VERB_NOT_CREATED; + } + } - CtlHalDynApiStreamVerbs[idx].verb = currentStreamName; - CtlHalDynApiStreamVerbs[idx].callback = HalCtlsActionOnStream; - CtlHalDynApiStreamVerbs[idx].info = "Peform action on this stream"; + if(dataType == MIXER_DATA_CAPTURES) { + if(afb_dynapi_add_verb(apiHandle, + HAL_CAPTURE_VERB, + "Capture action transferred to mixer", + HalCtlsActionOnCall, + (void *) currentMixerDataT->data, + NULL, + 0)) { + AFB_ApiError(apiHandle, "%s: error while creating verb for captures : '%s'", __func__, HAL_CAPTURE_VERB); + err += (int) MIXER_ERROR_CAPTURE_VERB_NOT_CREATED; } } - if(HalUtlLoadVerbs(apiHandle, CtlHalDynApiStreamVerbs)) { - AFB_ApiError(apiHandle, "%s: error while creating verbs for streams", __func__); - err += (int) MIXER_ERROR_COULDNT_ADD_STREAMS_AS_VERB; + return err; +} + +int HalCtlsHandleMixerAttachResponse(AFB_ApiT apiHandle, struct CtlHalSpecificData *currentHalSpecificData, json_object *mixerResponseJ) +{ + int err = (int) MIXER_NO_ERROR; + + json_object *mixerStreamsJ = NULL, *mixerPlaybacksJ = NULL, *mixerCapturesJ = NULL; + + if(! apiHandle) { + AFB_ApiError(apiHandle, "%s: Can't get current hal api handle", __func__); + return (int) MIXER_ERROR_API_UNAVAILABLE; } + if(wrap_json_unpack(mixerResponseJ, "{s:o s:o s:o}", "streams", &mixerStreamsJ, "playbacks", &mixerPlaybacksJ, "captures", &mixerCapturesJ)) { + AFB_ApiError(apiHandle, "%s: Can't get streams|playbacks|captures object in '%s'", __func__, json_object_get_string(mixerResponseJ)); + return (int) MIXER_ERROR_DATA_UNAVAILABLE; + } + + if((err += HalCtlsHandleMixerData(apiHandle, ¤tHalSpecificData->ctlHalStreamsData, mixerStreamsJ, MIXER_DATA_STREAMS))) + AFB_ApiError(apiHandle, "%s: Error during handling response mixer streams data '%s'", __func__, json_object_get_string(mixerStreamsJ)); + + if((err += HalCtlsHandleMixerData(apiHandle, ¤tHalSpecificData->ctlHalPlaybacksData, mixerPlaybacksJ, MIXER_DATA_PLAYBACKS))) + AFB_ApiError(apiHandle, "%s: Error during handling response mixer playbacks data '%s'", __func__, json_object_get_string(mixerPlaybacksJ)); + + if((err += HalCtlsHandleMixerData(apiHandle, ¤tHalSpecificData->ctlHalCapturesData, mixerCapturesJ, MIXER_DATA_CAPTURES))) + AFB_ApiError(apiHandle, "%s: Error during handling response mixer captures data '%s'", __func__, json_object_get_string(mixerCapturesJ)); + return err; } @@ -116,19 +185,36 @@ int HalCtlsAttachToMixer(AFB_ApiT apiHandle) json_object *returnJ, *toReturnJ; + if(! apiHandle) { + AFB_ApiError(apiHandle, "%s: Can't get current hal api handle", __func__); + return -1; + } + ctrlConfig = (CtlConfigT *) afb_dynapi_get_userdata(apiHandle); if(! ctrlConfig) { AFB_ApiError(apiHandle, "%s: Can't get current hal controller config", __func__); - return -1; + return -2; } currentCtlHalData = (struct SpecificHalData *) ctrlConfig->external; if(! currentCtlHalData) { AFB_ApiError(apiHandle, "%s: Can't get current hal controller data", __func__); - return -2; + return -3; + } + + switch(currentCtlHalData->status) { + case HAL_STATUS_UNAVAILABLE: + AFB_ApiError(apiHandle, "%s: Seems that the hal corresponding card was not found by alsacore at startup", __func__); + return -4; + + case HAL_STATUS_READY: + AFB_ApiNotice(apiHandle, "%s: Seems that the hal mixer is already initialized", __func__); + return 1; + + case HAL_STATUS_AVAILABLE: + break; } - // TODO JAI : add a test to see if the hal card id is already used firstHalData = HalMngGetFirstHalData(); if((concurentHalData = HalUtlSearchReadyHalDataByCarId(firstHalData, currentCtlHalData->sndCardId))) { AFB_ApiError(apiHandle, @@ -137,41 +223,28 @@ int HalCtlsAttachToMixer(AFB_ApiT apiHandle) currentCtlHalData->apiName, currentCtlHalData->sndCardId, concurentHalData->apiName); - return -3; + return -5; } apiToCall = currentCtlHalData->ctlHalSpecificData->mixerApiName; if(! apiToCall) { AFB_ApiError(apiHandle, "%s: Can't get mixer api", __func__); - return -4; - } - - switch(currentCtlHalData->status) { - case HAL_STATUS_UNAVAILABLE: - AFB_ApiError(apiHandle, "%s: Seems that the hal corresponding card was not found by alsacore at startup", __func__); - return -5; - - case HAL_STATUS_READY: - AFB_ApiNotice(apiHandle, "%s: Seems that the hal mixer is already initialized", __func__); - return 1; - - case HAL_STATUS_AVAILABLE: - break; + return -6; } if(AFB_ServiceSync(apiHandle, apiToCall, MIXER_ATTACH_VERB, json_object_get(currentCtlHalData->ctlHalSpecificData->halMixerJ), &returnJ)) { returnedError = HalUtlHandleAppFwCallError(apiHandle, apiToCall, MIXER_ATTACH_VERB, returnJ, &returnedStatus, &returnedInfo); - AFB_ApiWarning(apiHandle, - "Error %i during call to verb %s of %s api with status '%s' and info '%s'", - (int) returnedError, - apiToCall, - MIXER_ATTACH_VERB, - returnedStatus ? returnedStatus : "not returned", - returnedInfo ? returnedInfo : "not returned"); - return -6; + AFB_ApiError(apiHandle, + "Error %i during call to verb %s of %s api with status '%s' and info '%s'", + (int) returnedError, + apiToCall, + MIXER_ATTACH_VERB, + returnedStatus ? returnedStatus : "not returned", + returnedInfo ? returnedInfo : "not returned"); + return -7; } else if(json_object_object_get_ex(returnJ, "response", &toReturnJ)) { - err = HalCtlsHandleMixerAttachResponse(apiHandle, ¤tCtlHalData->ctlHalSpecificData->ctlHalStreamsData, toReturnJ); + err = HalCtlsHandleMixerAttachResponse(apiHandle, currentCtlHalData->ctlHalSpecificData, toReturnJ); if(err != (int) MIXER_NO_ERROR) { AFB_ApiError(apiHandle, "%s: Seems that %s call to api %s succeed but this warning was risen by response decoder : %i '%s'", @@ -180,7 +253,7 @@ int HalCtlsAttachToMixer(AFB_ApiT apiHandle) apiToCall, err, json_object_get_string(toReturnJ)); - return -7; + return -8; } AFB_ApiNotice(apiHandle, @@ -199,6 +272,63 @@ int HalCtlsAttachToMixer(AFB_ApiT apiHandle) MIXER_ATTACH_VERB, apiToCall, json_object_get_string(returnJ)); + return -9; + } + + return 0; +} + +int HalCtlsGetInfoFromMixer(AFB_ApiT apiHandle, char *apiToCall, json_object *requestJson, json_object **toReturnJ) +{ + char *returnedStatus = NULL, *returnedInfo = NULL; + + enum CallError returnedError; + + json_object *returnJ, *responseJ; + + if(! apiHandle) { + AFB_ApiError(apiHandle, "%s: Can't get current hal api handle", __func__); + return -1; + } + + if(! apiToCall) { + AFB_ApiError(apiHandle, "Can't get mixer api"); + return -2; + } + + if(! requestJson) { + AFB_ApiError(apiHandle, "Can't get request json"); + return -3; + } + + if(AFB_ServiceSync(apiHandle, apiToCall, MIXER_INFO_VERB, json_object_get(requestJson), &returnJ)) { + returnedError = HalUtlHandleAppFwCallError(apiHandle, apiToCall, MIXER_INFO_VERB, returnJ, &returnedStatus, &returnedInfo); + AFB_ApiError(apiHandle, + "Error %i during call to verb %s of %s api with status '%s' and info '%s'", + (int) returnedError, + apiToCall, + MIXER_INFO_VERB, + returnedStatus ? returnedStatus : "not returned", + returnedInfo ? returnedInfo : "not returned"); + return -4; + } + else if(json_object_object_get_ex(returnJ, "response", &responseJ)) { + AFB_ApiNotice(apiHandle, + "%s: Seems that %s call to api %s succeed with no warning raised : '%s'", + __func__, + MIXER_INFO_VERB, + apiToCall, + json_object_get_string(responseJ)); + + *toReturnJ = responseJ; + } + else { + AFB_ApiError(apiHandle, + "%s: Seems that %s call to api %s succeed, but response is not valid : '%s'", + __func__, + MIXER_INFO_VERB, + apiToCall, + json_object_get_string(returnJ)); return -8; } diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.h b/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.h index 74bca88..9218ed4 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.h +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.h @@ -26,19 +26,34 @@ #include "../4a-hal-utilities/4a-hal-utilities-data.h" -#define MIXER_ATTACH_VERB "create" +#define MIXER_ATTACH_VERB "attach" +#define MIXER_INFO_VERB "info" + +#define HAL_PLAYBACK_VERB "playback" +#define HAL_CAPTURE_VERB "capture" + +// Enum for the type of object sent back by the mixer +enum MixerDataType { + MIXER_DATA_STREAMS = 1, + MIXER_DATA_PLAYBACKS = 2, + MIXER_DATA_CAPTURES = 3 +}; // Enum for the type of error detected enum MixerStatus { MIXER_NO_ERROR=0, MIXER_ERROR_API_UNAVAILABLE=-1, - MIXER_ERROR_NO_STREAMS=-2, - MIXER_ERROR_STREAM_NAME_UNAVAILABLE=-10, - MIXER_ERROR_STREAM_CARDID_UNAVAILABLE=-1000, - MIXER_ERROR_COULDNT_ADD_STREAMS_AS_VERB =-100000, + MIXER_ERROR_DATA_UNAVAILABLE=-2, + MIXER_ERROR_DATA_EMPTY =-3, + MIXER_ERROR_DATA_NAME_UNAVAILABLE=-10, + MIXER_ERROR_DATA_CARDID_UNAVAILABLE=-1000, + MIXER_ERROR_STREAM_VERB_NOT_CREATED =-100000, + MIXER_ERROR_PLAYBACK_VERB_NOT_CREATED =-4, + MIXER_ERROR_CAPTURE_VERB_NOT_CREATED =-5 }; // HAL controllers handle mixer calls functions int HalCtlsAttachToMixer(AFB_ApiT apiHandle); +int HalCtlsGetInfoFromMixer(AFB_ApiT apiHandle, char *apiToCall, json_object *requestJson, json_object **toReturnJ); #endif /* _HAL_CTLS_SOFTMIXER_LINK_INCLUDE_ */ \ No newline at end of file diff --git a/4a-hal/4a-hal-utilities/4a-hal-utilities-data.c b/4a-hal/4a-hal-utilities/4a-hal-utilities-data.c index e8f54a2..aa4fabc 100644 --- a/4a-hal/4a-hal-utilities/4a-hal-utilities-data.c +++ b/4a-hal/4a-hal-utilities/4a-hal-utilities-data.c @@ -42,7 +42,8 @@ uint8_t HalUtlRemoveAllCtlHalStreamsData(struct CtlHalMixerDataT *ctlHalStreamsD return -2; for(cpt = 0; cpt < ctlHalStreamsData->count; cpt++) { - free(ctlHalStreamsData->data[cpt].name); + free(ctlHalStreamsData->data[cpt].verb); + free(ctlHalStreamsData->data[cpt].verbToCall); free(ctlHalStreamsData->data[cpt].streamCardId); } diff --git a/4a-hal/4a-hal-utilities/4a-hal-utilities-data.h b/4a-hal/4a-hal-utilities/4a-hal-utilities-data.h index 244546f..c33f90d 100644 --- a/4a-hal/4a-hal-utilities/4a-hal-utilities-data.h +++ b/4a-hal/4a-hal-utilities/4a-hal-utilities-data.h @@ -38,7 +38,8 @@ enum HalStatus { // Structure to store stream data struct CtlHalMixerData { - char *name; + char *verb; + char *verbToCall; char *streamCardId; }; @@ -51,10 +52,12 @@ struct CtlHalMixerDataT { // Structure to store specific controller hal data struct CtlHalSpecificData { char *mixerApiName; - char *mixerVerbName; + char *prefix; json_object *halMixerJ; struct CtlHalMixerDataT ctlHalStreamsData; + struct CtlHalMixerDataT ctlHalPlaybacksData; + struct CtlHalMixerDataT ctlHalCapturesData; struct CtlHalAlsaMapT *ctlHalAlsaMapT; AFB_ApiT apiHandle; -- cgit 1.2.3-korg