aboutsummaryrefslogtreecommitdiffstats
path: root/4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.c
diff options
context:
space:
mode:
Diffstat (limited to '4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.c')
-rw-r--r--4a-hal/4a-hal-controllers/4a-hal-controllers-mixer-handler.c266
1 files changed, 198 insertions, 68 deletions
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 <string.h>
#include <stdbool.h>
+#include <wrap-json.h>
+
#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", &currentStreamName)) {
- 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", &currentDataVerbName)) {
+ 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", &currentStreamCardId)) {
- 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", &currentStreamCardId)) {
+ 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(&currentDataVerbName[verbStart]);
+
+ if(afb_dynapi_add_verb(apiHandle,
+ currentMixerDataT->data[idx].verb,
+ "Stream action transferred to mixer",
+ HalCtlsActionOnCall,
+ (void *) &currentMixerDataT->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, &currentHalSpecificData->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, &currentHalSpecificData->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, &currentHalSpecificData->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, &currentCtlHalData->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;
}