summaryrefslogtreecommitdiffstats
path: root/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c
diff options
context:
space:
mode:
authorJonathan Aillet <jonathan.aillet@iot.bzh>2019-04-18 12:40:25 +0200
committerJonathan Aillet <jonathan.aillet@iot.bzh>2019-05-24 12:05:52 +0200
commit68138a3ec7a78ad7304d291ff92d8e5292847c4e (patch)
tree9157134d50a749c838afdf93a49c4ce17a018347 /4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c
parent196e723e79a1f5eae41cf4a8b1450df0679a4af8 (diff)
Clarify internals hal functions and files names
The purpose of this commit is to have of a more standard way to name files and functions used to generate/handle hal api (generated from hal json configuration file). It occurred to me that 'hal-controller' was not a good name because it is harder for people who don't know about the app-controller to understanded what is the purpose of these files/functions. It was renamed to 'internal-hal' because it's about hal that are all handle/load by hal-manager in opposition of external-hal that are independant binding/binder that can register themselves to hal-manager. BUG-AGL: SPEC-2329 Change-Id: I11b7efe64ec474b004a2a15ed8969b9db95d428f Signed-off-by: Jonathan Aillet <jonathan.aillet@iot.bzh>
Diffstat (limited to '4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c')
-rw-r--r--4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c771
1 files changed, 0 insertions, 771 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
deleted file mode 100644
index c38b057..0000000
--- a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
- * 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-controllers-cb.h"
-#include "4a-hal-controllers-alsacore-link.h"
-#include "4a-hal-controllers-mixer-link.h"
-#include "4a-hal-controllers-value-handler.h"
-
-/*******************************************************************************
- * HAL controller event handler function *
- ******************************************************************************/
-
-void HalCtlsDispatchApiEvent(afb_api_t apiHandle, const char *evtLabel, json_object *eventJ)
-{
- int numid, idx = 0, cardidx;
-
- CtlConfigT *ctrlConfig;
- CtlSourceT source;
-
- struct SpecificHalData *currentHalData;
- struct CtlHalAlsaMapT *currentHalAlsaCtlsT;
-
- json_object *valuesJ, *normalizedValuesJ;
-
- AFB_API_DEBUG(apiHandle, "Evtname=%s [msg=%s]", evtLabel, json_object_get_string(eventJ));
-
- if(! (ctrlConfig = (CtlConfigT *) afb_api_get_userdata(apiHandle))) {
- AFB_API_ERROR(apiHandle, "Can't get current hal controller config");
- return;
- }
-
- if(! (currentHalData = (struct SpecificHalData *) getExternalData(ctrlConfig))) {
- AFB_API_WARNING(apiHandle, "Can't get current hal controller data");
- return;
- }
-
- // Extract sound card index from event
- while(evtLabel[idx] != '\0' && evtLabel[idx] != ':')
- idx++;
-
- if(evtLabel[idx] != '\0' &&
- sscanf(&evtLabel[idx + 1], "%d", &cardidx) == 1 &&
- currentHalData->sndCardId == cardidx) {
- if(wrap_json_unpack(eventJ, "{s:i s:o !}", "id", &numid, "val", &valuesJ)) {
- AFB_API_ERROR(apiHandle, "Invalid Alsa Event label=%s value=%s", evtLabel, json_object_get_string(eventJ));
- return;
- }
-
- currentHalAlsaCtlsT = currentHalData->ctlHalSpecificData->ctlHalAlsaMapT;
-
- // Search for corresponding numid in halCtls, if found, launch callback (if available)
- for(idx = 0; idx < currentHalAlsaCtlsT->ctlsCount; idx++) {
- if(currentHalAlsaCtlsT->ctls[idx].ctl.numid == numid) {
- if(currentHalAlsaCtlsT->ctls[idx].action) {
- source.uid = currentHalAlsaCtlsT->ctls[idx].action->uid;
- source.api = currentHalAlsaCtlsT->ctls[idx].action->api;
- source.request = NULL;
-
- (void) ActionExecOne(&source, currentHalAlsaCtlsT->ctls[idx].action, valuesJ);
- }
- else {
- AFB_API_NOTICE(apiHandle,
- "The alsa control id '%i' is corresponding to a known control but without any action registered",
- numid);
- }
-
- if((! currentHalAlsaCtlsT->ctls[idx].alsaControlEvent) ||
- HalCtlsConvertJsonValues(apiHandle,
- &currentHalAlsaCtlsT->ctls[idx].ctl.alsaCtlProperties,
- valuesJ,
- &normalizedValuesJ,
- CONVERSION_ALSACORE_TO_NORMALIZED) ||
- (afb_event_push(currentHalAlsaCtlsT->ctls[idx].alsaControlEvent, normalizedValuesJ) < 0)) {
- AFB_API_ERROR(apiHandle,
- "Couldn't generate an event for known halmap %s (alsa control id %i)",
- currentHalAlsaCtlsT->ctls[idx].uid,
- currentHalAlsaCtlsT->ctls[idx].ctl.numid);
- }
-
- return;
- }
- }
-
- AFB_API_WARNING(apiHandle,
- "Alsacore event with an unrecognized numid: %i, evtname=%s [msg=%s]",
- numid,
- evtLabel,
- json_object_get_string(eventJ));
-
- return;
- }
-
- AFB_API_INFO(apiHandle,
- "Not an alsacore event '%s' [msg=%s]",
- evtLabel,
- json_object_get_string(eventJ));
-
- CtrlDispatchApiEvent(apiHandle, evtLabel, eventJ);
-}
-
-/*******************************************************************************
- * HAL controllers sections parsing functions *
- ******************************************************************************/
-
-int HalCtlsHalMixerConfig(afb_api_t apiHandle, CtlSectionT *section, json_object *MixerJ)
-{
- int err = 0;
-
- CtlConfigT *ctrlConfig;
- struct SpecificHalData *currentHalData;
-
- if(! apiHandle || ! section)
- return -1;
-
- if(! (ctrlConfig = (CtlConfigT *) afb_api_get_userdata(apiHandle)))
- return -2;
-
- if(! (currentHalData = (struct SpecificHalData *) getExternalData(ctrlConfig)))
- return -3;
-
- if(MixerJ) {
- if(json_object_is_type(MixerJ, json_type_object))
- currentHalData->ctlHalSpecificData->halMixerJ = MixerJ;
- else
- return -4;
-
- if(wrap_json_unpack(MixerJ, "{s:s}", "mixerapi", &currentHalData->ctlHalSpecificData->mixerApiName))
- return -5;
-
- wrap_json_unpack(MixerJ, "{s?:s}", "prefix", &currentHalData->ctlHalSpecificData->prefix);
- }
- else if(currentHalData->status == HAL_STATUS_AVAILABLE &&
- (err = HalCtlsAttachToMixer(apiHandle))) {
- AFB_API_ERROR(apiHandle, "%s: Error %i while attaching to mixer", __func__, err);
- return -6;
- }
-
- return 0;
-}
-
-int HalCtlsProcessOneHalMapObject(afb_api_t apiHandle, struct CtlHalAlsaMap *alsaMap, json_object *AlsaMapJ)
-{
- char *action = NULL, *typename = NULL;
-
- json_object *alsaJ = NULL, *createAlsaCtlJ = NULL;
-
- AFB_API_DEBUG(apiHandle, "AlsaMapJ=%s", json_object_get_string(AlsaMapJ));
-
- if(wrap_json_unpack(AlsaMapJ, "{s:s s?:s s:o s?:s !}",
- "uid", &alsaMap->uid,
- "info", &alsaMap->info,
- "alsa", &alsaJ,
- "action", &action)) {
- AFB_API_ERROR(apiHandle, "Parsing error, map should only contains [label]|[uid]|[tag]|[info]|[alsa]|[action] in:\n-- %s", json_object_get_string(AlsaMapJ));
- return -1;
- }
-
- if(wrap_json_unpack(alsaJ, "{s?:s s?:i s?:i s?:o !}",
- "name", &alsaMap->ctl.name,
- "numid", &alsaMap->ctl.numid,
- "value", &alsaMap->ctl.value,
- "create", &createAlsaCtlJ)) {
- AFB_API_ERROR(apiHandle, "Parsing error, alsa json should only contains [name]|[numid]||[value]|[create] in:\n-- %s", json_object_get_string(alsaJ));
- return -2;
- }
-
- if(createAlsaCtlJ) {
- alsaMap->ctl.alsaCtlCreation = &alsaMap->ctl.alsaCtlProperties;
-
- if(wrap_json_unpack(createAlsaCtlJ,
- "{s:s s:i s:i s:i s:i !}",
- "type", &typename,
- "count", &alsaMap->ctl.alsaCtlCreation->count,
- "minval", &alsaMap->ctl.alsaCtlCreation->minval,
- "maxval", &alsaMap->ctl.alsaCtlCreation->maxval,
- "step", &alsaMap->ctl.alsaCtlCreation->step)) {
- AFB_API_ERROR(apiHandle, "Parsing error, alsa creation json should only contains [type]|[count]|[minval]|[maxval]|[step] in:\n-- %s", json_object_get_string(alsaJ));
- return -3;
- }
-
- if(typename && (alsaMap->ctl.alsaCtlCreation->type = HalCtlsMapsAlsaTypeToEnum(typename)) == SND_CTL_ELEM_TYPE_NONE) {
- AFB_API_ERROR(apiHandle, "Couldn't get alsa type from string %s in:\n-- %s", typename, json_object_get_string(alsaJ));
- return -4;
- }
-
- if(! alsaMap->ctl.name)
- alsaMap->ctl.name = (char *) alsaMap->uid;
- }
- else if(alsaMap->ctl.name && alsaMap->ctl.numid > 0) {
- AFB_API_ERROR(apiHandle,
- "Can't have both a control name (%s) and a control uid (%i) in alsa object:\n-- %s",
- alsaMap->ctl.name,
- alsaMap->ctl.numid,
- json_object_get_string(alsaJ));
- return -5;
- }
- else if(! alsaMap->ctl.name && alsaMap->ctl.numid <= 0) {
- AFB_API_ERROR(apiHandle,
- "Need at least a control name or a control uid in alsa object:\n-- %s",
- json_object_get_string(alsaJ));
- return -6;
- }
-
- if(action)
- alsaMap->actionJ = AlsaMapJ;
-
- return 0;
-}
-
-int HalCtlsHandleOneHalMapObject(afb_api_t apiHandle, char *cardId, struct CtlHalAlsaMap *alsaMap)
-{
- int err;
-
- json_object *valueJ, *convertedValueJ = NULL;
-
- if(! (alsaMap->alsaControlEvent = afb_api_make_event(apiHandle, alsaMap->uid))) {
- AFB_API_ERROR(apiHandle,
- "Didn't succeed to create event for current alsa control to load action using alsa object:\n-- %s",
- json_object_get_string(alsaMap->actionJ));
- return -1;
- }
-
- if(alsaMap->ctl.alsaCtlCreation) {
- if(HalCtlsCreateAlsaCtl(apiHandle, cardId, &alsaMap->ctl)) {
- AFB_API_ERROR(apiHandle, "An error happened when trying to create a new alsa control");
- return -2;
- }
- }
- else if(HalCtlsUpdateAlsaCtlProperties(apiHandle, cardId, &alsaMap->ctl)) {
- AFB_API_ERROR(apiHandle, "An error happened when trying to get existing alsa control info");
- return -3;
- }
-
- if(alsaMap->ctl.value) {
- // TBD JAI : handle alsa controls type
- valueJ = json_object_new_int(alsaMap->ctl.value);
- err = 0;
-
- if(HalCtlsConvertJsonValues(apiHandle, &alsaMap->ctl.alsaCtlProperties, valueJ, &convertedValueJ, CONVERSION_NORMALIZED_TO_ALSACORE)) {
- AFB_API_ERROR(apiHandle, "Error when trying to convert initiate value json '%s'", json_object_get_string(valueJ));
- err = -4;
- }
- else if(HalCtlsSetAlsaCtlValue(apiHandle, cardId, alsaMap->ctl.numid, convertedValueJ)) {
- AFB_API_ERROR(apiHandle,
- "Error while trying to set initial value on alsa control %i, device '%s', value '%s'",
- alsaMap->ctl.numid,
- cardId,
- json_object_get_string(valueJ));
- err = -5;
- }
-
- json_object_put(valueJ);
-
- if(convertedValueJ)
- json_object_put(convertedValueJ);
-
- if(err)
- return err;
- }
-
- if(alsaMap->actionJ) {
- alsaMap->action = calloc(1, sizeof(CtlActionT));
- if(ActionLoadOne(apiHandle, alsaMap->action, alsaMap->actionJ, 0)) {
- AFB_API_ERROR(apiHandle,
- "Didn't succeed to load action using alsa object:\n-- %s",
- json_object_get_string(alsaMap->actionJ));
- return -6;
- }
- }
-
- if(afb_api_add_verb(apiHandle, alsaMap->uid, alsaMap->info, HalCtlsActionOnAlsaCtl, (void *) alsaMap, NULL, 0, 0)) {
- AFB_API_ERROR(apiHandle,
- "Didn't succeed to create verb for current alsa control to load action using alsa object:\n-- %s",
- json_object_get_string(alsaMap->actionJ));
- return -7;
- }
-
- return 0;
-}
-
-int HalCtlsProcessAllHalMap(afb_api_t apiHandle, json_object *AlsaMapJ, struct CtlHalAlsaMapT *currentCtlHalAlsaMapT)
-{
- int idx, err = 0;
-
- struct CtlHalAlsaMap *ctlMaps;
-
- json_type alsaMapType;
-
- alsaMapType = json_object_get_type(AlsaMapJ);
- switch(alsaMapType) {
- case json_type_array:
- currentCtlHalAlsaMapT->ctlsCount = (unsigned int) json_object_array_length(AlsaMapJ);
- break;
-
- case json_type_object:
- currentCtlHalAlsaMapT->ctlsCount = 1;
- break;
-
- default:
- currentCtlHalAlsaMapT->ctlsCount = 0;
- currentCtlHalAlsaMapT->ctls = NULL;
- AFB_API_WARNING(apiHandle, "Couldn't get content of 'halmap' section in:\n-- %s", json_object_get_string(AlsaMapJ));
- return -1;
- }
-
- ctlMaps = calloc(currentCtlHalAlsaMapT->ctlsCount, sizeof(struct CtlHalAlsaMap));
-
- for(idx = 0; idx < currentCtlHalAlsaMapT->ctlsCount; idx++)
- err += HalCtlsProcessOneHalMapObject(apiHandle, &ctlMaps[idx], alsaMapType == json_type_array ? json_object_array_get_idx(AlsaMapJ, idx) : AlsaMapJ);
-
- currentCtlHalAlsaMapT->ctls = ctlMaps;
-
- return err;
-}
-
-int HalCtlsHandleAllHalMap(afb_api_t apiHandle, int sndCardId, struct CtlHalAlsaMapT *currentCtlHalAlsaMapT)
-{
- int idx, err = 0;
-
- char cardIdString[6];
-
- snprintf(cardIdString, 6, "hw:%i", sndCardId);
-
- HalCtlsSubscribeToAlsaCardEvent(apiHandle, cardIdString);
-
- for(idx = 0; idx < currentCtlHalAlsaMapT->ctlsCount; idx++)
- err += HalCtlsHandleOneHalMapObject(apiHandle, cardIdString, &currentCtlHalAlsaMapT->ctls[idx]);
-
- return err;
-}
-
-int HalCtlsHalMapConfig(afb_api_t apiHandle, CtlSectionT *section, json_object *AlsaMapJ)
-{
- CtlConfigT *ctrlConfig;
- struct SpecificHalData *currentHalData;
-
- if(! (ctrlConfig = (CtlConfigT *) afb_api_get_userdata(apiHandle)))
- return -1;
-
- currentHalData = (struct SpecificHalData *) getExternalData(ctrlConfig);
- if(! currentHalData)
- return -2;
-
- if(AlsaMapJ) {
- currentHalData->ctlHalSpecificData->ctlHalAlsaMapT = calloc(1, sizeof(struct CtlHalAlsaMapT));
-
- if(HalCtlsProcessAllHalMap(apiHandle, AlsaMapJ, currentHalData->ctlHalSpecificData->ctlHalAlsaMapT)) {
- AFB_API_ERROR(apiHandle, "Failed to process 'halmap' section");
- return -3;
- }
- }
- else if(currentHalData->status == HAL_STATUS_UNAVAILABLE) {
- AFB_API_WARNING(apiHandle, "Hal is unavailable, 'halmap' section data can't be handle");
- return 1;
- }
- else if(currentHalData->sndCardId < 0) {
- AFB_API_ERROR(apiHandle, "Hal alsa card id is not valid, 'halmap' section data can't be handle");
- return -6;
- }
- else if(! currentHalData->ctlHalSpecificData->ctlHalAlsaMapT) {
- AFB_API_WARNING(apiHandle, "'halmap' section data is empty");
- return 2;
- }
- else if(! (currentHalData->ctlHalSpecificData->ctlHalAlsaMapT->ctlsCount > 0)) {
- AFB_API_WARNING(apiHandle, "No alsa controls defined in 'halmap' section");
- return 3;
- }
- else if(HalCtlsHandleAllHalMap(apiHandle, currentHalData->sndCardId, currentHalData->ctlHalSpecificData->ctlHalAlsaMapT)) {
- AFB_API_ERROR(apiHandle, "Failed to handle 'halmap' section");
- return -9;
- }
-
- return 0;
-}
-
-/*******************************************************************************
- * HAL controllers verbs functions *
- ******************************************************************************/
-
-json_object *HalCtlsGetJsonArrayForMixerDataTable(afb_api_t apiHandle, struct CtlHalMixerData **mixerDataList, enum MixerDataType dataType)
-{
- json_object *mixerDataArrayJ, *currentMixerDataJ;
-
- struct CtlHalMixerData *currentMixerData;
-
- if(! apiHandle) {
- AFB_API_ERROR(apiHandle, "Can't get current hal controller api handle");
- return NULL;
- }
-
- mixerDataArrayJ = json_object_new_array();
- if(! mixerDataArrayJ) {
- AFB_API_ERROR(apiHandle, "Can't generate json mixer data array");
- return NULL;
- }
-
- currentMixerData = *mixerDataList;
-
- while(currentMixerData) {
- switch(dataType) {
- case MIXER_DATA_STREAMS:
- wrap_json_pack(&currentMixerDataJ,
- "{s:s s:s}",
- "name", currentMixerData->verb,
- "cardId", currentMixerData->streamCardId);
- break;
-
- case MIXER_DATA_PLAYBACKS:
- case MIXER_DATA_CAPTURES :
- wrap_json_pack(&currentMixerDataJ,
- "{s:s s:s}",
- "name", currentMixerData->verb,
- "mixer-name", currentMixerData->verbToCall,
- "uid", currentMixerData->streamCardId ? currentMixerData->streamCardId : "none");
- break;
-
- default:
- json_object_put(mixerDataArrayJ);
- return NULL;
- }
- json_object_array_add(mixerDataArrayJ, currentMixerDataJ);
-
- currentMixerData = currentMixerData->next;
- }
-
- return mixerDataArrayJ;
-}
-
-json_object *HalCtlsGetJsonArrayForControls(afb_api_t apiHandle, struct CtlHalAlsaMapT *currentAlsaMapDataT)
-{
- unsigned int idx;
-
- json_object *alsaMapDataArray, *currentAlsaMapData;
-
- if(! apiHandle) {
- AFB_API_ERROR(apiHandle, "Can't get current hal controller api handle");
- return NULL;
- }
-
- if(! currentAlsaMapDataT) {
- AFB_API_ERROR(apiHandle, "Can't get Alsa map data table to handle");
- return NULL;
- }
-
- if(! (alsaMapDataArray = json_object_new_array())) {
- AFB_API_ERROR(apiHandle, "Can't generate json mixer data array");
- return NULL;
- }
-
- for(idx = 0; idx < currentAlsaMapDataT->ctlsCount; idx++) {
- wrap_json_pack(&currentAlsaMapData,
- "{s:s s:s}",
- "name", currentAlsaMapDataT->ctls[idx].uid,
- "info", currentAlsaMapDataT->ctls[idx].info ? currentAlsaMapDataT->ctls[idx].info : "none");
-
- json_object_array_add(alsaMapDataArray, currentAlsaMapData);
- }
-
- return alsaMapDataArray;
-}
-
-void HalCtlsInfo(afb_req_t request)
-{
- char *apiToCall, *returnedError = NULL, *returnedInfo = NULL;
-
- afb_api_t apiHandle;
- CtlConfigT *ctrlConfig;
-
- struct SpecificHalData *currentCtlHalData;
-
- json_object *requestJson, *toReturnJ = NULL, *requestAnswer, *streamsArray, *playbacksArray, *capturesArray, *controlsArray;
-
- 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;
- }
-
- if(! (currentCtlHalData = (struct SpecificHalData *) getExternalData(ctrlConfig))) {
- afb_req_fail(request, "hal_controller_data", "Can't get current hal controller data");
- return;
- }
-
- if(! (requestJson = afb_req_json(request))) {
- AFB_REQ_NOTICE(request, "Can't get request json");
- }
- else if(json_object_is_type(requestJson, json_type_object) && json_object_get_object(requestJson)->count > 0) {
- apiToCall = currentCtlHalData->ctlHalSpecificData->mixerApiName;
- if(! apiToCall) {
- afb_req_fail(request, "mixer_api", "Can't get mixer api");
- return;
- }
-
- if(HalCtlsGetInfoFromMixer(apiHandle, apiToCall, requestJson, &toReturnJ, &returnedError, &returnedInfo)) {
- afb_req_fail_f(request,
- "mixer_info",
- "Call to mixer info verb didn't succeed with status '%s' and info '%s'",
- returnedError ? returnedError : "not returned",
- returnedInfo ? returnedInfo : "not returned");
- return;
- }
-
- afb_req_success(request, toReturnJ, "Mixer requested data");
- return;
- }
-
- if(! (streamsArray = HalCtlsGetJsonArrayForMixerDataTable(apiHandle,
- &currentCtlHalData->ctlHalSpecificData->ctlHalStreamsData,
- MIXER_DATA_STREAMS))) {
- afb_req_fail(request, "streams_data", "Didn't succeed to generate streams data array");
- return;
- }
-
- if(! (playbacksArray = HalCtlsGetJsonArrayForMixerDataTable(apiHandle,
- &currentCtlHalData->ctlHalSpecificData->ctlHalPlaybacksData,
- MIXER_DATA_PLAYBACKS))) {
- afb_req_fail(request, "playbacks_data", "Didn't succeed to generate playbacks data array");
- return;
- }
-
- if(! (capturesArray = HalCtlsGetJsonArrayForMixerDataTable(apiHandle,
- &currentCtlHalData->ctlHalSpecificData->ctlHalCapturesData,
- MIXER_DATA_CAPTURES))) {
- afb_req_fail(request, "captures_data", "Didn't succeed to generate captures data array");
- return;
- }
-
- if(! (controlsArray = HalCtlsGetJsonArrayForControls(apiHandle,
- currentCtlHalData->ctlHalSpecificData->ctlHalAlsaMapT))) {
- afb_req_fail(request, "controls_data", "Didn't succeed to generate controls data array");
- return;
- }
-
- wrap_json_pack(&requestAnswer,
- "{s:o s:o s:o s:o}",
- "streams", streamsArray,
- "playbacks", playbacksArray,
- "captures", capturesArray,
- "controls", controlsArray);
-
- afb_req_success(request, requestAnswer, "Requested data");
-}
-
-void HalCtlsSubscribeUnsubscribe(afb_req_t request, enum SubscribeUnsubscribeType subscribeUnsubscribeType)
-{
- int arrayIdx, searchIdx, count, subscriptionFound, subscriptionDoneNb = 0;
-
- char *currentSubscriptionString;
-
- afb_api_t apiHandle;
- CtlConfigT *ctrlConfig;
-
- struct SpecificHalData *currentCtlHalData;
- struct CtlHalMixerData *currentStreamData;
- struct CtlHalAlsaMapT *halAlsaMapT;
-
- json_object *requestJson, *requestedSubscriptionsJ, *requestedSubscriptionJ = NULL;
- json_type requestJsonType;
-
- 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;
- }
-
- if(! (currentCtlHalData = (struct SpecificHalData *) getExternalData(ctrlConfig))) {
- afb_req_fail(request, "hal_controller_data", "Can't get current hal controller data");
- return;
- }
-
- if(! currentCtlHalData->ctlHalSpecificData) {
- afb_req_fail(request, "hal_controller_data", "Can't get current hal specific data");
- return;
- }
-
- halAlsaMapT = currentCtlHalData->ctlHalSpecificData->ctlHalAlsaMapT;
-
- if(! (requestJson = afb_req_json(request))) {
- afb_req_fail(request, "request_json", "Can't get request json");
- return;
- }
-
- if(wrap_json_unpack(requestJson, "{s:o}", "events", &requestedSubscriptionsJ)) {
- afb_req_fail(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_req_fail(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_req_fail_f(request, "request_json", "Request json number %i in array invalid", arrayIdx);
- return;
- }
- }
-
- subscriptionFound = 0;
- currentSubscriptionString = (char *) json_object_get_string(requestedSubscriptionJ);
-
- if(! strcasecmp(currentSubscriptionString, HAL_STREAM_UPDATES_EVENT_NAME)) {
- if(currentCtlHalData->ctlHalSpecificData->streamUpdates &&
- subscribeUnsubscribeType == SUBSCRIPTION &&
- afb_req_subscribe(request, currentCtlHalData->ctlHalSpecificData->streamUpdates)) {
- afb_req_fail_f(request,
- "request_stream_list_updates_event",
- "Error while trying to subscribe to stream list updates event");
- return;
- }
- else if(currentCtlHalData->ctlHalSpecificData->streamUpdates &&
- subscribeUnsubscribeType == UNSUBSCRIPTION &&
- afb_req_unsubscribe(request, currentCtlHalData->ctlHalSpecificData->streamUpdates)) {
- afb_req_fail_f(request,
- "request_stream_list_updates_event",
- "Error while trying to unsubscribe to stream list updates event");
- return;
- }
-
- subscriptionFound = 1;
- subscriptionDoneNb++;
- }
-
- currentStreamData = currentCtlHalData->ctlHalSpecificData->ctlHalStreamsData;
- while(currentStreamData &&
- (! subscriptionFound)) {
- if(! strcasecmp(currentSubscriptionString, currentStreamData->verb)) {
- if(currentStreamData->event &&
- subscribeUnsubscribeType == SUBSCRIPTION &&
- afb_req_subscribe(request, currentStreamData->event)) {
- afb_req_fail_f(request,
- "request_stream_event",
- "Error while trying to subscribe to %s stream events",
- currentStreamData->verb);
- return;
- }
- else if(currentStreamData->event &&
- subscribeUnsubscribeType == UNSUBSCRIPTION &&
- afb_req_unsubscribe(request, currentStreamData->event)) {
- afb_req_fail_f(request,
- "request_stream_event",
- "Error while trying to unsubscribe to %s stream events",
- currentStreamData->verb);
- return;
- }
-
- subscriptionFound = 1;
- subscriptionDoneNb++;
-
- break;
- }
-
- currentStreamData = currentStreamData->next;
- }
-
- searchIdx = 0;
- while((searchIdx < (halAlsaMapT ? halAlsaMapT->ctlsCount : 0)) &&
- (! subscriptionFound)) {
- if(! strcasecmp(currentSubscriptionString, halAlsaMapT->ctls[searchIdx].uid)) {
- if(halAlsaMapT->ctls[searchIdx].alsaControlEvent &&
- subscribeUnsubscribeType == SUBSCRIPTION &&
- afb_req_subscribe(request, halAlsaMapT->ctls[searchIdx].alsaControlEvent)) {
- afb_req_fail_f(request,
- "request_control_event",
- "Error while trying to subscribe to %s halmap controls events",
- halAlsaMapT->ctls[searchIdx].uid);
- return;
- }
- else if(halAlsaMapT->ctls[searchIdx].alsaControlEvent &&
- subscribeUnsubscribeType == UNSUBSCRIPTION &&
- afb_req_unsubscribe(request, halAlsaMapT->ctls[searchIdx].alsaControlEvent)) {
- afb_req_fail_f(request,
- "request_stream_event",
- "Error while trying to unsubscribe to %s halmap controls events",
- halAlsaMapT->ctls[searchIdx].uid);
- return;
- }
-
- subscriptionFound = 1;
- subscriptionDoneNb++;
-
- break;
- }
-
- searchIdx++;
- }
- }
-
- if(subscriptionDoneNb == 0)
- afb_req_fail_f(request,
- "events_not_found",
- "%s failed, event(s) were not found",
- subscribeUnsubscribeType == SUBSCRIPTION ? "Subscription" : "Unsubscription");
- if(subscriptionDoneNb == count)
- afb_req_success_f(request,
- json_object_new_int(subscriptionDoneNb),
- "%s succeed for all the %i events requested",
- subscribeUnsubscribeType == SUBSCRIPTION ? "Subscription" : "Unsubscription",
- subscriptionDoneNb);
- else if(subscriptionDoneNb < count)
- afb_req_success_f(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_req_success_f(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_req_t request)
-{
- HalCtlsSubscribeUnsubscribe(request, SUBSCRIPTION);
-}
-
-void HalCtlsUnsubscribe(afb_req_t request)
-{
- HalCtlsSubscribeUnsubscribe(request, UNSUBSCRIPTION);
-} \ No newline at end of file