summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFulup Ar Foll <fulup@iot.bzh>2017-10-27 16:45:10 +0200
committerFulup Ar Foll <fulup@iot.bzh>2017-10-27 16:45:10 +0200
commitf9774538ec99c812b7effc3b77160608a343fce0 (patch)
tree42e98dbb7cdd3d4ed880f7012e14d29a12b1135c
parent0206a78da6f11d2fec68ef50c44afb427eb132d6 (diff)
Initial working version with unix/ws
m---------afb-utilities0
m---------conf.d/app-templates0
-rw-r--r--hook-plugin/PolicyHookCb.c72
-rw-r--r--hook-plugin/README.md108
4 files changed, 126 insertions, 54 deletions
diff --git a/afb-utilities b/afb-utilities
-Subproject fd86e75feab42c0d0676a80e9aa415fa507e9a5
+Subproject 77c12fc3a44ce4fd1f4a83019547190d0f44549
diff --git a/conf.d/app-templates b/conf.d/app-templates
-Subproject 6230618d8e66dc4902e43e7e85fa03317f209a0
+Subproject c881d86fc8852a2b2215856d3503aba192c0f4e
diff --git a/hook-plugin/PolicyHookCb.c b/hook-plugin/PolicyHookCb.c
index b751ed6..1ca6670 100644
--- a/hook-plugin/PolicyHookCb.c
+++ b/hook-plugin/PolicyHookCb.c
@@ -30,6 +30,8 @@
#define _GNU_SOURCE
#include <stdio.h>
+#include <alloca.h>
+
#include <alsa/asoundlib.h>
#include <alsa/conf.h>
#include <alsa/pcm.h>
@@ -65,15 +67,12 @@
// Currently not implemented
#define UNUSED_ARG(x) UNUSED_ ## x __attribute__((__unused__))
-static void OnSuccessCB(void* UNUSED_ARG(handle) , void* UNUSED_ARG(request), struct json_object* UNUSED_ARG(reslt), const char* UNUSED_ARG(info)) {}
-static void OnFailureCB(void* UNUSED_ARG(closure), void* UNUSED_ARG(request), const char *UNUSED_ARG(status), const char *UNUSED_ARG(info)) {}
typedef struct {
const char *openVerb;
const char *closeVerb;
json_object *queryJ;
long timeout;
- size_t length;
sd_event_source *evtSource;
char *callIdTag;
@@ -169,46 +168,55 @@ OnErrorExit:
return;
}
-
-/* the callback interface for pws */
-static struct afb_proto_ws_client_itf itf = {
- .on_reply_success = OnSuccessCB,
- .on_reply_fail = OnFailureCB,
- .on_event_create = NULL,
- .on_event_remove = NULL,
- .on_event_subscribe = NULL,
- .on_event_unsubscribe = NULL,
- .on_event_push = OnEventCB,
- .on_event_broadcast = NULL,
- .on_subcall = NULL,
-};
-
-void OnResponseCB(void *handle, struct afb_wsj1_msg *msg) {
+static void OnSuccessCB(void* UNUSED_ARG(ctx) , void* handle, json_object* responseJ, const char* info) {
+
afbRequestT *afbRequest= (afbRequestT*)handle;
afbClientT *afbClient=(afbClientT*)afbRequest->afbClient;
- if (afbClient->verbose) printf("ON-RESPONSE call=%s response=%s\n", afbRequest->callIdTag, afb_wsj1_msg_object_s(msg));
+ if (afbClient->verbose) printf("OnSuccessCB callid='%s' response='%s' info='%s'\n", afbRequest->callIdTag, json_object_get_string(responseJ), info);
// Cancel timeout for this request
sd_event_source_unref(afbRequest->evtSource);
-
- if (! afb_wsj1_msg_is_reply_ok(msg)) goto OnErrorExit;
+ free(afbRequest->callIdTag);
// When not more waiting call release semaphore
afbClient->count--;
if (afbClient->count == 0) {
- if (afbClient->verbose) printf("ON-RESPONSE No More Waiting Request\n");
+ if (afbClient->verbose) printf("OnSuccessCB No More Waiting Request\n");
afbClient->error=0;
sem_post (&afbClient->semaphore);
}
- return;
+}
-OnErrorExit:
- fprintf(stderr, "ON-RESPONSE ERROR call=%s response=%s\n", afbRequest->callIdTag, afb_wsj1_msg_object_s(msg));
- afbClient->error=1;
+static void OnFailureCB(void* UNUSED_ARG(ctx), void* handle, const char *status, const char *info) {
+
+ afbRequestT *afbRequest= (afbRequestT*)handle;
+ afbClientT *afbClient=(afbClientT*)afbRequest->afbClient;
+
+ if (afbClient->verbose) printf("OnFailureCB callid='%s' status='%s' info='%s'\n", afbRequest->callIdTag, status, info);
+
+ // Cancel timeout for this request
+ sd_event_source_unref(afbRequest->evtSource);
+ free(afbRequest->callIdTag);
+
+ afbClient->error=1;
sem_post (&afbClient->semaphore);
}
+
+/* the callback interface for pws */
+static struct afb_proto_ws_client_itf itf = {
+ .on_reply_success = OnSuccessCB,
+ .on_reply_fail = OnFailureCB,
+ .on_event_create = NULL,
+ .on_event_remove = NULL,
+ .on_event_subscribe = NULL,
+ .on_event_unsubscribe = NULL,
+ .on_event_push = OnEventCB,
+ .on_event_broadcast = NULL,
+ .on_subcall = NULL,
+};
+
int OnTimeoutCB (sd_event_source* source, uint64_t timer, void* handle) {
afbClientT *afbClient= (afbClientT*)handle;
@@ -240,9 +248,11 @@ static int CallWithTimeout(afbClientT *afbClient, afbRequestT *afbRequest, int c
else apiVerb= afbRequest->openVerb;
// release action is optional
- if (apiVerb) {
+ if (apiVerb) {
+ char * sessionId;
+ (void) asprintf(&sessionId, "alsa-hook-pid:%d", getpid());
if (afbClient->verbose) printf("CALL-REQUEST verb=%s tag=%s\n", apiVerb, afbRequest->callIdTag);
- err = afb_proto_ws_client_call(afbClient->pws, apiVerb, afbRequest->queryJ, "xxxx", afbRequest);
+ err = afb_proto_ws_client_call(afbClient->pws, apiVerb, afbRequest->queryJ, sessionId, afbRequest);
if (err < 0 ) goto OnErrorExit;
}
// save client handle in request
@@ -372,7 +382,7 @@ int PLUGIN_ENTRY_POINT (snd_pcm_t *pcm, snd_config_t *conf) {
continue;
}
- if (strcmp(id, "request") == 0) {
+ if (strcmp(id, "controls") == 0) {
const char *callConf, *callLabel;
snd_config_type_t ctype;
snd_config_iterator_t currentCall, follow;
@@ -469,7 +479,7 @@ int PLUGIN_ENTRY_POINT (snd_pcm_t *pcm, snd_config_t *conf) {
}
continue;
}
- if (strcmp(id, "event") == 0) {
+ if (strcmp(id, "events") == 0) {
const char *callConf, *callLabel;
snd_config_type_t ctype;
snd_config_iterator_t currentCall, follow;
@@ -541,7 +551,7 @@ int PLUGIN_ENTRY_POINT (snd_pcm_t *pcm, snd_config_t *conf) {
return 0;
OnErrorExit:
- fprintf(stderr, "\nAlsaPcmHook Plugin Install Fail PCM=%s\n", snd_pcm_name(pcm));
+ fprintf(stderr, "\nAlsaPcmHook Plugin Policy Control Fail PCM=%s\n", snd_pcm_name(pcm));
if (h_close)
snd_pcm_hook_remove(h_close);
diff --git a/hook-plugin/README.md b/hook-plugin/README.md
index 748f66f..4297498 100644
--- a/hook-plugin/README.md
+++ b/hook-plugin/README.md
@@ -20,43 +20,104 @@ Test
Config
```
-# Define sharelib location and entry point
-# -----------------------------------------
-pcm_hook_type.MyHookPlugin {
- install "AlsaInstallHook"
- lib "/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/build/Alsa-Plugin/Alsa-Hook-Callback/alsa_hook_cb.so"
+#
+# Author: Fulup Ar Foll
+# Object: PCM hook type
+#
+# Test : Note: Jabra_USB=hw:v1340
+# Check SoundCard ==> speaker-test -Dhw:v1340 -c2 -twav
+# Check MixerPCM ==> speaker-test -DSpeakers -c2 -twav
+# Check SoftVol ==> speaker-test -DMusicPCM -c2 -twav
+# Check Plugin ==> speaker-test -DMultimedia -c2 -twav
+# MultiMedia aplay -DDMyNavPCM /usr/share/sounds/alsa/test.wav
+#
+# Bug/Feature: when softvol control is initialised from plugin and not
+# from AGL binding. At 1st run ctl has invalid TLV and cannot be
+# use. Bypass Solution:
+# * start audio-binder before playing sound (binding create control before softvol plugin)
+# * run a dummy aplay -DMyNavPCM "" to get a clean control
+#
+# References: https://www.spinics.net/lists/alsa-devel/msg54235.html
+# --------------------------------------------------------------------
+
+# ------------------------------------------------------
+# Mixer PCM allow to play multiple stream simultaneously
+# ------------------------------------------------------
+pcm.Speakers {
+ type dmix
+ slave {pcm "hw:v1340"} #Jabra Solmate 1
+ ipc_key 1001 # ipc_key should be unique to each dmix
+}
+
+# -----------------------------------------------------
+# Register ControllerHookPlugin (ToiBeFix fullpath)
+# -----------------------------------------------------
+pcm_hook_type.CtlHookPlugin {
+ install "AlsaInstallHook"
+ lib "/home/fulup/Workspace/Audio-4a/alsa-4a/build/hook-plugin/policy_hook_cb.so"
}
-# Create PCM HOOK with corresponding request calls to AGL Audio Agent
-# --------------------------------------------------------------------
-pcm.MyNavigationHook {
- type hooks
- slave.pcm "MyMixerPCM"
- # Defined used hook sharelib and provide arguments/config to install func
+# -------------------------------------------------------
+# Define one Audio Virtual Channel per Audio Roles
+# -------------------------------------------------------
+pcm.MusicPCM {
+ type softvol
+
+ # Point Slave on HOOK for policies control
+ slave.pcm "Speakers"
+
+ # name should match with HAL definition
+ control.name "Playback Multimedia"
+}
+
+pcm.NavPCM {
+ type softvol
+
+ # Point Slave on HOOK for policies control
+ slave.pcm "Speakers"
+
+ # name should match with HAL definition
+ control.name "Playback Navigation"
+}
+
+pcm.UrgentPCM {
+ type softvol
+
+ # Point Slave on HOOK for policies control
+ slave.pcm "Speakers"
+
+ # name should match with HAL definition
+ control.name "Playback Emergency"
+}
+
+# ----------------------------------------------------
+# Define one hooked PCM channel per Audio Roles
+# ----------------------------------------------------
+pcm.Multimedia {
+ type hooks
+ slave {pcm "MusicPCM"}
hooks.0 {
- type "MyHookPlugin"
+ comment "Defined used hook sharelib and provide arguments/config to install func"
+ type "CtlHookPlugin"
hook_args {
- verbose true # print few log messages (default false);
- # Every Call should return OK in order PCM to open (default timeout 100ms)
- uri "ws://localhost:1234/api?token='audio-agent-token'"
+ # print few log messages (default false)
+ verbose true
+
+ # uri to audio-4a policy engine
ws-client="unix:/var/tmp/pol4a"
- request {
+
+ # api subcall to request a role
+ controls {
# Request authorisation to write on navigation
navigation-ctl {
request "navigation-role"
release "release-role"
args "{'uid':'alsa-hook-navigation'}"
}
- # subscribe to Audio Agent Event map them to signal
- subscribe-evt {
- api "pol4a"
- verb "subscribe"
- }
}
- # map event reception to self generated signal
- event {
+ events { # map event reception to self generated signal
pause 30
resume 31
stop 3
@@ -65,6 +126,7 @@ pcm.MyNavigationHook {
}
}
+
```
NOTE: