From f29775f7da003bbadb44dd82d8b3974aa1e59274 Mon Sep 17 00:00:00 2001
From: Jonathan Aillet <jonathan.aillet@iot.bzh>
Date: Tue, 18 Jun 2019 18:00:13 +0200
Subject: Use of linked list for 'halmap' data

Use of linked list for 'halmap' data instead of a fixed array.
It uses the same mechanism already implemented for other linked list.

BUG-AGL: SPEC-2329

Change-Id: I2ff9c9a797a5547cd74f0240c5b7573a02c90781
Signed-off-by: Jonathan Aillet <jonathan.aillet@iot.bzh>
---
 lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c | 117 -------------------
 lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h |  19 ++--
 lib/4a-hal-utilities/4a-hal-utilities-data.c      | 133 +++++++++++++++++++++-
 lib/4a-hal-utilities/4a-hal-utilities-data.h      |  15 ++-
 lib/4a-hal-utilities/CMakeLists.txt               |   1 -
 5 files changed, 152 insertions(+), 133 deletions(-)
 delete mode 100644 lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c

(limited to 'lib')

diff --git a/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c b/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c
deleted file mode 100644
index 5d37c0a..0000000
--- a/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2019 "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 <wrap-json.h>
-
-#include <afb/afb-binding.h>
-
-#include "4a-hal-utilities-alsa-data.h"
-
-/*******************************************************************************
- *	Internal Hal - ALSA controls data handling functions		       *
- ******************************************************************************/
-
-json_object *HalUtGetJsonArrayForSpecificControl(afb_api_t apiHandle, struct InternalHalAlsaMap *currentAlsaMapData)
-{
-	int wrapRet;
-
-	json_object *currentAlsaMapDataJ;
-
-	if(! apiHandle) {
-		AFB_API_ERROR(apiHandle, "Can't get current internal hal api handle");
-		return NULL;
-	}
-
-	if(! currentAlsaMapData) {
-		AFB_API_ERROR(apiHandle, "ALSA control data to use to generate json object are empty");
-		return NULL;
-	}
-
-	wrapRet = wrap_json_pack(&currentAlsaMapDataJ,
-				 "{s:s s:s}",
-				 "name", currentAlsaMapData->uid,
-				 "info", currentAlsaMapData->info ? currentAlsaMapData->info : "none");
-	if(wrapRet) {
-		AFB_API_ERROR(apiHandle, "Didn't succeed to allocate current streams json object");
-		return NULL;
-	}
-
-	return currentAlsaMapDataJ;
-}
-
-json_object *HalUtGetJsonArrayForAllControls(afb_api_t apiHandle, struct InternalHalAlsaMapT *currentAlsaMapDataT)
-{
-	unsigned int idx;
-
-	json_object *alsaMapDataArrayJ, *currentAlsaMapDataJ;
-
-	if(! apiHandle) {
-		AFB_API_ERROR(apiHandle, "Can't get current internal hal api handle");
-		return NULL;
-	}
-
-	if(! currentAlsaMapDataT) {
-		AFB_API_ERROR(apiHandle, "Can't get Alsa map data table to handle");
-		return NULL;
-	}
-
-	alsaMapDataArrayJ = json_object_new_array();
-	if(! alsaMapDataArrayJ) {
-		AFB_API_ERROR(apiHandle, "Didn't succeed to allocate ALSA controls data json array");
-		return NULL;
-	}
-
-	for(idx = 0; idx < currentAlsaMapDataT->ctlsCount; idx++) {
-		currentAlsaMapDataJ = HalUtGetJsonArrayForSpecificControl(apiHandle, &currentAlsaMapDataT->ctls[idx]);
-		if(! currentAlsaMapDataJ) {
-			AFB_API_ERROR(apiHandle, "Didn't succeed to generate current ALSA control data json object");
-			json_object_put(alsaMapDataArrayJ);
-			return NULL;
-		}
-
-		json_object_array_add(alsaMapDataArrayJ, currentAlsaMapDataJ);
-	}
-
-	return alsaMapDataArrayJ;
-}
-
-int HalUtlFreeAlsaCtlsMap(struct InternalHalAlsaMapT *alsaCtlsMap)
-{
-	int idx;
-
-	if(! alsaCtlsMap)
-		return -1;
-
-	if(alsaCtlsMap->ctlsCount > 0 && ! alsaCtlsMap->ctls)
-		return -2;
-
-	for(idx = 0; idx < alsaCtlsMap->ctlsCount; idx++) {
-		free(alsaCtlsMap->ctls[idx].action);
-		free(alsaCtlsMap->ctls[idx].ctl.alsaCtlProperties.enums);
-		free(alsaCtlsMap->ctls[idx].ctl.alsaCtlProperties.dbscale);
-	}
-
-	free(alsaCtlsMap->ctls);
-
-	free(alsaCtlsMap);
-
-	return 0;
-}
\ No newline at end of file
diff --git a/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h b/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h
index 3a4c885..88b3e44 100644
--- a/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h
+++ b/lib/4a-hal-utilities/4a-hal-utilities-alsa-data.h
@@ -20,6 +20,8 @@
 
 #include <stdio.h>
 
+#include <urcu/list.h>
+
 #include <json-c/json.h>
 
 #include <alsa/asoundlib.h>
@@ -50,27 +52,24 @@ struct InternalHalAlsaCtl {
 	char *name;
 	int numid;
 	int value;
+
 	struct InternalHalAlsaCtlProperties alsaCtlProperties;
 	struct InternalHalAlsaCtlProperties *alsaCtlCreation;
 };
 
 struct InternalHalAlsaMap {
-	const char *uid;
+	char *uid;
 	char *info;
+
 	afb_event_t alsaControlEvent;
+
 	struct InternalHalAlsaCtl ctl;
+
 	json_object *actionJ;
+
 	CtlActionT *action;
-};
 
-struct InternalHalAlsaMapT {
-	struct InternalHalAlsaMap *ctls;
-	unsigned int ctlsCount;
+	struct cds_list_head node;
 };
 
-// Internal Hal - ALSA controls data handling functions
-json_object *HalUtGetJsonArrayForSpecificControl(afb_api_t apiHandle, struct InternalHalAlsaMap *currentAlsaMapData);
-json_object *HalUtGetJsonArrayForAllControls(afb_api_t apiHandle, struct InternalHalAlsaMapT *currentAlsaMapDataT);
-int HalUtlFreeAlsaCtlsMap(struct InternalHalAlsaMapT *alsaCtlsMap);
-
 #endif /* _HAL_UTILITIES_ALSA_DATA_INCLUDE_ */
\ No newline at end of file
diff --git a/lib/4a-hal-utilities/4a-hal-utilities-data.c b/lib/4a-hal-utilities/4a-hal-utilities-data.c
index 6121b33..d7ae1f6 100644
--- a/lib/4a-hal-utilities/4a-hal-utilities-data.c
+++ b/lib/4a-hal-utilities/4a-hal-utilities-data.c
@@ -33,6 +33,7 @@
 
 void HalUtlFreeSelectedProbedDeviceAllocation(struct InternalHalProbedDevice *probedDeviceToFree);
 void HalUtlFreeSelectedMixerDataAllocation(struct InternalHalMixerData *mixerDataToFree);
+void HalUtlFreeSelectedHalMapDataAllocation(struct InternalHalAlsaMap *halMapDataToFree);
 void HalUtlFreeSelectedHalAllocation(struct HalData *halDataToFree);
 
 /*******************************************************************************
@@ -62,6 +63,13 @@ void *HalUtlAddNodeInList(struct cds_list_head *listHead, enum LinkedListType li
 			nodeToAdd = &((struct InternalHalMixerData *) returned)->node;
 			break;
 
+		case LINKED_LIST_FOR_HALMAP_DATA:
+			returned = calloc(1, sizeof(struct InternalHalAlsaMap));
+			if(! returned)
+				return NULL;
+			nodeToAdd = &((struct InternalHalAlsaMap *) returned)->node;
+			break;
+
 		case LINKED_LIST_FOR_HAL_DATA:
 			returned = calloc(1, sizeof(struct HalData));
 			if(! returned)
@@ -96,6 +104,12 @@ int HalUtlRemoveNodeFromList(struct cds_list_head *listHead, void *dataToRemove,
 			HalUtlFreeSelectedMixerDataAllocation((struct InternalHalMixerData *) dataToRemove);
 			break;
 
+		case LINKED_LIST_FOR_HALMAP_DATA:
+			cds_list_del(&((struct InternalHalAlsaMap *) dataToRemove)->node);
+
+			HalUtlFreeSelectedHalMapDataAllocation((struct InternalHalAlsaMap *) dataToRemove);
+			break;
+
 		case LINKED_LIST_FOR_HAL_DATA:
 			cds_list_del(&((struct HalData *) dataToRemove)->node);
 
@@ -135,14 +149,20 @@ int HalUtlRemoveAllNodeFromList(struct cds_list_head *listHead, enum LinkedListT
 					return -3;
 				break;
 
+			case LINKED_LIST_FOR_HALMAP_DATA:
+				if(HalUtlRemoveSelectedHalMapData(listHead,
+								  cds_list_entry(nodeToRemove, struct InternalHalAlsaMap, node)))
+					return -4;
+				break;
+
 			case LINKED_LIST_FOR_HAL_DATA:
 				if(HalUtlRemoveSelectedHalFromList(listHead,
 								   cds_list_entry(nodeToRemove, struct HalData, node)))
-					return -4;
+					return -5;
 				break;
 
 			default:
-				return -5;
+				return -6;
 		}
 
 		nodesRemoved++;
@@ -820,6 +840,11 @@ json_object *HalUtlGetJsonArrayForAllMixersData(afb_api_t apiHandle, struct cds_
 		return NULL;
 	}
 
+	if(cds_list_empty(mixerDataListHead)) {
+		AFB_API_ERROR(apiHandle, "Mixer data list is empty");
+		return NULL;
+	}
+
 	mixerDataArrayJ = json_object_new_array();
 	if(! mixerDataArrayJ) {
 		AFB_API_ERROR(apiHandle, "Didn't succeed to allocate requested mixer data json array");
@@ -840,6 +865,108 @@ json_object *HalUtlGetJsonArrayForAllMixersData(afb_api_t apiHandle, struct cds_
 	return mixerDataArrayJ;
 }
 
+/*******************************************************************************
+ *	Internal Hal - Alsa Map data handling functions			       *
+ ******************************************************************************/
+
+void HalUtlFreeSelectedHalMapDataAllocation(struct InternalHalAlsaMap *halMapDataToFree)
+{
+	free(halMapDataToFree->uid);
+	free(halMapDataToFree->info);
+
+	free(halMapDataToFree->action);
+
+	free(halMapDataToFree->ctl.name);
+
+	free(halMapDataToFree);
+}
+
+struct InternalHalAlsaMap *HalUtlAddHalMapDataToHalMapDataList(struct cds_list_head *halMapListHead)
+{
+	return (struct InternalHalAlsaMap *) HalUtlAddNodeInList(halMapListHead, LINKED_LIST_FOR_HALMAP_DATA);
+}
+
+int HalUtlRemoveSelectedHalMapData(struct cds_list_head *halMapListHead,
+				   struct InternalHalAlsaMap *halMapDataToRemove)
+{
+	return HalUtlRemoveNodeFromList(halMapListHead, (void *) halMapDataToRemove, LINKED_LIST_FOR_HALMAP_DATA);
+}
+
+int HalUtlRemoveAllHalMapData(struct cds_list_head *halMapListHead)
+{
+	return HalUtlRemoveAllNodeFromList(halMapListHead, LINKED_LIST_FOR_HALMAP_DATA);
+}
+
+int HalUtlGetNumberOfHalMapDataInList(struct cds_list_head *halMapListHead)
+{
+	return HalUtlGetNumberOfNodesInList(halMapListHead);
+}
+
+json_object *HalUtGetJsonArrayForSpecificHalMapControl(afb_api_t apiHandle,
+						       struct InternalHalAlsaMap *currentHalMapData)
+{
+	int wrapRet;
+
+	json_object *currentAlsaMapDataJ;
+
+	if(! apiHandle) {
+		AFB_API_ERROR(apiHandle, "Can't get current internal hal api handle");
+		return NULL;
+	}
+
+	if(! currentHalMapData) {
+		AFB_API_ERROR(apiHandle, "ALSA control data to use to generate json object are empty");
+		return NULL;
+	}
+
+	wrapRet = wrap_json_pack(&currentAlsaMapDataJ,
+				 "{s:s s:s}",
+				 "name", currentHalMapData->uid,
+				 "info", currentHalMapData->info ? currentHalMapData->info : "none");
+	if(wrapRet) {
+		AFB_API_ERROR(apiHandle, "Didn't succeed to allocate current streams json object");
+		return NULL;
+	}
+
+	return currentAlsaMapDataJ;
+}
+
+json_object *HalUtGetJsonArrayForAllHalMapControls(afb_api_t apiHandle, struct cds_list_head *halMapListHead)
+{
+	struct InternalHalAlsaMap *currentHalMapData;
+
+	json_object *halMapDataArrayJ, *currentHalMapDataJ;
+
+	if(! apiHandle) {
+		AFB_API_ERROR(apiHandle, "Can't get current internal hal api handle");
+		return NULL;
+	}
+
+	if(! halMapListHead || cds_list_empty(halMapListHead)) {
+		AFB_API_ERROR(apiHandle, "HalMap data list is empty");
+		return NULL;
+	}
+
+	halMapDataArrayJ = json_object_new_array();
+	if(! halMapDataArrayJ) {
+		AFB_API_ERROR(apiHandle, "Didn't succeed to allocate ALSA controls data json array");
+		return NULL;
+	}
+
+	cds_list_for_each_entry(currentHalMapData, halMapListHead, node) {
+		currentHalMapDataJ = HalUtGetJsonArrayForSpecificHalMapControl(apiHandle, currentHalMapData);
+		if(! currentHalMapDataJ) {
+			AFB_API_ERROR(apiHandle, "Didn't succeed to generate current HalMap data json object");
+			json_object_put(halMapDataArrayJ);
+			return NULL;
+		}
+
+		json_object_array_add(halMapDataArrayJ, currentHalMapDataJ);
+	}
+
+	return halMapDataArrayJ;
+}
+
 /*******************************************************************************
  *	Hal data handling functions					       *
  ******************************************************************************/
@@ -857,7 +984,7 @@ void HalUtlFreeSelectedHalAllocation(struct HalData *halDataToFree)
 
 		HalUtlRemoveAllMixerData(&halDataToFree->internalHalData->streamsDataListHead);
 
-		HalUtlFreeAlsaCtlsMap(halDataToFree->internalHalData->alsaMapT);
+		HalUtlRemoveAllHalMapData(&halDataToFree->internalHalData->halMapListHead);
 
 		free(halDataToFree->internalHalData);
 	}
diff --git a/lib/4a-hal-utilities/4a-hal-utilities-data.h b/lib/4a-hal-utilities/4a-hal-utilities-data.h
index 1571485..1ecfe00 100644
--- a/lib/4a-hal-utilities/4a-hal-utilities-data.h
+++ b/lib/4a-hal-utilities/4a-hal-utilities-data.h
@@ -38,7 +38,8 @@
 enum LinkedListType {
 	LINKED_LIST_FOR_DEPENDENCIES_DATA = 0,
 	LINKED_LIST_FOR_MIXER_DATA = 1,
-	LINKED_LIST_FOR_HAL_DATA = 2
+	LINKED_LIST_FOR_HALMAP_DATA = 2,
+	LINKED_LIST_FOR_HAL_DATA = 3
 };
 
 // Enum for hal status
@@ -116,7 +117,7 @@ struct InternalHalData {
 	struct cds_list_head streamsDataListHead;
 	afb_event_t streamUpdates;
 
-	struct InternalHalAlsaMapT *alsaMapT;
+	struct cds_list_head halMapListHead;
 
 	afb_api_t apiHandle;
 	CtlConfigT *ctrlConfig;
@@ -191,6 +192,16 @@ struct InternalHalMixerData *HalUtlSearchMixerDataByProperties(struct cds_list_h
 json_object *HalUtlGetJsonArrayForSpecificMixerData(afb_api_t apiHandle, struct InternalHalMixerData *mixerData);
 json_object *HalUtlGetJsonArrayForAllMixersData(afb_api_t apiHandle, struct cds_list_head *mixerDataListHead);
 
+// Internal Hal - Alsa Map data handling functions
+struct InternalHalAlsaMap *HalUtlAddHalMapDataToHalMapDataList(struct cds_list_head *halMapListHead);
+int HalUtlRemoveSelectedHalMapData(struct cds_list_head *halMapListHead,
+				   struct InternalHalAlsaMap *halMapDataToRemove);
+int HalUtlRemoveAllHalMapData(struct cds_list_head *halMapListHead);
+int HalUtlGetNumberOfHalMapDataInList(struct cds_list_head *halMapListHead);
+json_object *HalUtGetJsonArrayForSpecificHalMapControl(afb_api_t apiHandle,
+						       struct InternalHalAlsaMap *currentHalMapData);
+json_object *HalUtGetJsonArrayForAllHalMapControls(afb_api_t apiHandle, struct cds_list_head *halMapListHead);
+
 // Hal data handling functions
 struct HalData *HalUtlAddHalToHalList(struct cds_list_head *halDataListHead);
 int HalUtlRemoveSelectedHalFromList(struct cds_list_head *halDataListHead, struct HalData *halToRemove);
diff --git a/lib/4a-hal-utilities/CMakeLists.txt b/lib/4a-hal-utilities/CMakeLists.txt
index 8eb2c62..9689565 100644
--- a/lib/4a-hal-utilities/CMakeLists.txt
+++ b/lib/4a-hal-utilities/CMakeLists.txt
@@ -22,7 +22,6 @@ PROJECT_TARGET_ADD(4a-hal-utilities)
 
 	# Define project Targets
 	ADD_LIBRARY(${TARGET_NAME} STATIC
-		    4a-hal-utilities-alsa-data.c
 		    4a-hal-utilities-data.c
 		    4a-hal-utilities-hal-streams-handler.c)
 
-- 
cgit