From 10c42e135b22bf323836100ede042ec47ddb22a1 Mon Sep 17 00:00:00 2001 From: fulup Date: Tue, 27 Jun 2017 18:21:20 +0200 Subject: Work in Progress --- HighLevel-afb/CMakeLists.txt | 43 ------ HighLevel-afb/HighLevelApiConf.c | 98 ------------ HighLevel-afb/HighLevelBinding.c | 316 --------------------------------------- HighLevel-afb/HighLevelBinding.h | 54 ------- HighLevel-afb/README.md | 35 ----- 5 files changed, 546 deletions(-) delete mode 100644 HighLevel-afb/CMakeLists.txt delete mode 100644 HighLevel-afb/HighLevelApiConf.c delete mode 100644 HighLevel-afb/HighLevelBinding.c delete mode 100644 HighLevel-afb/HighLevelBinding.h delete mode 100644 HighLevel-afb/README.md (limited to 'HighLevel-afb') diff --git a/HighLevel-afb/CMakeLists.txt b/HighLevel-afb/CMakeLists.txt deleted file mode 100644 index 9d7af4c..0000000 --- a/HighLevel-afb/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -########################################################################### -# Copyright 2015, 2016, 2017 IoT.bzh -# -# author: Fulup Ar Foll -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################### - - -# Add target to project dependency list -PROJECT_TARGET_ADD(audio) - - # Define project Targets - ADD_LIBRARY(audio MODULE HighLevelApiConf.c HighLevelBinding.c) - - # Binder exposes a unique public entry point - SET_TARGET_PROPERTIES(audio PROPERTIES - PREFIX "afb-" - LABELS "BINDING" - LINK_FLAGS ${BINDINGS_LINK_FLAG} - OUTPUT_NAME ${TARGET_NAME} - - ) - - # Library dependencies (include updates automatically) - TARGET_LINK_LIBRARIES(audio - audio-inter - ${link_libraries} - ) - - # installation directory - INSTALL(TARGETS audio - LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR}) diff --git a/HighLevel-afb/HighLevelApiConf.c b/HighLevel-afb/HighLevelApiConf.c deleted file mode 100644 index 75e4a2f..0000000 --- a/HighLevel-afb/HighLevelApiConf.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2016 "IoT.bzh" - * Author Fulup Ar Foll - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "HighLevelBinding.h" - -PUBLIC const struct afb_binding_interface *afbIface; - -// Map HAL Enum to Labels -typedef const struct { - halCtlsEnumT control; - char *label; -} LogicControlT; - -// High Level Control Mapping to String for JSON & HTML5 -STATIC LogicControlT LogicControl[] = { - {.control= Master_Playback_Volume,.label= "Master_Volume"}, - {.control= PCM_Playback_Volume, .label= "Playback_Volume"}, - {.control= PCM_Playback_Switch, .label= "Playback_Switch"}, - {.control= Capture_Volume, .label= "Capture_Volume"}, - - {.control= 0,.label= NULL} // closing convention -}; - - -/* - * array of the verbs exported to afb-daemon - */ -STATIC const struct afb_verb_desc_v1 binding_verbs[] = { - /* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */ - { .name= "ping" , .session= AFB_SESSION_NONE, .callback= pingtest, .info= "Ping Binding" }, - { .name= "setvolume", .session= AFB_SESSION_CHECK, .callback= audioLogicSetVol, .info= "Set Volume" }, - { .name= "getvolume", .session= AFB_SESSION_CHECK, .callback= audioLogicGetVol, .info= "Get Volume" }, - { .name= "subscribe", .session= AFB_SESSION_CHECK, .callback= audioLogicSubscribe, .info= "Subscribe AudioBinding Events" }, - { .name= "monitor", .session= AFB_SESSION_CHECK, .callback= audioLogicMonitor, .info= "Activate AlsaCtl Monitoring" }, - { .name= "open", .session= AFB_SESSION_CREATE,.callback= audioLogicOpen, .info= "Open a Dedicated SoundCard" }, - { .name= "close", .session= AFB_SESSION_CLOSE, .callback= audioLogicClose, .info= "Close previously open SoundCard" }, - { .name= NULL } /* marker for end of the array */ -}; - -/* - * description of the binding for afb-daemon - */ -STATIC const struct afb_binding binding_description = { - /* description conforms to VERSION 1 */ - .type= AFB_BINDING_VERSION_1, - .v1= { - .prefix= "audio", - .info= "High Level Interface to Audio bindings", - .verbs = binding_verbs - } -}; - -// This receive all event this binding subscribe to -PUBLIC void afbBindingV1ServiceEvent(const char *evtname, struct json_object *object) { - - NOTICE (afbIface, "afbBindingV1ServiceEvent evtname=%s [msg=%s]", evtname, json_object_to_json_string(object)); -} - -// this is call when after all bindings are loaded -PUBLIC int afbBindingV1ServiceInit(struct afb_service service) { - - return (audioLogicInit(service)); -}; - -/* - * activation function for registering the binding called by afb-daemon - */ -PUBLIC const struct afb_binding *afbBindingV1Register(const struct afb_binding_interface *itf) { - afbIface= itf; - - return &binding_description; /* returns the description of the binding */ -} - diff --git a/HighLevel-afb/HighLevelBinding.c b/HighLevel-afb/HighLevelBinding.c deleted file mode 100644 index 07ed2fc..0000000 --- a/HighLevel-afb/HighLevelBinding.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (C) 2016 "IoT.bzh" - * Author Fulup Ar Foll - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "HighLevelBinding.h" - -static struct afb_service srvitf; - - -// This callback is fired when afb_service_call for api/alsacore/subctl returns -STATIC void audioLogicSetVolCB(void *handle, int iserror, struct json_object *result) { - struct afb_req request = afb_req_unstore(handle); - - if (!cbCheckResponse(request, iserror, result)) goto OnExit; - -OnExit: - return; -} - -PUBLIC void audioLogicSetVol(struct afb_req request) { - struct json_object *queryurl; - int volume=0; // FULUP TBD !!!!!!!!!!!! - - // keep request for callback to respond - struct afb_req *handle = afb_req_store(request); - - // get client context - AudioLogicCtxT *ctx = afb_req_context_get(request); - - const char *vol = afb_req_value(request, "vol"); - if (vol == NULL) { - afb_req_fail_f(request, "argument-missing", "vol=+-%%[0,100] missing"); - goto OnExit; - } - - switch (vol[0]) { - case '+': - break; - case '-': - break; - case '%': - break; - - default: - afb_req_fail_f(request, "value-invalid", "volume should be (+-%%[0-100]xxx) vol=%s", vol); - goto OnExit; - } - - if (!ctx->halapi) { - afb_req_fail_f(request, "context-invalid", "No valid halapi in client context"); - goto OnExit; - } - - // ********** Caluler le volume en % de manière intelligente - queryurl = json_object_new_object(); - json_object_object_add(ctx->queryurl, "pcm", json_object_new_int(Master_Playback_Volume)); - json_object_object_add(ctx->queryurl, "value", json_object_new_int(volume)); - - // subcontract HAL API to process volume - afb_service_call(srvitf, ctx->halapi, "volume", queryurl, audioLogicSetVolCB, handle); - - // final success/failure messages handle from callback -OnExit: - return; -} - -// This callback is fired when afb_service_call for api/alsacore/subctl returns - -STATIC void alsaSubcribeCB(void *handle, int iserror, struct json_object *result) { - struct afb_req request = afb_req_unstore(handle); - - if (!cbCheckResponse(request, iserror, result)) goto OnExit; - -OnExit: - return; -} - -// Create and subscribe to alsacore ctl events -PUBLIC void audioLogicMonitor(struct afb_req request) { - - - // get client context - AudioLogicCtxT *ctx = afb_req_context_get(request); - if (!ctx) { - afb_req_fail_f(request, "ctx-notfound", "No Client Context HAL/getcontrol devid=[%s] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; - } - - // push request to low level binding - NOTICE(afbIface, "audioLogicMonitor ctx->devid=%s [ctx->queryurl=%s]", ctx->devid, json_object_to_json_string(ctx->queryurl)); - - if (ctx->queryurl) { - json_object_get(ctx->queryurl); // Make sure usage count does not fall to zero - struct afb_req *handle = afb_req_store(request); - afb_service_call(srvitf, "alsacore", "subscribe", ctx->queryurl, alsaSubcribeCB, handle); - } - else afb_req_fail_f(request, "context-invalid", "No valid queryurl in client context"); - - // success/failure messages return from callback -OnExit: - return; -} - -// Subscribe to AudioBinding events - -PUBLIC void audioLogicSubscribe(struct afb_req request) { - - return; -} - - -// Call when all bindings are loaded and ready to accept request -PUBLIC void audioLogicGetVol(struct afb_req request) { - - // Should call here Hardware Alsa Abstraction Layer for corresponding Sound Card - afb_req_success(request, NULL, NULL); - return; - -} - -// This callback is fired when afb_service_call for api/alsacore/subctl returns - -STATIC void audioLogicOpenCB2(void *handle, int iserror, struct json_object *result) { - struct json_object *response; - - // Make sure we got a response from API - struct afb_req request = afb_req_unstore(handle); - if (!cbCheckResponse(request, iserror, result)) goto OnExit; - - // get client context - AudioLogicCtxT *ctx = afb_req_context_get(request); - if (!ctx) { - afb_req_fail_f(request, "ctx-notfound", "No Client Context HAL/getcontrol devid=[%s] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; - } - - // Get response from object - json_object_object_get_ex(result, "response", &response); - if (!response) { - afb_req_fail_f(request, "response-notfound", "No Controls return from HAL/getcontrol devid=[%s] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; - } - - // extract sounds controls information from received Object - struct json_object *ctls; - json_object_object_get_ex(response, "ctls", &ctls); - if (!ctls) { - afb_req_fail_f(request, "ctls-notfound", "No Controls return from HAL/getcontrol devid=[%s] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; - } - - // make sure return controls have a valid type - if (json_object_get_type(ctls) != json_type_array) { - afb_req_fail_f(request, "ctls-notarray", "Invalid Controls return from HAL/getcontrol devid=[%s] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; - } - - // loop on array and store values into client context - for (int idx = 0; idx < json_object_array_length(ctls); idx++) { - struct json_object *ctl; - halCtlsEnumT control; - int value; - - ctl = json_object_array_get_idx(ctls, idx); - if (json_object_array_length(ctl) != 2) { - afb_req_fail_f(request, "ctl-invalid", "Invalid Control return from HAL/getcontrol devid=[%s] name=[%s] ctl=%s" - , ctx->devid, ctx->shortname, json_object_get_string(ctl)); - goto OnExit; - } - - // As HAL and Business logic use the same AlsaMixerHal.h direct conversion is not an issue - control = (halCtlsEnumT) json_object_get_int(json_object_array_get_idx(ctl, 0)); - value = json_object_get_int(json_object_array_get_idx(ctl, 1)); - - switch (control) { - case Master_Playback_Volume: - ctx->volumes.masterPlaybackVolume = value; - break; - - case PCM_Playback_Volume: - ctx->volumes.pcmPlaybackVolume = value; - break; - - case PCM_Playback_Switch: - ctx->volumes.pcmPlaybackSwitch = value; - break; - - case Capture_Volume: - ctx->volumes.captureVolume = value; - break; - - default: - NOTICE(afbIface, "audioLogicOpenCB2 unknown HAL control=[%s]", json_object_get_string(ctl)); - } - } - -OnExit: - afb_req_context_set(request, ctx, free); - return; -} - -// This callback is fired when afb_service_call for api/alsacore/subctl returns -STATIC void audioLogicOpenCB1(void *handle, int iserror, struct json_object *result) { - struct json_object *response, *subobj; - - // Make sure we got a valid API response - struct afb_req request = afb_req_unstore(handle); - if (!cbCheckResponse(request, iserror, result)) goto OnExit; - - // Get response from object - json_object_object_get_ex(result, "response", &response); - if (!response) { - afb_req_fail_f(request, "response-notfound", "No Controls return from HAL/getcontrol"); - goto OnExit; - } - - // attach client context to session - AudioLogicCtxT *ctx = malloc(sizeof (AudioLogicCtxT)); - - // extract information from Json Alsa Object - json_object_object_get_ex(response, "cardid", &subobj); - if (subobj) ctx->cardid = json_object_get_int(subobj); - - // store devid as an object for further alsa request - json_object_object_get_ex(response, "devid", &subobj); - if (subobj) ctx->devid = strdup(json_object_get_string(subobj)); - - json_object_object_get_ex(response, "halapi", &subobj); - if (subobj) ctx->halapi = strdup(json_object_get_string(subobj)); - - json_object_object_get_ex(response, "shortname", &subobj); - if (subobj)ctx->shortname = strdup(json_object_get_string(subobj)); - - json_object_object_get_ex(response, "longname", &subobj); - if (subobj)ctx->longname = strdup(json_object_get_string(subobj)); - - // save queryurl with devid only for further ALSA request - ctx->queryurl = json_object_new_object(); - json_object_object_add(ctx->queryurl, "devid", json_object_new_string(ctx->devid)); - - afb_req_context_set(request, ctx, free); - - // sound card was find let's store keycontrols into client session - if (!ctx->halapi) { - afb_req_fail_f(request, "hal-notfound", "No HAL found devid=[%s] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; - } - - struct json_object *queryurl = json_object_new_object(); - struct json_object *ctls = json_object_new_array(); - - // add sound controls we want to keep track of into client session context - json_object_array_add(ctls, json_object_new_int((int) Master_Playback_Volume)); - json_object_array_add(ctls, json_object_new_int((int) PCM_Playback_Volume)); - json_object_array_add(ctls, json_object_new_int((int) PCM_Playback_Switch)); - json_object_array_add(ctls, json_object_new_int((int) Capture_Volume)); - - // send request to soundcard HAL binding - json_object_object_add(queryurl, "ctls", ctls); - handle = afb_req_store(request); // FULUP ???? Needed for 2nd Callback ???? - afb_service_call(srvitf, ctx->halapi, "getControl", queryurl, audioLogicOpenCB2, handle); - - afb_req_success(request, response, NULL); - -OnExit: - // release original calling request - afb_req_unref(request); - return; -} - -// Delegate to lowerlevel the mapping of soundcard name with soundcard ID -PUBLIC void audioLogicOpen(struct afb_req request) { - - // Delegate query to lower level - struct afb_req *handle = afb_req_store(request); - afb_service_call(srvitf, "alsacore", "getCardId", json_object_get(afb_req_json(request)), audioLogicOpenCB1, handle); -} - -// Free client context create from audioLogicOpenCB -PUBLIC void audioLogicClose(struct afb_req request) { - - // retrieve current client context to print debug info - AudioLogicCtxT *ctx = (AudioLogicCtxT*) afb_req_context_get(request); - DEBUG(afbIface, "audioLogicClose cardid=%d devid=%s shortname=%s longname=%s", ctx->cardid, ctx->devid, ctx->shortname, ctx->longname); -} - - -// this function is call after all binder are loaded and initialised -PUBLIC int audioLogicInit(struct afb_service service) { - srvitf = service; - return 0; -} diff --git a/HighLevel-afb/HighLevelBinding.h b/HighLevel-afb/HighLevelBinding.h deleted file mode 100644 index c1a0aef..0000000 --- a/HighLevel-afb/HighLevelBinding.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * AlsaLibMapping -- provide low level interface with AUDIO lib (extracted from alsa-json-gateway code) - * Copyright (C) 2015,2016,2017, Fulup Ar Foll fulup@iot.bzh - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef AUDIOLOGIC_H -#define AUDIOLOGIC_H - -#include "audio-interface.h" - -// import from AlsaAfbBinding -extern const struct afb_binding_interface *afbIface; - - -// This structure hold private data for a given client of binding -typedef struct { - - int cardid; - const char *devid; - const char *shortname; - const char *longname; - const char *halapi; - struct { // volume in % [0-100] - int masterPlaybackVolume; - int pcmPlaybackVolume; - int pcmPlaybackSwitch; - int captureVolume; - } volumes; - json_object *queryurl; -} AudioLogicCtxT; - -// import from AlsaAfbMapping -PUBLIC void audioLogicSetVol (struct afb_req request); -PUBLIC void audioLogicGetVol(struct afb_req request); -PUBLIC void audioLogicMonitor(struct afb_req request); -PUBLIC void audioLogicOpen(struct afb_req request); -PUBLIC void audioLogicClose(struct afb_req request); -PUBLIC void audioLogicSubscribe(struct afb_req request); -PUBLIC int audioLogicInit (struct afb_service service); - -#endif /* AUDIOLOGIC_H */ - diff --git a/HighLevel-afb/README.md b/HighLevel-afb/README.md deleted file mode 100644 index fa50173..0000000 --- a/HighLevel-afb/README.md +++ /dev/null @@ -1,35 +0,0 @@ ------------------------------------------------------------------------- - AudioLogic High Level APIs ------------------------------------------------------------------------- - -Testing: (from project directory bindings) - * start binder: ~/opt/bin/afb-daemon --ldpaths=./build --token=mysecret --roothttp=htdocs - * connect browser on http://localhost:1234?devid=hw:0 - - # Open Sound Card from its name - http://localhost:1234/api/audio/open?token=mysecret&sndname=H650e - - # Subscribe event for a given board - http://localhost:1234/api/audio/subscribe?token=mysecret&devid=hw:0 - - # Increase Volume - http://localhost:1234/api/audio/setvol?token=mysecret&devid=hw:0&pcm=master&vol=50% - - # Get Volume - http://localhost:1234/api/audio/getvol?token=mysecret&devid=hw:0&pcm=master - - # Close Session - http://localhost:1234/api/audio/close?token=mysecret - - -Testing with afb-client-demo - -``` -~/opt/bin/afb-client-demo localhost:1234/api?token=mysecret -alsacore subctl {"devid":"hw:0"} -``` - -Start AlsaMixer and change volume -``` -alsamixer -D hw:0 -``` \ No newline at end of file -- cgit 1.2.3-korg