summaryrefslogtreecommitdiffstats
path: root/plugins/alsa/alsa-transaction.c
blob: bd32603d8394dd2d7ab62ea07f22f5644962bc63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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;

}