From 24b80b0044e0a9636eecb5c5649e8e404c06090f Mon Sep 17 00:00:00 2001 From: Jonathan Aillet Date: Mon, 17 Dec 2018 19:41:41 +0100 Subject: Rework calls to mixer streams When using 'playback'/'capture' verbs, call all associated controls. When at least one stream has been created by the mixer, a verb called 'all-streams' is added to transfer a request to all the streams. Bug-AGL: SPEC-1313 Change-Id: Ie574e2ef0dcae8abbd45523b49093ec2ed1413cf Signed-off-by: Jonathan Aillet --- 4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c | 161 ++++++++++++++++++--- 4a-hal/4a-hal-controllers/4a-hal-controllers-cb.h | 13 +- .../4a-hal-controllers-mixer-link.c | 42 ++++-- .../4a-hal-controllers-mixer-link.h | 11 +- .../4a-hal-utilities-appfw-responses-handler.c | 8 + 5 files changed, 193 insertions(+), 42 deletions(-) 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 d235f2a..07dd49c 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c @@ -385,17 +385,20 @@ int HalCtlsHalMapConfig(AFB_ApiT apiHandle, CtlSectionT *section, json_object *A * HAL controllers verbs functions * ******************************************************************************/ -void HalCtlsActionOnCall(AFB_ReqT request) +void HalCtlsActionOnMixer(AFB_ReqT request, enum ActionOnMixerType actionType) { + int idx, count; + char *apiToCall; AFB_ApiT apiHandle; CtlConfigT *ctrlConfig; struct SpecificHalData *currentCtlHalData; - struct CtlHalMixerData *currentMixerData; + struct CtlHalMixerData *currentMixerData = NULL; + struct CtlHalMixerDataT *currentMixerDataT = NULL; - json_object *requestJson, *returnJ = NULL, *toReturnJ; + json_object *requestJson, *returnJ = NULL, *responseJ, *toReturnJ = NULL; apiHandle = (AFB_ApiT) afb_request_get_dynapi(request); if(! apiHandle) { @@ -416,6 +419,7 @@ void HalCtlsActionOnCall(AFB_ReqT request) } currentCtlHalData = (struct SpecificHalData *) ctrlConfig->external; + if(! currentCtlHalData) { AFB_ReqFail(request, "hal_controller_data", "Can't get current hal controller data"); return; @@ -427,6 +431,9 @@ void HalCtlsActionOnCall(AFB_ReqT request) 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 = currentCtlHalData->ctlHalSpecificData->mixerApiName; if(! apiToCall) { AFB_ReqFail(request, "mixer_api", "Can't get mixer api"); @@ -438,32 +445,140 @@ void HalCtlsActionOnCall(AFB_ReqT request) 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)); + switch(actionType) { + case ACTION_ON_MIXER_STREAM: + currentMixerData = (struct CtlHalMixerData *) AFB_ReqVCBData(request); + if(! currentMixerData) { + AFB_ReqFail(request, "hal_call_data", "Can't get current call data"); + return; + } + count = 1; + break; - // TBD JAI : handle the case of there is multiple 'playbacks' or 'captures' entries (call them all) + case ACTION_ON_MIXER_PLAYBACK: + case ACTION_ON_MIXER_CAPTURE: + case ACTION_ON_MIXER_ALL_STREAM: + currentMixerDataT = (struct CtlHalMixerDataT *) AFB_ReqVCBData(request); + if(! currentMixerDataT) { + AFB_ReqFail(request, "hal_call_data", "Can't get current call data"); + return; + } + count = currentMixerDataT->count; + toReturnJ = json_object_new_object(); + break; - if(AFB_ServiceSync(apiHandle, apiToCall, currentMixerData->verbToCall, json_object_get(requestJson), &returnJ)) { - HalUtlHandleAppFwCallErrorInRequest(request, apiToCall, currentMixerData->verbToCall, returnJ, "call_action"); + default: + AFB_ReqFail(request, "hal_call_data", "Can't get current call data"); + return; } - else if(wrap_json_unpack(returnJ, "{s:o}", "response", &toReturnJ)) { - AFB_ReqSuccessF(request, - json_object_get(returnJ), - "Seems that %s call to api %s succeed, but no response was found : '%s'", - currentMixerData->verbToCall, - apiToCall, - json_object_get_string(returnJ)); + + for(idx = 0; idx < count; idx++) { + switch(actionType) { + case ACTION_ON_MIXER_PLAYBACK: + case ACTION_ON_MIXER_CAPTURE: + case ACTION_ON_MIXER_ALL_STREAM: + currentMixerData = ¤tMixerDataT->data[idx]; + break; + + default: + break; + } + + if(AFB_ServiceSync(apiHandle, + apiToCall, + currentMixerData->verbToCall, + json_object_get(requestJson), + &returnJ)) { + HalUtlHandleAppFwCallErrorInRequest(request, apiToCall, currentMixerData->verbToCall, returnJ, "call_action"); + json_object_put(returnJ); + if(toReturnJ) + json_object_put(toReturnJ); + return; + } + + if(wrap_json_unpack(returnJ, "{s:o}", "response", &responseJ)) { + AFB_ReqFailF(request, + "Seems that %s call to api %s succeed, but no response was found in : '%s'", + currentMixerData->verbToCall, + apiToCall, + json_object_get_string(returnJ)); + json_object_put(returnJ); + if(toReturnJ) + json_object_put(toReturnJ); + return; + } + + switch(actionType) { + case ACTION_ON_MIXER_STREAM: + toReturnJ = json_object_get(responseJ); + break; + + case ACTION_ON_MIXER_PLAYBACK: + case ACTION_ON_MIXER_CAPTURE: + json_object_object_add(toReturnJ, currentMixerData->verbToCall, json_object_get(responseJ)); + break; + + case ACTION_ON_MIXER_ALL_STREAM: + json_object_object_add(toReturnJ, currentMixerData->verb, json_object_get(responseJ)); + break; + + default: + break; + } + + json_object_put(returnJ); } - else { - AFB_ReqSuccessF(request, - json_object_get(toReturnJ), - "Action %s correctly transferred to %s without any error raised", - currentMixerData->verbToCall, - apiToCall); + + switch(actionType) { + case ACTION_ON_MIXER_STREAM: + AFB_ReqSuccessF(request, + toReturnJ, + "Action %s correctly transferred to %s without any error raised", + currentMixerData->verbToCall, + apiToCall); + break; + + case ACTION_ON_MIXER_PLAYBACK: + AFB_ReqSuccess(request, + toReturnJ, + "Actions correctly transferred to all playbacks without any error raised"); + break; + + case ACTION_ON_MIXER_CAPTURE: + AFB_ReqSuccess(request, + toReturnJ, + "Actions correctly transferred to all captures without any error raised"); + break; + + case ACTION_ON_MIXER_ALL_STREAM: + AFB_ReqSuccess(request, + toReturnJ, + "Actions correctly transferred to all streams without any error raised"); + break; + + default: + break; } +} - if(returnJ) - json_object_put(returnJ); +void HalCtlsActionOnStream(AFB_ReqT request) +{ + HalCtlsActionOnMixer(request, ACTION_ON_MIXER_STREAM); +} + +void HalCtlsActionOnPlayback(AFB_ReqT request) +{ + HalCtlsActionOnMixer(request, ACTION_ON_MIXER_PLAYBACK); +} + +void HalCtlsActionOnCapture(AFB_ReqT request) +{ + HalCtlsActionOnMixer(request, ACTION_ON_MIXER_CAPTURE); +} + +void HalCtlsActionOnAllStream(AFB_ReqT request) +{ + HalCtlsActionOnMixer(request, ACTION_ON_MIXER_ALL_STREAM); } json_object *HalCtlsGetJsonArrayForMixerDataTable(AFB_ApiT apiHandle, struct CtlHalMixerDataT *currentMixerDataT, enum MixerDataType dataType) 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 cfb72b4..1f91b62 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.h +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.h @@ -24,6 +24,14 @@ #include +// 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 +}; + // HAL controller event handler function void HalCtlsDispatchApiEvent(afb_dynapi *apiHandle, const char *evtLabel, json_object *eventJ); @@ -32,7 +40,10 @@ int HalCtlsHalMixerConfig(AFB_ApiT apiHandle, CtlSectionT *section, json_object int HalCtlsHalMapConfig(AFB_ApiT apiHandle, CtlSectionT *section, json_object *StreamControlsJ); // HAL controllers verbs functions -void HalCtlsActionOnCall(AFB_ReqT request); +void HalCtlsActionOnStream(AFB_ReqT request); +void HalCtlsActionOnPlayback(AFB_ReqT request); +void HalCtlsActionOnCapture(AFB_ReqT request); +void HalCtlsActionOnAllStream(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-link.c b/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-link.c index 254c57b..aa169c7 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-link.c +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-link.c @@ -83,21 +83,21 @@ int HalCtlsHandleMixerData(AFB_ApiT apiHandle, struct CtlHalMixerDataT *currentM size = (int) strlen(currentDataVerbName); for(verbStart = 0; verbStart < size; verbStart++) { - if(currentDataVerbName[verbStart] == '#') + if(currentDataVerbName[verbStart] == '#') { + 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, + HalCtlsActionOnStream, (void *) ¤tMixerDataT->data[idx], NULL, 0)) { @@ -108,36 +108,36 @@ int HalCtlsHandleMixerData(AFB_ApiT apiHandle, struct CtlHalMixerDataT *currentM } } else if(dataType == MIXER_DATA_PLAYBACKS) { - currentMixerDataT->data[idx].verb = strdup(HAL_PLAYBACK_VERB); + currentMixerDataT->data[idx].verb = strdup(HAL_PLAYBACK_ID); } else if(dataType == MIXER_DATA_CAPTURES) { - currentMixerDataT->data[idx].verb = strdup(HAL_CAPTURE_VERB); + currentMixerDataT->data[idx].verb = strdup(HAL_CAPTURE_ID); } } } if(dataType == MIXER_DATA_PLAYBACKS) { if(afb_dynapi_add_verb(apiHandle, - HAL_PLAYBACK_VERB, + HAL_PLAYBACK_ID, "Playback action transferred to mixer", - HalCtlsActionOnCall, - (void *) currentMixerDataT->data, + HalCtlsActionOnPlayback, + (void *) currentMixerDataT, NULL, 0)) { - AFB_ApiError(apiHandle, "Error while creating verb for playbacks : '%s'", HAL_PLAYBACK_VERB); + AFB_ApiError(apiHandle, "Error while creating verb for playbacks : '%s'", HAL_PLAYBACK_ID); err += (int) MIXER_ERROR_PLAYBACK_VERB_NOT_CREATED; } } if(dataType == MIXER_DATA_CAPTURES) { if(afb_dynapi_add_verb(apiHandle, - HAL_CAPTURE_VERB, + HAL_CAPTURE_ID, "Capture action transferred to mixer", - HalCtlsActionOnCall, - (void *) currentMixerDataT->data, + HalCtlsActionOnCapture, + (void *) currentMixerDataT, NULL, 0)) { - AFB_ApiError(apiHandle, "Error while creating verb for captures : '%s'", HAL_CAPTURE_VERB); + AFB_ApiError(apiHandle, "Error while creating verb for captures : '%s'", HAL_CAPTURE_ID); err += (int) MIXER_ERROR_CAPTURE_VERB_NOT_CREATED; } } @@ -170,6 +170,20 @@ int HalCtlsHandleMixerAttachResponse(AFB_ApiT apiHandle, struct CtlHalSpecificDa if(mixerCapturesJ && (err += HalCtlsHandleMixerData(apiHandle, ¤tHalSpecificData->ctlHalCapturesData, mixerCapturesJ, MIXER_DATA_CAPTURES))) AFB_ApiError(apiHandle, "Error during handling response mixer captures data '%s'", json_object_get_string(mixerCapturesJ)); + if(! currentHalSpecificData->ctlHalStreamsData.count) { + AFB_ApiWarning(apiHandle, "No stream detected in mixer response, %s verb won't be created", HAL_ALL_STREAMS_VERB); + } + else if(afb_dynapi_add_verb(apiHandle, + HAL_ALL_STREAMS_VERB, + "Send a stream action on all streams", + HalCtlsActionOnAllStream, + (void *) ¤tHalSpecificData->ctlHalStreamsData, + NULL, + 0)) { + AFB_ApiError(apiHandle, "Error while creating verb for all streams : '%s'", HAL_ALL_STREAMS_VERB); + return (int) MIXER_ERROR_ALL_STREAMS_VERB_NOT_CREATED; + } + return err; } diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-link.h b/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-link.h index 4ba5e8d..7deef1b 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-link.h +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-link.h @@ -29,8 +29,10 @@ #define MIXER_ATTACH_VERB "attach" #define MIXER_INFO_VERB "info" -#define HAL_PLAYBACK_VERB "playback" -#define HAL_CAPTURE_VERB "capture" +#define HAL_PLAYBACK_ID "playback" +#define HAL_CAPTURE_ID "capture" + +#define HAL_ALL_STREAMS_VERB "all-streams" // Enum for the type of object sent back by the mixer enum MixerDataType { @@ -45,11 +47,12 @@ enum MixerStatus { MIXER_ERROR_API_UNAVAILABLE=-1, MIXER_ERROR_DATA_UNAVAILABLE=-2, MIXER_ERROR_DATA_EMPTY =-3, + MIXER_ERROR_PLAYBACK_VERB_NOT_CREATED =-4, + MIXER_ERROR_CAPTURE_VERB_NOT_CREATED =-5, + MIXER_ERROR_ALL_STREAMS_VERB_NOT_CREATED =-6, 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 diff --git a/4a-hal/4a-hal-utilities/4a-hal-utilities-appfw-responses-handler.c b/4a-hal/4a-hal-utilities/4a-hal-utilities-appfw-responses-handler.c index aa3d95f..f45a783 100644 --- a/4a-hal/4a-hal-utilities/4a-hal-utilities-appfw-responses-handler.c +++ b/4a-hal/4a-hal-utilities/4a-hal-utilities-appfw-responses-handler.c @@ -133,7 +133,15 @@ void HalUtlHandleAppFwCallErrorInRequest(AFB_ReqT request, char *apiCalled, char return; case CALL_ERROR_INVALID_ARGS: + AFB_ReqFailF(request, + errorStatusToSend, + "Api %s and verb %s found, but the arguments are invalid", + apiCalled, + verbCalled); + return; + default: + AFB_ReqFailF(request, errorStatusToSend, "Unknown error happened during call to verb %s of api %s", verbCalled, apiCalled); return; } } \ No newline at end of file -- cgit 1.2.3-korg