aboutsummaryrefslogtreecommitdiffstats
path: root/src/avirt-config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/avirt-config.c')
-rw-r--r--src/avirt-config.c107
1 files changed, 100 insertions, 7 deletions
diff --git a/src/avirt-config.c b/src/avirt-config.c
index 6f1391c..a52ef0a 100644
--- a/src/avirt-config.c
+++ b/src/avirt-config.c
@@ -134,9 +134,29 @@ static bool configfs_mounted = false;
static bool card_configured = false;
static int card_index = -1;
+bool check_dir_empty(char *dirname)
+{
+ int n = 0;
+ struct dirent *d;
+
+ DIR *dir = opendir(dirname);
+ if (dir == NULL) // Not a directory or doesn't exist
+ return 1;
+ while ((d = readdir(dir)) != NULL) {
+ if (++n > 2) // Ignore the '.' and '..' directories
+ break;
+ }
+
+ closedir(dir);
+ if (n <= 2) // Directory Empty
+ return true;
+
+ return false;
+}
+
static int mount_configfs()
{
- int err;
+ int err = 0;
char fsline[100];
bool configfs_supported = false;
FILE *procfs;
@@ -164,14 +184,18 @@ static int mount_configfs()
if (stat("/config", &st) == -1)
mkdir("/config", S_IRWXU | S_IRWXG | S_IRWXO);
- err = mount("none", "/config", "configfs", 0, NULL);
- if (!err)
+ // Check whether configfs is mounted, if not, mount it
+ if (check_dir_empty("/config"))
{
- AVIRT_DEBUG("Successfully mounted configfs");
- configfs_mounted = true;
+ err = mount("none", "/config", "configfs", 0, NULL);
+ if (!err)
+ {
+ AVIRT_DEBUG("Successfully mounted configfs");
+ configfs_mounted = true;
+ }
+ else
+ AVIRT_ERROR("Failed to mount configfs filesystem!");
}
- else
- AVIRT_ERROR("Failed to mount configfs filesystem!");
return err;
}
@@ -409,6 +433,48 @@ close_handle:
return retval;
}
+static int snd_avirt_stream_reset_all()
+{
+ int err;
+ DIR *d;
+ struct dirent *dir;
+ char path[AVIRT_CONFIGFS_PATH_MAXLEN];
+
+ d = opendir(AVIRT_CONFIGFS_PATH_STREAMS);
+ if (d)
+ {
+ while ((dir = readdir(d)) != NULL)
+ {
+ // Ignore the directory . and ..
+ if ((!strcmp(dir->d_name, ".")) || (!strcmp(dir->d_name, "..")))
+ continue;
+
+ memset(path, 0, AVIRT_CONFIGFS_PATH_MAXLEN);
+ strcpy(path, AVIRT_CONFIGFS_PATH_STREAMS);
+ strcat(path, dir->d_name);
+
+ // If not a directory, continue
+ struct stat path_stat;
+ stat(path, &path_stat);
+ if (S_ISREG(path_stat.st_mode))
+ continue;
+
+ err = rmdir(path);
+ if (err < 0)
+ {
+ AVIRT_ERROR_V("Cannot remove config item '%s' at directory '%s'", dir->d_name, path);
+ return err;
+ }
+ }
+
+ AVIRT_DEBUG("Reset streams!");
+
+ return 0;
+ }
+
+ return -EPERM;
+}
+
int snd_avirt_stream_new(const char *name, unsigned int channels, int direction,
const char *map, bool internal)
{
@@ -526,6 +592,33 @@ int snd_avirt_card_configure()
AVIRT_DEBUG_V("Running router: '%s'", cmd);
}
+
+ return 0;
+}
+
+int snd_avirt_card_unconfigure()
+{
+ // Check if card is already configured
+ if (!card_configured)
+ {
+ AVIRT_ERROR("Card is already unconfigured!");
+ return -EPERM;
+ }
+
+ IS_CONFIGFS_MOUNTED();
+
+ snd_avirt_stream_reset_all();
+
+ WRITE_ATTR_TO_DIR(AVIRT_CONFIGFS_PATH_STREAMS, "configured", "%d", 0);
+
+ AVIRT_DEBUG("Card unconfigured!");
+ card_configured = false;
+
+ if (card_index < 0)
+ card_index = snd_avirt_card_index_get(0);
+ if (card_index < 0)
+ return card_index;
+
return 0;
}