summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ALSA-afb/Alsa-AddCtl.c180
-rw-r--r--ALSA-afb/Alsa-ApiHat.c1
-rw-r--r--ALSA-afb/Alsa-ApiHat.h1
-rw-r--r--ALSA-afb/Alsa-SetGet.c2
-rw-r--r--ALSA-afb/CMakeLists.txt2
-rw-r--r--Common/AudioCommonLib.c102
-rw-r--r--Common/AudioCommonLib.h68
-rw-r--r--Common/CMakeLists.txt31
-rw-r--r--HAL-afb/HAL-interface/hal-interface.c111
-rw-r--r--HAL-afb/HAL-interface/hal-interface.h2
-rw-r--r--HAL-afb/HDA-intel/CMakeLists.txt2
-rw-r--r--HAL-afb/HDA-intel/IntelHdaHAL.c21
-rw-r--r--HighLevel-afb/CMakeLists.txt14
-rw-r--r--Shared-Interface/CMakeLists.txt3
-rw-r--r--Shared-Interface/audio-interface.h3
m---------conf.d/app-templates0
-rw-r--r--htdocs/CMakeLists.txt22
-rw-r--r--nbproject/configurations.xml63
18 files changed, 528 insertions, 100 deletions
diff --git a/ALSA-afb/Alsa-AddCtl.c b/ALSA-afb/Alsa-AddCtl.c
new file mode 100644
index 0000000..e30ebea
--- /dev/null
+++ b/ALSA-afb/Alsa-AddCtl.c
@@ -0,0 +1,180 @@
+/*
+ * AlsaUseCase -- provide low level interface with ALSA 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.
+
+*/
+#define _GNU_SOURCE // needed for vasprintf
+
+#include <alsa/asoundlib.h>
+#include <systemd/sd-event.h>
+#include "Alsa-ApiHat.h"
+
+STATIC int addOneSndCtl(struct afb_req request, snd_ctl_t *ctlDev, json_object *ctlJ) {
+ snd_ctl_elem_info_t *cinfo;
+ int err;
+ int i;
+ unsigned int def_val;
+ json_object *jName, *jNumid, *jTmp;
+ const char *ctlName;
+ int ctlNumid, ctlMax, ctlMin, ctlStep, ctlCount, ctlSubDev;
+ snd_ctl_elem_type_t ctlType;
+ snd_ctl_elem_info_t *elemInfo;
+
+ // parse json ctl object
+ json_object_object_get_ex (ctlJ, "name" , &jName);
+ json_object_object_get_ex (ctlJ, "numid", &jNumid);
+ if (!jName || !jNumid) {
+ afb_req_fail_f (request, "ctl-invalid", "crl=%s name/numid missing", json_object_to_json_string(ctlJ));
+ goto OnErrorExit;
+ }
+
+ ctlName = json_object_to_json_string(jName);
+ ctlNumid = json_object_get_int(jNumid);
+
+ // default for json_object_get_int is zero
+ json_object_object_get_ex (ctlJ, "min" , &jTmp);
+ ctlMin = json_object_get_int(jTmp);
+
+ json_object_object_get_ex (ctlJ, "max" , &jTmp);
+ if (!jTmp) ctlMax=1;
+ else ctlMax = json_object_get_int(jTmp);
+
+ json_object_object_get_ex (ctlJ, "step" , &jTmp);
+ if (!jTmp) ctlStep=1;
+ else ctlStep = json_object_get_int(jTmp);
+
+ json_object_object_get_ex (ctlJ, "count" , &jTmp);
+ if (!jTmp) ctlCount=2;
+ else ctlCount = json_object_get_int(jTmp);
+
+ json_object_object_get_ex (ctlJ, "subdev" , &jTmp);
+ ctlSubDev = json_object_get_int(jTmp);
+
+ json_object_object_get_ex (ctlJ, "type" , &jTmp);
+ if (!jTmp) ctlType=SND_CTL_ELEM_TYPE_INTEGER;
+ else ctlType = json_object_get_int(jTmp);
+
+ // set info event ID and get value
+ snd_ctl_elem_info_alloca(&elemInfo);
+ snd_ctl_elem_info_set_name (elemInfo, ctlName); // map ctlInfo to ctlId elemInfo is updated !!!
+ snd_ctl_elem_info_set_numid(elemInfo, ctlNumid); // map ctlInfo to ctlId elemInfo is updated !!!
+
+ if (snd_ctl_elem_info(ctlDev, elemInfo) >= 0) {
+ afb_req_fail_f (request, "ctl-already-exist", "crl=%s name/numid not unique", json_object_to_json_string(ctlJ));
+ goto OnErrorExit;
+ }
+
+ snd_ctl_elem_info_set_subdevice(elemInfo, ctlSubDev);
+
+ switch (ctlType) {
+ case SND_CTL_ELEM_TYPE_BOOLEAN:
+ err = snd_ctl_add_boolean_elem_set(ctlDev, cinfo, 1, ctlCount);
+ if (err) {
+ afb_req_fail_f (request, "ctl-invalid-bool", "crl=%s invalid boolean data", json_object_to_json_string(ctlJ));
+ goto OnErrorExit;
+ }
+ break;
+
+ case SND_CTL_ELEM_TYPE_INTEGER:
+ break;
+
+ case SND_CTL_ELEM_TYPE_INTEGER64:
+ break;
+
+ case SND_CTL_ELEM_TYPE_ENUMERATED:
+ break;
+
+ case SND_CTL_ELEM_TYPE_BYTES:
+ break;
+
+ default:
+ afb_req_fail_f (request, "ctl-invalid-type", "crl=%s invalid/unknown type", json_object_to_json_string(ctlJ));
+ goto OnErrorExit;
+ }
+
+
+ snd_ctl_elem_write(ctlDev, &ctlElem);
+
+ return 0;
+
+ OnErrorExit:
+ return -1;
+}
+
+// Subscribe to every Alsa CtlEvent send by a given board
+PUBLIC void alsaAddCustomCtl (struct afb_req request) {
+ snd_ctl_t *ctlDev;
+ int err;
+ const char *devid, *ctls;
+ json_object *ctlsJ;
+
+ devid = afb_req_value(request, "devid");
+ if (!devid) {
+ afb_req_fail_f (request, "missing-devid", "devid=xxx missing");
+ goto OnErrorExit;
+ }
+
+ // open control interface for devid
+ err = snd_ctl_open(&ctlDev, devid, 0);
+ if (err < 0) {
+ ctlDev=NULL;
+ afb_req_fail_f (request, "devid-unknown", "SndCard devid=%s Not Found err=%s", queryValues.devid, snd_strerror(err));
+ goto OnErrorExit;
+ }
+
+ ctls = afb_req_value(request, "ctls");
+ if (!ctls) {
+ afb_req_fail_f (request, "missing-ctls", "ctls=[{name:xxx, numdid=xx, ...}] missing");
+ goto OnErrorExit;
+ }
+
+ ctlsJ = json_tokener_parse(ctls);
+ if (!ctlsJ) {
+ afb_req_fail_f (request, "ctls-notjson","ctls=%s not a valid json entry", ctls);
+ goto OnErrorExit;
+ };
+
+ enum json_type jtype= json_object_get_type(ctlsJ);
+ switch (jtype) {
+ int error;
+ json_object *ctlJ;
+
+ case json_type_array:
+ int count = json_object_array_length (ctlsJ);
+ for (int idx=0; idx < count; idx ++) {
+ ctlJ = json_object_array_get_idx (ctlsJ, idx);
+ error = alsaAddCtrl (request, ctlDev, ctlsJ);
+ if (error) goto OnErrorExit;
+ }
+ break;
+
+ case json_type_object:
+ error = alsaAddCtrl (request, ctlDev, ctlsJ);
+ if (error) goto OnErrorExit;
+ break;
+
+ default:
+ afb_req_fail_f (request, "ctls-notarray","ctls=%s not valid JSON control object", ctls);
+ goto OnErrorExit;
+ }
+
+ snd_ctl_close(ctlDev);
+ return;
+
+ OnErrorExit:
+ if (ctlDev) snd_ctl_close(ctlDev);
+ return;
+}
+
diff --git a/ALSA-afb/Alsa-ApiHat.c b/ALSA-afb/Alsa-ApiHat.c
index 261b54d..9520ce7 100644
--- a/ALSA-afb/Alsa-ApiHat.c
+++ b/ALSA-afb/Alsa-ApiHat.c
@@ -47,6 +47,7 @@ static const struct afb_verb_desc_v1 binding_verbs[] = {
{ .name= "ucmget", .session= AFB_SESSION_NONE, .callback= alsaUseCaseGet, .info= "Use Case Get" },
{ .name= "ucmreset", .session= AFB_SESSION_NONE, .callback= alsaUseCaseReset,.info= "Use Case Reset to Default" },
{ .name= "ucmclose", .session= AFB_SESSION_NONE, .callback= alsaUseCaseClose,.info= "Use Case Close Manager" },
+ { .name= "addctl", .session= AFB_SESSION_NONE, .callback= alsaAddCustomCtl ,.info= "Add User Custom Sound Control" },
{ .name= NULL } /* marker for end of the array */
};
diff --git a/ALSA-afb/Alsa-ApiHat.h b/ALSA-afb/Alsa-ApiHat.h
index c0fd51f..44ef26f 100644
--- a/ALSA-afb/Alsa-ApiHat.h
+++ b/ALSA-afb/Alsa-ApiHat.h
@@ -53,6 +53,7 @@ PUBLIC void alsaUseCaseSet(struct afb_req request);
PUBLIC void alsaUseCaseGet(struct afb_req request);
PUBLIC void alsaUseCaseClose(struct afb_req request);
PUBLIC void alsaUseCaseReset(struct afb_req request);
+PUBLIC void alsaAddCustomCtl(struct afb_req request);
diff --git a/ALSA-afb/Alsa-SetGet.c b/ALSA-afb/Alsa-SetGet.c
index abf1a6a..025846f 100644
--- a/ALSA-afb/Alsa-SetGet.c
+++ b/ALSA-afb/Alsa-SetGet.c
@@ -896,7 +896,7 @@ PUBLIC void alsaSubcribe (struct afb_req request) {
if (err) goto OnErrorExit;
- // open control interface for devid
+ // open control interface for devid
err = snd_ctl_open(&ctlDev, queryValues.devid, SND_CTL_READONLY);
if (err < 0) {
ctlDev=NULL;
diff --git a/ALSA-afb/CMakeLists.txt b/ALSA-afb/CMakeLists.txt
index 8ba1a78..5c62149 100644
--- a/ALSA-afb/CMakeLists.txt
+++ b/ALSA-afb/CMakeLists.txt
@@ -20,7 +20,7 @@
PROJECT_TARGET_ADD(alsa-lowlevel)
# Define project Targets
- ADD_LIBRARY(alsa-lowlevel MODULE Alsa-ApiHat.c Alsa-SetGet.c Alsa-Ucm.c)
+ ADD_LIBRARY(alsa-lowlevel MODULE Alsa-ApiHat.c Alsa-SetGet.c Alsa-Ucm.c Alsa-AddCtl.c)
# Binder exposes a unique public entry point
SET_TARGET_PROPERTIES(alsa-lowlevel PROPERTIES
diff --git a/Common/AudioCommonLib.c b/Common/AudioCommonLib.c
new file mode 100644
index 0000000..0055896
--- /dev/null
+++ b/Common/AudioCommonLib.c
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ *
+ */
+#define _GNU_SOURCE // needed for vasprintf
+
+#include <json-c/json.h>
+#include <afb/afb-binding.h>
+#include <afb/afb-service-itf.h>
+#include <semaphore.h>
+#include <string.h>
+
+#include "AudioCommonLib.h"
+
+typedef struct {
+ int index;
+ int numid;
+} shareHallMap_T;
+
+
+PUBLIC 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 OnErrorExit;
+ }
+ } else {
+ afb_req_fail(request, "cbCheckFail", "No Result inside API response");
+ }
+ goto OnErrorExit;
+ }
+ return (0);
+
+OnErrorExit:
+ return (-1);
+}
+
+
+// This function should be part of Generic AGL Framework
+PUBLIC json_object* afb_service_call_sync(struct afb_service srvitf, struct afb_req request, char* api, char* verb, struct json_object* queryurl) {
+ json_object* response = NULL;
+ int status = 0;
+ sem_t semid;
+
+ // Nested procedure are allow in GNU and allow us to keep caller stack valid
+
+ void callback(void *handle, int iserror, struct json_object *result) {
+
+ // Process Basic Error
+ if (!cbCheckResponse(request, iserror, result)) {
+ status = -1;
+ goto OnExitCB;
+ }
+
+ // 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 OnExitCB;
+ }
+
+OnExitCB:
+ sem_post(&semid);
+ }
+
+ // Create an exclusive semaphore
+ status = sem_init(&semid, 0, 0);
+ if (status < 0) {
+ afb_req_fail_f(request, "error:seminit", "Fail to allocate semaphore err=[%s]", strerror(status));
+ goto OnExit;
+ }
+
+ // Call service and wait for call back to finish before moving any further
+ afb_service_call(srvitf, api, verb, queryurl, callback, NULL);
+ sem_wait(&semid);
+
+OnExit:
+ return (response);
+}
+
+PUBLIC void pingtest(struct afb_req request) {
+ json_object *query = afb_req_json(request);
+ afb_req_success(request, query, NULL);
+}
diff --git a/Common/AudioCommonLib.h b/Common/AudioCommonLib.h
new file mode 100644
index 0000000..ffefbfc
--- /dev/null
+++ b/Common/AudioCommonLib.h
@@ -0,0 +1,68 @@
+/*
+ * 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
+ */
+
+#ifndef AUDIOCOMMON_H
+#define AUDIOCOMMON_H
+
+#include <json-c/json.h>
+#include <afb/afb-binding.h>
+#include <afb/afb-service-itf.h>
+
+#ifndef PUBLIC
+ #define PUBLIC
+#endif
+#define STATIC static
+
+// Most controls are MIXER but some vendor specific are possible
+typedef enum {
+ OUTVOL,
+ PCMVOL,
+ INVOL,
+ SWITCH,
+ ROUTE,
+ CARD,
+ ENUM,
+} halGroupEnumT;
+
+typedef enum {
+ READ,
+ WRITE,
+ RW,
+} halAclEnumT;
+
+typedef enum {
+ StartHalCrlTag=0,
+
+ // HighLevel Audio Control List
+ Master_Playback_Volume,
+ PCM_Playback_Volume,
+ PCM_Playback_Switch,
+ Capture_Volume,
+
+ EndHalCrlTag // used to compute number of ctls
+} halCtlsEnumT;
+
+PUBLIC int cbCheckResponse(struct afb_req request, int iserror, struct json_object *result) ;
+PUBLIC json_object* afb_service_call_sync(struct afb_service srvitf, struct afb_req request, char* api, char* verb, struct json_object* queryurl);
+PUBLIC void pingtest(struct afb_req request);
+
+#endif /* AUDIOCOMMON_H */
+
diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt
new file mode 100644
index 0000000..79ee8ac
--- /dev/null
+++ b/Common/CMakeLists.txt
@@ -0,0 +1,31 @@
+###########################################################################
+# Copyright 2015, 2016, 2017 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.
+###########################################################################
+
+PROJECT(audio-common C)
+
+INCLUDE_DIRECTORIES(${include_dirs})
+
+##################################################
+# AudioCommon is a local static Library
+##################################################
+ADD_LIBRARY(audiocommon STATIC AudioCommonLib.c)
+SET_TARGET_PROPERTIES(audiocommon PROPERTIES OUTPUT_NAME audiocommon)
+SET(link_libraries ${libefence_LIBRARIES} ${json-c_LIBRARIES})
+TARGET_LINK_LIBRARIES(audiocommon ${link_libraries})
+
+
diff --git a/HAL-afb/HAL-interface/hal-interface.c b/HAL-afb/HAL-interface/hal-interface.c
index 7876715..510ed2a 100644
--- a/HAL-afb/HAL-interface/hal-interface.c
+++ b/HAL-afb/HAL-interface/hal-interface.c
@@ -36,6 +36,7 @@ typedef struct {
int numid;
} shareHallMap_T;
+
static struct afb_service srvitf;
static const struct afb_binding_interface *afbIface;
static shareHallMap_T *shareHallMap;
@@ -267,75 +268,85 @@ STATIC void halInitCB(void *handle, int iserror, struct json_object *result) {
}
// This receive all event this binding subscribe to
-PUBLIC void afbBindingV1ServiceEvent(const char *evtname, struct json_object *object) {
+PUBLIC void afbServiceEvent(const char *evtname, struct json_object *object) {
- NOTICE(afbIface, "afbBindingV1ServiceEvent evtname=%s [msg=%s]", evtname, json_object_to_json_string(object));
+ NOTICE(daemon, "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;
+STATIC int afbServiceInit(struct afb_service service) {
+ int rc=0, err;
srvitf = service;
- struct json_object *queryurl;
+ struct json_object *queryurl, jResponse;
+ alsaHalMapT *halCtls = alsaHalSndCard.ctls; // Get sndcard specific HAL control mapping
if (alsaHalSndCard.initCB) {
rc= (alsaHalSndCard.initCB) (afbIface, service);
- if (rc != 0) goto OnExit;
+ if (rc != 0) goto OnErrorExit;
}
// 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);
+ err= afb_req_subcall_sync (request, "alsacore", "registerHal", queryurl, &jResponse);
+ if (err) {
+ ERROR (daemon, "Fail to register HAL to ALSA lowlevel binding");
+ goto OnErrorExit;
+ }
+ json_object_put(queryurl);
+
+ // for each Non Alsa Control callback create a custom control
+ for (int idx = 0; halCtls[idx].alsa.numid != 0; idx++) {
+ if (halCtls[idx].cb.callback != NULL) {
+ queryurl = json_object_new_object();
+ if (json_object_new_string(halCtls[idx].alsa.name) json_object_object_add(queryurl, "name" , json_object_new_string(halCtls[idx].alsa.name));
+ if (json_object_new_string(halCtls[idx].alsa.numid) json_object_object_add(queryurl, "numid" , json_object_new_int(halCtls[idx].alsa.numid));
+ if (json_object_new_string(halCtls[idx].alsa.minval) json_object_object_add(queryurl, "minval", json_object_new_int(halCtls[idx].alsa.minval));
+ if (json_object_new_string(halCtls[idx].alsa.maxval) json_object_object_add(queryurl, "maxval", json_object_new_int(halCtls[idx].alsa.maxval));
+ if (json_object_new_string(halCtls[idx].alsa.step) json_object_object_add(queryurl, "step" , json_object_new_int(halCtls[idx].alsa.step));
+ if (json_object_new_string(halCtls[idx].alsa.type) json_object_object_add(queryurl, "type" , json_object_new_int(halCtls[idx].alsa.type));
+
+ err= afb_req_subcall_sync (request, "alsacore", "addUserCtl", queryurl, &jResponse);
+ if (err) {
+ ERROR (daemon, "Fail to register Callback for ctrl=[%s]", halCtls[idx].alsa.name);
+ goto OnErrorExit;
+ }
+ }
+ }
+
+ // finally register for alsa lowlevel event
+ err= afb_req_subcall_sync (request, "alsacore", "subscribe", queryurl, &jResponse);
+ if (err) {
+ ERROR (daemon, "Fail subscribing to ALSA lowlevel events");
+ goto OnErrorExit;
+ }
+
- OnExit:
- return (rc);
+ return (0);
+
+ OnErrorExit:
+ return (1);
};
// 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 const struct afb_verb_v2 halSharedApi[] = {
+ /* VERB'S NAME FUNCTION TO CALL SHORT DESCRIPTION */
+ { .verb = "ping", .callback = pingtest, .info = "Ping Binding"},
+ { .verb = "getctls", .callback = halGetCtls, .info = "Get Control"},
+ { .verb = "setvol", .callback = halSetVol, .info = "Set Volume"},
+ { .verb = "getvol", .callback = halGetVol, .info = "Get Volume"},
+ { .verb = "subscribe", .callback = halSubscribe,.info = "Subscribe Alsa Events"},
+ { .verb = "monitor", .callback = halMonitor ,.info = "Monitor Alsa Events"},
+ { .verb = 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,
+const struct afb_binding_v2 afbBindingV2 = {
+ .api = "audio-hal",
+ .specification = "",
.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 */
+ .preinit = NULL,
+ .init = afbServiceInit,
+ .onevent = afbServiceEvent,
+ .noconcurrency = 0
};
diff --git a/HAL-afb/HAL-interface/hal-interface.h b/HAL-afb/HAL-interface/hal-interface.h
index cebbd21..6aebb6e 100644
--- a/HAL-afb/HAL-interface/hal-interface.h
+++ b/HAL-afb/HAL-interface/hal-interface.h
@@ -23,12 +23,14 @@
typedef struct {
halCtlsEnumT control;
+ char* name;
int numid;
halGroupEnumT group;
int values;
int minval;
int maxval;
int step;
+ snd_ctl_elem_type_t type;
halAclEnumT acl;
} alsaHalCtlMapT;
diff --git a/HAL-afb/HDA-intel/CMakeLists.txt b/HAL-afb/HDA-intel/CMakeLists.txt
index 08a39dd..4a12aee 100644
--- a/HAL-afb/HDA-intel/CMakeLists.txt
+++ b/HAL-afb/HDA-intel/CMakeLists.txt
@@ -39,4 +39,4 @@ PROJECT_TARGET_ADD(hal-intel-hda)
# installation directory
INSTALL(TARGETS hal-intel-hda
- LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR})
+ LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR}) \ No newline at end of file
diff --git a/HAL-afb/HDA-intel/IntelHdaHAL.c b/HAL-afb/HDA-intel/IntelHdaHAL.c
index bc8fc43..6967c1f 100644
--- a/HAL-afb/HDA-intel/IntelHdaHAL.c
+++ b/HAL-afb/HDA-intel/IntelHdaHAL.c
@@ -28,6 +28,18 @@ STATIC int IntelHalInit (const struct afb_binding_interface *itf, struct afb_ser
return 0; // 0=OK
}
+STATIC void MasterOnOff (void * handle) {
+ static powerStatus=0;
+
+ if (! powerStatus) {
+ powerStatus = 1;
+ DEBUG (itf, "Power Set to On");
+ } else {
+ powerStatus = 0;
+ DEBUG (itf, "Power Set to Off");
+ }
+}
+
/******************************************************************************************
* alsaCtlsMap link hight level sound control with low level Alsa numid ctls.
*
@@ -41,10 +53,11 @@ STATIC int IntelHalInit (const struct afb_binding_interface *itf, struct afb_ser
* .cb={.handle=xxxx, .callback=(json_object)MyCtlFunction(struct afb_service service, int controle, int value, const struct alsaHalCtlMapS *map)};
********************************************************************************************/
STATIC alsaHalMapT alsaHalMap[]= {
- { .alsa={.control=Master_Playback_Volume,.numid=16,.group=OUTVOL,.values=1,.minval=0,.maxval= 87 ,.step=0,.acl=RW}, .info= "Master Playback Volume" },
- { .alsa={.control=PCM_Playback_Volume ,.numid=27,.group=PCMVOL,.values=2,.minval=0,.maxval= 255,.step=0,.acl=RW}, .info= "PCM Playback Volume" },
- { .alsa={.control=PCM_Playback_Switch ,.numid=17,.group=SWITCH,.values=1,.minval=0,.maxval= 1 ,.step=0,.acl=RW}, .info= "Master Playback Switch" },
- { .alsa={.control=Capture_Volume ,.numid=12,.group=INVOL ,.values=2,.minval=0,.maxval= 31 ,.step=0,.acl=RW}, .info= "Capture Volume" },
+ { .alsa={.control=Master_Playback_Volume,.numid=16, .name="Master-Vol" , .values=1,.minval=0,.maxval= 87 ,.step=0}, .info= "Master Playback Volume" },
+ { .alsa={.control=PCM_Playback_Volume ,.numid=27, .name="Play-Vol" , .values=2,.minval=0,.maxval= 255,.step=0}, .info= "PCM Playback Volume" },
+ { .alsa={.control=PCM_Playback_Switch ,.numid=17, .name="Play-Switch" , .values=1,.minval=0,.maxval= 1 ,.step=0}, .info= "Master Playback Switch" },
+ { .alsa={.control=Capture_Volume ,.numid=12, .name="Capt-vol" , .values=2,.minval=0,.maxval= 31 ,.step=0}, .info= "Capture Volume" },
+ { .alsa={.control=Master_OnOff_Switch ,.numid=1000, .name="Power-Switch"}, .cb={.callback=MasterOnOff, .handle=NULL}} /* marker for end of the array */
{ .alsa={.numid=0}, .cb={.callback=NULL, .handle=NULL}} /* marker for end of the array */
} ;
diff --git a/HighLevel-afb/CMakeLists.txt b/HighLevel-afb/CMakeLists.txt
index 9b540e3..9d7af4c 100644
--- a/HighLevel-afb/CMakeLists.txt
+++ b/HighLevel-afb/CMakeLists.txt
@@ -16,26 +16,28 @@
# limitations under the License.
###########################################################################
+
# Add target to project dependency list
-PROJECT_TARGET_ADD(audio-afb)
+PROJECT_TARGET_ADD(audio)
# Define project Targets
- ADD_LIBRARY(audio-afb MODULE HighLevelApiConf.c HighLevelBinding.c)
+ ADD_LIBRARY(audio MODULE HighLevelApiConf.c HighLevelBinding.c)
# Binder exposes a unique public entry point
- SET_TARGET_PROPERTIES(audio-afb PROPERTIES
+ 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-afb
- audio-interface
+ TARGET_LINK_LIBRARIES(audio
+ audio-inter
${link_libraries}
)
# installation directory
- INSTALL(TARGETS audio-afb
+ INSTALL(TARGETS audio
LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR})
diff --git a/Shared-Interface/CMakeLists.txt b/Shared-Interface/CMakeLists.txt
index 87018c9..9a5c74d 100644
--- a/Shared-Interface/CMakeLists.txt
+++ b/Shared-Interface/CMakeLists.txt
@@ -35,5 +35,4 @@ PROJECT_TARGET_ADD(audio-interface)
# Define target includes
TARGET_INCLUDE_DIRECTORIES(audio-interface
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
- )
-
+) \ No newline at end of file
diff --git a/Shared-Interface/audio-interface.h b/Shared-Interface/audio-interface.h
index 24fcfaa..ee681aa 100644
--- a/Shared-Interface/audio-interface.h
+++ b/Shared-Interface/audio-interface.h
@@ -23,7 +23,7 @@
#define AUDIOCOMMON_H
#include <json-c/json.h>
-#define AFB_BINDING_VERSION 1
+#define AFB_BINDING_VERSION 2
#include <afb/afb-binding.h>
#ifndef PUBLIC
@@ -53,6 +53,7 @@ typedef enum {
// HighLevel Audio Control List
Master_Playback_Volume,
+ Master_OnOff_Switch,
PCM_Playback_Volume,
PCM_Playback_Switch,
Capture_Volume,
diff --git a/conf.d/app-templates b/conf.d/app-templates
-Subproject ff516d186889808ff61358c6ea8f88662401aca
+Subproject 0d3bfaf0888cb350f8721db4a4115ecb8dc4f00
diff --git a/htdocs/CMakeLists.txt b/htdocs/CMakeLists.txt
index 751ff40..0026b8c 100644
--- a/htdocs/CMakeLists.txt
+++ b/htdocs/CMakeLists.txt
@@ -21,19 +21,25 @@
##################################################
# HTML Testing Files
##################################################
-PROJECT_TARGET_ADD(html-simple-test)
+PROJECT_TARGET_ADD(www_test)
- add_custom_command(OUTPUT htdocs
- DEPENDS ${TARGET_NAME}
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- COMMAND cp "*.html" PATTERN "*.js" PATTERN "*.jpg" ${CMAKE_CURRENT_BINARY_DIR}
- )
+ file(GLOB SOURCE_FILES "*.html" "*.js" "*.jpg")
+
+ add_custom_target(${TARGET_NAME}
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}
+ )
- add_custom_target(${TARGET_NAME} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR})
+ add_custom_command(
+ DEPENDS ${SOURCE_FILES}
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}
+ COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}
+ COMMAND touch ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}
+ COMMAND cp -r ${SOURCE_FILES} ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}
+ )
SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
LABELS "HTDOCS"
- OUTPUT_NAME htdocs
+ OUTPUT_NAME ${TARGET_NAME}
)
# use only under native Linux when using "make install"
diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml
index 1ba69e3..c1f4a61 100644
--- a/nbproject/configurations.xml
+++ b/nbproject/configurations.xml
@@ -3,6 +3,7 @@
<logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
<df root="." name="0">
<df name="ALSA-afb">
+ <in>Alsa-AddCtl.c</in>
<in>Alsa-ApiHat.c</in>
<in>Alsa-SetGet.c</in>
<in>Alsa-Ucm.c</in>
@@ -62,7 +63,8 @@
<rebuildPropChanged>false</rebuildPropChanged>
</toolsSet>
<flagsDictionary>
- <element flagsID="0" commonFlags="-mtune=generic -march=x86-64 -g -g -fPIC"/>
+ <element flagsID="0" commonFlags="-g -fPIC -fPIC -g"/>
+ <element flagsID="1" commonFlags="-mtune=generic -march=x86-64 -g -g -fPIC"/>
</flagsDictionary>
<codeAssistance>
<includeAdditional>true</includeAdditional>
@@ -76,52 +78,39 @@
</makeTool>
<preBuild>
<preBuildCommandWorkingDir>build</preBuildCommandWorkingDir>
- <preBuildCommand>cmake -Wno-dev -DCXX=g++-5 -DCC=gcc-5 ..</preBuildCommand>
+ <preBuildCommand>cmake ..</preBuildCommand>
<preBuildFirst>true</preBuildFirst>
</preBuild>
</makefileType>
+ <item path="ALSA-afb/Alsa-AddCtl.c" ex="false" tool="0" flavor2="0">
+ <cTool flags="0">
+ </cTool>
+ </item>
<item path="ALSA-afb/Alsa-ApiHat.c" ex="false" tool="0" flavor2="3">
<cTool flags="0">
- <incDir>
- <pElem>ALSA-afb</pElem>
- <pElem>../../../opt/include/afb</pElem>
- <pElem>build/ALSA-afb</pElem>
- </incDir>
</cTool>
</item>
<item path="ALSA-afb/Alsa-SetGet.c" ex="false" tool="0" flavor2="3">
<cTool flags="0">
- <incDir>
- <pElem>../../../opt/include/afb</pElem>
- <pElem>ALSA-afb</pElem>
- <pElem>/usr/include/json-c</pElem>
- <pElem>build/ALSA-afb</pElem>
- </incDir>
</cTool>
</item>
<item path="ALSA-afb/Alsa-Ucm.c" ex="false" tool="0" flavor2="3">
<cTool flags="0">
- <incDir>
- <pElem>../../../opt/include/afb</pElem>
- <pElem>ALSA-afb</pElem>
- <pElem>/usr/include/json-c</pElem>
- <pElem>build/ALSA-afb</pElem>
- </incDir>
</cTool>
</item>
<item path="HAL-afb/HAL-interface/hal-interface.c"
ex="false"
tool="0"
flavor2="3">
- <cTool flags="0">
+ <cTool flags="1">
</cTool>
</item>
<item path="HAL-afb/HDA-intel/IntelHdaHAL.c" ex="false" tool="0" flavor2="3">
- <cTool flags="0">
+ <cTool flags="1">
</cTool>
</item>
<item path="HighLevel-afb/HighLevelApiConf.c" ex="false" tool="0" flavor2="3">
- <cTool flags="0">
+ <cTool flags="1">
<incDir>
<pElem>Shared-Interface</pElem>
<pElem>../../../opt/include</pElem>
@@ -130,7 +119,7 @@
</cTool>
</item>
<item path="HighLevel-afb/HighLevelBinding.c" ex="false" tool="0" flavor2="3">
- <cTool flags="0">
+ <cTool flags="1">
<incDir>
<pElem>/usr/include/json-c</pElem>
<pElem>Shared-Interface</pElem>
@@ -177,6 +166,23 @@
<cTool flags="0">
</cTool>
</item>
+ <folder path="0/ALSA-afb">
+ <cTool>
+ <incDir>
+ <pElem>/usr/include/alsa</pElem>
+ <pElem>../../../opt/include</pElem>
+ <pElem>/usr/include/json-c</pElem>
+ <pElem>Shared-Interface</pElem>
+ <pElem>build/ALSA-afb</pElem>
+ </incDir>
+ <preprocessorList>
+ <Elem>CONTROL_CDEV_RX="/dev/inic-usb-crx"</Elem>
+ <Elem>CONTROL_CDEV_TX="/dev/inic-usb-ctx"</Elem>
+ <Elem>MAX_SND_CARD=16</Elem>
+ <Elem>alsa_lowlevel_EXPORTS</Elem>
+ </preprocessorList>
+ </cTool>
+ </folder>
<folder path="0/HAL-afb">
<cTool>
<incDir>
@@ -217,12 +223,17 @@
<folder path="0/Shared-Interface">
<cTool>
<incDir>
- <pElem>../../../opt/include/afb</pElem>
- <pElem>Shared-Interface</pElem>
- <pElem>/usr/include/json-c</pElem>
+ <pElem>/usr/include/alsa</pElem>
<pElem>../../../opt/include</pElem>
+ <pElem>/usr/include/json-c</pElem>
+ <pElem>Shared-Interface</pElem>
<pElem>build/Shared-Interface</pElem>
</incDir>
+ <preprocessorList>
+ <Elem>CONTROL_CDEV_RX="/dev/inic-usb-crx"</Elem>
+ <Elem>CONTROL_CDEV_TX="/dev/inic-usb-ctx"</Elem>
+ <Elem>MAX_SND_CARD=16</Elem>
+ </preprocessorList>
</cTool>
</folder>
</conf>