summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--alsa-hook/PolicyAlsaHook.c66
1 files changed, 50 insertions, 16 deletions
diff --git a/alsa-hook/PolicyAlsaHook.c b/alsa-hook/PolicyAlsaHook.c
index 38d3402..50c603b 100644
--- a/alsa-hook/PolicyAlsaHook.c
+++ b/alsa-hook/PolicyAlsaHook.c
@@ -66,9 +66,10 @@
// Currently not implemented
#define UNUSED_ARG(x) UNUSED_ ## x __attribute__((__unused__))
+#define MAGIC_HOOK 22562935
typedef struct {
- const char *apiverb;
+ char *apiverb;
json_object *queryJ;
sd_event_source *evtSource;
char *callIdTag;
@@ -76,17 +77,18 @@ typedef struct {
} afbRequestT;
typedef struct {
- const char *search;
- const char *value;
+ char *search;
+ char *value;
long ivalue;
int signal;
} afbEventT;
typedef struct {
+ long magic;
char *name;
char *uid;
snd_pcm_t *pcm;
- const char *uri;
+ char *uri;
struct afb_proto_ws *pws;
sd_event *sdLoop;
int verbose;
@@ -99,6 +101,7 @@ typedef struct {
afbRequestT **release;
afbEventT **event;
pthread_t tid;
+ json_object * streamIdJ;
} afbClientT;
@@ -170,7 +173,6 @@ void OnEventCB(void *handle, const char *event, int evtid, struct json_object *d
if (ivalue == afbEvent[index]->ivalue) signal=afbEvent[index]->signal;
}
break;
-
}
}
if (signal) {
@@ -192,6 +194,12 @@ static void OnSuccessCB(void* UNUSED_ARG(ctx) , void* handle, json_object* respo
if (afbClient->verbose) printf("OnSuccessCB callid='%s' response='%s' info='%s'\n", afbRequest->callIdTag, json_object_get_string(responseJ), info);
+ // as pulse does not close PCM even timeout=0 session is not enough and we have to handle stream_id manually
+ if (json_object_object_get_ex(responseJ, "stream_id", &afbClient->streamIdJ) && afbClient->verbose) {
+ json_object_get(afbClient->streamIdJ);
+ printf("OnSuccessCB session store stream_id='%s'\n", json_object_get_string(afbClient->streamIdJ));
+ }
+
// Cancel timeout for this request
sd_event_source_unref(afbRequest->evtSource);
free(afbRequest->callIdTag);
@@ -251,20 +259,31 @@ int OnTimeoutCB (sd_event_source* source, uint64_t timer, void* handle) {
// Call AGL binder asynchronously by with a timeout
static int CallWithTimeout(afbClientT *afbClient, afbRequestT *afbRequest, int count) {
uint64_t usec;
+ json_object *queryJ;
int err;
// create a unique tag for request
- int res= asprintf(&afbRequest->callIdTag, "%d:%s", count, afbRequest->apiverb);
+ (void)asprintf(&afbRequest->callIdTag, "%d:%s", count, afbRequest->apiverb);
// create a timer with ~250us accuracy
sd_event_now(afbClient->sdLoop, CLOCK_MONOTONIC, &usec);
sd_event_add_time(afbClient->sdLoop, &afbRequest->evtSource, CLOCK_MONOTONIC, usec+afbClient->timeout*1000, 250, OnTimeoutCB, afbClient);
+ // if steamId is set then add it to api query
+ if (!afbClient->streamIdJ) {
+ queryJ=afbRequest->queryJ;
+ } else {
+ queryJ=json_object_new_object();
+ json_object_object_foreach(afbRequest->queryJ, key, obj) {
+ json_object_object_add(queryJ, key, obj);
+ }
+ json_object_object_add(queryJ,"stream_id",afbClient->streamIdJ);
+ }
+
// release action is optional
if (afbRequest->apiverb) {
- err = afb_proto_ws_client_call(afbClient->pws, afbRequest->apiverb, afbRequest->queryJ, afbClient->uid, afbRequest);
- if (afbClient->verbose) printf("CALL-REQUEST verb=%s query=%s tag=%s session=%s err=%d\n", afbRequest->apiverb, json_object_get_string(afbRequest->queryJ), afbRequest->callIdTag, afbClient->uid, err);
-
+ if (afbClient->verbose) printf("CALL-REQUEST verb=%s query=%s tag=%s session=%s\n", afbRequest->apiverb, json_object_get_string(queryJ), afbRequest->callIdTag, afbClient->uid);
+ err = afb_proto_ws_client_call(afbClient->pws, afbRequest->apiverb, queryJ, afbClient->uid, afbRequest);
if (err < 0 ) goto OnErrorExit;
}
@@ -367,7 +386,7 @@ static int LaunchCallRequest(afbClientT *afbClient, hookActionT action) {
return 0;
OnErrorExit:
- return -1;
+ return 1;
}
static void AlsaHookClean (afbClientT *afbClient)
@@ -399,13 +418,25 @@ static void AlsaHookClean (afbClientT *afbClient)
}
free(afbRelease);
}
+ afbClient->magic=0;
+
+ // free systemd loop
+ if (afbClient->sdLoop) sd_event_unref(afbClient->sdLoop);
+ if (afbClient->streamIdJ) json_object_put(afbClient->streamIdJ);
+ // close binder websocket
+ //ISSUE for Jose
+ //if (afbClient->pws) afb_proto_ws_unref(afbClient->pws);
free(afbClient);
}
static int AlsaCloseHook(snd_pcm_hook_t *hook) {
afbClientT *afbClient = (afbClientT*) snd_pcm_hook_get_private (hook);
-
+ //hook is already close
+ if (!afbClient || afbClient->magic != MAGIC_HOOK ) {
+ if (afbClient->verbose) printf("AlsaCloseHook Ignored, invalid afbClient\n");
+ return 0;
+ }
// launch call request and create a waiting mainloop thread
int err = LaunchCallRequest(afbClient, HOOK_CLOSE);
if (err < 0) {
@@ -431,13 +462,14 @@ static int AlsaCloseHook(snd_pcm_hook_t *hook) {
if (s != 0)
printf("AlsaCloseHook: ERROR on pthread_join err %d\n",s);
- if (res == PTHREAD_CANCELED)
+ if (res == PTHREAD_CANCELED) {
if (afbClient->verbose) fprintf(stdout, "\nAlsaHook Close Success PCM=%s URI=%s\n", snd_pcm_name(afbClient->pcm), afbClient->uri);
- else
+ } else {
printf("AlsaCloseHook: EventLoop thread failed to canceled (shouldn't happen!)\n");
+ }
AlsaHookClean(afbClient);
-
+ snd_pcm_hook_set_private(hook,NULL);
return 0;
OnErrorExit:
@@ -627,6 +659,8 @@ int PLUGIN_ENTRY_POINT (snd_pcm_t *pcm, snd_config_t *conf) {
afbClient->verbose = 0;
(void) asprintf(&afbClient->uid, "hook:%s:%d", afbClient->name, getpid());
// Get PCM arguments from asoundrc
+
+ printf("HookEntry handle=0x%x pcm=%s\n", afbClient, afbClient->name);
snd_config_for_each(it, next, conf) {
snd_config_t *node = snd_config_iterator_entry(it);
const char *id;
@@ -697,7 +731,7 @@ int PLUGIN_ENTRY_POINT (snd_pcm_t *pcm, snd_config_t *conf) {
err = snd_pcm_hook_add(&h_close, afbClient->pcm, SND_PCM_HOOK_TYPE_CLOSE, AlsaCloseHook, afbClient);
if (err < 0) goto OnErrorExit;
-
+ afbClient->magic=MAGIC_HOOK;
// launch call request and create a waiting mainloop thread
err = LaunchCallRequest(afbClient, HOOK_INSTALL);
if (err < 0) {
@@ -720,6 +754,6 @@ OnErrorExit:
if (h_close)
snd_pcm_hook_remove(h_close);
- return -EINVAL;
+ return 0;
}