summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/avirt/avirt.h10
-rw-r--r--src/avirt-config.c187
2 files changed, 146 insertions, 51 deletions
diff --git a/include/avirt/avirt.h b/include/avirt/avirt.h
index 46c2c19..9389f47 100644
--- a/include/avirt/avirt.h
+++ b/include/avirt/avirt.h
@@ -37,10 +37,6 @@ struct snd_avirt_audiopath {
const char *uid; /* Unique identifier */
const char *name; /* Pretty name */
unsigned int version[3]; /* Version - Major.Minor.Ext */
-
- // MUST be at the end
- struct snd_avirt_audiopath *route_from_ap;
- struct snd_avirt_audiopath *route_to_ap;
};
/*
@@ -57,11 +53,11 @@ struct snd_avirt_stream {
* Audio routing
*/
struct snd_avirt_route {
- const char name[MAX_NAME_LEN]; /* Route name */
+ char name[MAX_NAME_LEN]; /* Route name */
unsigned int channels; /* Route channel count */
unsigned int direction; /* Stream direction */
- struct snd_avirt_audiopath *from_ap;
- struct snd_avirt_audiopath *to_ap;
+ char source_ap[MAX_NAME_LEN];
+ char sink_ap[MAX_NAME_LEN];
};
/**
diff --git a/src/avirt-config.c b/src/avirt-config.c
index 45a54b7..6f1391c 100644
--- a/src/avirt-config.c
+++ b/src/avirt-config.c
@@ -27,6 +27,8 @@
#include <alsa/asoundlib.h>
#include <sys/stat.h>
#include <sys/mount.h>
+#include <dirent.h>
+#include <libgen.h>
#define AVIRT_CONFIGFS_PATH_STREAMS "/config/snd-avirt/streams/"
#define AVIRT_CONFIGFS_PATH_ROUTES "/config/snd-avirt/routes/"
@@ -88,16 +90,45 @@
/**
* Write the given formatted string to a file given by path
*/
-#define WRITE_TO_PATH(path, fmt, args...) \
- do { \
- FILE *fd = fopen(path, "w"); \
- if (!fd) { \
- AVIRT_ERROR_V("Failed to open file at '%s'", path); \
+#define WRITE_ATTR_TO_DIR(path_dir, attr, fmt, args...) \
+ ({ \
+ int __err = 0; \
+ char __path_attr[AVIRT_CONFIGFS_PATH_MAXLEN]; \
+ strcpy(__path_attr, path_dir); \
+ strcat(__path_attr, "/"); \
+ strcat(__path_attr, attr); \
+ FILE *__fd = fopen(__path_attr, "w"); \
+ if (!__fd) { \
+ AVIRT_ERROR_V("Failed to open file at '%s'", \
+ __path_attr); \
return -EPERM; \
} \
- fprintf(fd, fmt, ##args); \
- fclose(fd); \
- } while (0)
+ __err = fprintf(__fd, fmt, ##args); \
+ __err = fclose(__fd); \
+ (__err); \
+ })
+
+/**
+ * Read the given formatted string from a file given by path
+ */
+#define READ_ATTR_FROM_DIR(path_dir, attr, fmt, args...) \
+ ({ \
+ int __err = 0; \
+ char __path_attr[AVIRT_CONFIGFS_PATH_MAXLEN]; \
+ strcpy(__path_attr, path_dir); \
+ strcat(__path_attr, "/"); \
+ strcat(__path_attr, attr); \
+ FILE *__fd = fopen(__path_attr, "r"); \
+ if (!__fd) { \
+ AVIRT_ERROR_V("Failed to open file at '%s'", \
+ __path_attr); \
+ return -EPERM; \
+ } \
+ __err = fscanf(__fd, fmt, ##args); \
+ __err = fclose(__fd); \
+ (__err); \
+ })
+
static bool configfs_mounted = false;
static bool card_configured = false;
@@ -382,7 +413,6 @@ int snd_avirt_stream_new(const char *name, unsigned int channels, int direction,
const char *map, bool internal)
{
char path[AVIRT_CONFIGFS_PATH_MAXLEN];
- char path_attr[AVIRT_CONFIGFS_PATH_MAXLEN];
if ((channels > __INT_MAX__) || (channels == 0))
{
@@ -394,17 +424,12 @@ int snd_avirt_stream_new(const char *name, unsigned int channels, int direction,
CHK_ERR(snd_avirt_configfs_item_new(name, direction, path, internal), "");
// Write channels
- strcpy(path_attr, path);
- strcat(path_attr, "/channels");
- WRITE_TO_PATH(path_attr, "%d", channels);
+ WRITE_ATTR_TO_DIR(path, "channels", "%d", channels);
if (map)
{
// Write mapping
- memset(path_attr, 0, AVIRT_CONFIGFS_PATH_MAXLEN);
- strcpy(path_attr, path);
- strcat(path_attr, "/map");
- WRITE_TO_PATH(path_attr, "%s", map);
+ WRITE_ATTR_TO_DIR(path, "map", "%s", map);
}
else
{
@@ -421,7 +446,6 @@ int snd_avirt_route_new(const char *name, int channels, int direction,
{
int err;
char path[AVIRT_CONFIGFS_PATH_MAXLEN];
- char path_attr[AVIRT_CONFIGFS_PATH_MAXLEN];
if ((channels > __INT_MAX__) || (channels == 0))
{
@@ -441,21 +465,13 @@ int snd_avirt_route_new(const char *name, int channels, int direction,
CHK_ERR(snd_avirt_configfs_item_new(name, direction, path, false), "");
// Write channels
- strcpy(path_attr, path);
- strcat(path_attr, "/channels");
- WRITE_TO_PATH(path_attr, "%d", channels);
-
- // Write route_sink_ap into route_source_ap's 'to' path
- memset(path_attr, 0, AVIRT_CONFIGFS_PATH_MAXLEN);
- strcpy(path_attr, path);
- strcat(path_attr, "/sink_ap");
- WRITE_TO_PATH(path_attr, sink_ap);
-
- // Write route_source_ap into route_sink_ap's 'from' path
- memset(path_attr, 0, AVIRT_CONFIGFS_PATH_MAXLEN);
- strcpy(path_attr, path);
- strcat(path_attr, "/source_ap");
- WRITE_TO_PATH(path_attr, source_ap);
+ WRITE_ATTR_TO_DIR(path, "channels", "%d", channels);
+
+ // Write route_sink_ap into route_source_ap's 'sink' path
+ WRITE_ATTR_TO_DIR(path, "sink_ap", sink_ap);
+
+ // Write route_source_ap into route_sink_ap's 'source' path
+ WRITE_ATTR_TO_DIR(path, "source_ap", source_ap);
CHK_ERR(snd_avirt_stream_new(name, channels, !direction, source_ap, true),
"Couldn't create stream: %s", name);
@@ -471,9 +487,9 @@ int snd_avirt_route_new(const char *name, int channels, int direction,
int snd_avirt_card_configure()
{
char cmd[128];
- char path_sealed[AVIRT_CONFIGFS_PATH_MAXLEN];
snd_pcm_info_t *route_pcm_info;
- int err = 0;
+ struct snd_avirt_route *routes = NULL;
+ int route_count = 0, i;
// Check if card is already configured
if (card_configured)
@@ -484,9 +500,9 @@ int snd_avirt_card_configure()
IS_CONFIGFS_MOUNTED();
- strcpy(path_sealed, AVIRT_CONFIGFS_PATH_STREAMS);
strcat(path_sealed, "/configured");
WRITE_TO_PATH(path_sealed, "%d", 1);
+ WRITE_ATTR_TO_DIR(AVIRT_CONFIGFS_PATH_STREAMS, "configured", "%d", 1);
AVIRT_DEBUG("Card configured!");
card_configured = true;
@@ -496,19 +512,102 @@ int snd_avirt_card_configure()
if (card_index < 0)
return card_index;
- // TD MF: HACK: Open the UNICENS device
- snd_pcm_info_alloca(&route_pcm_info);
- snd_avirt_pcm_info("ep01-6ch", route_pcm_info);
+ // Get any routes, and run the router for them
+ CHK_ERR(snd_avirt_routes(&routes, &route_count), "Get AVIRT routes failed");
+ for (i = 0; i < route_count; i++)
+ {
+ snd_pcm_info_alloca(&route_pcm_info);
+ CHK_ERR(snd_avirt_pcm_info(routes[i].name,
+ route_pcm_info), "PCM info failed");
+
+ sprintf(cmd, "speaker-test -Dhw:%d,%d -c6 >/dev/null &",
+ card_index, snd_pcm_info_get_device(route_pcm_info));
+ CHK_ERR(system(cmd), "Running router failed: '%s'", cmd);
+ AVIRT_DEBUG_V("Running router: '%s'", cmd);
+ }
- sprintf(cmd, "speaker-test -Dhw:%d,%d -c6 >/dev/null &",
- card_index, snd_pcm_info_get_device(route_pcm_info));
- AVIRT_DEBUG_V("Running router: '%s'", cmd);
- err = system(cmd);
+ return 0;
+}
+static int snd_avirt_route_get(const char *path_dir, struct snd_avirt_route *route)
+{
+ DIR *d;
+ struct dirent *dir;
- return 0;
+ AVIRT_DEBUG_V("Opening route dir: %s", path_dir);
+ d = opendir(path_dir);
+ if (d)
+ {
+ while ((dir = readdir(d)) != NULL)
+ {
+ if ((!strcmp(dir->d_name, ".")) || (!strcmp(dir->d_name, "..")))
+ continue;
+
+ if (!strcmp(dir->d_name, "channels"))
+ READ_ATTR_FROM_DIR(path_dir, dir->d_name, "%d", &route->channels);
+ else if (!strcmp(dir->d_name, "direction"))
+ READ_ATTR_FROM_DIR(path_dir, dir->d_name, "%d", &route->direction);
+ else if (!strcmp(dir->d_name, "source_ap"))
+ READ_ATTR_FROM_DIR(path_dir, dir->d_name, "%s", route->source_ap);
+ else if (!strcmp(dir->d_name, "sink_ap"))
+ READ_ATTR_FROM_DIR(path_dir, dir->d_name, "%s", route->sink_ap);
+ }
+
+ char *name = basename((char *)path_dir);
+ strsep(&name, "_");
+ strcpy(route->name, name);
+
+ return 0;
+ }
+
+ return -ENOENT;
}
+int snd_avirt_routes(struct snd_avirt_route **routes, int *count)
+{
+ int i;
+ DIR *d;
+ struct dirent *dir;
+ char path_dir[AVIRT_CONFIGFS_PATH_MAXLEN];
+ struct snd_avirt_route routes_temp[4];
- return 0;
+ IS_CONFIGFS_MOUNTED();
+
+ strcpy(path_dir, AVIRT_CONFIGFS_PATH_ROUTES);
+ d = opendir(path_dir);
+ if (d)
+ {
+ *count = 0;
+ while (((dir = readdir(d)) != NULL) && (*count <= 4))
+ {
+ if ((!strcmp(dir->d_name, ".")) || (!strcmp(dir->d_name, "..")))
+ continue;
+
+ char path_route_dir[AVIRT_CONFIGFS_PATH_MAXLEN];
+ strcpy(path_route_dir, AVIRT_CONFIGFS_PATH_ROUTES);
+ strcat(path_route_dir, dir->d_name);
+ snd_avirt_route_get(path_route_dir, &routes_temp[*count]);
+ (*count)++;
+ }
+
+ *routes = malloc(sizeof(struct snd_avirt_route) * (*count));
+ if (!(*routes))
+ {
+ AVIRT_ERROR("Failed to alloc memory for snd_avirt_route");
+ return -EFAULT;
+ }
+
+ for (i = 0; i < (*count); i++)
+ {
+ strcpy((*routes)[i].name, routes_temp[i].name);
+ strcpy((*routes)[i].sink_ap, routes_temp[i].sink_ap);
+ strcpy((*routes)[i].source_ap, routes_temp[i].source_ap);
+ (*routes)[i].channels = routes_temp[i].channels;
+ (*routes)[i].direction = routes_temp[i].direction;
+ }
+
+ return 0;
+ }
+
+ return -ENOENT;
}