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;
}
|