aboutsummaryrefslogtreecommitdiffstats
path: root/alsa-binding/Alsa-SetGet.c
diff options
context:
space:
mode:
Diffstat (limited to 'alsa-binding/Alsa-SetGet.c')
-rw-r--r--alsa-binding/Alsa-SetGet.c90
1 files changed, 70 insertions, 20 deletions
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) {