summaryrefslogtreecommitdiffstats
path: root/alsa-binding/Alsa-RegEvt.c
diff options
context:
space:
mode:
Diffstat (limited to 'alsa-binding/Alsa-RegEvt.c')
-rw-r--r--alsa-binding/Alsa-RegEvt.c74
1 files changed, 55 insertions, 19 deletions
diff --git a/alsa-binding/Alsa-RegEvt.c b/alsa-binding/Alsa-RegEvt.c
index a60ffc8..a9cce2b 100644
--- a/alsa-binding/Alsa-RegEvt.c
+++ b/alsa-binding/Alsa-RegEvt.c
@@ -192,7 +192,7 @@ STATIC void freeCardAlsaControlHandle(ctrlEvtHandleT **cardControlHandle)
STATIC void updateSelectedAlsaCardsAvailabilityAndFireEvents(sndCardsT *sndCards, int first, int last)
{
- int idx, available;
+ int idx, available, subscriberCount = -1;
char *cardId;
json_object *generatedEventJ = NULL;
@@ -213,7 +213,7 @@ STATIC void updateSelectedAlsaCardsAvailabilityAndFireEvents(sndCardsT *sndCards
if(sndCards->cardMonitoring &&
! wrap_json_pack(&generatedEventJ, "{s:o}", "cardAdded", getCardInfo(idx)))
- afb_event_push(sndCards->cardMonitoring->afbevt, generatedEventJ);
+ subscriberCount = afb_event_push(sndCards->cardMonitoring->afbevt, generatedEventJ);
}
else if(! available && sndCards->sndHandles[idx].available) {
sndCards->sndHandles[idx].available = 0;
@@ -221,7 +221,7 @@ STATIC void updateSelectedAlsaCardsAvailabilityAndFireEvents(sndCardsT *sndCards
if(sndCards->cardMonitoring &&
(asprintf(&cardId, "hw:%i", idx) > 0) &&
! wrap_json_pack(&generatedEventJ, "{s:s}", "cardRemoved", cardId))
- afb_event_push(sndCards->cardMonitoring->afbevt, generatedEventJ);
+ subscriberCount = afb_event_push(sndCards->cardMonitoring->afbevt, generatedEventJ);
if(sndCards->sndHandles[idx].evtHandle) {
sd_event_source_unref(sndCards->sndHandles[idx].evtHandle->src);
@@ -232,6 +232,11 @@ STATIC void updateSelectedAlsaCardsAvailabilityAndFireEvents(sndCardsT *sndCards
}
}
}
+
+ if(! subscriberCount) {
+ AFB_WARNING("Nobody listening for 'card-monitoring' events, stop monitoring from now on");
+ freeSndCardHandle(&sndCards->cardMonitoring);
+ }
}
STATIC void updateAllAlsaCardsAvailabilityAndFireEvents(sndCardsT *sndCards) {
@@ -326,7 +331,7 @@ STATIC int sndCardEventCB(sd_event_source* src, int fd, uint32_t revents, void*
// This routine is called when ALSA control events are fired
STATIC int sndCtlEventCB(sd_event_source* src, int fd, uint32_t revents, void* userData)
{
- int err, ctlNumid;
+ int err, ctlNumid, subscriberCount = -1;
unsigned int mask;
snd_ctl_elem_id_t *elemId;
@@ -398,21 +403,29 @@ STATIC int sndCtlEventCB(sd_event_source* src, int fd, uint32_t revents, void* u
wrap_json_object_add(ctlEventJ, ctlEventAdditionalInfoJ);
AFB_DEBUG("sndCtlEventCB=%s", json_object_get_string(ctlEventJ));
+ subscriberCount = afb_event_push(sndHandle->evtHandle->afbevt, ctlEventJ);
+ }
- afb_event_push(sndHandle->evtHandle->afbevt, ctlEventJ);
+ if(! subscriberCount) {
+ AFB_WARNING("Nobody listening for card %i control events, stop monitoring from now on", snd_ctl_event_elem_get_interface(eventId));
+ freeCardAlsaControlHandle(&sndHandle->evtHandle);
+ return -4;
}
return 0;
}
// Subscribe to each time a sound card is added/removed (using inotify '/dev/snd/by-path' events)
-STATIC afb_event_t alsaEvtSubscribeSoundCardEvent(afb_req_t request,
- sndCardsT *sndCards)
+STATIC afb_event_t alsaEvtSubscribeUnsubscribeSoundCardEvent(afb_req_t request,
+ sndCardsT *sndCards,
+ EventSubscribeUnsubscribeT subscriptionType)
{
int err;
if(sndCards->cardMonitoring)
return sndCards->cardMonitoring->afbevt;
+ else if(subscriptionType == EVENT_UNSUBSCRIBE)
+ return NULL;
updateAllAlsaCardsAvailabilityAndFireEvents(sndCards);
@@ -467,9 +480,10 @@ STATIC afb_event_t alsaEvtSubscribeSoundCardEvent(afb_req_t request,
}
// Subscribe to every Alsa CtlEvent send by a given board
-STATIC afb_event_t alsaEvtSubscribeAlsaControlEvent(afb_req_t request,
- sndCardsT *sndCards,
- char* devId)
+STATIC afb_event_t alsaEvtSubscribeUnsubscribeAlsaControlEvent(afb_req_t request,
+ sndCardsT *sndCards,
+ char* devId,
+ EventSubscribeUnsubscribeT subscriptionType)
{
sndHandleT *currentSndHandle = NULL;
snd_ctl_t *ctlDev = NULL;
@@ -505,6 +519,10 @@ STATIC afb_event_t alsaEvtSubscribeAlsaControlEvent(afb_req_t request,
snd_ctl_close(ctlDev);
return currentSndHandle->evtHandle->afbevt;
}
+ else if(subscriptionType == EVENT_UNSUBSCRIBE) {
+ snd_ctl_close(ctlDev);
+ return NULL;
+ }
currentSndHandle->evtHandle = malloc(sizeof (ctrlEvtHandleT));
currentSndHandle->evtHandle->ctlDev = ctlDev;
@@ -545,8 +563,9 @@ STATIC afb_event_t alsaEvtSubscribeAlsaControlEvent(afb_req_t request,
}
// Subscribe to alsacore event
-PUBLIC void alsaEvtSubcribe(afb_req_t request) {
- int err;
+PUBLIC void alsaEvtSubscribeUnsubscribe(afb_req_t request, EventSubscribeUnsubscribeT subscriptionType)
+{
+ int err = -1;
EventTypeT eventType;
@@ -554,7 +573,7 @@ PUBLIC void alsaEvtSubcribe(afb_req_t request) {
static sndCardsT *sndCards = NULL;
- afb_event_t eventToSubscribe;
+ afb_event_t eventToSubscribeUnsubscribe;
json_object *queryJ;
@@ -574,11 +593,11 @@ PUBLIC void alsaEvtSubcribe(afb_req_t request) {
return;
}
- eventToSubscribe = alsaEvtSubscribeAlsaControlEvent(request, sndCards, devId);
+ eventToSubscribeUnsubscribe = alsaEvtSubscribeUnsubscribeAlsaControlEvent(request, sndCards, devId, subscriptionType);
break;
case CARD_MONITORING_EVENTS:
- eventToSubscribe = alsaEvtSubscribeSoundCardEvent(request, sndCards);
+ eventToSubscribeUnsubscribe = alsaEvtSubscribeUnsubscribeSoundCardEvent(request, sndCards, subscriptionType);
break;
case UNKNOWN_EVENT:
@@ -587,19 +606,36 @@ PUBLIC void alsaEvtSubcribe(afb_req_t request) {
return;
}
- if(! eventToSubscribe)
+ if(! eventToSubscribeUnsubscribe)
return;
- // subscribe to binder event
- err = afb_req_subscribe(request, eventToSubscribe);
+ // subscribe/unsubscribe to binder event
+ if(subscriptionType == EVENT_SUBSCRIBE)
+ err = afb_req_subscribe(request, eventToSubscribeUnsubscribe);
+ else if(subscriptionType == EVENT_UNSUBSCRIBE)
+ err = afb_req_unsubscribe(request, eventToSubscribeUnsubscribe);
+
if(err) {
- afb_req_fail_f(request, "register-eventname", "Cannot subscribe binder event");
+ afb_req_fail_f(request,
+ "register-eventname",
+ "Cannot %s binder event",
+ (subscriptionType == EVENT_SUBSCRIBE) ? "subscribe" : "unsubscribe");
return;
}
afb_req_success(request, NULL, NULL);
}
+PUBLIC void alsaEvtSubscribe(afb_req_t request)
+{
+ alsaEvtSubscribeUnsubscribe(request, EVENT_SUBSCRIBE);
+}
+
+PUBLIC void alsaEvtUnsubscribe(afb_req_t request)
+{
+ alsaEvtSubscribeUnsubscribe(request, EVENT_UNSUBSCRIBE);
+}
+
// Subscribe to every Alsa CtlEvent send by a given board
STATIC json_object *alsaProbeCardId(afb_req_t request) {