diff options
Diffstat (limited to 'plugins/alsa/alsa-transaction.c')
-rw-r--r-- | plugins/alsa/alsa-transaction.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/plugins/alsa/alsa-transaction.c b/plugins/alsa/alsa-transaction.c new file mode 100644 index 0000000..bd32603 --- /dev/null +++ b/plugins/alsa/alsa-transaction.c @@ -0,0 +1,111 @@ +#include <malloc.h> +#include <string.h> + +#include "alsa-softmixer.h" +#include "alsa-transaction.h" +#include "wrap-json.h" + +AlsaMixerTransaction * AlsaMixerTransactionNew(struct SoftMixerT_ * mixer, const char * uid) { + AlsaMixerTransaction * newList = (AlsaMixerTransaction *) malloc(sizeof(AlsaMixerTransaction)); + if (newList == NULL) + goto fail; + + CDS_INIT_LIST_HEAD(&newList->list); + newList->uid = strdup(uid); + if (newList->uid == NULL) { + goto fail_list; + } + + newList->mixer = mixer; + + return newList; + +fail_list: + free(newList); +fail: + return NULL; +} + +void AlsaMixerTransactionDataListDestroy(AlsaMixerTransaction* list) { + free(list); +} + +bool AlsaMixerTransactionObjectAdd(AlsaMixerTransaction* list, void* object, AlsaTransactionDestructor destructor) { + bool ret = false; + AlsaMixerTransactionDataItem * newItem = NULL; + if (!list) + goto fail; + + newItem = (AlsaMixerTransactionDataItem *) malloc(sizeof(AlsaMixerTransactionDataItem)); + if (newItem == NULL) + goto fail; + + CDS_INIT_LIST_HEAD(&newItem->list_entry); + newItem->object = object; + newItem->destructor = destructor; + cds_list_add(&newItem->list_entry, &list->list); + + ret = true; +fail: + return ret; + +} + +void AlsaMixerTransactionDoCleanup(AlsaMixerTransaction* transaction) { + AlsaMixerTransactionDataItem * item, *sav; + + cds_list_for_each_entry_safe(item, sav, &transaction->list, list_entry) { + if (item->destructor) + item->destructor(transaction->mixer, item->object); + + cds_list_del(&item->list_entry); + free(item); + } +} + +void AlsaMixerTransactionVerbCB(AFB_ReqT request) { + json_object *responseJ = NULL; + AlsaMixerTransaction *transaction = (AlsaMixerTransaction*) afb_req_get_vcbdata(request); + json_object *argsJ = afb_req_json(request); + int error; + char * action = NULL; + const char * uid; + + error = wrap_json_unpack(argsJ, "{ss!}", + "action", &action); + + if (error) { + AFB_ReqFailF(request, "missing action", "%s: missing 'action' field: %s", transaction->uid, json_object_get_string(argsJ)); + goto OnErrorExit; + } + + uid = strdup(transaction->uid); + if (!uid) { + SOFTMIXER_NOMEM(transaction->mixer->api); + goto OnErrorExit; + } + + if (strcmp(action, "remove") == 0) { + AlsaMixerTransactionDoCleanup(transaction); + error = afb_api_del_verb(transaction->mixer->api, transaction->uid, (void**)transaction); + if (error) { + AFB_ReqFail(request, "verb deletion" , "verb was not removed"); + goto OnErrorExit; + } + + } else { + AFB_ReqFailF(request, "unsupported action", "%s: unsupported action %s (supported ones are ['remove']", transaction->uid, action); + goto OnErrorExit; + } + + responseJ=json_object_new_object(); + json_object_object_add(responseJ, "result", json_object_new_string("OK")); + AFB_ReqSuccess(request, responseJ, uid); + + free((char*)uid); + return; + +OnErrorExit: + return; + +} |