summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfulup <fulup.arfoll@iot.bzh>2017-07-01 00:22:00 +0200
committerfulup <fulup.arfoll@iot.bzh>2017-07-01 00:22:00 +0200
commitc326a053cdf8a4a9ce0fb02448293b45083d553c (patch)
treeaa1209094f735e96ad506615fe04d375b773543a
parent10c42e135b22bf323836100ede042ec47ddb22a1 (diff)
Ongoing work
-rw-r--r--ALSA-afb/Alsa-AddCtl.c54
-rw-r--r--ALSA-afb/Alsa-ApiHat.c8
-rw-r--r--ALSA-afb/Alsa-ApiHat.h23
-rw-r--r--ALSA-afb/Alsa-RegEvt.c309
-rw-r--r--ALSA-afb/Alsa-SetGet.c318
-rw-r--r--ALSA-afb/Alsa-Ucm.c12
-rw-r--r--ALSA-afb/CMakeLists.txt2
-rw-r--r--CMakeLists.txt11
-rw-r--r--HAL-afb/CMakeLists.txt2
-rw-r--r--HAL-afb/HAL-interface/hal-interface.c112
-rw-r--r--HAL-afb/HAL-interface/hal-interface.h12
-rw-r--r--HAL-afb/HDA-intel/IntelHdaHAL.c73
-rw-r--r--HAL-afb/Scarlett-Focusrite/CMakeLists.txt42
-rw-r--r--HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c74
-rw-r--r--README.md17
m---------conf.d/app-templates0
-rwxr-xr-xconf.d/autobuild/agl/autobuild47
-rwxr-xr-xconf.d/autobuild/linux/autobuild47
-rw-r--r--conf.d/cmake/config.cmake (renamed from conf.d/config.cmake)18
-rw-r--r--nbproject/configurations.xml58
20 files changed, 767 insertions, 472 deletions
diff --git a/ALSA-afb/Alsa-AddCtl.c b/ALSA-afb/Alsa-AddCtl.c
index 7593f2d..2edec5f 100644
--- a/ALSA-afb/Alsa-AddCtl.c
+++ b/ALSA-afb/Alsa-AddCtl.c
@@ -67,7 +67,7 @@ STATIC int addOneSndCtl(afb_req request, snd_ctl_t *ctlDev, json_object *ctlJ)
// 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 !!!
+ 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));
@@ -101,10 +101,58 @@ STATIC int addOneSndCtl(afb_req request, snd_ctl_t *ctlDev, json_object *ctlJ)
afb_req_fail_f (request, "ctl-invalid-type", "crl=%s invalid/unknown type", json_object_to_json_string(ctlJ));
goto OnErrorExit;
}
-
-
+
return 0;
OnErrorExit:
return -1;
}
+
+PUBLIC void alsaAddCustomCtls(afb_req request) {
+ int err;
+ json_object *ctlsJ;
+ enum json_type;
+ snd_ctl_t *ctlDev=NULL;
+ const char *devid;
+
+ devid = afb_req_value(request, "devid");
+ if (devid == NULL) {
+ afb_req_fail_f (request, "devid-missing", "devid MUST be defined for alsaAddCustomCtls");
+ goto OnErrorExit;
+ }
+
+ // open control interface for devid
+ err = snd_ctl_open(&ctlDev, devid, SND_CTL_READONLY);
+ if (err < 0) {
+ afb_req_fail_f (request, "devid-unknown", "SndCard devid=[%s] Not Found err=%s", devid, snd_strerror(err));
+ goto OnErrorExit;
+ }
+
+ // extract sound controls and parse json
+ ctlsJ = json_tokener_parse (afb_req_value(request, "ctls"));
+ if (!ctlsJ) {
+ afb_req_fail_f (request, "ctls-missing", "ctls MUST be defined as a JSON array for alsaAddCustomCtls");
+ goto OnErrorExit;
+ }
+
+ switch (json_object_get_type(ctlsJ)) {
+ case json_type_object:
+ addOneSndCtl(request, ctlDev, ctlsJ);
+ break;
+
+ case json_type_array:
+ for (int idx= 1; idx < json_object_array_length (ctlsJ); idx++) {
+ json_object *ctlJ = json_object_array_get_idx (ctlsJ, idx);
+ addOneSndCtl(request, ctlDev, ctlJ) ;
+ }
+ break;
+
+ default:
+ afb_req_fail_f (request, "ctls-invalid","ctls=%s not valid JSON array", json_object_to_json_string(ctlsJ));
+ goto OnErrorExit;
+ }
+
+ OnErrorExit:
+ if (ctlDev) snd_ctl_close(ctlDev);
+ return;
+} \ No newline at end of file
diff --git a/ALSA-afb/Alsa-ApiHat.c b/ALSA-afb/Alsa-ApiHat.c
index ced5d50..588e91b 100644
--- a/ALSA-afb/Alsa-ApiHat.c
+++ b/ALSA-afb/Alsa-ApiHat.c
@@ -31,13 +31,13 @@
/*
* array of the verbs exported to afb-daemon
*/
-static const struct afb_verb_v2 binding_verbs[] = {
+static const struct afb_verb_v2 api_verbs[] = {
/* VERB'S NAME FUNCTION TO CALL */
{ .verb= "ping" , .callback= pingtest },
{ .verb= "getinfo", .callback= alsaGetInfo},
{ .verb= "getctls", .callback= alsaGetCtls},
{ .verb= "setctls", .callback= alsaSetCtls},
- { .verb= "subscribe", .callback= alsaSubcribe},
+ { .verb= "subscribe", .callback= alsaEvtSubcribe},
{ .verb= "getcardid", .callback= alsaGetCardId},
{ .verb= "registerHal", .callback= alsaRegisterHal},
{ .verb= "ucmquery", .callback= alsaUseCaseQuery},
@@ -45,7 +45,7 @@ static const struct afb_verb_v2 binding_verbs[] = {
{ .verb= "ucmget", .callback= alsaUseCaseGet},
{ .verb= "ucmreset", .callback= alsaUseCaseReset},
{ .verb= "ucmclose", .callback= alsaUseCaseClose},
- { .verb= "addctl", .callback= alsaAddCustomCtl},
+ { .verb= "addcustomctl",.callback= alsaAddCustomCtls},
{ .verb= NULL } /* marker for end of the array */
};
@@ -54,5 +54,5 @@ static const struct afb_verb_v2 binding_verbs[] = {
*/
const struct afb_binding_v2 afbBindingV2 = {
.api = "alsacore",
- .verbs = binding_verbs,
+ .verbs = api_verbs,
};
diff --git a/ALSA-afb/Alsa-ApiHat.h b/ALSA-afb/Alsa-ApiHat.h
index c33f92e..bd8518f 100644
--- a/ALSA-afb/Alsa-ApiHat.h
+++ b/ALSA-afb/Alsa-ApiHat.h
@@ -19,6 +19,9 @@
#ifndef ALSALIBMAPPING_H
#define ALSALIBMAPPING_H
+
+#include <alsa/asoundlib.h>
+#include <systemd/sd-event.h>
#include "audio-interface.h"
typedef enum {
@@ -34,17 +37,24 @@ typedef struct {
int count;
} queryValuesT;
+// use to store crl numid user request
+typedef struct {
+ unsigned int numId;
+ json_object *jToken;
+ json_object *jValues;
+ int used;
+} ctlRequestT;
+
// import from AlsaAfbBinding
extern const struct afb_binding_interface *afbIface;
PUBLIC int alsaCheckQuery (struct afb_req request, queryValuesT *queryValues);
// AlseCoreSetGet exports
+PUBLIC int alsaGetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRequestT *ctlRequest, int quiet);
PUBLIC void alsaGetInfo (struct afb_req request);
PUBLIC void alsaGetCtls(struct afb_req request);
PUBLIC void alsaSetCtls(struct afb_req request);
-PUBLIC void alsaSubcribe (struct afb_req request);
-PUBLIC void alsaGetCardId (struct afb_req request);
-PUBLIC void alsaRegisterHal (struct afb_req request);
+
// AlsaUseCase exports
PUBLIC void alsaUseCaseQuery(struct afb_req request);
@@ -52,9 +62,12 @@ 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);
-
+PUBLIC void alsaAddCustomCtls(struct afb_req request);
+// AlsaRegEvt
+PUBLIC void alsaEvtSubcribe (struct afb_req request);
+PUBLIC void alsaGetCardId (struct afb_req request);
+PUBLIC void alsaRegisterHal (struct afb_req request);
#endif /* ALSALIBMAPPING_H */
diff --git a/ALSA-afb/Alsa-RegEvt.c b/ALSA-afb/Alsa-RegEvt.c
new file mode 100644
index 0000000..e06cf87
--- /dev/null
+++ b/ALSA-afb/Alsa-RegEvt.c
@@ -0,0 +1,309 @@
+/*
+ * AlsaLibMapping -- 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-ApiHat.h"
+
+// generic sndctrl event handle hook to event callback when pooling
+typedef struct {
+ struct pollfd pfds;
+ sd_event_source *src;
+ snd_ctl_t *ctlDev;
+ int quiet;
+ struct afb_event afbevt;
+} evtHandleT;
+
+typedef struct {
+ int ucount;
+ int cardId;
+ evtHandleT *evtHandle;
+} sndHandleT;
+
+typedef struct {
+ char *apiprefix;
+ char *shortname;
+}cardRegistryT;
+
+cardRegistryT *cardRegistry[MAX_SND_CARD+1];
+
+// This routine is called when ALSA event are fired
+STATIC int sndCtlEventCB (sd_event_source* src, int fd, uint32_t revents, void* userData) {
+ int err;
+ evtHandleT *evtHandle = (evtHandleT*)userData;
+ snd_ctl_event_t *eventId;
+ json_object *ctlEventJ;
+ unsigned int mask;
+ int iface;
+ int device;
+ int subdev;
+ const char*devname;
+ ctlRequestT ctlRequest;
+ snd_ctl_elem_id_t *elemId;
+
+ if ((revents & EPOLLHUP) != 0) {
+ AFB_NOTICE( "SndCtl hanghup [car disconnected]");
+ goto ExitOnSucess;
+ }
+
+ if ((revents & EPOLLIN) != 0) {
+
+ // initialise event structure on stack
+ snd_ctl_event_alloca(&eventId);
+ snd_ctl_elem_id_alloca(&elemId);
+
+ err = snd_ctl_read(evtHandle->ctlDev, eventId);
+ if (err < 0) goto OnErrorExit;
+
+ // we only process sndctrl element
+ if (snd_ctl_event_get_type(eventId) != SND_CTL_EVENT_ELEM) goto ExitOnSucess;
+
+ // we only process value changed events
+ mask = snd_ctl_event_elem_get_mask(eventId);
+ if (!(mask & SND_CTL_EVENT_MASK_VALUE)) goto ExitOnSucess;
+
+ snd_ctl_event_elem_get_id (eventId, elemId);
+
+ err = alsaGetSingleCtl (evtHandle->ctlDev, elemId, &ctlRequest, evtHandle->quiet);
+ if (err) goto OnErrorExit;
+
+ iface = snd_ctl_event_elem_get_interface(eventId);
+ device = snd_ctl_event_elem_get_device(eventId);
+ subdev = snd_ctl_event_elem_get_subdevice(eventId);
+ devname= snd_ctl_event_elem_get_name(eventId);
+
+ // proxy ctlevent as a binder event
+ ctlEventJ = json_object_new_object();
+ json_object_object_add(ctlEventJ, "device" ,json_object_new_int (device));
+ json_object_object_add(ctlEventJ, "subdev" ,json_object_new_int (subdev));
+ if (evtHandle->quiet < 2) {
+ json_object_object_add(ctlEventJ, "iface" ,json_object_new_int (iface));
+ json_object_object_add(ctlEventJ, "devname",json_object_new_string (devname));
+ }
+ if (ctlRequest.jValues) (json_object_object_add(ctlEventJ, "values" ,ctlRequest.jValues));
+ AFB_DEBUG( "sndCtlEventCB=%s", json_object_get_string(ctlEventJ));
+ afb_event_push(evtHandle->afbevt, ctlEventJ);
+ }
+
+ ExitOnSucess:
+ return 0;
+
+ OnErrorExit:
+ WARNING ("sndCtlEventCB: ignored unsupported event type");
+ return (0);
+}
+
+// Subscribe to every Alsa CtlEvent send by a given board
+PUBLIC void alsaEvtSubcribe (afb_req request) {
+ static sndHandleT sndHandles[MAX_SND_CARD];
+ evtHandleT *evtHandle;
+ snd_ctl_t *ctlDev;
+ int err, idx, cardId, idxFree=-1;
+ snd_ctl_card_info_t *cardinfo;
+ queryValuesT queryValues;
+
+
+ err = alsaCheckQuery (request, &queryValues);
+ if (err) goto OnErrorExit;
+
+
+ // open control interface for devid
+ err = snd_ctl_open(&ctlDev, queryValues.devid, SND_CTL_READONLY);
+ 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;
+ }
+
+ snd_ctl_card_info_alloca(&cardinfo);
+ if ((err = snd_ctl_card_info(ctlDev, cardinfo)) < 0) {
+ afb_req_fail_f (request, "devid-invalid", "SndCard devid=%s Not Found err=%s", queryValues.devid, snd_strerror(err));
+ goto OnErrorExit;
+ }
+
+ cardId=snd_ctl_card_info_get_card(cardinfo);
+
+ // search for an existing subscription and mark 1st free slot
+ for (idx= 0; idx < MAX_SND_CARD; idx ++) {
+ if (sndHandles[idx].ucount > 0 && cardId == sndHandles[idx].cardId) {
+ evtHandle= sndHandles[idx].evtHandle;
+ break;
+ } else if (idxFree == -1) idxFree= idx;
+ };
+
+ // if not subscription exist for the event let's create one
+ if (idx == MAX_SND_CARD) {
+
+ // reach MAX_SND_CARD event registration
+ if (idxFree == -1) {
+ afb_req_fail_f (request, "register-toomany", "Cannot register new event Maxcard==%d", idx);
+ goto OnErrorExit;
+ }
+
+ evtHandle = malloc (sizeof(evtHandleT));
+ evtHandle->ctlDev = ctlDev;
+ evtHandle->quiet = queryValues.quiet;
+ sndHandles[idxFree].ucount = 0;
+ sndHandles[idxFree].cardId = cardId;
+ sndHandles[idxFree].evtHandle = evtHandle;
+
+ // subscribe for sndctl events attached to devid
+ err = snd_ctl_subscribe_events(evtHandle->ctlDev, 1);
+ if (err < 0) {
+ afb_req_fail_f (request, "subscribe-fail", "Cannot subscribe events from devid=%s err=%d", queryValues.devid, err);
+ goto OnErrorExit;
+ }
+
+ // get pollfd attach to this sound board
+ snd_ctl_poll_descriptors(evtHandle->ctlDev, &evtHandle->pfds, 1);
+
+ // register sound event to binder main loop
+ err = sd_event_add_io(afb_daemon_get_event_loop(), &evtHandle->src, evtHandle->pfds.fd, EPOLLIN, sndCtlEventCB, evtHandle);
+ if (err < 0) {
+ afb_req_fail_f (request, "register-mainloop", "Cannot hook events to mainloop devid=%s err=%d", queryValues.devid, err);
+ goto OnErrorExit;
+ }
+
+ // create binder event attached to devid name
+ evtHandle->afbevt = afb_daemon_make_event (queryValues.devid);
+ if (!afb_event_is_valid (evtHandle->afbevt)) {
+ afb_req_fail_f (request, "register-event", "Cannot register new binder event name=%s", queryValues.devid);
+ goto OnErrorExit;
+ }
+
+ // everything looks OK let's move forward
+ idx=idxFree;
+ }
+
+ // subscribe to binder event
+ err = afb_req_subscribe(request, evtHandle->afbevt);
+ if (err != 0) {
+ afb_req_fail_f (request, "register-eventname", "Cannot subscribe binder event name=%s [invalid channel]", queryValues.devid);
+ goto OnErrorExit;
+ }
+
+ // increase usage count and return success
+ sndHandles[idx].ucount ++;
+ afb_req_success(request, NULL, NULL);
+ return;
+
+ OnErrorExit:
+ if (ctlDev) snd_ctl_close(ctlDev);
+ return;
+}
+
+// Subscribe to every Alsa CtlEvent send by a given board
+PUBLIC void alsaGetCardId (afb_req request) {
+ char devid [10];
+ const char *devname, *shortname, *longname;
+ int card, err, index, idx;
+ json_object *respJson;
+ snd_ctl_t *ctlDev;
+ snd_ctl_card_info_t *cardinfo;
+
+ const char *sndname = afb_req_value(request, "sndname");
+ if (sndname == NULL) {
+ afb_req_fail_f (request, "argument-missing", "sndname=SndCardName missing");
+ goto OnErrorExit;
+ }
+
+ // loop on potential card number
+ snd_ctl_card_info_alloca(&cardinfo);
+ for (card =0; card < MAX_SND_CARD; card++) {
+
+ // build card devid and probe it
+ snprintf (devid, sizeof(devid), "hw:%i", card);
+
+ // open control interface for devid
+ err = snd_ctl_open(&ctlDev, devid, SND_CTL_READONLY);
+ if (err < 0) continue;
+
+ // extract sound card information
+ snd_ctl_card_info(ctlDev, cardinfo);
+ index = snd_ctl_card_info_get_card(cardinfo);
+ devname = snd_ctl_card_info_get_id(cardinfo);
+ shortname= snd_ctl_card_info_get_name(cardinfo);
+ longname = snd_ctl_card_info_get_longname(cardinfo);
+
+ // check if short|long name match
+ if (!strcmp (sndname, devname)) break;
+ if (!strcmp (sndname, shortname)) break;
+ if (!strcmp (sndname, longname)) break;
+ }
+
+ if (card == MAX_SND_CARD) {
+ afb_req_fail_f (request, "ctlDev-notfound", "Fail to find card with name=%s", sndname);
+ goto OnErrorExit;
+ }
+
+ // proxy ctlevent as a binder event
+ respJson = json_object_new_object();
+ json_object_object_add(respJson, "index" ,json_object_new_int (index));
+ json_object_object_add(respJson, "devid" ,json_object_new_string (devid));
+ json_object_object_add(respJson, "shortname" ,json_object_new_string (shortname));
+ json_object_object_add(respJson, "longname" ,json_object_new_string (longname));
+
+ // search for a HAL binder card mapping name to api prefix
+ for (idx=0; idx < MAX_SND_CARD; idx++) {
+ if (!strcmp (cardRegistry[idx]->shortname, shortname)) break;
+ }
+ // if a match if found, then we have an HAL for this board let's return its value
+ if (idx < MAX_SND_CARD) json_object_object_add(respJson, "halapi",json_object_new_string (cardRegistry[idx]->apiprefix));
+
+ afb_req_success(request, respJson, NULL);
+ return;
+
+ OnErrorExit:
+ return;
+}
+
+// Register loaded HAL with board Name and API prefix
+PUBLIC void alsaRegisterHal (afb_req request) {
+ static int index=0;
+ const char *shortname, *apiPrefix;
+
+ apiPrefix = afb_req_value(request, "prefix");
+ if (apiPrefix == NULL) {
+ afb_req_fail_f (request, "argument-missing", "prefix=BindingApiPrefix missing");
+ goto OnErrorExit;
+ }
+
+ shortname = afb_req_value(request, "sndname");
+ if (shortname == NULL) {
+ afb_req_fail_f (request, "argument-missing", "sndname=SndCardName missing");
+ goto OnErrorExit;
+ }
+
+ if (index == MAX_SND_CARD) {
+ afb_req_fail_f (request, "alsahal-toomany", "Fail to register sndname=[%s]", shortname);
+ goto OnErrorExit;
+ }
+
+ cardRegistry[index]= malloc (sizeof(cardRegistry));
+ cardRegistry[index]->apiprefix=strdup(apiPrefix);
+ cardRegistry[index]->shortname=strdup(shortname);
+ index++;cardRegistry[index]=NULL;
+
+ // If OK return sound card Alsa ID+Info
+ alsaGetCardId(request);
+ return;
+
+ OnErrorExit:
+ return;
+}
+
diff --git a/ALSA-afb/Alsa-SetGet.c b/ALSA-afb/Alsa-SetGet.c
index d6cf50d..280078c 100644
--- a/ALSA-afb/Alsa-SetGet.c
+++ b/ALSA-afb/Alsa-SetGet.c
@@ -26,41 +26,8 @@
#define _GNU_SOURCE // needed for vasprintf
-#include <alsa/asoundlib.h>
-#include <systemd/sd-event.h>
-
#include "Alsa-ApiHat.h"
-// use to store crl numid user request
-typedef struct {
- unsigned int numId;
- json_object *jToken;
- json_object *jValues;
- int used;
-} ctlRequestT;
-
-// generic sndctrl event handle hook to event callback when pooling
-typedef struct {
- struct pollfd pfds;
- sd_event_source *src;
- snd_ctl_t *ctlDev;
- int quiet;
- struct afb_event afbevt;
-} evtHandleT;
-
-typedef struct {
- int ucount;
- int cardId;
- evtHandleT *evtHandle;
-} sndHandleT;
-
-typedef struct {
- char *apiprefix;
- char *shortname;
-}cardRegistryT;
-
-cardRegistryT *cardRegistry[MAX_SND_CARD+1];
-
PUBLIC void NumidsListParse (queryValuesT *queryValues, ctlRequestT *ctlRequest) {
json_object *jValues;
int length;
@@ -103,7 +70,7 @@ PUBLIC void NumidsListParse (queryValuesT *queryValues, ctlRequestT *ctlRequest)
case json_type_object:
// numid+values formated as {id:xxx, val:[aa,bb...,nn]}
if (!json_object_object_get_ex (ctlRequest[idx].jToken,"id", &jId) || !json_object_object_get_ex (ctlRequest[idx].jToken,"val",&jVal)) {
- NOTICE("Invalid Json=%s missing 'id'|'val'", json_object_get_string(ctlRequest[idx].jToken));
+ AFB_NOTICE("Invalid Json=%s missing 'id'|'val'", json_object_get_string(ctlRequest[idx].jToken));
ctlRequest[idx].used=-1;
} else {
ctlRequest[idx].numId =json_object_get_int(jId);
@@ -478,7 +445,7 @@ STATIC json_object *getControlAcl (snd_ctl_elem_info_t *info) {
}
// process ALSA control and store resulting value into ctlRequest
-STATIC int alsaSetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRequestT *ctlRequest) {
+PUBLIC int alsaSetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRequestT *ctlRequest) {
snd_ctl_elem_value_t *elemData;
snd_ctl_elem_info_t *elemInfo;
int count, length, err, valueIsArray;
@@ -490,13 +457,13 @@ STATIC int alsaSetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRe
snd_ctl_elem_info_alloca(&elemInfo);
snd_ctl_elem_info_set_id(elemInfo, elemId); // map ctlInfo to ctlId elemInfo is updated !!!
if (snd_ctl_elem_info(ctlDev, elemInfo) < 0) {
- NOTICE( "Fail to load ALSA NUMID=%d Values=[%s]", ctlRequest->numId, json_object_to_json_string(ctlRequest->jValues));
+ AFB_NOTICE( "Fail to load ALSA NUMID=%d Values=[%s]", ctlRequest->numId, json_object_to_json_string(ctlRequest->jValues));
goto OnErrorExit;
}
snd_ctl_elem_info_get_id(elemInfo, elemId); // map ctlInfo to ctlId elemInfo is updated !!!
if (!snd_ctl_elem_info_is_writable(elemInfo)) {
- NOTICE( "Not Writable ALSA NUMID=%d Values=[%s]", ctlRequest->numId, json_object_to_json_string(ctlRequest->jValues));
+ AFB_NOTICE( "Not Writable ALSA NUMID=%d Values=[%s]", ctlRequest->numId, json_object_to_json_string(ctlRequest->jValues));
goto OnErrorExit;
}
@@ -515,12 +482,13 @@ STATIC int alsaSetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRe
break;
default:
count =0;
+ length = 0;
break;
}
if (count == 0 || count < length) {
- NOTICE( "Invalid values NUMID='%d' Values='%s' count='%d' wanted='%d'", ctlRequest->numId, json_object_to_json_string(ctlRequest->jValues), length, count);
+ AFB_NOTICE( "Invalid values NUMID='%d' Values='%s' count='%d' wanted='%d'", ctlRequest->numId, json_object_to_json_string(ctlRequest->jValues), length, count);
goto OnErrorExit;
}
@@ -542,7 +510,7 @@ STATIC int alsaSetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRe
err = snd_ctl_elem_write(ctlDev, elemData);
if (err < 0) {
- NOTICE( "Fail to write ALSA NUMID=%d Values=[%s] Error=%s", ctlRequest->numId, json_object_to_json_string(ctlRequest->jValues), snd_strerror(err));
+ AFB_NOTICE( "Fail to write ALSA NUMID=%d Values=[%s] Error=%s", ctlRequest->numId, json_object_to_json_string(ctlRequest->jValues), snd_strerror(err));
goto OnErrorExit;
}
@@ -555,7 +523,7 @@ STATIC int alsaSetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRe
}
// process ALSA control and store then into ctlRequest
-STATIC int alsaGetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRequestT *ctlRequest, int quiet) {
+PUBLIC int alsaGetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRequestT *ctlRequest, int quiet) {
snd_ctl_elem_type_t elemType;
snd_ctl_elem_value_t *elemData;
snd_ctl_elem_info_t *elemInfo;
@@ -681,7 +649,7 @@ STATIC int alsaGetSingleCtl (snd_ctl_t *ctlDev, snd_ctl_elem_id_t *elemId, ctlRe
}
// assign multiple control to the same value
-PUBLIC void alsaSetGetCtls (afb_req request, ActionSetGetT action) {
+STATIC void alsaSetGetCtls (afb_req request, ActionSetGetT action) {
ctlRequestT *ctlRequest;
const char *warmsg=NULL;
int err=0, status=0;
@@ -736,7 +704,7 @@ PUBLIC void alsaSetGetCtls (afb_req request, ActionSetGetT action) {
} else {
int numid = snd_ctl_elem_list_get_numid(ctlList, ctlIndex);
if (numid < 0) {
- NOTICE("snd_ctl_elem_list_get_numid index=%d fail", ctlIndex);
+ AFB_NOTICE("snd_ctl_elem_list_get_numid index=%d fail", ctlIndex);
continue;
}
// check if current control was requested in query numids list
@@ -814,269 +782,3 @@ PUBLIC void alsaSetCtls (afb_req request) {
}
-// This routine is called when ALSA event are fired
-STATIC int sndCtlEventCB (sd_event_source* src, int fd, uint32_t revents, void* userData) {
- int err;
- evtHandleT *evtHandle = (evtHandleT*)userData;
- snd_ctl_event_t *eventId;
- json_object *ctlEventJ;
- unsigned int mask;
- int iface;
- int device;
- int subdev;
- const char*devname;
- ctlRequestT ctlRequest;
- snd_ctl_elem_id_t *elemId;
-
- if ((revents & EPOLLHUP) != 0) {
- NOTICE( "SndCtl hanghup [car disconnected]");
- goto ExitOnSucess;
- }
-
- if ((revents & EPOLLIN) != 0) {
-
- // initialise event structure on stack
- snd_ctl_event_alloca(&eventId);
- snd_ctl_elem_id_alloca(&elemId);
-
- err = snd_ctl_read(evtHandle->ctlDev, eventId);
- if (err < 0) goto OnErrorExit;
-
- // we only process sndctrl element
- if (snd_ctl_event_get_type(eventId) != SND_CTL_EVENT_ELEM) goto ExitOnSucess;
-
- // we only process value changed events
- mask = snd_ctl_event_elem_get_mask(eventId);
- if (!(mask & SND_CTL_EVENT_MASK_VALUE)) goto ExitOnSucess;
-
- snd_ctl_event_elem_get_id (eventId, elemId);
-
- err = alsaGetSingleCtl (evtHandle->ctlDev, elemId, &ctlRequest, evtHandle->quiet);
- if (err) goto OnErrorExit;
-
- iface = snd_ctl_event_elem_get_interface(eventId);
- device = snd_ctl_event_elem_get_device(eventId);
- subdev = snd_ctl_event_elem_get_subdevice(eventId);
- devname= snd_ctl_event_elem_get_name(eventId);
-
- // proxy ctlevent as a binder event
- ctlEventJ = json_object_new_object();
- json_object_object_add(ctlEventJ, "device" ,json_object_new_int (device));
- json_object_object_add(ctlEventJ, "subdev" ,json_object_new_int (subdev));
- if (evtHandle->quiet < 2) {
- json_object_object_add(ctlEventJ, "iface" ,json_object_new_int (iface));
- json_object_object_add(ctlEventJ, "devname",json_object_new_string (devname));
- }
- if (ctlRequest.jValues) (json_object_object_add(ctlEventJ, "values" ,ctlRequest.jValues));
- DEBUG( "sndCtlEventCB=%s", json_object_get_string(ctlEventJ));
- afb_event_push(evtHandle->afbevt, ctlEventJ);
-
- }
-
- ExitOnSucess:
- return 0;
-
- OnErrorExit:
- WARNING ("sndCtlEventCB: ignored unsupported event type");
- return (0);
-}
-
-// Subscribe to every Alsa CtlEvent send by a given board
-PUBLIC void alsaSubcribe (afb_req request) {
- static sndHandleT sndHandles[MAX_SND_CARD];
- evtHandleT *evtHandle;
- snd_ctl_t *ctlDev;
- int err, idx, cardId, idxFree=-1;
- snd_ctl_card_info_t *cardinfo;
- queryValuesT queryValues;
-
-
- err = alsaCheckQuery (request, &queryValues);
- if (err) goto OnErrorExit;
-
-
- // open control interface for devid
- err = snd_ctl_open(&ctlDev, queryValues.devid, SND_CTL_READONLY);
- 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;
- }
-
- snd_ctl_card_info_alloca(&cardinfo);
- if ((err = snd_ctl_card_info(ctlDev, cardinfo)) < 0) {
- afb_req_fail_f (request, "devid-invalid", "SndCard devid=%s Not Found err=%s", queryValues.devid, snd_strerror(err));
- goto OnErrorExit;
- }
-
- cardId=snd_ctl_card_info_get_card(cardinfo);
-
- // search for an existing subscription and mark 1st free slot
- for (idx= 0; idx < MAX_SND_CARD; idx ++) {
- if (sndHandles[idx].ucount > 0 && cardId == sndHandles[idx].cardId) {
- evtHandle= sndHandles[idx].evtHandle;
- break;
- } else if (idxFree == -1) idxFree= idx;
- };
-
- // if not subscription exist for the event let's create one
- if (idx == MAX_SND_CARD) {
-
- // reach MAX_SND_CARD event registration
- if (idxFree == -1) {
- afb_req_fail_f (request, "register-toomany", "Cannot register new event Maxcard==%d", idx);
- goto OnErrorExit;
- }
-
- evtHandle = malloc (sizeof(evtHandleT));
- evtHandle->ctlDev = ctlDev;
- evtHandle->quiet = queryValues.quiet;
- sndHandles[idxFree].ucount = 0;
- sndHandles[idxFree].cardId = cardId;
- sndHandles[idxFree].evtHandle = evtHandle;
-
- // subscribe for sndctl events attached to devid
- err = snd_ctl_subscribe_events(evtHandle->ctlDev, 1);
- if (err < 0) {
- afb_req_fail_f (request, "subscribe-fail", "Cannot subscribe events from devid=%s err=%d", queryValues.devid, err);
- goto OnErrorExit;
- }
-
- // get pollfd attach to this sound board
- snd_ctl_poll_descriptors(evtHandle->ctlDev, &evtHandle->pfds, 1);
-
- // register sound event to binder main loop
- err = sd_event_add_io(afb_daemon_get_event_loop(), &evtHandle->src, evtHandle->pfds.fd, EPOLLIN, sndCtlEventCB, evtHandle);
- if (err < 0) {
- afb_req_fail_f (request, "register-mainloop", "Cannot hook events to mainloop devid=%s err=%d", queryValues.devid, err);
- goto OnErrorExit;
- }
-
- // create binder event attached to devid name
- evtHandle->afbevt = afb_daemon_make_event (queryValues.devid);
- if (!afb_event_is_valid (evtHandle->afbevt)) {
- afb_req_fail_f (request, "register-event", "Cannot register new binder event name=%s", queryValues.devid);
- goto OnErrorExit;
- }
-
- // everything looks OK let's move forward
- idx=idxFree;
- }
-
- // subscribe to binder event
- err = afb_req_subscribe(request, evtHandle->afbevt);
- if (err != 0) {
- afb_req_fail_f (request, "register-eventname", "Cannot subscribe binder event name=%s [invalid channel]", queryValues.devid);
- goto OnErrorExit;
- }
-
- // increase usage count and return success
- sndHandles[idx].ucount ++;
- afb_req_success(request, NULL, NULL);
- return;
-
- OnErrorExit:
- if (ctlDev) snd_ctl_close(ctlDev);
- return;
-}
-
-// Subscribe to every Alsa CtlEvent send by a given board
-PUBLIC void alsaGetCardId (afb_req request) {
- char devid [10];
- const char *devname, *shortname, *longname;
- int card, err, index, idx;
- json_object *respJson;
- snd_ctl_t *ctlDev;
- snd_ctl_card_info_t *cardinfo;
-
- const char *sndname = afb_req_value(request, "sndname");
- if (sndname == NULL) {
- afb_req_fail_f (request, "argument-missing", "sndname=SndCardName missing");
- goto OnErrorExit;
- }
-
- // loop on potential card number
- snd_ctl_card_info_alloca(&cardinfo);
- for (card =0; card < MAX_SND_CARD; card++) {
-
- // build card devid and probe it
- snprintf (devid, sizeof(devid), "hw:%i", card);
-
- // open control interface for devid
- err = snd_ctl_open(&ctlDev, devid, SND_CTL_READONLY);
- if (err < 0) continue;
-
- // extract sound card information
- snd_ctl_card_info(ctlDev, cardinfo);
- index = snd_ctl_card_info_get_card(cardinfo);
- devname = snd_ctl_card_info_get_id(cardinfo);
- shortname= snd_ctl_card_info_get_name(cardinfo);
- longname = snd_ctl_card_info_get_longname(cardinfo);
-
- // check if short|long name match
- if (!strcmp (sndname, devname)) break;
- if (!strcmp (sndname, shortname)) break;
- if (!strcmp (sndname, longname)) break;
- }
-
- if (card == MAX_SND_CARD) {
- afb_req_fail_f (request, "ctlDev-notfound", "Fail to find card with name=%s", sndname);
- goto OnErrorExit;
- }
-
- // proxy ctlevent as a binder event
- respJson = json_object_new_object();
- json_object_object_add(respJson, "index" ,json_object_new_int (index));
- json_object_object_add(respJson, "devid" ,json_object_new_string (devid));
- json_object_object_add(respJson, "shortname" ,json_object_new_string (shortname));
- json_object_object_add(respJson, "longname" ,json_object_new_string (longname));
-
- // search for a HAL binder card mapping name to api prefix
- for (idx=0; idx < MAX_SND_CARD; idx++) {
- if (!strcmp (cardRegistry[idx]->shortname, shortname)) break;
- }
- // if a match if found, then we have an HAL for this board let's return its value
- if (idx < MAX_SND_CARD) json_object_object_add(respJson, "halapi",json_object_new_string (cardRegistry[idx]->apiprefix));
-
- afb_req_success(request, respJson, NULL);
- return;
-
- OnErrorExit:
- return;
-}
-
-// Register loaded HAL with board Name and API prefix
-PUBLIC void alsaRegisterHal (afb_req request) {
- static int index=0;
- const char *shortname, *apiPrefix;
-
- apiPrefix = afb_req_value(request, "prefix");
- if (apiPrefix == NULL) {
- afb_req_fail_f (request, "argument-missing", "prefix=BindingApiPrefix missing");
- goto OnErrorExit;
- }
-
- shortname = afb_req_value(request, "name");
- if (shortname == NULL) {
- afb_req_fail_f (request, "argument-missing", "sndname=SndCardName missing");
- goto OnErrorExit;
- }
-
- if (index == MAX_SND_CARD) {
- afb_req_fail_f (request, "alsahal-toomany", "Fail to register sndname=[%s]", shortname);
- goto OnErrorExit;
- }
-
- cardRegistry[index]= malloc (sizeof(cardRegistry));
- cardRegistry[index]->apiprefix=strdup(apiPrefix);
- cardRegistry[index]->shortname=strdup(shortname);
- index++;cardRegistry[index]=NULL;
-
- // when OK nothing to return
- afb_req_success(request, NULL, NULL);
- return;
-
- OnErrorExit:
- return;
-}
-
diff --git a/ALSA-afb/Alsa-Ucm.c b/ALSA-afb/Alsa-Ucm.c
index 78a80ad..c9ee4f9 100644
--- a/ALSA-afb/Alsa-Ucm.c
+++ b/ALSA-afb/Alsa-Ucm.c
@@ -143,7 +143,7 @@ PUBLIC void alsaUseCaseQuery(struct afb_req request) {
json_object_object_add (ucmJ, "verb", json_object_new_string(verbList[idx]));
if (verbList[idx+1]) json_object_object_add (ucmJ, "info", json_object_new_string(verbList[idx+1]));
- DEBUG (afbIface, "Verb[%d] Action=%s Info=%s", idx, verbList[idx], verbList[idx+1]);
+ AFB_DEBUG ("Verb[%d] Action=%s Info=%s", idx, verbList[idx], verbList[idx+1]);
snprintf (identifier, sizeof(identifier), "_devices/%s", verbList[idx]);
devCount = snd_use_case_get_list (ucmHandle, identifier, &devList);
@@ -152,7 +152,7 @@ PUBLIC void alsaUseCaseQuery(struct afb_req request) {
for (int jdx=0; jdx < devCount; jdx+=2) {
json_object *devJ = json_object_new_object();
- DEBUG (afbIface, "device[%d] Action=%s Info=%s", jdx, devList[jdx], devList[jdx+1]);
+ AFB_DEBUG ("device[%d] Action=%s Info=%s", jdx, devList[jdx], devList[jdx+1]);
json_object_object_add (devJ, "dev", json_object_new_string(devList[jdx]));
if (devList[jdx+1]) json_object_object_add (devJ, "info", json_object_new_string(devList[jdx+1]));
json_object_array_add (devsJ, devJ);
@@ -168,7 +168,7 @@ PUBLIC void alsaUseCaseQuery(struct afb_req request) {
for (int jdx=0; jdx < modCount; jdx+=2) {
json_object *modJ = json_object_new_object();
- DEBUG (afbIface, "modifier[%d] Action=%s Info=%s", jdx, modList[jdx], modList[jdx+1]);
+ AFB_DEBUG ("modifier[%d] Action=%s Info=%s", jdx, modList[jdx], modList[jdx+1]);
json_object_object_add (modJ, "mod", json_object_new_string(modList[jdx]));
if (modList[jdx+1]) json_object_object_add (modJ, "info", json_object_new_string(modList[jdx+1]));
json_object_array_add (modsJ, modJ);
@@ -184,7 +184,7 @@ PUBLIC void alsaUseCaseQuery(struct afb_req request) {
for (int jdx=0; jdx < tqCount; jdx+=2) {
json_object *tqJ = json_object_new_object();
- DEBUG (afbIface, "toneqa[%d] Action=%s Info=%s", jdx, tqList[jdx], tqList[jdx+1]);
+ AFB_DEBUG ("toneqa[%d] Action=%s Info=%s", jdx, tqList[jdx], tqList[jdx+1]);
json_object_object_add (tqJ, "tq", json_object_new_string(tqList[jdx]));
if (tqList[jdx+1]) json_object_object_add (tqJ, "info", json_object_new_string(tqList[jdx+1]));
json_object_array_add (tqsJ, tqJ);
@@ -214,14 +214,14 @@ STATIC json_object *ucmGetValue (ucmHandleT *ucmHandle, const char *verb, const
if (!verb) verb="";
if (!label) {
- NOTICE (afbIface, "ucmGetValue cardname=[%s] value label missing", ucmHandle->cardName);
+ AFB_NOTICE ("ucmGetValue cardname=[%s] value label missing", ucmHandle->cardName);
goto OnErrorExit;
}
snprintf (identifier, sizeof(identifier), "%s/%s/%s", label, mod, verb);
err = snd_use_case_get (ucmHandle->ucm, identifier, (const char**)&value); // Note: value casting is a known "FEATURE" of AlsaUCM API
if (err) {
- DEBUG (afbIface, "ucmGetValue cardname=[%s] identifier=[%s] error=%s", ucmHandle->cardName, identifier, snd_strerror (err));
+ AFB_DEBUG ("ucmGetValue cardname=[%s] identifier=[%s] error=%s", ucmHandle->cardName, identifier, snd_strerror (err));
goto OnErrorExit;
}
diff --git a/ALSA-afb/CMakeLists.txt b/ALSA-afb/CMakeLists.txt
index 5c62149..4ca7158 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 Alsa-AddCtl.c)
+ ADD_LIBRARY(alsa-lowlevel MODULE Alsa-ApiHat.c Alsa-SetGet.c Alsa-Ucm.c Alsa-AddCtl.c Alsa-RegEvt.c)
# Binder exposes a unique public entry point
SET_TARGET_PROPERTIES(alsa-lowlevel PROPERTIES
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 38949e4..faef509 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,14 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
###########################################################################
-
CMAKE_MINIMUM_REQUIRED(VERSION 3.3)
-include(${CMAKE_CURRENT_SOURCE_DIR}/conf.d/config.cmake)
-include(${CMAKE_CURRENT_SOURCE_DIR}/conf.d/app-templates/cmake/common.cmake)
-
-project_subdirs_add("[^_]*")
-
-project_targets_populate()
-project_package_build()
-project_closing_msg()
+# Do not change this file, config is located into conf.d
+include(${CMAKE_CURRENT_SOURCE_DIR}/conf.d/cmake/config.cmake)
diff --git a/HAL-afb/CMakeLists.txt b/HAL-afb/CMakeLists.txt
index 1b8cc0e..b0c2e6a 100644
--- a/HAL-afb/CMakeLists.txt
+++ b/HAL-afb/CMakeLists.txt
@@ -19,5 +19,5 @@
# Include any directory starting with a Capital letter
# -----------------------------------------------------
-PROJECT_SUBDIRS_ADD("*")
+PROJECT_SUBDIRS_ADD(${PROJECT_SRC_DIR_PATTERN})
diff --git a/HAL-afb/HAL-interface/hal-interface.c b/HAL-afb/HAL-interface/hal-interface.c
index 2c6595f..29c5e88 100644
--- a/HAL-afb/HAL-interface/hal-interface.c
+++ b/HAL-afb/HAL-interface/hal-interface.c
@@ -37,31 +37,11 @@ typedef struct {
} shareHallMap_T;
static shareHallMap_T *shareHallMap;
+static alsaHalMapT *halCtls;
// 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) {
- afb_req request = afb_req_unstore(handle);
- struct json_object *x, *resp = NULL;
- const char *info = NULL;
-
- if (result) {
- INFO( "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);
-}
-
// Subscribe to AudioBinding events
STATIC void halSubscribe(afb_req request) {
const char *devid = afb_req_value(request, "devid");
@@ -125,7 +105,6 @@ STATIC int NormaliseValue(const alsaHalCtlMapT *halCtls, int valuein) {
// 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
@@ -218,8 +197,8 @@ STATIC void halGetCtls(afb_req request) {
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);
+ afb_req_fail_f(request, "ctl-invalid", "Invalid Control devid=%s ctl=[%s] should be [%d-%d]"
+ , json_object_get_string(devid), json_object_get_string(ctl), StartHalCrlTag, EndHalCrlTag);
goto OnExit;
}
@@ -241,60 +220,69 @@ OnExit:
// This receive all event this binding subscribe to
-PUBLIC void afbServiceEvent(const char *evtname, struct json_object *object) {
+PUBLIC void halServiceEvent(const char *evtname, struct json_object *object) {
- NOTICE("afbBindingV1ServiceEvent evtname=%s [msg=%s]", evtname, json_object_to_json_string(object));
+ AFB_NOTICE("afbBindingV1ServiceEvent evtname=%s [msg=%s]", evtname, json_object_to_json_string(object));
}
// this is call when after all bindings are loaded
-STATIC int afbServiceInit() {
- int rc=0, err;
- struct json_object *queryurl, *jResponse;
- alsaHalMapT *halCtls = alsaHalSndCard.ctls; // Get sndcard specific HAL control mapping
+PUBLIC int halServiceInit (const char *apiPrefix, alsaHalSndCardT *alsaHalSndCard) {
+ int ok, err;
+ struct json_object *queryurl, *responseJ, *devidJ, *tmpJ;
+ halCtls = alsaHalSndCard->ctls; // Get sndcard specific HAL control mapping
- if (alsaHalSndCard.initCB) {
- rc= (alsaHalSndCard.initCB)();
- if (rc != 0) goto OnErrorExit;
- }
-
err= afb_daemon_require_api("alsacore", 1);
+ if (err) {
+ AFB_ERROR ("AlsaCore missing cannot use AlsaHAL");
+ goto OnErrorExit;
+ }
// register HAL with Alsa Low Level Binder
queryurl = json_object_new_object();
- json_object_object_add(queryurl, "prefix", json_object_new_string(sndCardApiPrefix));
- json_object_object_add(queryurl, "name", json_object_new_string(alsaHalSndCard.name));
+ json_object_object_add(queryurl, "prefix", json_object_new_string(apiPrefix));
+ json_object_object_add(queryurl, "sndname", json_object_new_string(alsaHalSndCard->name));
- afb_service_call_sync("alsacore", "registerHal", queryurl, &jResponse);
- err= afb_service_call_sync ("alsacore", "registerHal", queryurl, &jResponse);
- if (err) {
- ERROR ("Fail to register HAL to ALSA lowlevel binding");
+ ok= afb_service_call_sync ("alsacore", "registerHal", queryurl, &responseJ);
+ json_object_put(queryurl);
+ if (!ok) {
+ NOTICE ("Fail to register HAL to ALSA lowlevel binding Response=[%s]", json_object_to_json_string(responseJ));
goto OnErrorExit;
}
- json_object_put(queryurl);
-
+
+ // extract sound devid from HAL registration
+ if (!json_object_object_get_ex(responseJ, "response", &tmpJ) || !json_object_object_get_ex(tmpJ, "devid", &devidJ)) {
+ AFB_ERROR ("Ooops: Internal error no devid return from HAL registration Response=[%s]", json_object_to_json_string(responseJ));
+ goto OnErrorExit;
+ }
+
// 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 (halCtls[idx].alsa.name) json_object_object_add(queryurl, "name" , json_object_new_string(halCtls[idx].alsa.name));
- if (halCtls[idx].alsa.numid) json_object_object_add(queryurl, "numid" , json_object_new_int(halCtls[idx].alsa.numid));
- if (halCtls[idx].alsa.minval) json_object_object_add(queryurl, "minval", json_object_new_int(halCtls[idx].alsa.minval));
- if (halCtls[idx].alsa.maxval) json_object_object_add(queryurl, "maxval", json_object_new_int(halCtls[idx].alsa.maxval));
- if (halCtls[idx].alsa.step) json_object_object_add(queryurl, "step" , json_object_new_int(halCtls[idx].alsa.step));
- if (halCtls[idx].alsa.type) json_object_object_add(queryurl, "type" , json_object_new_int(halCtls[idx].alsa.type));
+ json_object_object_add(queryurl, "devid",devidJ);
+ tmpJ = json_object_new_object();
+ if (halCtls[idx].alsa.name) json_object_object_add(tmpJ, "name" , json_object_new_string(halCtls[idx].alsa.name));
+ if (halCtls[idx].alsa.numid) json_object_object_add(tmpJ, "numid" , json_object_new_int(halCtls[idx].alsa.numid));
+ if (halCtls[idx].alsa.minval) json_object_object_add(tmpJ, "minval", json_object_new_int(halCtls[idx].alsa.minval));
+ if (halCtls[idx].alsa.maxval) json_object_object_add(tmpJ, "maxval", json_object_new_int(halCtls[idx].alsa.maxval));
+ if (halCtls[idx].alsa.step) json_object_object_add(tmpJ, "step" , json_object_new_int(halCtls[idx].alsa.step));
+ if (halCtls[idx].alsa.type) json_object_object_add(tmpJ, "type" , json_object_new_int(halCtls[idx].alsa.type));
+ json_object_object_add(queryurl, "ctls",tmpJ);
- err= afb_service_call_sync ("alsacore", "addUserCtl", queryurl, &jResponse);
- if (err) {
- ERROR ("Fail to register Callback for ctrl=[%s]", halCtls[idx].alsa.name);
+ AFB_NOTICE("QUERY=%s", json_object_to_json_string(queryurl));
+
+ ok= afb_service_call_sync ("alsacore", "addcustomctl", queryurl, &responseJ);
+ if (!ok) {
+ AFB_ERROR ("Fail to add Customer Sound Control for ctrl=[%s] Response=[%s]", halCtls[idx].alsa.name, json_object_to_json_string(responseJ));
goto OnErrorExit;
- }
+ }
}
}
// finally register for alsa lowlevel event
- err= afb_service_call_sync ("alsacore", "subscribe", queryurl, &jResponse);
+ err= afb_service_call_sync ("alsacore", "subscribe", queryurl, &responseJ);
if (err) {
- ERROR ("Fail subscribing to ALSA lowlevel events");
+ AFB_ERROR ("Fail subscribing to ALSA lowlevel events");
goto OnErrorExit;
}
@@ -305,24 +293,12 @@ STATIC int afbServiceInit() {
};
// Every HAL export the same API & Interface Mapping from SndCard to AudioLogic is done through alsaHalSndCardT
-STATIC afb_verb_v2 halSharedApi[] = {
+PUBLIC afb_verb_v2 halServiceApi[] = {
/* VERB'S NAME FUNCTION TO CALL SHORT DESCRIPTION */
{ .verb = "ping", .callback = pingtest},
{ .verb = "getctls", .callback = halGetCtls},
{ .verb = "setvol", .callback = halSetVol},
{ .verb = "getvol", .callback = halGetVol},
{ .verb = "subscribe", .callback = halSubscribe},
- { .verb = "monitor", .callback = halMonitor},
{ .verb = NULL} /* marker for end of the array */
};
-
-
-PUBLIC const struct afb_binding_v2 afbBindingV2 = {
- .api = sndCardApiPrefix,
- .specification = NULL,
- .verbs = halSharedApi,
- .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 e08ec18..16da901 100644
--- a/HAL-afb/HAL-interface/hal-interface.h
+++ b/HAL-afb/HAL-interface/hal-interface.h
@@ -39,9 +39,6 @@ typedef struct {
// avoid compiler warning [Jose does not like typedef :) ]
typedef struct afb_service alsaHalServiceT;
-// static value for HAL sound card API prefix
-extern const char sndCardApiPrefix[];
-
typedef struct {
struct json_object* (*callback)(alsaHalCtlMapT *control, void* handle);
void* handle;
@@ -57,12 +54,13 @@ typedef struct {
typedef const struct {
const char *name;
const char *info;
- alsaHalMapT *ctls;
- int (*initCB) (void);
-
+ alsaHalMapT *ctls;
} alsaHalSndCardT;
-PUBLIC alsaHalSndCardT alsaHalSndCard;
+extern afb_verb_v2 halServiceApi[];
+PUBLIC void halServiceEvent(const char *evtname, struct json_object *object);
+PUBLIC int halServiceInit (const char *apiPrefix, alsaHalSndCardT *alsaHalSndCard);
+
#endif /* SHAREHALLIB_H */
diff --git a/HAL-afb/HDA-intel/IntelHdaHAL.c b/HAL-afb/HDA-intel/IntelHdaHAL.c
index 98ac442..f394fd6 100644
--- a/HAL-afb/HDA-intel/IntelHdaHAL.c
+++ b/HAL-afb/HDA-intel/IntelHdaHAL.c
@@ -13,42 +13,33 @@
* 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.
+ *
+ *
+ * To find out which control your sound card uses
+ * aplay -l # Check sndcard name name in between []
+ * amixer -D hw:xx controls # get supported controls
+ * amixer -D "hw:3" cget numid=xx # get control settings
+ *
*/
#define _GNU_SOURCE
#include "hal-interface.h"
#include "audio-interface.h"
-// Init is call after all binding are loaded
-STATIC int IntelHalInit (void) {
- DEBUG ("IntelHalBinding Initialised");
-
- return 0; // 0=OK
-}
-
-STATIC void MasterOnOff (alsaHalCtlMapT *control, void* handle) {
+STATIC struct json_object* MasterOnOff (alsaHalCtlMapT *control, void* handle) {
static int powerStatus=0;
if (! powerStatus) {
powerStatus = 1;
- DEBUG ("Power Set to On");
+ AFB_DEBUG ("Power Set to On");
} else {
powerStatus = 0;
- DEBUG ("Power Set to Off");
+ AFB_DEBUG ("Power Set to Off");
}
+
+ return NULL;
}
-/******************************************************************************************
- * alsaCtlsMap link hight level sound control with low level Alsa numid ctls.
- *
- * To find out which control your sound card uses
- * aplay -l
- * amixer -D hw:xx controls
- * amixer -D hw:xx contents
- * amixer -D "hw:3" cget numid=xx
- *
- * When automatic mapping to Alsa numid is not enough a custom callback might be used
- * .cb={.handle=xxxx, .callback=(json_object)MyCtlFunction(struct afb_service service, int controle, int value, const struct alsaHalCtlMapS *map)};
- ********************************************************************************************/
+// Map HAL hight sndctl with Alsa numid and optionally with a custom callback for non Alsa supported functionalities.
STATIC alsaHalMapT alsaHalMap[]= {
{ .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" },
@@ -58,26 +49,26 @@ STATIC alsaHalMapT alsaHalMap[]= {
{ .alsa={.numid=0}, .cb={.callback=NULL, .handle=NULL}} /* marker for end of the array */
} ;
-/***********************************************************************************
- * AlsaHalSndT provides
- * - cardname used to map a given card to its HAL
- * - ctls previously defined AlsaHalMapT control maps
- * - info free text
- *
- * WARNING: name should fit with 'aplay -l' as it used to map from devid to HAL
- * you may also retreive shortname when AudioBinder is running from a browser
- * http://localhost:1234/api/alsacore/getcardid?devid=hw:xxx
- *
- ***********************************************************************************/
-
-// API prefix should be unique for each snd card
-PUBLIC const char sndCardApiPrefix[] = "intel-hda";
-
-// HAL sound card controls mapping
-PUBLIC alsaHalSndCardT alsaHalSndCard = {
- .name = "HDA Intel PCH",
+// HAL sound card mapping info
+STATIC alsaHalSndCardT alsaHalSndCard = {
+ .name = "HDA Intel PCH", // WARNING: name MUST match with 'aplay -l'
.info = "Hardware Abstraction Layer for IntelHDA sound card",
.ctls = alsaHalMap,
- .initCB=IntelHalInit, // if NULL no initcallback
};
+
+STATIC int sndServiceInit () {
+ int err;
+ AFB_DEBUG ("IntelHalBinding Init");
+
+ err = halServiceInit (afbBindingV2.api, &alsaHalSndCard);
+ return err;
+}
+
+// API prefix should be unique for each snd card
+PUBLIC const struct afb_binding_v2 afbBindingV2 = {
+ .api = "intel-hda",
+ .init = sndServiceInit,
+ .verbs = halServiceApi,
+ .onevent = halServiceEvent,
+};
diff --git a/HAL-afb/Scarlett-Focusrite/CMakeLists.txt b/HAL-afb/Scarlett-Focusrite/CMakeLists.txt
new file mode 100644
index 0000000..a2ca912
--- /dev/null
+++ b/HAL-afb/Scarlett-Focusrite/CMakeLists.txt
@@ -0,0 +1,42 @@
+###########################################################################
+# 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.
+###########################################################################
+
+
+# Add target to project dependency list
+PROJECT_TARGET_ADD(hal-scalett-usb)
+
+ # Define project Targets
+ ADD_LIBRARY(hal-scalett-usb MODULE ScarlettUsbHAL.c)
+
+ # Binder exposes a unique public entry point
+ SET_TARGET_PROPERTIES(hal-scalett-usb PROPERTIES
+ PREFIX "afb-"
+ LABELS "BINDING"
+ LINK_FLAGS ${BINDINGS_LINK_FLAG}
+ OUTPUT_NAME ${TARGET_NAME}
+ )
+
+ # Library dependencies (include updates automatically)
+ TARGET_LINK_LIBRARIES(hal-scalett-usb
+ hal-interface
+ audio-interface
+ )
+
+ # installation directory
+ INSTALL(TARGETS hal-scalett-usb
+ LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR}) \ No newline at end of file
diff --git a/HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c b/HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c
new file mode 100644
index 0000000..1ff5320
--- /dev/null
+++ b/HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ *
+ *
+ * To find out which control your sound card uses
+ * aplay -l # Check sndcard name name in between []
+ * amixer -D hw:xx controls # get supported controls
+ * amixer -D "hw:3" cget numid=xx # get control settings
+ *
+ */
+#define _GNU_SOURCE
+#include "hal-interface.h"
+#include "audio-interface.h"
+
+STATIC struct json_object* MasterOnOff (alsaHalCtlMapT *control, void* handle) {
+ static int powerStatus=0;
+
+ if (! powerStatus) {
+ powerStatus = 1;
+ AFB_DEBUG ("Power Set to On");
+ } else {
+ powerStatus = 0;
+ AFB_DEBUG ("Power Set to Off");
+ }
+
+ return NULL;
+}
+
+// Map HAL hight sndctl with Alsa numid and optionally with a custom callback for non Alsa supported functionalities.
+STATIC alsaHalMapT alsaHalMap[]= {
+ { .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=99, .name="Power-Switch"}, .cb={.callback=MasterOnOff, .handle=NULL}, .info= "OnOff Global Switch"},
+ { .alsa={.numid=0}, .cb={.callback=NULL, .handle=NULL}} /* marker for end of the array */
+} ;
+
+// HAL sound card mapping info
+STATIC alsaHalSndCardT alsaHalSndCard = {
+ .name = "Scarlett 18i8 USB", // WARNING: name MUST match with 'aplay -l'
+ .info = "Hardware Abstraction Layer for Scarlett Focusrite USB professional music sound card",
+ .ctls = alsaHalMap,
+};
+
+
+STATIC int sndServiceInit () {
+ int err;
+ AFB_DEBUG ("IntelHalBinding Init");
+
+ err = halServiceInit (afbBindingV2.api, &alsaHalSndCard);
+ return err;
+}
+
+// API prefix should be unique for each snd card
+PUBLIC const struct afb_binding_v2 afbBindingV2 = {
+ .api = "scarlett-usb",
+ .init = sndServiceInit,
+ .verbs = halServiceApi,
+ .onevent = halServiceEvent,
+};
diff --git a/README.md b/README.md
index a694859..bd86da6 100644
--- a/README.md
+++ b/README.md
@@ -84,11 +84,22 @@ make install
# From $INSTALL_PREFIX
mkdir $INSTALL_PREFIX/share/wssocks
afb-daemon --verbose --token="" --ldpaths=$INSTALL_PREFIX/lib/audio --port=1234 --roothttp=$INSTALL_PREFIX/htdocs/audio-bindings
+
+# Debug with GDB
+ In order your debugger to find bindings(sharelib) symbols ldpath and workdir should match with GDB solib-search-path
+ --workdir=. #default value: in this case solib-search-path is not requirer
+ --workdir=.. --ldpath=build in this case set (solib-search-path=build) should be used
+
+ To debug from desktop directly within './build' directory use following commands
+```
+ cd ./build
+ gdb afb-daemon --args afb-daemon --ldpaths=. --port=1234 --workdir=. --roothttp=../htdocs --tracereq=common --token='' --verbose
```
-# replace hd:XX with your own sound card ID ex: "hw:0", "hw:PCH", ...
-Start a browser on http://localhost:1234?devid=hw:XX
-Start AlsaMixer and change volume you should see event in your browser
+# replace hd:XX with your own sound card ID ex: "hw:0", "hw:PCH", ...
+```
+- Start a browser on http://localhost:1234?devid=hw:XX
+- Start AlsaMixer and change volume you should see event in your browser
```
alsamixer -D hw:0
```
diff --git a/conf.d/app-templates b/conf.d/app-templates
-Subproject 0d3bfaf0888cb350f8721db4a4115ecb8dc4f00
+Subproject 011277d2af3cfee674b50fa8a7362e91e8ad29e
diff --git a/conf.d/autobuild/agl/autobuild b/conf.d/autobuild/agl/autobuild
new file mode 100755
index 0000000..31e29f7
--- /dev/null
+++ b/conf.d/autobuild/agl/autobuild
@@ -0,0 +1,47 @@
+#!/usr/bin/make -f
+# Copyright (C) 2015, 2016 "IoT.bzh"
+# Author "Romain Forlot" <romain.forlot@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.
+
+THISFILE := $(lastword $(MAKEFILE_LIST))
+BUILD_DIR := $(abspath $(dir $(THISFILE)/../../../../..)/build)
+
+.PHONY: all clean distclean configure build package
+
+all: build
+
+clean:
+ @([ -d ${BUILD_DIR} ] && make -C ${BUILD_DIR} clean) || echo Nothing to clean
+
+distclean:
+ @rm -rf ${BUILD_DIR}
+
+configure: ${BUILD_DIR}/Makefile
+
+build: configure
+ @cmake --build ${BUILD_DIR} ${BUILD_ARGS} --target all
+
+package: build
+ @mkdir -p ${BUILD_DIR}/$@/bin
+ @mkdir -p ${BUILD_DIR}/$@/etc
+ @mkdir -p ${BUILD_DIR}/$@/lib
+ @mkdir -p ${BUILD_DIR}/$@/htdocs
+ @mkdir -p ${BUILD_DIR}/$@/data
+ @[ "${DEST}" ] && mkdir -p ${DEST}
+ @cmake --build ${BUILD_DIR} --target widget
+ @[ "${DEST}" ] && cp ${BUILD_DIR}/*wgt ${DEST}
+
+${BUILD_DIR}/Makefile:
+ @[ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}
+ @[ -f ${BUILD_DIR}/Makefile ] || (cd ${BUILD_DIR} && cmake ${CONFIGURE_ARGS} ..)
diff --git a/conf.d/autobuild/linux/autobuild b/conf.d/autobuild/linux/autobuild
new file mode 100755
index 0000000..31e29f7
--- /dev/null
+++ b/conf.d/autobuild/linux/autobuild
@@ -0,0 +1,47 @@
+#!/usr/bin/make -f
+# Copyright (C) 2015, 2016 "IoT.bzh"
+# Author "Romain Forlot" <romain.forlot@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.
+
+THISFILE := $(lastword $(MAKEFILE_LIST))
+BUILD_DIR := $(abspath $(dir $(THISFILE)/../../../../..)/build)
+
+.PHONY: all clean distclean configure build package
+
+all: build
+
+clean:
+ @([ -d ${BUILD_DIR} ] && make -C ${BUILD_DIR} clean) || echo Nothing to clean
+
+distclean:
+ @rm -rf ${BUILD_DIR}
+
+configure: ${BUILD_DIR}/Makefile
+
+build: configure
+ @cmake --build ${BUILD_DIR} ${BUILD_ARGS} --target all
+
+package: build
+ @mkdir -p ${BUILD_DIR}/$@/bin
+ @mkdir -p ${BUILD_DIR}/$@/etc
+ @mkdir -p ${BUILD_DIR}/$@/lib
+ @mkdir -p ${BUILD_DIR}/$@/htdocs
+ @mkdir -p ${BUILD_DIR}/$@/data
+ @[ "${DEST}" ] && mkdir -p ${DEST}
+ @cmake --build ${BUILD_DIR} --target widget
+ @[ "${DEST}" ] && cp ${BUILD_DIR}/*wgt ${DEST}
+
+${BUILD_DIR}/Makefile:
+ @[ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR}
+ @[ -f ${BUILD_DIR}/Makefile ] || (cd ${BUILD_DIR} && cmake ${CONFIGURE_ARGS} ..)
diff --git a/conf.d/config.cmake b/conf.d/cmake/config.cmake
index 8ced9f6..e9367bc 100644
--- a/conf.d/config.cmake
+++ b/conf.d/cmake/config.cmake
@@ -29,13 +29,17 @@ set(PROJECT_AUTHOR_MAIL "fulup@iot.bzh")
set(PROJECT_LICENCE "Apache-V2")
set(PROJECT_LANGUAGES,"C")
+
# Where are stored default templates files from submodule or subtree app-templates in your project tree
# relative to the root project directory
set(PROJECT_APP_TEMPLATES_DIR "conf.d/app-templates")
-# Compilation Mode (DEBUG, RELEASE)
+# Use any directory that does not start with _ as valid source rep
+set(PROJECT_SRC_DIR_PATTERN "[^_]*")
+
+# Compilation Mode (AFB_DEBUG, RELEASE)
# ----------------------------------
-set(CMAKE_BUILD_TYPE "DEBUG")
+set(CMAKE_BUILD_TYPE "AFB_DEBUG")
# Static constante definition
# -----------------------------
@@ -61,6 +65,9 @@ set (PKG_REQUIRED_LIST
# set(CMAKE_C_FLAGS "")
# set(CMAKE_CXX_FLAGS "")
+# Do not optimise when debugging
+set(CMAKE_C_FLAGS_DEBUG "-g -ggdb -Wp,-U_FORTIFY_SOURCE")
+
# Define CONTROL_CDEV_NAME should match MOST driver values
# ---------------------------------------------------------
add_compile_options(-DCONTROL_CDEV_TX="/dev/inic-usb-ctx")
@@ -68,7 +75,7 @@ set (PKG_REQUIRED_LIST
# Print a helper message when every thing is finished
# ----------------------------------------------------
-set(CLOSING_MESSAGE "Test with: afb-daemon --ldpaths=. --port=1234 --workdir=.. --roothttp=./htdocs --tracereq=common --token='' --verbose")
+set(CLOSING_MESSAGE "Debug in ./buid: afb-daemon --port=1234 --ldpaths=. --workdir=. --roothttp=../htdocs --tracereq=common --token='' --verbose")
# (BUG!!!) as PKG_CONFIG_PATH does not work [should be an env variable]
# ---------------------------------------------------------------------
@@ -120,3 +127,8 @@ set(WIDGET_TYPE application/vnd.agl.service)
# Optional force binding Linking flag
# ------------------------------------
# set(BINDINGS_LINK_FLAG LinkOptions )
+
+# This include is mandatory and MUST happens at the end
+# of this file, else you expose you to unexpected behavior
+# -----------------------------------------------------------
+include(${PROJECT_APP_TEMPLATES_DIR}/cmake/common.cmake)
diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml
index 02884db..c476dbc 100644
--- a/nbproject/configurations.xml
+++ b/nbproject/configurations.xml
@@ -5,6 +5,7 @@
<df name="ALSA-afb">
<in>Alsa-AddCtl.c</in>
<in>Alsa-ApiHat.c</in>
+ <in>Alsa-RegEvt.c</in>
<in>Alsa-SetGet.c</in>
<in>Alsa-Ucm.c</in>
</df>
@@ -18,6 +19,9 @@
<df name="HDA-intel">
<in>IntelHdaHAL.c</in>
</df>
+ <df name="Scarlett-Focusrite">
+ <in>ScarlettUsbHAL.c</in>
+ </df>
</df>
<df name="HighLevel-afb">
<in>HighLevelApiConf.c</in>
@@ -67,7 +71,8 @@
</toolsSet>
<flagsDictionary>
<element flagsID="0" commonFlags="-g -fPIC -fPIC -g"/>
- <element flagsID="1" commonFlags="-mtune=generic -march=x86-64 -g -g -fPIC"/>
+ <element flagsID="1" commonFlags="-mtune=generic -march=x86-64 -g -fPIC"/>
+ <element flagsID="2" commonFlags="-mtune=generic -march=x86-64 -g -g -fPIC"/>
</flagsDictionary>
<codeAssistance>
<includeAdditional>true</includeAdditional>
@@ -100,6 +105,14 @@
</incDir>
</cTool>
</item>
+ <item path="ALSA-afb/Alsa-RegEvt.c" ex="false" tool="0" flavor2="3">
+ <cTool flags="1">
+ <incDir>
+ <pElem>/usr/include/json-c</pElem>
+ <pElem>build/ALSA-afb</pElem>
+ </incDir>
+ </cTool>
+ </item>
<item path="ALSA-afb/Alsa-SetGet.c" ex="false" tool="0" flavor2="3">
<cTool flags="1">
<incDir>
@@ -124,15 +137,22 @@
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">
+ <item path="HAL-afb/Scarlett-Focusrite/ScarlettUsbHAL.c"
+ ex="false"
+ tool="0"
+ flavor2="3">
<cTool flags="1">
+ </cTool>
+ </item>
+ <item path="HighLevel-afb/HighLevelApiConf.c" ex="false" tool="0" flavor2="3">
+ <cTool flags="2">
<incDir>
<pElem>Shared-Interface</pElem>
<pElem>../../../opt/include</pElem>
@@ -141,7 +161,7 @@
</cTool>
</item>
<item path="HighLevel-afb/HighLevelBinding.c" ex="false" tool="0" flavor2="3">
- <cTool flags="1">
+ <cTool flags="2">
<incDir>
<pElem>/usr/include/json-c</pElem>
<pElem>Shared-Interface</pElem>
@@ -214,11 +234,7 @@
<folder path="0/HAL-afb">
<cTool>
<incDir>
- <pElem>/usr/include/alsa</pElem>
- <pElem>../../../opt/include</pElem>
- <pElem>/usr/include/json-c</pElem>
- <pElem>HAL-afb/HAL-interface</pElem>
- <pElem>Shared-Interface</pElem>
+ <pElem>../../../opt/include/afb</pElem>
</incDir>
<preprocessorList>
<Elem>CONTROL_CDEV_RX="/dev/inic-usb-crx"</Elem>
@@ -230,6 +246,10 @@
<folder path="0/HAL-afb/HAL-interface">
<cTool>
<incDir>
+ <pElem>HAL-afb/HAL-interface</pElem>
+ <pElem>/usr/include/json-c</pElem>
+ <pElem>Shared-Interface</pElem>
+ <pElem>../../../opt/include</pElem>
<pElem>build/HAL-afb/HAL-interface</pElem>
</incDir>
</cTool>
@@ -237,11 +257,23 @@
<folder path="0/HAL-afb/HDA-intel">
<cTool>
<incDir>
+ <pElem>HAL-afb/HDA-intel</pElem>
+ <pElem>Shared-Interface</pElem>
+ <pElem>HAL-afb/HAL-interface</pElem>
+ <pElem>../../../opt/include</pElem>
<pElem>build/HAL-afb/HDA-intel</pElem>
</incDir>
- <preprocessorList>
- <Elem>hal_intel_hda_EXPORTS</Elem>
- </preprocessorList>
+ </cTool>
+ </folder>
+ <folder path="0/HAL-afb/Scarlett-Focusrite">
+ <cTool>
+ <incDir>
+ <pElem>HAL-afb/Scarlett-Focusrite</pElem>
+ <pElem>Shared-Interface</pElem>
+ <pElem>HAL-afb/HAL-interface</pElem>
+ <pElem>../../../opt/include</pElem>
+ <pElem>build/HAL-afb/Scarlett-Focusrite</pElem>
+ </incDir>
</cTool>
</folder>
<folder path="0/HighLevel-afb">