summaryrefslogtreecommitdiffstats
path: root/src/ahl-config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ahl-config.c')
-rw-r--r--src/ahl-config.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/ahl-config.c b/src/ahl-config.c
new file mode 100644
index 0000000..432910f
--- /dev/null
+++ b/src/ahl-config.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2017 "Audiokinetic Inc"
+ * Author Francois Thibault <fthibault@audiokinetic.com>
+ *
+ * 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 <json-c/json.h>
+#include "wrap-json.h"
+
+#include "ahl-binding.h"
+
+// TODO: Term() to free all allocs upon exit...
+
+extern AHLCtxT g_AHLCtx;
+
+PUBLIC int ParseHLBConfig() {
+ char * versionStr = NULL;
+ json_object * jAudioRoles = NULL;
+ json_object * jHALList = NULL;
+ json_object * jStateList = NULL;
+
+ // TODO: This should be retrieve from binding startup arguments
+ char configfile_path[256];
+ sprintf(configfile_path, "%s/opt/config/ahl-config.json", getenv("HOME"));
+ AFB_INFO("High-level config file -> %s\n", configfile_path);
+
+ // Open configuration file
+ json_object *config_JFile=json_object_from_file(configfile_path);
+ if(config_JFile == NULL)
+ {
+ AFB_ERROR("Error: Can't open configuration file -> %s",configfile_path);
+ return 1;
+ }
+
+ int err = wrap_json_unpack(config_JFile, "{s:s,s:o,s:o,s:o}", "version", &versionStr,"audio_roles",&jAudioRoles,"hal_list",&jHALList,"state_list",&jStateList);
+ if (err) {
+ AFB_ERROR("Invalid configuration file -> %s", configfile_path);
+ return 1;
+ }
+
+ // Parse and populate list of known states
+ g_AHLCtx.pDefaultStatesHT = g_hash_table_new(g_str_hash, g_str_equal);
+ int iStateListLength = json_object_array_length(jStateList);
+ for ( int i = 0; i < iStateListLength; i++)
+ {
+ char * pStateName = NULL;
+ char * pStateVal = NULL;
+ json_object * jStateobject = json_object_array_get_idx(jStateList,i);
+ err = wrap_json_unpack(jStateobject, "{s:s,s:s}", "name", &pStateName,"default_val",&pStateVal);
+ if (err) {
+ AFB_ERROR("Invalid state object -> %s", json_object_get_string(jStateobject));
+ return 1;
+ }
+
+ g_hash_table_insert(g_AHLCtx.pDefaultStatesHT, pStateName, pStateVal);
+ }
+
+ int iHALListLength = json_object_array_length(jHALList);
+ int iNumberOfRoles = json_object_array_length(jAudioRoles);
+ // Dynamically allocated based on number or roles found
+ g_AHLCtx.pHALList = g_array_sized_new(FALSE, TRUE, sizeof(GString), iHALListLength);
+ g_AHLCtx.policyCtx.pRolePriority = g_array_sized_new(FALSE, TRUE, sizeof(int), iNumberOfRoles);
+ g_AHLCtx.policyCtx.pAudioRoles = g_array_sized_new(FALSE, TRUE, sizeof(GString), iNumberOfRoles);
+ g_AHLCtx.policyCtx.pSourceEndpoints = g_ptr_array_sized_new(iNumberOfRoles);
+ g_AHLCtx.policyCtx.pSinkEndpoints = g_ptr_array_sized_new(iNumberOfRoles);
+ g_AHLCtx.policyCtx.iNumberRoles = iNumberOfRoles;
+
+ for (unsigned int i = 0; i < iHALListLength; i++)
+ {
+ char * pHAL = NULL;
+ json_object * jHAL = json_object_array_get_idx(jHALList,i);
+ pHAL = (char *)json_object_get_string(jHAL);
+ GString * gHALName = g_string_new( pHAL );
+ g_array_append_val( g_AHLCtx.pHALList, *gHALName );
+
+ // Set dependency on HAL
+ err = afb_daemon_require_api_v2(pHAL,1) ;
+ if( err != 0 )
+ {
+ AFB_ERROR("Audio high level API could not set dependenvy on API: %s",pHAL);
+ return 1;
+ }
+ }
+
+ for (unsigned int i = 0; i < iNumberOfRoles; i++)
+ {
+ int priority = 0;
+ json_object * jAudioRole = json_object_array_get_idx(jAudioRoles,i);
+ json_object * jOutputDevices = NULL;
+ json_object * jInputDevices = NULL;
+ char * pRoleName = NULL;
+ int iNumOutDevices = 0;
+ int iNumInDevices = 0;
+
+ err = wrap_json_unpack(jAudioRole, "{s:s,s:i,s?o,s?o}", "name", &pRoleName,"priority",&priority,"output",&jOutputDevices,"input",&jInputDevices);
+ if (err) {
+ AFB_ERROR("Invalid audio role configuration : %s", json_object_to_json_string(jAudioRole));
+ return 1;
+ }
+
+ if (jOutputDevices)
+ iNumOutDevices = json_object_array_length(jOutputDevices);
+ if (jInputDevices)
+ iNumInDevices = json_object_array_length(jInputDevices);
+
+ GString * gRoleName = g_string_new( pRoleName );
+ g_array_append_val( g_AHLCtx.policyCtx.pAudioRoles, *gRoleName );
+ g_array_append_val( g_AHLCtx.policyCtx.pRolePriority, priority );
+
+ // Sources
+ GArray * pRoleSourceDeviceArray = g_array_new(FALSE, TRUE, sizeof(EndpointInfoT));
+ g_ptr_array_add(g_AHLCtx.policyCtx.pSourceEndpoints,pRoleSourceDeviceArray);
+ if (iNumInDevices) {
+ err = EnumerateSources(jInputDevices,i,pRoleName);
+ if (err) {
+ AFB_ERROR("Invalid input devices : %s", json_object_to_json_string(jInputDevices));
+ return 1;
+ }
+ }
+ GArray * pRoleSinkDeviceArray = g_array_new(FALSE, TRUE, sizeof(EndpointInfoT));
+ g_ptr_array_add(g_AHLCtx.policyCtx.pSinkEndpoints,pRoleSinkDeviceArray);
+ if (iNumOutDevices) {
+ err = EnumerateSinks(jOutputDevices,i,pRoleName);
+ if (err) {
+ AFB_ERROR("Invalid output devices : %s", json_object_to_json_string(jOutputDevices));
+ return 1;
+ }
+ }
+ }
+
+ // Build lists of all device URI referenced in config file (input/output)
+ AFB_DEBUG ("Audio high-level - Parse high-level audio configuration done");
+ return 0;
+}