aboutsummaryrefslogtreecommitdiffstats
path: root/alsa-binding
diff options
context:
space:
mode:
authorJonathan Aillet <jonathan.aillet@iot.bzh>2018-06-02 00:52:09 +0200
committerJonathan Aillet <jonathan.aillet@iot.bzh>2018-06-06 16:50:12 +0000
commita79fdcf92f9f94bdaed68dd57091e4e8fb665e18 (patch)
tree5270dad68367021cec4e49bacf6042c35422ee15 /alsa-binding
parentee41b0386fae5d4d753313d6e4cae1f07ba18138 (diff)
Add an option to 'infoget' verb
Add a new way to get card info when using 'infoget' verb : When the request contains a section 'devpath', the path specified will be used to search for the device. Bug-AGL: SPEC-1405 Change-Id: Idc99a27229f0db3484f62f8f761b7e0daee13a3c Signed-off-by: Jonathan Aillet <jonathan.aillet@iot.bzh>
Diffstat (limited to 'alsa-binding')
-rw-r--r--alsa-binding/Alsa-ApiHat.h5
-rw-r--r--alsa-binding/Alsa-SetGet.c90
2 files changed, 75 insertions, 20 deletions
diff --git a/alsa-binding/Alsa-ApiHat.h b/alsa-binding/Alsa-ApiHat.h
index 97517f3..f5feacd 100644
--- a/alsa-binding/Alsa-ApiHat.h
+++ b/alsa-binding/Alsa-ApiHat.h
@@ -50,6 +50,11 @@ typedef enum {
} queryModeE;
typedef enum {
+ INFO_BY_DEVID,
+ INFO_BY_PATH
+} InfoGetT;
+
+typedef enum {
ACTION_SET,
ACTION_GET
} ActionSetGetT;
diff --git a/alsa-binding/Alsa-SetGet.c b/alsa-binding/Alsa-SetGet.c
index 1b7d4a8..6681415 100644
--- a/alsa-binding/Alsa-SetGet.c
+++ b/alsa-binding/Alsa-SetGet.c
@@ -26,8 +26,16 @@
*/
#define _GNU_SOURCE // needed for vasprintf
+
+#include <sys/ioctl.h>
+
#include "Alsa-ApiHat.h"
+// extracted IOCTLs from <alsa/asoundlib.h>
+#define _IOR_HACKED(type,nr,size) _IOC(_IOC_READ,(type),(nr),size)
+#define SNDRV_CTL_IOCTL_CARD_INFO(size) _IOR_HACKED('U', 0x01, size)
+
+
PUBLIC void NumidsListParse(ActionSetGetT action, queryValuesT *queryValues, ctlRequestT *ctlRequest) {
int length;
@@ -332,45 +340,79 @@ STATIC json_object *decodeTlv(unsigned int *tlv, unsigned int tlv_size, int mode
// retreive info for one given card
-STATIC json_object* alsaCardProbe(const char *rqtSndId) {
+STATIC json_object* alsaCardProbe(const char *rqt, InfoGetT infoType) {
const char *info, *name;
- const char *devid, *driver;
+ const char *driver;
+ char devid[6];
json_object *ctlDev;
snd_ctl_t *handle;
snd_ctl_card_info_t *cardinfo;
- int err;
-
- if ((err = snd_ctl_open(&handle, rqtSndId, 0)) < 0) {
- AFB_INFO("alsaCardProbe '%s' Not Found", rqtSndId);
- return NULL;
- }
+ int err, open_dev;
snd_ctl_card_info_alloca(&cardinfo);
- if ((err = snd_ctl_card_info(handle, cardinfo)) < 0) {
- snd_ctl_close(handle);
- AFB_WARNING("SndCard '%s' info error: %s", rqtSndId, snd_strerror(err));
- return NULL;
+
+ switch(infoType) {
+ case INFO_BY_DEVID:
+ if((snd_ctl_open(&handle, rqt, 0)) < 0) {
+ AFB_INFO("%s: '%s' Not Found", __func__, rqt);
+ return NULL;
+ }
+
+ err = snd_ctl_card_info(handle, cardinfo);
+
+ snd_ctl_close(handle);
+
+ if(err < 0) {
+ AFB_WARNING("%s: SndCard '%s' info error: %s", __func__, rqt, snd_strerror(err));
+ return NULL;
+ }
+
+ break;
+
+ case INFO_BY_PATH:
+ if(! rqt) {
+ AFB_INFO("%s: no dev path specified", __func__);
+ return NULL;
+ }
+
+ open_dev = open(rqt, O_RDONLY);
+ if(open_dev < 0) {
+ AFB_WARNING("%s: DevPath '%s' open error: %i", __func__, rqt, open_dev);
+ return NULL;
+ }
+
+ err = ioctl(open_dev, SNDRV_CTL_IOCTL_CARD_INFO(snd_ctl_card_info_sizeof()), cardinfo);
+
+ close(open_dev);
+
+ if(err < 0) {
+ AFB_WARNING("%s: DevPath '%s' ioctl error: %i", __func__, rqt, err);
+ return NULL;
+ }
+
+ break;
}
// start a new json object to store card info
ctlDev = json_object_new_object();
- devid = snd_ctl_card_info_get_id(cardinfo);
+ snprintf(devid, 6, "hw:%i", snd_ctl_card_info_get_card(cardinfo));
json_object_object_add(ctlDev, "devid", json_object_new_string(devid));
name = snd_ctl_card_info_get_name(cardinfo);
json_object_object_add(ctlDev, "name", json_object_new_string(name));
if (AFB_GET_VERBOSITY > 1) {
- json_object_object_add(ctlDev, "devid", json_object_new_string(rqtSndId));
driver = snd_ctl_card_info_get_driver(cardinfo);
json_object_object_add(ctlDev, "driver", json_object_new_string(driver));
info = strdup(snd_ctl_card_info_get_longname(cardinfo));
json_object_object_add(ctlDev, "info", json_object_new_string(info));
- AFB_INFO("AJG: Soundcard Devid=%-5s devid=%-7s Name=%s\n", rqtSndId, devid, info);
+ if(infoType == INFO_BY_DEVID)
+ AFB_INFO("AJG: Soundcard Devid=%-5s devid=%-7s Name=%s\n", rqt, devid, info);
+ else if(infoType == INFO_BY_DEVID)
+ AFB_INFO("AJG: Soundcard DevPath=%-5s devid=%-7s Name=%s\n", rqt, devid, info);
}
- // free card handle and return info
- snd_ctl_close(handle);
+ // return info
return (ctlDev);
}
@@ -382,16 +424,24 @@ PUBLIC void alsaGetInfo(afb_req request) {
char devid[32];
const char *rqtSndId = afb_req_value(request, "devid");
+ const char *rqtDevPath = afb_req_value(request, "devpath");
// if no specific card requested loop on all
if (rqtSndId != NULL) {
// only one card was requested let's probe it
- ctlDev = alsaCardProbe(rqtSndId);
+ ctlDev = alsaCardProbe(rqtSndId, INFO_BY_DEVID);
if (ctlDev != NULL) afb_req_success(request, ctlDev, NULL);
else afb_req_fail_f(request, "sndscard-notfound", "SndCard '%s' Not Found", rqtSndId);
- } else {
+ }
+ else if (rqtDevPath != NULL) {
+ // only one card was requested let's probe it
+ ctlDev = alsaCardProbe(rqtDevPath, INFO_BY_PATH);
+ if (ctlDev != NULL) afb_req_success(request, ctlDev, NULL);
+ else afb_req_fail_f(request, "sndscard-notfound", "SndCard '%s' Not Found", rqtSndId);
+ }
+ else {
// return an array of ctlDev
ctlDevs = json_object_new_array();
@@ -400,7 +450,7 @@ PUBLIC void alsaGetInfo(afb_req request) {
// build card devid and probe it
snprintf(devid, sizeof (devid), "hw:%i", card);
- ctlDev = alsaCardProbe(devid);
+ ctlDev = alsaCardProbe(devid, INFO_BY_DEVID);
// Alsa has hole within card list [ignore them]
if (ctlDev != NULL) {