[asterisk-commits] kmoore: branch kmoore/stasis-http_sounds r389585 - in /team/kmoore/stasis-htt...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu May 23 14:29:25 CDT 2013
Author: kmoore
Date: Thu May 23 14:29:21 2013
New Revision: 389585
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=389585
Log:
Pull res_sounds back into main and drop the API
Removed:
team/kmoore/stasis-http_sounds/res/res_sounds.c
Modified:
team/kmoore/stasis-http_sounds/include/asterisk/_private.h
team/kmoore/stasis-http_sounds/include/asterisk/sounds.h
team/kmoore/stasis-http_sounds/main/asterisk.c
team/kmoore/stasis-http_sounds/main/sounds.c
team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c
Modified: team/kmoore/stasis-http_sounds/include/asterisk/_private.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/include/asterisk/_private.h?view=diff&rev=389585&r1=389584&r2=389585
==============================================================================
--- team/kmoore/stasis-http_sounds/include/asterisk/_private.h (original)
+++ team/kmoore/stasis-http_sounds/include/asterisk/_private.h Thu May 23 14:29:21 2013
@@ -123,4 +123,7 @@
/*! \brief initializes the rtp engine arrays */
int ast_rtp_engine_init(void);
+
+/*! \brief initialize the sounds indexer */
+int ast_sounds_init(void);
#endif /* _ASTERISK__PRIVATE_H */
Modified: team/kmoore/stasis-http_sounds/include/asterisk/sounds.h
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/include/asterisk/sounds.h?view=diff&rev=389585&r1=389584&r2=389585
==============================================================================
--- team/kmoore/stasis-http_sounds/include/asterisk/sounds.h (original)
+++ team/kmoore/stasis-http_sounds/include/asterisk/sounds.h Thu May 23 14:29:21 2013
@@ -28,46 +28,6 @@
#endif
struct ast_format_cap;
-
-/*! \brief Interface for sound indexers to use when registering themselves */
-struct ast_sounds_indexer {
- /*! \brief Function pointer called by ast_sounds_get_description */
- char *(*get_description)(const char *filename, const char *lang);
-
- /*! \brief Function pointer called by ast_sounds_get_format_cap */
- struct ast_format_cap *(*get_format_cap)(const char *filename, const char *lang);
-
- /*! \brief Function pointer called by ast_sounds_get_languages */
- struct ao2_container *(*get_languages)(const char *filename);
-
- /*! \brief Function pointer called by ast_sounds_get_sounds */
- struct ao2_container *(*get_sounds)(void);
-
- /*! \brief Function pointer called by ast_sounds_reindex */
- int (*reindex)(void);
-};
-
-/*!
- * \brief Register callbacks for a sound indexer
- *
- * \param indexer Struct containing necessary callback functions
- */
-void ast_sounds_indexer_register(struct ast_sounds_indexer *indexer);
-
-/*!
- * \brief Unregister callbacks for a sound indexer
- *
- * \param indexer The struct that was used to register the functions
- */
-void ast_sounds_indexer_unregister(struct ast_sounds_indexer *indexer);
-
-/*!
- * \brief Determine whether a sounds indexer is registered
- *
- * \retval zero if not registered
- * \retval non-zero if registered
- */
-int ast_sounds_indexer_registered(void);
/*!
* \brief Get the description for a sound
Modified: team/kmoore/stasis-http_sounds/main/asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/main/asterisk.c?view=diff&rev=389585&r1=389584&r2=389585
==============================================================================
--- team/kmoore/stasis-http_sounds/main/asterisk.c (original)
+++ team/kmoore/stasis-http_sounds/main/asterisk.c Thu May 23 14:29:21 2013
@@ -4350,6 +4350,11 @@
exit(1);
}
+ if (ast_sounds_init()) {
+ printf("%s", term_quit());
+ exit(1);
+ }
+
if ((moduleresult = load_modules(0))) { /* Load modules */
printf("%s", term_quit());
exit(moduleresult == -2 ? 2 : 1);
Modified: team/kmoore/stasis-http_sounds/main/sounds.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/main/sounds.c?view=diff&rev=389585&r1=389584&r2=389585
==============================================================================
--- team/kmoore/stasis-http_sounds/main/sounds.c (original)
+++ team/kmoore/stasis-http_sounds/main/sounds.c Thu May 23 14:29:21 2013
@@ -21,70 +21,723 @@
*/
#include "asterisk.h"
+
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include "asterisk/utils.h"
+#include "asterisk/lock.h"
+#include "asterisk/format.h"
+#include "asterisk/format_cap.h"
+#include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
#include "asterisk/sounds.h"
-
-/*! \brief Holder for the registered indexer interface */
-static struct ast_sounds_indexer *sounds_indexer = NULL;
-
-void ast_sounds_indexer_register(struct ast_sounds_indexer *indexer)
-{
- sounds_indexer = indexer;
-}
-
-void ast_sounds_indexer_unregister(struct ast_sounds_indexer *indexer)
-{
- if (indexer == sounds_indexer) {
- indexer = NULL;
- }
-}
-
-int ast_sounds_indexer_registered(void)
-{
- return sounds_indexer ? 1 : 0;
-}
-
+#include "asterisk/file.h"
+#include "asterisk/cli.h"
+#include "asterisk/module.h"
+#include "asterisk/_private.h"
+
+/*** MODULEINFO
+ <support_level>core</support_level>
+ ***/
+
+/*! \brief The number of buckets to be used for storing language-keyed objects */
+#define LANGUAGE_BUCKETS 7
+
+/*! \brief The number of buckets to be used for storing sound filename-keyed objects */
+#define SOUNDS_BUCKETS 157
+
+static struct ao2_container *sounds_index;
+
+/*! \brief Structure to hold a list of the format variations for a sound file in a specific language */
+struct sound_variant {
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(language); /*!< The language this sound is available in */
+ AST_STRING_FIELD(description); /*!< The description of the sound */
+ );
+ struct ast_format_cap *formats; /*!< The formats this sound is available in for this language */
+};
+
+static void sound_variant_destroy(void *obj)
+{
+ struct sound_variant *variant = obj;
+
+ ast_string_field_free_memory(variant);
+ variant->formats = ast_format_cap_destroy(variant->formats);
+}
+
+static struct sound_variant *sound_variant_alloc(const char *language)
+{
+ RAII_VAR(struct sound_variant *, variant, ao2_alloc(sizeof(*variant), sound_variant_destroy), ao2_cleanup);
+
+ if (ast_string_field_init(variant, 8)) {
+ return NULL;
+ }
+
+ variant->formats = ast_format_cap_alloc();
+ if (!variant->formats) {
+ return NULL;
+ }
+
+ ast_string_field_set(variant, language, language);
+
+ ao2_ref(variant, 1);
+ return variant;
+}
+
+static int sound_variant_hash(const void *obj, const int flags)
+{
+ const char *language = (flags & OBJ_KEY) ? obj : ((struct sound_variant*) obj)->language;
+ return ast_str_case_hash(language);
+}
+
+static int sound_variant_cmp(void *obj, void *arg, int flags)
+{
+ struct sound_variant *opt1 = obj, *opt2 = arg;
+ const char *language = (flags & OBJ_KEY) ? arg : opt2->language;
+ return strcasecmp(opt1->language, language) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+/*! \brief Structure to hold information about a sound file */
+struct sound_info {
+ AST_DECLARE_STRING_FIELDS(
+ AST_STRING_FIELD(name); /*!< The name of the sound */
+ );
+ struct ao2_container *variant_list; /*!< The list of (language, format) tuples for which this sound is available */
+};
+
+static void sound_info_destroy(void *obj)
+{
+ struct sound_info *info = obj;
+
+ ast_string_field_free_memory(info);
+ ao2_cleanup(info->variant_list);
+ info->variant_list = NULL;
+}
+
+static struct sound_info *sound_info_alloc(const char *name)
+{
+ RAII_VAR(struct sound_info *, info, ao2_alloc(sizeof(*info), sound_info_destroy), ao2_cleanup);
+
+ if (ast_string_field_init(info, 128)) {
+ return NULL;
+ }
+
+ info->variant_list = ao2_container_alloc(LANGUAGE_BUCKETS, sound_variant_hash, sound_variant_cmp);
+ if (!info->variant_list) {
+ return NULL;
+ }
+
+ ast_string_field_set(info, name, name);
+
+ ao2_ref(info, 1);
+ return info;
+}
+
+static int sound_info_hash(const void *obj, const int flags)
+{
+ const char *name = (flags & OBJ_KEY) ? obj : ((struct sound_info*) obj)->name;
+ return ast_str_case_hash(name);
+}
+
+static int sound_info_cmp(void *obj, void *arg, int flags)
+{
+ struct sound_info *opt1 = obj, *opt2 = arg;
+ const char *name = (flags & OBJ_KEY) ? arg : opt2->name;
+ return strcasecmp(opt1->name, name) ? 0 : CMP_MATCH | CMP_STOP;
+}
+
+/*! \brief Get the languages in which sound files are available */
+static struct ao2_container *get_languages(void)
+{
+ RAII_VAR(struct ao2_container *, lang_dirs, NULL, ao2_cleanup);
+ struct dirent* dent;
+ DIR* srcdir;
+ RAII_VAR(struct ast_str *, sounds_dir, ast_str_create(64), ast_free);
+
+ lang_dirs = ast_str_container_alloc(LANGUAGE_BUCKETS);
+ if (!sounds_dir || !lang_dirs) {
+ return NULL;
+ }
+
+ ast_str_set(&sounds_dir, 0, "%s/sounds", ast_config_AST_DATA_DIR);
+
+ srcdir = opendir(ast_str_buffer(sounds_dir));
+
+ if (srcdir == NULL) {
+ ast_log(LOG_ERROR, "Failed to open %s\n", ast_str_buffer(sounds_dir));
+ return NULL;
+ }
+
+ while((dent = readdir(srcdir)) != NULL) {
+ struct stat st;
+
+ if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
+ continue;
+ }
+
+ if (fstatat(dirfd(srcdir), dent->d_name, &st, 0) < 0) {
+ ast_log(LOG_ERROR, "Failed to stat %s\n", dent->d_name);
+ continue;
+ }
+
+ if (S_ISDIR(st.st_mode)) {
+ ast_str_container_add(lang_dirs, dent->d_name);
+ }
+ }
+
+ closedir(srcdir);
+ ao2_ref(lang_dirs, +1);
+ return lang_dirs;
+}
+
+static struct sound_variant *find_variant(const char *filename, const char *lang)
+{
+ RAII_VAR(struct sound_info *, info, NULL, ao2_cleanup);
+
+ info = ao2_find(sounds_index, filename, OBJ_KEY);
+ if (!info) {
+ return NULL;
+ }
+
+ return ao2_find(info->variant_list, lang, OBJ_KEY);
+}
+
+/*! \brief create the appropriate sound_variant and any necessary structures */
+static struct sound_variant *alloc_variant(const char *filename, const char *lang)
+{
+ RAII_VAR(struct sound_info *, info, NULL, ao2_cleanup);
+ RAII_VAR(struct sound_variant *, variant, NULL, ao2_cleanup);
+
+ info = ao2_find(sounds_index, filename, OBJ_KEY);
+ if (!info) {
+ /* This is the first time the index has seen this filename,
+ * allocate and link */
+ info = sound_info_alloc(filename);
+ if (!info) {
+ return NULL;
+ }
+
+ ao2_link(sounds_index, info);
+ }
+
+ variant = ao2_find(info->variant_list, lang, OBJ_KEY);
+ if (!variant) {
+ /* This is the first time the index has seen this language for
+ * this filename, allocate and link */
+ variant = sound_variant_alloc(lang);
+ if (!variant) {
+ return NULL;
+ }
+
+ ao2_link(info->variant_list, variant);
+ }
+
+ ao2_ref(variant, +1);
+ return variant;
+}
+
+/*! \brief Get the description associated with the sound filename for the given language if available */
char *ast_sounds_get_description(const char *filename, const char *lang)
{
- if (sounds_indexer && sounds_indexer->get_description) {
- return sounds_indexer->get_description(filename, lang);
- }
-
- return NULL;
-}
-
+ RAII_VAR(struct sound_variant *, variant, NULL, ao2_cleanup);
+ if (ast_strlen_zero(filename) || ast_strlen_zero(lang)) {
+ return NULL;
+ }
+
+ variant = find_variant(filename, lang);
+ if (!variant) {
+ return NULL;
+ }
+
+ return ast_strdup(variant->description);
+}
+
+/*! \brief Get the ast_format_cap associated with the sound filename and language if available */
struct ast_format_cap *ast_sounds_get_format_cap(const char *filename, const char *lang)
{
- if (sounds_indexer && sounds_indexer->get_format_cap) {
- return sounds_indexer->get_format_cap(filename, lang);
- }
-
- return NULL;
-}
-
+ RAII_VAR(struct sound_variant *, variant, NULL, ao2_cleanup);
+ if (ast_strlen_zero(filename) || ast_strlen_zero(lang)) {
+ return NULL;
+ }
+
+ variant = find_variant(filename, lang);
+ if (!variant) {
+ return NULL;
+ }
+
+ return ast_format_cap_dup(variant->formats);
+}
+
+/*! \brief Add the variant's language to the list of languages requested */
+static int add_language_cb(void *obj, void *arg, int flags)
+{
+ struct sound_variant *variant = obj;
+ struct ao2_container *languages = arg;
+ ast_str_container_add(languages, variant->language);
+ return 0;
+}
+
+/*! \brief Return the requested container of languages */
struct ao2_container *ast_sounds_get_languages(const char *filename)
{
- if (sounds_indexer && sounds_indexer->get_languages) {
- return sounds_indexer->get_languages(filename);
- }
-
- return NULL;
-}
-
+ RAII_VAR(struct sound_info *, info, NULL, ao2_cleanup);
+ RAII_VAR(struct ao2_container *, languages, NULL, ao2_cleanup);
+ if (!filename) {
+ return NULL;
+ }
+
+ languages = ast_str_container_alloc(LANGUAGE_BUCKETS);
+ if (!languages) {
+ return NULL;
+ }
+
+ info = ao2_find(sounds_index, filename, OBJ_KEY);
+ if (!info) {
+ return NULL;
+ }
+
+ ao2_callback(info->variant_list, OBJ_NODATA, add_language_cb, languages);
+
+ ao2_ref(languages, +1);
+ return languages;
+}
+
+/*! \brief Add the sound_info's sound filename to the container of filenames requested */
+static int add_sound_cb(void *obj, void *arg, int flags)
+{
+ struct sound_info *info = obj;
+ struct ao2_container *sounds = arg;
+ ast_str_container_add(sounds, info->name);
+ return 0;
+}
+
+/*! \brief Return the requested container of sounds */
struct ao2_container *ast_sounds_get_sounds(void)
{
- if (sounds_indexer && sounds_indexer->get_sounds) {
- return sounds_indexer->get_sounds();
- }
-
- return NULL;
-}
-
+ RAII_VAR(struct ao2_container *, sounds, NULL, ao2_cleanup);
+
+ sounds = ast_str_container_alloc(SOUNDS_BUCKETS);
+ if (!sounds) {
+ return NULL;
+ }
+
+ ao2_callback(sounds_index, OBJ_NODATA, add_sound_cb, sounds);
+
+ ao2_ref(sounds, +1);
+ return sounds;
+}
+
+/*! \brief Update an index with new format/language information */
+static int update_file_format_info(const char *filename, const char *lang, const struct ast_format *file_format)
+{
+ RAII_VAR(struct sound_variant *, variant, find_variant(filename, lang), ao2_cleanup);
+ if (!variant) {
+ variant = alloc_variant(filename, lang);
+ if (!variant) {
+ return -1;
+ }
+ }
+
+ ast_format_cap_add(variant->formats, file_format);
+ return 0;
+}
+
+/*! \brief Process a sound file into the index */
+static int process_sound_file(const char *lang, const char *subdir, const char *filename_stripped, const char *ext)
+{
+ const struct ast_format *file_format;
+ const char *file_identifier = filename_stripped;
+ RAII_VAR(struct ast_str *, file_id_str, NULL, ast_free);
+
+ file_format = ast_get_format_for_file_ext(ext);
+ if (!file_format) {
+ /* extension not registered */
+ return 0;
+ }
+
+ /* handle updating the file information */
+ if (subdir) {
+ file_id_str = ast_str_create(64);
+ if (!file_id_str) {
+ return -1;
+ }
+
+ ast_str_set(&file_id_str, 0, "%s/%s", subdir, filename_stripped);
+ file_identifier = ast_str_buffer(file_id_str);
+ }
+
+ if (update_file_format_info(file_identifier, lang, file_format)) {
+ return -1;
+ }
+ return 0;
+}
+
+/*!
+ * \brief Process a sounds description text file
+ *
+ * This currently processes core-sounds-*.txt and extra-sounds-*.txt, but will
+ * process others if present.
+ */
+static int process_description_file(const char *lang, const char *filename)
+{
+ RAII_VAR(struct ast_str *, description_file_path, ast_str_create(64), ast_free);
+ RAII_VAR(struct ast_str *, cumulative_description, ast_str_create(64), ast_free);
+ char *file_id_persist = NULL;
+ int res = 0;
+ FILE *f = NULL;
+#if defined(LOW_MEMORY)
+ char buf[256];
+#else
+ char buf[2048];
+#endif
+
+ if (!description_file_path || !cumulative_description) {
+ return -1;
+ }
+
+ ast_str_set(&description_file_path, 0, "%s/sounds/%s/%s", ast_config_AST_DATA_DIR, lang, filename);
+ f = fopen(ast_str_buffer(description_file_path), "r");
+ if (!f) {
+ ast_log(LOG_WARNING, "Could not open sound description file '%s'\n", ast_str_buffer(description_file_path));
+ return -1;
+ }
+
+ while (!feof(f)) {
+ char *file_identifier, *description;
+ if (!fgets(buf, sizeof(buf), f)) {
+ if (ferror(f)) {
+ ast_log(LOG_ERROR, "Error reading from file %s\n", ast_str_buffer(description_file_path));
+ }
+ continue;
+ }
+
+ /* Skip lines that are too long */
+ if (strlen(buf) == sizeof(buf) - 1 && buf[sizeof(buf) - 1] != '\n') {
+ ast_log(LOG_WARNING, "Line too long, skipping. It begins with: %.32s...\n", buf);
+ while (fgets(buf, sizeof(buf), f)) {
+ if (strlen(buf) != sizeof(buf) - 1 || buf[sizeof(buf) - 1] == '\n') {
+ break;
+ }
+ }
+ if (ferror(f)) {
+ ast_log(LOG_ERROR, "Error reading from file %s\n", ast_str_buffer(description_file_path));
+ }
+ continue;
+ }
+
+ if (buf[0] == ';') {
+ /* ignore comments */
+ continue;
+ }
+
+ ast_trim_blanks(buf);
+ description = buf;
+ file_identifier = strsep(&description, ":");
+ if (!description) {
+ /* no ':' means this is a continuation */
+ if (file_id_persist) {
+ ast_str_append(&cumulative_description, 0, "\n%s", file_identifier);
+ }
+ continue;
+ } else {
+ /* if there's text in cumulative_description, archive it and start anew */
+ if (file_id_persist && !ast_strlen_zero(ast_str_buffer(cumulative_description))) {
+ RAII_VAR(struct sound_variant *, variant, NULL, ao2_cleanup);
+ variant = find_variant(file_id_persist, lang);
+ if (!variant) {
+ variant = alloc_variant(filename, lang);
+ if (!variant) {
+ res = -1;
+ break;
+ }
+ }
+
+ ast_string_field_set(variant, description, ast_str_buffer(cumulative_description));
+
+ ast_str_reset(cumulative_description);
+ ast_free(file_id_persist);
+ file_id_persist = NULL;
+ }
+
+ file_id_persist = strdup(file_identifier);
+ description = ast_skip_blanks(description);
+ ast_str_set(&cumulative_description, 0, "%s", description);
+ }
+ }
+
+ /* handle the last one */
+ if (file_id_persist && !ast_strlen_zero(ast_str_buffer(cumulative_description))) {
+ RAII_VAR(struct sound_variant *, variant, NULL, ao2_cleanup);
+ variant = find_variant(file_id_persist, lang);
+ if (!variant) {
+ variant = alloc_variant(filename, lang);
+ }
+
+ if (variant) {
+ ast_string_field_set(variant, description, ast_str_buffer(cumulative_description));
+ ast_free(file_id_persist);
+ } else {
+ res = -1;
+ }
+ }
+
+ fclose(f);
+ return res;
+}
+
+/*! \brief process an individual file listing */
+static int process_file(const char *lang, const char *subdir, const char *filename)
+{
+ RAII_VAR(char *, filename_stripped, ast_strdup(filename), ast_free);
+ char *ext;
+
+ if (!filename_stripped) {
+ return -1;
+ }
+
+ ext = strrchr(filename_stripped, '.');
+ if (!ext) {
+ /* file has no extension */
+ return 0;
+ }
+
+ *ext++ = '\0';
+ if (!strcmp(ext, "txt")) {
+ if (!subdir && process_description_file(lang, filename)) {
+ return -1;
+ }
+ } else {
+ if (process_sound_file(lang, subdir, filename_stripped, ext)) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*! \brief Callback to process an individual language directory or subdirectory */
+static int update_index_cb(void *obj, void *arg, int flags)
+{
+ char *lang = obj;
+ char *subdir = arg;
+ struct dirent* dent;
+ DIR* srcdir;
+ RAII_VAR(struct ast_str *, sounds_lang_dir, ast_str_create(64), ast_free);
+ int res = 0;
+
+ if (!sounds_lang_dir) {
+ return 0;
+ }
+
+ if (subdir) {
+ ast_str_set(&sounds_lang_dir, 0, "%s/sounds/%s/%s", ast_config_AST_DATA_DIR, lang, subdir);
+ } else {
+ ast_str_set(&sounds_lang_dir, 0, "%s/sounds/%s", ast_config_AST_DATA_DIR, lang);
+ }
+
+ srcdir = opendir(ast_str_buffer(sounds_lang_dir));
+ if (srcdir == NULL) {
+ ast_log(LOG_ERROR, "Failed to open %s\n", ast_str_buffer(sounds_lang_dir));
+ return -1;
+ }
+
+ while((dent = readdir(srcdir)) != NULL) {
+ struct stat st;
+
+ if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
+ continue;
+ }
+
+ if (fstatat(dirfd(srcdir), dent->d_name, &st, 0) < 0) {
+ ast_log(LOG_ERROR, "Failed to stat %s\n", dent->d_name);
+ res = -1;
+ break;
+ }
+
+ if (S_ISDIR(st.st_mode)) {
+ /* only recurse one level */
+ if (!subdir) {
+ update_index_cb(lang, dent->d_name, 0);
+ } else {
+ ast_log(LOG_ERROR, "Not recursing again on lang %s subdir %s, subsubdir %s\n", lang, subdir, dent->d_name);
+ }
+ continue;
+ }
+
+ if (!S_ISREG(st.st_mode)) {
+ continue;
+ }
+
+ if (process_file(lang, subdir, dent->d_name)) {
+ res = -1;
+ break;
+ }
+ }
+
+ closedir(srcdir);
+ return res;
+}
+
+/*! \brief Reindex sounds and sound descriptions */
+static int index_sounds(void)
+{
+ RAII_VAR(struct ao2_container *, languages, get_languages(), ao2_cleanup);
+
+ if (sounds_index || !languages) {
+ return -1;
+ }
+
+ sounds_index = ao2_container_alloc(SOUNDS_BUCKETS, sound_info_hash, sound_info_cmp);
+ if (!sounds_index) {
+ return -1;
+ }
+
+ ao2_callback(languages, OBJ_NODATA, update_index_cb, NULL);
+ return 0;
+}
+
+/*! \brief Free the current sounds index */
+static void drop_sound_index(void)
+{
+ ao2_cleanup(sounds_index);
+ sounds_index = NULL;
+}
+
+/*! \brief Drop and then reindex available sounds */
int ast_sounds_reindex(void)
{
- if (sounds_indexer && sounds_indexer->reindex) {
- return sounds_indexer->reindex();
- }
-
- return -1;
-}
-
+ drop_sound_index();
+ if (index_sounds()) {
+ return -1;
+ }
+ return 0;
+}
+
+static int show_sounds_cb(void *obj, void *arg, int flags)
+{
+ struct sound_info *info = obj;
+ struct ast_cli_args *a = arg;
+ ast_cli(a->fd, "%s\n", info->name);
+ return 0;
+}
+
+static int show_sound_info_cb(void *obj, void *arg, int flags)
+{
+ struct sound_variant *variant = obj;
+ struct ast_cli_args *a = arg;
+ struct ast_format format;
+
+ ast_cli(a->fd, " Language %s:\n", variant->language);
+ ast_cli(a->fd, " Description: %s\n", variant->description);
+
+ ast_format_cap_iter_start(variant->formats);
+ while (!ast_format_cap_iter_next(variant->formats, &format)) {
+ ast_cli(a->fd, " Format: %s\n", ast_getformatname(&format));
+ }
+ ast_format_cap_iter_end(variant->formats);
+
+ return 0;
+}
+
+/*! \brief Allow for reloading of sounds via the command line */
+static char *handle_cli_sounds_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "sounds reload";
+ e->usage =
+ "Usage: sounds reload\n"
+ " Reloads the index of sound files and their descriptions.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if (a->argc != 2) {
+ return CLI_SHOWUSAGE;
+ }
+
+ if (ast_sounds_reindex()) {
+ ast_cli(a->fd, "Sound re-indexing failed.\n");
+ return CLI_FAILURE;
+ }
+
+ ast_cli(a->fd, "Sound files re-indexed.\n");
+ return CLI_SUCCESS;
+}
+
+/*! \brief Allow for reloading of sounds via the command line */
+static char *handle_cli_sounds_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "sounds show";
+ e->usage =
+ "Usage: sounds show[ soundid]\n"
+ " Shows a listing of sound files or information about the specified sound.\n";
+ return NULL;
+ case CLI_GENERATE:
+ {
+ int length = strlen(a->word);
+ int which = 0;
+ struct ao2_iterator it_sounds;
+ char *match = NULL;
+ struct sound_info *info;
+
+ it_sounds = ao2_iterator_init(sounds_index, 0);
+ while ((info = ao2_iterator_next(&it_sounds))) {
+ if (!strncasecmp(a->word, info->name, length) && ++which > a->n) {
+ match = ast_strdup(info->name);
+ ao2_ref(info, -1);
+ break;
+ }
+ ao2_ref(info, -1);
+ }
+ ao2_iterator_destroy(&it_sounds);
+ return match;
+ }
+ }
+
+ if (a->argc == 2) {
+ ast_cli(a->fd, "Available audio files:\n");
+ ao2_callback(sounds_index, OBJ_MULTIPLE | OBJ_NODATA, show_sounds_cb, a);
+ return CLI_SUCCESS;
+ }
+
+ if (a->argc == 3) {
+ RAII_VAR(struct sound_info *, info, ao2_find(sounds_index, a->argv[2], OBJ_KEY), ao2_cleanup);
+ if (!info) {
+ ast_cli(a->fd, "ERROR: File %s not found in index\n", a->argv[2]);
+ return CLI_FAILURE;
+ }
+
+ ast_cli(a->fd, "Indexed Information for %s:\n", info->name);
+ ao2_callback(info->variant_list, OBJ_MULTIPLE | OBJ_NODATA, show_sound_info_cb, a);
+ return CLI_SUCCESS;
+ }
+
+ return CLI_SHOWUSAGE;
+}
+
+/*! \brief Struct for registering CLI commands */
+static struct ast_cli_entry cli_sounds[] = {
+ AST_CLI_DEFINE(handle_cli_sounds_show, "Shows available sounds"),
+ AST_CLI_DEFINE(handle_cli_sounds_reload, "Reload sounds index"),
+};
+
+static void sounds_cleanup(void)
+{
+ ast_cli_unregister_multiple(cli_sounds, ARRAY_LEN(cli_sounds));
+ drop_sound_index();
+}
+
+int ast_sounds_init(void)
+{
+ sounds_index = NULL;
+ if (index_sounds()) {
+ return -1;
+ }
+ ast_cli_register_multiple(cli_sounds, ARRAY_LEN(cli_sounds));
+ ast_register_atexit(sounds_cleanup);
+ return 0;
+}
+
Modified: team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c?view=diff&rev=389585&r1=389584&r2=389585
==============================================================================
--- team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c (original)
+++ team/kmoore/stasis-http_sounds/res/stasis_http/resource_sounds.c Thu May 23 14:29:21 2013
@@ -162,11 +162,6 @@
RAII_VAR(struct ao2_container *, sound_files, NULL, ao2_cleanup);
struct ast_json *sounds_blob;
- if (!ast_sounds_indexer_registered()) {
- stasis_http_response_error(response, 500, "Internal Error", "Sound indexer not available");
- return;
- }
-
sound_files = ast_sounds_get_sounds();
if (!sound_files) {
stasis_http_response_error(response, 500, "Internal Error", "Allocation Error");
@@ -191,11 +186,6 @@
{
struct ast_json *sound_blob;
- if (!ast_sounds_indexer_registered()) {
- stasis_http_response_error(response, 500, "Internal Error", "Sound indexer not available");
- return;
- }
-
sound_blob = create_sound_blob(args->sound_id, NULL);
if (sound_blob) {
stasis_http_response_ok(response, sound_blob);
More information about the asterisk-commits
mailing list