diff options
author | fulup <fulup.arfoll@iot.bzh> | 2017-04-09 14:35:00 +0200 |
---|---|---|
committer | fulup <fulup.arfoll@iot.bzh> | 2017-04-09 14:35:00 +0200 |
commit | 6e70aac6c9f02496978d3d02efb355d66fb36ceb (patch) | |
tree | d50df20591076b3da2031b2b9eb249f2a1921f53 /AlsaSound/HALayer/SharedHal/SharedHalLib.c | |
parent | c75c329e08f4c189419aa4c5607f38890885b46c (diff) |
Clean CMAKE structure and rename files/directories
Diffstat (limited to 'AlsaSound/HALayer/SharedHal/SharedHalLib.c')
-rw-r--r-- | AlsaSound/HALayer/SharedHal/SharedHalLib.c | 341 |
1 files changed, 0 insertions, 341 deletions
diff --git a/AlsaSound/HALayer/SharedHal/SharedHalLib.c b/AlsaSound/HALayer/SharedHal/SharedHalLib.c deleted file mode 100644 index 43d0cfe..0000000 --- a/AlsaSound/HALayer/SharedHal/SharedHalLib.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (C) 2016 "IoT.bzh" - * Author 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. - * - * reference: - * amixer contents; amixer controls; - * http://www.tldp.org/HOWTO/Alsa-sound-6.html - */ -#define _GNU_SOURCE // needed for vasprintf -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <netdb.h> -#include <fcntl.h> -#include <math.h> -#include <sys/time.h> -#include <sys/types.h> - -#include "SharedHalLib.h" - -typedef struct { - int index; - int numid; -} shareHallMap_T; - -static struct afb_service srvitf; -static const struct afb_binding_interface *afbIface; -static shareHallMap_T *shareHallMap; - -// Force specific HAL to depend on ShareHalLib -PUBLIC char* SharedHalLibVersion="1.0"; - -// This callback when api/alsacore/subscribe returns -STATIC void alsaSubcribeCB(void *handle, int iserror, struct json_object *result) { - struct afb_req request = afb_req_unstore(handle); - struct json_object *x, *resp = NULL; - const char *info = NULL; - - if (result) { - INFO(afbIface, "result=[%s]\n", json_object_to_json_string(result)); - if (json_object_object_get_ex(result, "request", &x) && json_object_object_get_ex(x, "info", &x)) - info = json_object_get_string(x); - if (!json_object_object_get_ex(result, "response", &resp)) resp = NULL; - } - - // push message respond - if (iserror) afb_req_fail_f(request, "Fail", info); - else afb_req_success(request, resp, info); - - // free calling request - afb_req_unref(request); -} - -// Create and subscribe to alsacore ctl events - -STATIC void halMonitor(struct afb_req request) { - - // save request in session as it might be used after return by callback - struct afb_req *handle = afb_req_store(request); - - // push request to low level binding - if (!handle) afb_req_fail(request, "error", "out of memory"); - else afb_service_call(srvitf, "alsacore", "subctl", json_object_get(afb_req_json(request)), alsaSubcribeCB, handle); - - // success/failure messages return from callback -} - -// Subscribe to AudioBinding events - -STATIC void halSubscribe(struct afb_req request) { - const char *devid = afb_req_value(request, "devid"); - if (devid == NULL) { - afb_req_fail_f(request, "devid-missing", "devid=hw:xxx missing"); - } -} - -// Call when all bindings are loaded and ready to accept request - -STATIC void halGetVol(struct afb_req request) { - - // Should call here Hardware Alsa Abstraction Layer for corresponding Sound Card - afb_req_success(request, NULL, NULL); - return; - -} - -STATIC void halSetVol(struct afb_req request) { - const char *arg; - const char *pcm; - - arg = afb_req_value(request, "vol"); - if (arg == NULL) { - afb_req_fail_f(request, "argument-missing", "vol=[0,100] missing"); - goto OnErrorExit; - } - - pcm = afb_req_value(request, "pcm"); - if (pcm == NULL) pcm = "Master"; - - // Should call here Hardware Alsa Abstraction Layer for corresponding Sound Card - afb_req_success(request, NULL, NULL); - return; - -OnErrorExit: - return; - -} - -// AudioLogic expect volume values to be 0-100% - -STATIC int NormaliseValue(const alsaHalCtlMapT *halCtls, int valuein) { - int valueout; - - if (valuein > halCtls->maxval) valuein= halCtls->maxval; - if (valuein < halCtls->minval) valuein= halCtls->minval; - - // volume are ajusted to 100% any else is ignored - switch (halCtls->group) { - case OUTVOL: - case PCMVOL: - case INVOL: - valueout = (valuein * 100) / (halCtls->maxval - halCtls->minval); - break; - default: - valueout = valuein; - } - return (valueout); -} - -// receive controls for LowLevel remap them to hight level before returning them - -STATIC void halGetControlCB(void *handle, int iserror, struct json_object *result) { - alsaHalMapT *halCtls = alsaHalSndCard.ctls; - struct json_object *response; - - // retrieve request and check for errors - 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 alsa/getcontrol result=[%s]", json_object_get_string(result)); - goto OnExit; - } - - // extract sounds controls information from received Object - struct json_object *ctls; - json_object_object_get_ex(result, "ctls", &ctls); - if (!ctls) { - afb_req_fail_f(request, "ctls-notfound", "No Controls return from alsa/getcontrol response=[%s]", json_object_get_string(response)); - 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 alsa/getcontrol response=[%s]", json_object_get_string(response)); - 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; - int rawvalue, numid; - - 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 alsa/getcontrol ctl=[%s]", json_object_get_string(ctl)); - goto OnExit; - } - - // As HAL and Business logic use the same AlsaMixerHal.h direct conversion is not an issue - numid = (halCtlsEnumT) json_object_get_int(json_object_array_get_idx(ctl, 0)); - rawvalue = json_object_get_int(json_object_array_get_idx(ctl, 1)); - - for (int idx = 0; halCtls[idx].alsa.numid != 0; idx++) { - if (halCtls[idx].alsa.numid == numid) { - struct json_object *ctlAndValue = json_object_new_array(); - json_object_array_add(ctlAndValue, json_object_new_int(idx)); // idx == high level control - json_object_array_add(ctlAndValue, json_object_new_int(NormaliseValue(&halCtls[idx].alsa, rawvalue))); - break; - } - } - if (shareHallMap[idx].numid == 0) { - - afb_req_fail_f(request, "ctl-invalid", "Invalid Control numid from alsa/getcontrol ctl=[%s]", json_object_get_string(ctl)); - goto OnExit; - } - } - - OnExit: - return; -} - - -// Translate high level control to low level and call lower layer -STATIC void halGetCtls(struct afb_req request) { - - struct json_object *queryin, *queryout, *ctlsin, *devid; - struct json_object *ctlsout = json_object_new_array(); - - // get query from request - queryin = afb_req_json(request); - - // check devid was given - if (!json_object_object_get_ex (queryin, "devid", &devid)) { - afb_req_fail_f(request, "devid-notfound", "No DevID given query=[%s]", json_object_get_string(queryin)); - goto OnExit; - } - - // loop on requested controls - if (!json_object_object_get_ex(queryin, "ctls", &ctlsin) || json_object_array_length(ctlsin) <= 0) { - afb_req_fail_f(request, "ctlsin-notfound", "No Controls given query=[%s]", json_object_get_string(queryin)); - goto OnExit; - } - - // loop on controls - for (int idx = 0; idx < json_object_array_length(ctlsin); idx++) { - struct json_object *ctl; - halCtlsEnumT control; - - // each control should be halCtlsEnumT - ctl = json_object_array_get_idx(ctlsin, idx); - control = (halCtlsEnumT) json_object_get_int(ctl); - if (control >= EndHalCrlTag || control <= StartHalCrlTag) { - afb_req_fail_f(request, "ctl-invalid", "Invalid Control devid=%s sndcard=%s ctl=[%s] should be [%d-%d]" - , json_object_get_string(devid), alsaHalSndCard.name, json_object_get_string(ctl), StartHalCrlTag, EndHalCrlTag); - goto OnExit; - } - - // add corresponding lowlevel numid to querylist - json_object_array_add(ctlsout, json_object_new_int(shareHallMap[control].numid)); - } - - // register HAL with Alsa Low Level Binder devid=hw:0&numid=1&quiet=0 - queryout = json_object_new_object(); - json_object_object_add(queryout, "devid", devid); - json_object_object_add(queryout, "ctls", ctlsout); - - // save request context dans call lowlevel API - struct afb_req *handle = afb_req_store(request); - afb_service_call(srvitf, "alsacore", "getctl", queryout, halGetControlCB, handle); - -OnExit: - // Under normal situation success/failure is set from callback - return; -}; - -STATIC void halInitCB(void *handle, int iserror, struct json_object *result) { - struct json_object *queryurl = (json_object*) handle; - - if (iserror) NOTICE(afbIface, "halInitCB: registration alsaHAL query=[%s] Fail", json_object_to_json_string(queryurl)); - else DEBUG(afbIface, "halInitCB: registration alsaHAL card=[%s] Success", json_object_to_json_string(queryurl)); -} - -// 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) { - int rc=0; - srvitf = service; - struct json_object *queryurl; - - if (alsaHalSndCard.initCB) { - rc= (alsaHalSndCard.initCB) (afbIface, service); - if (rc != 0) goto OnExit; - } - - // register HAL with Alsa Low Level Binder - queryurl = json_object_new_object(); - json_object_object_add(queryurl, "prefix", json_object_new_string(alsaHalSndCard.prefix)); - json_object_object_add(queryurl, "name", json_object_new_string(alsaHalSndCard.name)); - afb_service_call(srvitf, "alsacore", "registerHal", queryurl, halInitCB, queryurl); - - OnExit: - return (rc); -}; - -// Every HAL export the same API & Interface Mapping from SndCard to AudioLogic is done through alsaHalSndCardT -static const struct afb_verb_desc_v1 halSharedApi[] = { - /* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */ - { .name = "ping", .session = AFB_SESSION_NONE, .callback = pingtest, .info = "Ping Binding"}, - { .name = "getctls", .session = AFB_SESSION_NONE, .callback = halGetCtls, .info = "Get Control"}, - { .name = "setvol", .session = AFB_SESSION_NONE, .callback = halSetVol, .info = "Set Volume"}, - { .name = "getvol", .session = AFB_SESSION_NONE, .callback = halGetVol, .info = "Get Volume"}, - { .name = "subscribe", .session = AFB_SESSION_NONE, .callback = halSubscribe,.info = "Subscribe Alsa Events"}, - { .name = "monitor", .session = AFB_SESSION_NONE, .callback = halMonitor ,.info = "Monitor Alsa Events"}, - { .name = NULL} /* marker for end of the array */ -}; - - -static struct afb_binding alsaHalBinding = { - /* description conforms to VERSION 1 */ - .type= AFB_BINDING_VERSION_1, - .v1= { - .prefix= NULL, - .info = NULL, - .verbs = halSharedApi, - } -}; - -// Process HAL mapping from alsaHalSndCardT before registering HAL binder -PUBLIC const struct afb_binding *afbBindingV1Register(const struct afb_binding_interface *itf) { - - afbIface = itf; // need to keep a static trace of binder interface for avances functions - // alsaHalBinding.v1.verbs = halSharedApi; // complete sndcard specific alsaHalBinding with standard HAL APIs - alsaHalMapT *halCtls = alsaHalSndCard.ctls; // Get sndcard specific HAL control mapping - - if (halCtls == NULL) { - ERROR(afbIface, "afbBindingV1Register Fail alsaHalCtlsMap==NULL"); - return NULL; - } - - // Create a zone to store HAL high/low level mapping - shareHallMap = malloc(EndHalCrlTag * sizeof (shareHallMap_T)); - for (int idx = 0; (halCtls[idx].alsa.numid != 0 || halCtls[idx].cb.callback != NULL); idx++) { - if (halCtls[idx].alsa.numid == 0) halCtls[idx].alsa.numid =-1; - shareHallMap[halCtls[idx].alsa.control].numid = halCtls[idx].alsa.numid; - } - - alsaHalBinding.v1.prefix= alsaHalSndCard.prefix; - alsaHalBinding.v1.info = alsaHalSndCard.info; - return &alsaHalBinding; /* returns the description of the binding */ -}; |