diff options
Diffstat (limited to 'src/4a-internals-hal/4a-internals-hal-alsacore-link.c')
-rw-r--r-- | src/4a-internals-hal/4a-internals-hal-alsacore-link.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/4a-internals-hal/4a-internals-hal-alsacore-link.c b/src/4a-internals-hal/4a-internals-hal-alsacore-link.c index 7b2fd5f..99b50a8 100644 --- a/src/4a-internals-hal/4a-internals-hal-alsacore-link.c +++ b/src/4a-internals-hal/4a-internals-hal-alsacore-link.c @@ -66,6 +66,160 @@ snd_ctl_elem_type_t InternalHalMapsAlsaTypeToEnum(const char *label) } /******************************************************************************* + * Internals HAL - Alsacore events handler function * + ******************************************************************************/ + +enum aslacoreEventType InternalHalGetAlsaCoreEventType(const char *evtLabel) +{ + if(! evtLabel) + return ALSACORE_UNRECOGNIZED_EVENT; + + if(! strncmp(&evtLabel[ALSACORE_EVENT_NAME_BEGIN], + ALSACORE_CARD_CONTROL_EVENT_NAME_PREFIX, + ALSACORE_CARD_CONTROL_EVENT_NAME_PREFIX_LENGTH)) + return ALSACORE_EVENT_CARD_CONTROL_CHANGE; + + return ALSACORE_UNRECOGNIZED_EVENT; +} + +int InternalHalHandleAlsaCoreCardControlEvent(afb_api_t apiHandle, + const char *evtLabel, + json_object *eventJ, + struct HalData *currentHalData) +{ + int numid, cardidx; + + json_object *valuesJ, *normalizedValuesJ; + + CtlSourceT source; + + struct InternalHalAlsaMap *currentHalMapControl; + + if(! apiHandle || ! evtLabel || ! eventJ || ! currentHalData) { + AFB_API_ERROR(apiHandle, "Invalid argument(s)"); + return -1; + } + + if(sscanf(&evtLabel[ALSACORE_CARD_CONTROL_EVENT_BEGIN], "%d", &cardidx) != 1) { + AFB_API_ERROR(apiHandle, + "Did not succeed to get ALSA card number of the modified control : evtname=%s [msg=%s]", + evtLabel, + json_object_get_string(eventJ)); + return -2; + } + + if(wrap_json_unpack(eventJ, "{s:i s:o}", "id", &numid, "val", &valuesJ)) { + AFB_API_ERROR(apiHandle, + "Invalid alsacore modified control event received label=%s value=%s", + evtLabel, + json_object_get_string(eventJ)); + return -3; + } + + if(cds_list_empty(¤tHalData->internalHalData->halMapListHead)) { + AFB_API_ERROR(apiHandle, + "No halmap data is available, cannot handle alsacore event label=%s value=%s", + evtLabel, + json_object_get_string(eventJ)); + return -4; + } + + // Search for corresponding numid in ALSA controls list, if found, launch callback (if available) + cds_list_for_each_entry(currentHalMapControl, ¤tHalData->internalHalData->halMapListHead, node) { + if(currentHalMapControl->cardNb != cardidx || + ! currentHalMapControl->ctl.alsaCtlProperties || + currentHalMapControl->ctl.numid != numid) + continue; + + if(currentHalMapControl->action) { + memset(&source, 0, sizeof(CtlSourceT)); + source.uid = currentHalMapControl->action->uid; + source.api = currentHalMapControl->action->api; + + ActionExecOne(&source, currentHalMapControl->action, valuesJ); + } + else if(currentHalMapControl->actionJ) { + AFB_API_WARNING(apiHandle, + "The alsa control id '%i' is corresponding to a known control which " + "has a registered action, but action is not ready to be executed", + numid); + } + else { + AFB_API_NOTICE(apiHandle, + "The alsa control id '%i' is corresponding to a known control " + "but without any action registered", + numid); + } + + if(! currentHalMapControl->alsaControlEvent || + InternalHalConvertJsonValues(apiHandle, + currentHalMapControl->ctl.alsaCtlProperties, + valuesJ, + &normalizedValuesJ, + CONVERSION_ALSACORE_TO_NORMALIZED) || + (afb_event_push(currentHalMapControl->alsaControlEvent, normalizedValuesJ) < 0)) { + AFB_API_ERROR(apiHandle, + "Couldn't generate an event for known halmap %s (alsa control id %i)", + currentHalMapControl->uid, + currentHalMapControl->ctl.numid); + } + + return 0; + } + + AFB_API_INFO(apiHandle, + "Alsacore event with an unrecognized numid: %i, evtname=%s [msg=%s]", + numid, + evtLabel, + json_object_get_string(eventJ)); + + return 1; + +} + +int InternalHalHandleAlsaCoreEvents(afb_api_t apiHandle, + const char *evtLabel, + json_object *eventJ, + struct HalData *currentHalData) +{ + int returned; + + if(! apiHandle || ! evtLabel || ! eventJ || ! currentHalData) { + AFB_API_ERROR(apiHandle, "Invalid argument(s)"); + return -1; + } + + switch(InternalHalGetAlsaCoreEventType(evtLabel)) { + case ALSACORE_EVENT_CARD_CONTROL_CHANGE: + returned = InternalHalHandleAlsaCoreCardControlEvent(apiHandle, evtLabel, eventJ, currentHalData); + if(returned < 0) { + AFB_API_ERROR(apiHandle, + "Error %i caught when tried to handle alsacore card control event evtname=%s [msg=%s]", + returned, + evtLabel, + json_object_get_string(eventJ)); + return -2; + } + else if(returned > 0) { + AFB_API_INFO(apiHandle, + "Warning %i raised when tried to handle alsacore card control event evtname=%s [msg=%s]", + returned, + evtLabel, + json_object_get_string(eventJ)); + } + return 0; + + case ALSACORE_UNRECOGNIZED_EVENT: + default: + AFB_API_NOTICE(apiHandle, + "Alsacore event with an unrecognized evtname=%s [msg=%s]", + evtLabel, + json_object_get_string(eventJ)); + return 1; + } +} + +/******************************************************************************* * Internals HAL - Alsacore calls funtions * ******************************************************************************/ |