aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/4a-internals-hal/4a-internals-hal-cb.c317
1 files changed, 317 insertions, 0 deletions
diff --git a/src/4a-internals-hal/4a-internals-hal-cb.c b/src/4a-internals-hal/4a-internals-hal-cb.c
index 10ed6c0..d0e4909 100644
--- a/src/4a-internals-hal/4a-internals-hal-cb.c
+++ b/src/4a-internals-hal/4a-internals-hal-cb.c
@@ -457,6 +457,323 @@ int InternalHalHalMapConfig(afb_api_t apiHandle, CtlSectionT *section, json_obje
}
/*******************************************************************************
+ * Internals HAL - 'haldependencies' section parsing/handling functions *
+ ******************************************************************************/
+
+json_type InternalHalDependencyGetExpectedContentTypeFromKey(char *key)
+{
+ if(! key)
+ return json_type_null;
+
+ if(! strcmp(key, "cardNb") ||
+ ! strcmp(key, "playbackDeviceNb"))
+ return json_type_int;
+
+ if(! strcmp(key, "cardPath") ||
+ ! strcmp(key, "cardId") ||
+ ! strcmp(key, "cardShortName") ||
+ ! strcmp(key, "cardLongName") ||
+ ! strcmp(key, "cardDriver") ||
+ ! strcmp(key, "cardMixerName") ||
+ ! strcmp(key, "cardComponents") ||
+ ! strcmp(key, "playbackDeviceId") ||
+ ! strcmp(key, "playbackDeviceName"))
+ return json_type_string;
+
+ if(! strcmp(key, "AnyOf"))
+ return json_type_object;
+
+ return json_type_null;
+}
+
+int InternalHalDependencyIsObjectToAddValid(json_object *objectToAddJ)
+{
+ struct json_object_iterator currentPropertyToAdd, lastPropertyToAdd;
+ json_type currentPropertyValueExpectedType;
+
+ if(! objectToAddJ)
+ return -1;
+
+ currentPropertyToAdd = json_object_iter_begin(objectToAddJ);
+ lastPropertyToAdd = json_object_iter_end(objectToAddJ);
+
+ while(! json_object_iter_equal(&currentPropertyToAdd, &lastPropertyToAdd)) {
+ currentPropertyValueExpectedType = InternalHalDependencyGetExpectedContentTypeFromKey((char *) json_object_iter_peek_name(&currentPropertyToAdd));
+ if(! json_object_is_type(json_object_iter_peek_value(&currentPropertyToAdd),
+ currentPropertyValueExpectedType))
+ return -2;
+
+ json_object_iter_next(&currentPropertyToAdd);
+ }
+
+ return 0;
+}
+
+int InternalHalProcessOneDependencyProperty(afb_api_t apiHandle, char *key, json_object *valueJ, json_object **deviceToProbeRequestGenerationJ)
+{
+ int valueIdx, previouslyGeneratedRequestIdx, valueCount, previouslyGeneratedRequestCount;
+
+ json_object *previouslyGeneratedRequestJ, *updatedGeneratedRequestJ, *currentValueJ, *objectToBeefUpJ;
+ json_type expectedContentType, contentType;
+
+ if(! key || ! valueJ || ! deviceToProbeRequestGenerationJ) {
+ AFB_API_ERROR(apiHandle, "Invalid argument(s)");
+ return -1;
+ }
+
+ previouslyGeneratedRequestJ = *deviceToProbeRequestGenerationJ;
+ if(! previouslyGeneratedRequestJ) {
+ previouslyGeneratedRequestCount = 0;
+ }
+ else if(! json_object_is_type(previouslyGeneratedRequestJ, json_type_array)) {
+ AFB_API_ERROR(apiHandle,
+ "Invalid previously generated request (not an array : '%s')",
+ json_object_get_string(previouslyGeneratedRequestJ));
+ return -2;
+ }
+ else {
+ previouslyGeneratedRequestCount = (int) json_object_array_length(previouslyGeneratedRequestJ);
+ }
+
+ expectedContentType = InternalHalDependencyGetExpectedContentTypeFromKey(key);
+ if(expectedContentType == json_type_null) {
+ AFB_API_ERROR(apiHandle, "Unrecognized key '%s'", key);
+ return -3;
+ }
+
+ contentType = json_object_get_type(valueJ);
+ switch(contentType) {
+ case json_type_int:
+ case json_type_string:
+ valueCount = 1;
+ break;
+
+ case json_type_array:
+ valueCount = (int) json_object_array_length(valueJ);
+ break;
+
+ default:
+ AFB_API_ERROR(apiHandle,
+ "Value doesn't have the expected type (value: '%s')",
+ json_object_get_string(valueJ));
+ return -4;
+ }
+
+ updatedGeneratedRequestJ = json_object_new_array();
+ if(! updatedGeneratedRequestJ) {
+ AFB_API_ERROR(apiHandle, "Didn't succeed to allocate updated request json array");
+ return -5;
+ }
+
+ for(valueIdx = 0; valueIdx < valueCount; valueIdx++) {
+ if(contentType == json_type_array)
+ currentValueJ = json_object_array_get_idx(valueJ, valueIdx);
+ else
+ currentValueJ = valueJ;
+
+ if(! json_object_is_type(currentValueJ, expectedContentType)) {
+ AFB_API_ERROR(apiHandle,
+ "Current value '%s' (index %i in value array) does not have the expected type, "
+ "won't be able to process property (key '%s')",
+ json_object_get_string(currentValueJ),
+ valueIdx,
+ key);
+ json_object_put(updatedGeneratedRequestJ);
+ return -6;
+ }
+
+ previouslyGeneratedRequestIdx = 0;
+ do {
+ if(! previouslyGeneratedRequestCount)
+ objectToBeefUpJ = json_object_new_object();
+ else
+ objectToBeefUpJ = wrap_json_clone(json_object_array_get_idx(previouslyGeneratedRequestJ, previouslyGeneratedRequestIdx));
+
+ if(! objectToBeefUpJ) {
+ AFB_API_ERROR(apiHandle, "Didn't succeed to allocate/clone object to beef up json object");
+ json_object_put(objectToBeefUpJ);
+ json_object_put(updatedGeneratedRequestJ);
+ return -7;
+ }
+
+ if(! json_object_is_type(currentValueJ, json_type_object)) {
+ json_object_object_add(objectToBeefUpJ, key, wrap_json_clone(currentValueJ));
+ }
+ else if(! InternalHalDependencyIsObjectToAddValid(currentValueJ)) {
+ wrap_json_object_add(objectToBeefUpJ, wrap_json_clone(currentValueJ));
+ }
+ else {
+ AFB_API_ERROR(apiHandle,
+ "Object '%s' is not valid",
+ json_object_get_string(currentValueJ));
+ json_object_put(objectToBeefUpJ);
+ json_object_put(updatedGeneratedRequestJ);
+ return -8;
+ }
+
+ json_object_array_add(updatedGeneratedRequestJ, objectToBeefUpJ);
+
+ previouslyGeneratedRequestIdx++;
+ } while(previouslyGeneratedRequestIdx < previouslyGeneratedRequestCount);
+ }
+
+ *deviceToProbeRequestGenerationJ = updatedGeneratedRequestJ;
+ json_object_put(previouslyGeneratedRequestJ);
+
+ return 0;
+}
+
+int InternalHalProcessOneHalDependency(afb_api_t apiHandle, json_object *DependencyJ, struct InternalHalProbedDevice *halDeviceToProbe)
+{
+ int ret;
+
+ json_object *dependencyUidJ, *dependencyClassJ;
+ struct json_object_iterator dependencyCurrentProperty, dependencyLastProperty;
+
+ if(! apiHandle || ! DependencyJ || ! halDeviceToProbe) {
+ AFB_API_ERROR(apiHandle, "Invalid argument(s)");
+ return -1;
+ }
+
+ if(! json_object_object_get_ex(DependencyJ, "uid", &dependencyUidJ)) {
+ AFB_API_ERROR(apiHandle,
+ "No dependency 'uid' has been specified, won't be able to process it ('%s')",
+ json_object_get_string(DependencyJ));
+ return -2;
+ }
+ else if(! json_object_is_type(dependencyUidJ, json_type_string)) {
+ AFB_API_ERROR(apiHandle,
+ "Specified dependency 'uid' is not a string ('%s')",
+ json_object_get_string(dependencyUidJ));
+ return -3;
+ }
+
+ halDeviceToProbe->uid = strdup(json_object_get_string(dependencyUidJ));
+ if(! halDeviceToProbe->uid) {
+ AFB_API_ERROR(apiHandle, "Didn't succeed to store (allocate) dependency 'uid' string");
+ return -4;
+ }
+
+ if(! json_object_object_get_ex(DependencyJ, "class", &dependencyClassJ)) {
+ AFB_API_NOTICE(apiHandle,
+ "No class has been specified for dependency with uid:'%s', will be considered as static",
+ halDeviceToProbe->uid);
+ halDeviceToProbe->deviceClass = STATIC_PROBED_DEVICE;
+ }
+ else if(! json_object_is_type(dependencyClassJ, json_type_string)) {
+ AFB_API_ERROR(apiHandle,
+ "Specified dependency class is not a string ('%s')",
+ json_object_get_string(dependencyClassJ));
+ return -5;
+ }
+ else {
+ halDeviceToProbe->deviceClass = HalUtlGetProbedDeviceClassFromString((char *) json_object_get_string(dependencyClassJ));
+ if(halDeviceToProbe->deviceClass == INVALID_PROBED_DEVICE) {
+ AFB_API_ERROR(apiHandle,
+ "Specified device class is unknown ('%s')",
+ json_object_get_string(dependencyClassJ));
+ return -6;
+ }
+ }
+
+ dependencyCurrentProperty = json_object_iter_begin(DependencyJ);
+ dependencyLastProperty = json_object_iter_end(DependencyJ);
+
+ while(! json_object_iter_equal(&dependencyCurrentProperty, &dependencyLastProperty)) {
+ if(! strcmp("uid", json_object_iter_peek_name(&dependencyCurrentProperty)) ||
+ ! strcmp("class", json_object_iter_peek_name(&dependencyCurrentProperty))) {
+ json_object_iter_next(&dependencyCurrentProperty);
+ continue;
+ }
+
+ ret = InternalHalProcessOneDependencyProperty(apiHandle,
+ (char *) json_object_iter_peek_name(&dependencyCurrentProperty),
+ json_object_iter_peek_value(&dependencyCurrentProperty),
+ &halDeviceToProbe->requestedDeviceJ);
+ if(ret) {
+ AFB_API_ERROR(apiHandle,
+ "Error %i while processing property with key '%s' and value '%s' in dependency '%s'",
+ ret,
+ json_object_iter_peek_name(&dependencyCurrentProperty),
+ json_object_get_string(json_object_iter_peek_value(&dependencyCurrentProperty)),
+ json_object_get_string(DependencyJ));
+ return -7;
+ }
+
+ json_object_iter_next(&dependencyCurrentProperty);
+ }
+
+ return 0;
+}
+
+int InternalHalProcessAllHalDependencies(afb_api_t apiHandle, json_object *DependenciesJ, struct InternalHalProbedDevice **halDevicesToProbeList)
+{
+ int idx, dependenciesCount, ret;
+
+ struct InternalHalProbedDevice *currentDeviceToProbe;
+
+ json_type dependenciesJType;
+ json_object *currentDependencyJ;
+
+ if(! apiHandle || ! DependenciesJ || ! halDevicesToProbeList) {
+ AFB_API_ERROR(apiHandle, "Invalid argument(s)");
+ return -1;
+ }
+
+ dependenciesJType = json_object_get_type(DependenciesJ);
+ switch(dependenciesJType) {
+ case json_type_object:
+ dependenciesCount = 1;
+ break;
+
+ case json_type_array:
+ dependenciesCount = (int) json_object_array_length(DependenciesJ);
+ break;
+
+ default:
+ AFB_API_ERROR(apiHandle,
+ "'haldependencies' section is malformed, won't be able to handle it ('haldependencies' : '%s')",
+ json_object_get_string(DependenciesJ));
+ return -2;
+ }
+
+ for(idx = 0; idx < dependenciesCount; idx++) {
+ if(dependenciesJType == json_type_array)
+ currentDependencyJ = json_object_array_get_idx(DependenciesJ, idx);
+ else
+ currentDependencyJ = DependenciesJ;
+
+ if(! json_object_is_type(currentDependencyJ, json_type_object)) {
+ AFB_API_ERROR(apiHandle,
+ "Dependency ('%s') is not an object, section is malformed, won't be able to handle it ('haldependencies' : '%s')",
+ json_object_get_string(currentDependencyJ),
+ json_object_get_string(DependenciesJ));
+ HalUtlRemoveAllProbedDevicesFromList(halDevicesToProbeList);
+ return -3;
+ }
+
+ currentDeviceToProbe = HalUtlAddProbedDeviceToProbedDeviceList(halDevicesToProbeList);
+ if(! currentDeviceToProbe) {
+ AFB_API_ERROR(apiHandle, "Error when tried to add a device to probe into device to probe list");
+ HalUtlRemoveAllProbedDevicesFromList(halDevicesToProbeList);
+ return -4;
+ }
+
+ ret = InternalHalProcessOneHalDependency(apiHandle, currentDependencyJ, currentDeviceToProbe);
+ if(ret) {
+ AFB_API_ERROR(apiHandle,
+ "Error %i returned when tried to process '%s' dependency",
+ ret,
+ json_object_get_string(currentDependencyJ));
+ HalUtlRemoveAllProbedDevicesFromList(halDevicesToProbeList);
+ return -5;
+ }
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
* Internals HAL verbs functions *
******************************************************************************/