diff options
-rw-r--r-- | alsa-hook/PolicyAlsaHook.c | 66 |
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; } |