From f5ebbebfe47312c4cd74f5614ee7523f106f3f59 Mon Sep 17 00:00:00 2001
From: Jonathan Aillet <jonathan.aillet@iot.bzh>
Date: Mon, 17 Dec 2018 19:42:38 +0100
Subject: Add halmap controls events generation for all hal

Each hal will now allow other bindings to subscribe to halmap ALSA
controls events to be notified when a modification happened on a control.

Bug-AGL: SPEC-1313

Change-Id: Ia6a019b254c78e5e752b0d39a7cf35114c1fc460
Signed-off-by: Jonathan Aillet <jonathan.aillet@iot.bzh>
---
 .../4a-hal-controllers-alsacore-link.h             |  1 +
 4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c  | 61 ++++++++++++++++++++--
 2 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-alsacore-link.h b/4a-hal/4a-hal-controllers/4a-hal-controllers-alsacore-link.h
index 45dc996..5d687aa 100644
--- a/4a-hal/4a-hal-controllers/4a-hal-controllers-alsacore-link.h
+++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-alsacore-link.h
@@ -62,6 +62,7 @@ struct CtlHalAlsaCtl {
 struct CtlHalAlsaMap {
 	const char *uid;
 	char *info;
+	AFB_EventT alsaControlEvent;
 	struct CtlHalAlsaCtl ctl;
 	json_object *actionJ;
 	CtlActionT *action;
diff --git a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c
index f5099c3..97caecd 100644
--- a/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c
+++ b/4a-hal/4a-hal-controllers/4a-hal-controllers-cb.c
@@ -44,7 +44,7 @@ void HalCtlsDispatchApiEvent(afb_dynapi *apiHandle, const char *evtLabel, json_o
 	struct SpecificHalData *currentHalData;
 	struct CtlHalAlsaMapT *currentHalAlsaCtlsT;
 
-	json_object *valuesJ;
+	json_object *valuesJ, *normalizedValuesJ;
 
 	AFB_ApiDebug(apiHandle, "Evtname=%s [msg=%s]", evtLabel, json_object_get_string(eventJ));
 
@@ -90,6 +90,19 @@ void HalCtlsDispatchApiEvent(afb_dynapi *apiHandle, const char *evtLabel, json_o
 						      numid);
 				}
 
+				if((! currentHalAlsaCtlsT->ctls[idx].alsaControlEvent) ||
+				   HalCtlsConvertJsonValues(apiHandle,
+							    &currentHalAlsaCtlsT->ctls[idx].ctl.alsaCtlProperties,
+							    valuesJ,
+							    &normalizedValuesJ,
+							    CONVERSION_ALSACORE_TO_NORMALIZED) ||
+				   (AFB_EventPush(currentHalAlsaCtlsT->ctls[idx].alsaControlEvent, normalizedValuesJ) < 0)) {
+					AFB_ApiError(apiHandle,
+						     "Couldn't generate an event for known halmap %s (alsa control id %i)",
+						     currentHalAlsaCtlsT->ctls[idx].uid,
+						     currentHalAlsaCtlsT->ctls[idx].ctl.numid);
+				}
+
 				return;
 			}
 		}
@@ -275,13 +288,21 @@ int HalCtlsHandleOneHalMapObject(AFB_ApiT apiHandle, char *cardId, struct CtlHal
 		}
 	}
 
-	if(afb_dynapi_add_verb(apiHandle, alsaMap->uid, alsaMap->info, HalCtlsActionOnAlsaCtl, (void *) alsaMap, NULL, 0)) {
+	alsaMap->alsaControlEvent = AFB_EventMake(apiHandle, alsaMap->uid);
+	if(! AFB_EventIsValid(alsaMap->alsaControlEvent)) {
 		AFB_ApiError(apiHandle,
-			     "Didn't to create verb for current alsa control to load action using alsa object:\n-- %s",
+			     "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 -6;
 	}
 
+	if(afb_dynapi_add_verb(apiHandle, alsaMap->uid, alsaMap->info, HalCtlsActionOnAlsaCtl, (void *) alsaMap, NULL, 0)) {
+		AFB_ApiError(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;
 }
 
@@ -779,6 +800,7 @@ void HalCtlsSubscribeUnsubscribe(AFB_ReqT request, enum SubscribeUnsubscribeType
 
 	struct SpecificHalData *currentCtlHalData;
 	struct CtlHalMixerDataT *halStreamsData;
+	struct CtlHalAlsaMapT *halAlsaMapT;
 
 	json_object *requestJson, *requestedSubscriptionsJ, *requestedSubscriptionJ = NULL;
 	json_type requestJsonType;
@@ -807,6 +829,7 @@ void HalCtlsSubscribeUnsubscribe(AFB_ReqT request, enum SubscribeUnsubscribeType
 	}
 
 	halStreamsData = &currentCtlHalData->ctlHalSpecificData->ctlHalStreamsData;
+	halAlsaMapT = currentCtlHalData->ctlHalSpecificData->ctlHalAlsaMapT;
 
 	requestJson = AFB_ReqJson(request);
 	if(! requestJson) {
@@ -877,6 +900,38 @@ void HalCtlsSubscribeUnsubscribe(AFB_ReqT request, enum SubscribeUnsubscribeType
 
 			searchIdx++;
 		}
+
+		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_ReqFailF(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_ReqFailF(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)
-- 
cgit