From 521281617cec5d89725c4844eac68b5a772fab57 Mon Sep 17 00:00:00 2001 From: Fulup Ar Foll Date: Sat, 11 Mar 2017 00:27:30 +0100 Subject: Work in Progress Static/Dynamic Lib Fixed. Source Tree cleaned up Compile but to be tested Business Logic not done --- AudioLogic/AudioLogicBinding.c | 21 +++- AudioLogic/AudioLogicLib.c | 253 ++++++++++++++++++++--------------------- AudioLogic/AudioLogicLib.h | 24 +--- 3 files changed, 143 insertions(+), 155 deletions(-) (limited to 'AudioLogic') diff --git a/AudioLogic/AudioLogicBinding.c b/AudioLogic/AudioLogicBinding.c index 0c63d00..002ff42 100644 --- a/AudioLogic/AudioLogicBinding.c +++ b/AudioLogic/AudioLogicBinding.c @@ -30,10 +30,21 @@ PUBLIC const struct afb_binding_interface *afbIface; -STATIC void localping(struct afb_req request) { - json_object *query = afb_req_json(request); - afb_req_success(request, query, NULL); -} +// 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 +}; /* @@ -41,7 +52,7 @@ STATIC void localping(struct afb_req request) { */ 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= localping, .info= "Ping Binding" }, + { .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" }, diff --git a/AudioLogic/AudioLogicLib.c b/AudioLogic/AudioLogicLib.c index b45707a..e9d7104 100644 --- a/AudioLogic/AudioLogicLib.c +++ b/AudioLogic/AudioLogicLib.c @@ -30,45 +30,33 @@ static struct afb_service srvitf; -STATIC int cbCheckResponse (struct afb_req request, int iserror, struct json_object *result) { - struct json_object *response, *status, *info; - - if (iserror) { // on error proxy information we got from lower layer - if (result) { - if (json_object_object_get_ex(result, "request", &response)) { - json_object_object_get_ex(response, "info" , &info); - json_object_object_get_ex(response, "status", &status); - afb_req_fail(request, json_object_get_string(status), json_object_get_string(info)); - goto OnExit; - } - } else { - afb_req_fail(request, "cbCheckFail", "No Result inside API response" ); - } - goto OnErrorExit; - } - return (0); - - OnErrorExit: - return (1); -} +// 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"); + afb_req_fail_f(request, "argument-missing", "vol=+-%[0,100] missing"); goto OnExit; } - + switch (vol[0]) { case '+': break; @@ -76,99 +64,105 @@ PUBLIC void audioLogicSetVol(struct afb_req request) { break; case '%': break; - + default: - afb_req_fail_f (request, "value-invalid", "volume should be (+-%[0-100]xxx) vol=%s", vol); - goto OnExit; + 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)); - + + // ********** 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; +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) { + +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: + if (!cbCheckResponse(request, iserror, result)) goto OnExit; + +OnExit: return; } // Create and subscribe to alsacore ctl events PUBLIC void audioLogicMonitor(struct afb_req request) { - - // keep request for callback to respond - struct afb_req *handle = afb_req_store(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=[%] 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)); - + 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 + 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"); + else afb_req_fail_f(request, "context-invalid", "No valid queryurl in client context"); - // success/failure messages return from callback + // success/failure messages return from callback +OnExit: + return; } // Subscribe to AudioBinding events -PUBLIC void audioLogicSubscribe (struct afb_req request) { - - return; + +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); + 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) { + +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 + 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=[%] 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=[%] name=[%s]", ctx->devid, ctx->shortname); - 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=[%] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; + goto OnExit; } // extract sounds controls information from received Object @@ -176,97 +170,97 @@ STATIC void audioLogicOpenCB2 (void *handle, int iserror, struct json_object *re json_object_object_get_ex(response, "ctls", &ctls); if (!ctls) { afb_req_fail_f(request, "ctls-notfound", "No Controls return from HAL/getcontrol devid=[%] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; + goto OnExit; } - + // make sure return controls have a valid type - if (json_object_get_type (ctls) != json_type_array ) { + if (json_object_get_type(ctls) != json_type_array) { afb_req_fail_f(request, "ctls-notarray", "Invalid Controls return from HAL/getcontrol devid=[%] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; + goto OnExit; } - + // loop on array and store values into client context - for (int idx=0; idx < json_object_array_length (ctls), idx++) { + for (int idx = 0; idx < json_object_array_length(ctls); idx++) { struct json_object *ctl; - halControlEnumT control; + halCtlsEnumT control; int value; - + ctl = json_object_array_get_idx(ctls, idx); - if (json_object_array_length(ctl != 2)) { + if (json_object_array_length(ctl) != 2) { afb_req_fail_f(request, "ctl-invalid", "Invalid Control return from HAL/getcontrol devid=[%] name=[%s] ctl=%s" - , ctx->devid, ctx->shortname, json_object_get_string(ctl)); - goto OnExit; + , 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 = (halControlEnumT)json_object_get_int(json_object_array_get_idx(ctl,0)); - value = json_object_get_int(json_object_array_get_idx(ctl,0)); - - switch(control) { + 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; + 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)): + NOTICE(afbIface, "audioLogicOpenCB2 unknown HAL control=[%s]", json_object_get_string(ctl)); } } - - OnExit: + +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) { +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 - + 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 devid=[%] name=[%s]", ctx->devid, ctx->shortname); - goto OnExit; + 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)); + 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); + 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)); + 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)); + 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)); + 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)); + 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)); + 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); @@ -274,25 +268,25 @@ STATIC void audioLogicOpenCB1 (void *handle, int iserror, struct json_object *re if (!ctx->halapi) { afb_req_fail_f(request, "hal-notfound", "No HAL found devid=[%] name=[%s]", ctx->devid, ctx->shortname); goto OnExit; - } - - struct json_object *queryurl =json_object_new_object(); - struct json_object *ctls =json_object_new_object(); + } + + 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_object_add(ctls, json_object_new_int((int)Master_Playback_Volume)); - json_object_object_add(ctls, json_object_new_int((int)PCM_Playback_Volume)); - json_object_object_add(ctls, json_object_new_int((int)PCM_Playback_Switch)); - json_object_object_add(ctls, json_object_new_int((int)Capture_Volume)); + 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_array_add(queryurl, ctx->queryurl); - json_object_object_add(queryurl, "ctls",ctls); + 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: + +OnExit: // release original calling request afb_req_unref(request); return; @@ -303,21 +297,20 @@ PUBLIC void audioLogicOpen(struct afb_req request) { // Delegate query to lower level struct afb_req *handle = afb_req_store(request); - if (!handle) afb_req_fail(request, "error", "out of memory"); - else afb_service_call(srvitf, "alsacore", "getCardId", json_object_get(afb_req_json(request)), audioLogicOpenCB1, handle); + 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) { - +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); + 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; +PUBLIC int audioLogicInit(struct afb_service service) { + srvitf = service; return 0; } diff --git a/AudioLogic/AudioLogicLib.h b/AudioLogic/AudioLogicLib.h index 10e431d..77b8b7b 100644 --- a/AudioLogic/AudioLogicLib.h +++ b/AudioLogic/AudioLogicLib.h @@ -15,30 +15,14 @@ * limitations under the License. */ +#ifndef AUDIOLOGIC_H +#define AUDIOLOGIC_H -// few coding convention -typedef int BOOL; -#ifndef PUBLIC - #define PUBLIC -#endif -#ifndef FALSE - #define FALSE 0 -#endif -#ifndef TRUE - #define TRUE 1 -#endif -#define STATIC static - -#ifndef AUDIOLIBMAPPING_H -#define AUDIOLIBMAPPING_H - +#include "AudioCommonLib.h" #include #include #include -#include "AlsaHalCtls.h" // Alsa Hardware Abstraction Layer Controls - - // import from AlsaAfbBinding extern const struct afb_binding_interface *afbIface; @@ -69,5 +53,5 @@ PUBLIC void audioLogicClose(struct afb_req request); PUBLIC void audioLogicSubscribe(struct afb_req request); PUBLIC int audioLogicInit (struct afb_service service); -#endif /* AUDIOLIBMAPPING_H */ +#endif /* AUDIOLOGIC_H */ -- cgit 1.2.3-korg