From 40a55bf64139a51123dd93a4a268088848b0dd17 Mon Sep 17 00:00:00 2001 From: Jonathan Aillet Date: Mon, 17 Dec 2018 19:42:32 +0100 Subject: Add streams events generation for each hal Each hal will now have subscribe/unsubscribe verbs to allow other bindings to be notified when a modification (volume, mute, ...) happened on a stream. Bug-AGL: SPEC-1313 Change-Id: If68d3b4b4e39385c1fffdd04b9f3e2b7fa5ae108 Signed-off-by: Jonathan Aillet --- 4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c | 156 ++++++++++++++++++++++ 1 file changed, 156 insertions(+) (limited to '4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c') 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 07dd49c..f5099c3 100644 --- a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c +++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c @@ -508,6 +508,14 @@ void HalCtlsActionOnMixer(AFB_ReqT request, enum ActionOnMixerType actionType) 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_EventPush(currentMixerData->event, json_object_get(responseJ)) < 0))) { + AFB_ApiError(apiHandle, "Couldn't generate an event for stream %s", currentMixerData->verb); + } + switch(actionType) { case ACTION_ON_MIXER_STREAM: toReturnJ = json_object_get(responseJ); @@ -758,4 +766,152 @@ void HalCtlsInfo(AFB_ReqT request) "controls", controlsArray); AFB_ReqSuccess(request, requestAnswer, "Requested data"); +} + +void HalCtlsSubscribeUnsubscribe(AFB_ReqT request, enum SubscribeUnsubscribeType subscribeUnsubscribeType) +{ + int arrayIdx, searchIdx, count, subscriptionFound, subscriptionDoneNb = 0; + + char *currentSubscriptionString; + + AFB_ApiT apiHandle; + CtlConfigT *ctrlConfig; + + struct SpecificHalData *currentCtlHalData; + struct CtlHalMixerDataT *halStreamsData; + + json_object *requestJson, *requestedSubscriptionsJ, *requestedSubscriptionJ = NULL; + json_type requestJsonType; + + apiHandle = (AFB_ApiT) AFB_ReqGetApi(request); + if(! apiHandle) { + AFB_ReqFail(request, "api_handle", "Can't get current hal controller api handle"); + return; + } + + ctrlConfig = (CtlConfigT *) AFB_ApiGetUserData(apiHandle); + if(! ctrlConfig) { + AFB_ReqFail(request, "hal_controller_config", "Can't get current hal controller config"); + return; + } + + currentCtlHalData = (struct SpecificHalData *) ctrlConfig->external; + if(! currentCtlHalData) { + AFB_ReqFail(request, "hal_controller_data", "Can't get current hal controller data"); + return; + } + + if(! currentCtlHalData->ctlHalSpecificData) { + AFB_ReqFail(request, "hal_controller_data", "Can't get current hal specific data"); + return; + } + + halStreamsData = ¤tCtlHalData->ctlHalSpecificData->ctlHalStreamsData; + + requestJson = AFB_ReqJson(request); + if(! requestJson) { + AFB_ReqFail(request, "request_json", "Can't get request json"); + } + + if(wrap_json_unpack(requestJson, "{s:o}", "events", &requestedSubscriptionsJ)) { + AFB_ReqFail(request, "request_json", "Request json invalid"); + return; + } + + requestJsonType = json_object_get_type(requestedSubscriptionsJ); + switch(requestJsonType) { + case json_type_string: + count = 1; + requestedSubscriptionJ = requestedSubscriptionsJ; + break; + + case json_type_array: + count = (int) json_object_array_length(requestedSubscriptionsJ); + break; + + default: + AFB_ReqFail(request, "request_json", "Request json invalid"); + return; + } + + for(arrayIdx = 0; arrayIdx < count; arrayIdx++) { + if(requestJsonType == json_type_array) { + requestedSubscriptionJ = json_object_array_get_idx(requestedSubscriptionsJ, arrayIdx); + if(! json_object_is_type(requestedSubscriptionJ, json_type_string)) { + AFB_ReqFailF(request, "request_json", "Request json number %i in array invalid", arrayIdx); + return; + } + } + + subscriptionFound = 0; + currentSubscriptionString = (char *) json_object_get_string(requestedSubscriptionJ); + + searchIdx = 0; + while((searchIdx < halStreamsData->count) && + (! subscriptionFound)) { + if(! strcasecmp(currentSubscriptionString, halStreamsData->data[searchIdx].verb)) { + if(halStreamsData->data[searchIdx].event && + subscribeUnsubscribeType == SUBSCRIPTION && + afb_req_subscribe(request, halStreamsData->data[searchIdx].event)) { + AFB_ReqFailF(request, + "request_stream_event", + "Error while trying to subscribe to %s stream events", + halStreamsData->data[searchIdx].verb); + return; + } + else if(halStreamsData->data[searchIdx].event && + subscribeUnsubscribeType == UNSUBSCRIPTION && + afb_req_unsubscribe(request, halStreamsData->data[searchIdx].event)) { + AFB_ReqFailF(request, + "request_stream_event", + "Error while trying to unsubscribe to %s stream events", + halStreamsData->data[searchIdx].verb); + return; + } + + subscriptionFound = 1; + subscriptionDoneNb++; + + break; + } + + searchIdx++; + } + } + + if(subscriptionDoneNb == 0) + AFB_ReqFailF(request, + "events_not_found", + "%s failed, event(s) were not found", + subscribeUnsubscribeType == SUBSCRIPTION ? "Subscription" : "Unsubscription"); + if(subscriptionDoneNb == count) + AFB_ReqSuccessF(request, + json_object_new_int(subscriptionDoneNb), + "%s succeed for all the %i events requested", + subscribeUnsubscribeType == SUBSCRIPTION ? "Subscription" : "Unsubscription", + subscriptionDoneNb); + else if(subscriptionDoneNb < count) + AFB_ReqSuccessF(request, + json_object_new_int(subscriptionDoneNb), + "%s succeed but only to %i events requested out of %i", + subscribeUnsubscribeType == SUBSCRIPTION ? "Subscription" : "Unsubscription", + subscriptionDoneNb, + count); + else + AFB_ReqSuccessF(request, + json_object_new_int(subscriptionDoneNb), + "%s succeed but to more events than requested (%i out of %i)", + subscribeUnsubscribeType == SUBSCRIPTION ? "Subscription" : "Unsubscription", + subscriptionDoneNb, + count); +} + +void HalCtlsSubscribe(AFB_ReqT request) +{ + HalCtlsSubscribeUnsubscribe(request, SUBSCRIPTION); +} + +void HalCtlsUnsubscribe(AFB_ReqT request) +{ + HalCtlsSubscribeUnsubscribe(request, UNSUBSCRIPTION); } \ No newline at end of file -- cgit 1.2.3-korg