diff options
Diffstat (limited to 'alsa-binding/Alsa-RegEvt.c')
-rw-r--r-- | alsa-binding/Alsa-RegEvt.c | 74 |
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) { |