diff options
author | Mark Farrugia <mark.farrugia@fiberdyne.com.au> | 2019-04-04 10:28:56 +1100 |
---|---|---|
committer | Mark Farrugia <mark.farrugia@fiberdyne.com.au> | 2019-04-04 10:32:46 +1100 |
commit | 2f73499dd43cc9f27c30f8267d14281beec6a785 (patch) | |
tree | 6a0a92d3234747ae9037d3e5471ee0b38a258762 | |
parent | c6e6cf2c36b08504bae115ddab97b45abc3750c7 (diff) |
Revamp write and read macros, add route retrieval functions
Signed-off-by: Mark Farrugia <mark.farrugia@fiberdyne.com.au>
-rw-r--r-- | include/avirt/avirt.h | 10 | ||||
-rw-r--r-- | src/avirt-config.c | 187 |
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; } |