Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
Macros | Functions | Variables
sounds.c File Reference

Sound file format and description index. More...

#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"
#include "asterisk/media_index.h"
#include "asterisk/sounds_index.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/module.h"
#include "asterisk/stasis_message_router.h"
#include "asterisk/stasis_system.h"
Include dependency graph for sounds.c:

Go to the source code of this file.

Macros

#define LANGUAGE_BUCKETS   7
 The number of buckets to be used for storing language-keyed objects.
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
struct ast_media_indexast_sounds_get_index (void)
 Get the sounds index.
 
struct ast_media_indexast_sounds_get_index_for_file (const char *filename)
 Get the index for a specific sound file.
 
static struct ao2_containerget_languages (void)
 Get the languages in which sound files are available.
 
static char * handle_cli_sound_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show details about a sound available in the system.
 
static char * handle_cli_sounds_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show a list of sounds available on the system.
 
static int load_module (void)
 
static int show_sound_info_cb (void *obj, void *arg, void *data, int flags)
 
static int show_sounds_cb (void *obj, void *arg, int flags)
 
static int sound_sorter (const void *obj_left, const void *obj_right, int flags)
 
static int unload_module (void)
 
static int update_index_cb (void *obj, void *arg, void *data, int flags)
 Callback to process an individual language directory or subdirectory.
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Sounds Index" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND + 1, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_sounds []
 Struct for registering CLI commands.
 

Detailed Description

Sound file format and description index.

Definition in file sounds.c.

Macro Definition Documentation

◆ LANGUAGE_BUCKETS

#define LANGUAGE_BUCKETS   7

The number of buckets to be used for storing language-keyed objects.

Definition at line 46 of file sounds.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 354 of file sounds.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 354 of file sounds.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 354 of file sounds.c.

◆ ast_sounds_get_index()

struct ast_media_index * ast_sounds_get_index ( void  )

Get the sounds index.

Return values
soundsindex (must be ao2_cleanup()'ed)
NULLon failure

Definition at line 308 of file sounds.c.

309{
311}
#define NULL
Definition resample.c:96
struct ast_media_index * ast_sounds_get_index_for_file(const char *filename)
Get the index for a specific sound file.
Definition sounds.c:313

References ast_sounds_get_index_for_file(), and NULL.

Referenced by ast_ari_sounds_list(), handle_cli_sound_show(), and handle_cli_sounds_show().

◆ ast_sounds_get_index_for_file()

struct ast_media_index * ast_sounds_get_index_for_file ( const char *  filename)

Get the index for a specific sound file.

Since
13.25.0
16.2.0
Parameters
filenameSound file name without extension
Return values
soundsindex (must be ao2_cleanup()'ed)
NULLon failure

Definition at line 313 of file sounds.c.

314{
315 struct ast_str *sounds_dir = ast_str_create(64);
316 struct ao2_container *languages;
317 char *failed_index;
318 struct ast_media_index *new_index;
319
320 if (!sounds_dir) {
321 return NULL;
322 }
323
324 ast_str_set(&sounds_dir, 0, "%s/sounds", ast_config_AST_DATA_DIR);
325 new_index = ast_media_index_create(ast_str_buffer(sounds_dir));
326 ast_free(sounds_dir);
327 if (!new_index) {
328 return NULL;
329 }
330
331 languages = get_languages();
332 if (!languages) {
333 ao2_ref(new_index, -1);
334 return NULL;
335 }
336
337 failed_index = ao2_callback_data(languages, 0, update_index_cb, new_index, (void *)filename);
338 ao2_ref(languages, -1);
339 if (failed_index) {
340 ao2_ref(failed_index, -1);
341 ao2_ref(new_index, -1);
342 new_index = NULL;
343 }
344
345 return new_index;
346}
#define ast_free(a)
Definition astmm.h:180
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition astobj2.h:1723
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
struct ast_media_index * ast_media_index_create(const char *base_dir)
Creates a new media index.
const char * ast_config_AST_DATA_DIR
Definition options.c:159
static struct ao2_container * get_languages(void)
Get the languages in which sound files are available.
Definition sounds.c:49
static int update_index_cb(void *obj, void *arg, void *data, int flags)
Callback to process an individual language directory or subdirectory.
Definition sounds.c:295
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition strings.h:1113
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
Generic container type.
Support for dynamic strings.
Definition strings.h:623

References ao2_callback_data, ao2_ref, ast_config_AST_DATA_DIR, ast_free, ast_media_index_create(), ast_str_buffer(), ast_str_create, ast_str_set(), get_languages(), NULL, and update_index_cb().

Referenced by ast_ari_sounds_get(), ast_sounds_get_index(), and handle_cli_sound_show().

◆ get_languages()

static struct ao2_container * get_languages ( void  )
static

Get the languages in which sound files are available.

Definition at line 49 of file sounds.c.

50{
51 RAII_VAR(struct ao2_container *, lang_dirs, NULL, ao2_cleanup);
52 struct dirent* dent;
53 DIR* srcdir;
54 RAII_VAR(struct ast_str *, media_dir, ast_str_create(64), ast_free);
55 RAII_VAR(struct ast_str *, variant_dir, ast_str_create(64), ast_free);
56
58 if (!media_dir || !lang_dirs) {
59 return NULL;
60 }
61
62 ast_str_set(&media_dir, 0, "%s/sounds", ast_config_AST_DATA_DIR);
63
64 srcdir = opendir(ast_str_buffer(media_dir));
65
66 if (srcdir == NULL) {
67 ast_log(LOG_ERROR, "Failed to open %s\n", ast_str_buffer(media_dir));
68 return NULL;
69 }
70
71 while((dent = readdir(srcdir)) != NULL) {
72 struct stat st;
73
74 if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
75 continue;
76 }
77
78 ast_str_reset(variant_dir);
79 ast_str_set(&variant_dir, 0, "%s/%s", ast_str_buffer(media_dir), dent->d_name);
80
81 if (stat(ast_str_buffer(variant_dir), &st) < 0) {
82 ast_log(LOG_ERROR, "Failed to stat %s\n", ast_str_buffer(variant_dir));
83 continue;
84 }
85
86 if (S_ISDIR(st.st_mode)) {
87 ast_str_container_add(lang_dirs, dent->d_name);
88 }
89 }
90
91 closedir(srcdir);
92 ao2_ref(lang_dirs, +1);
93 return lang_dirs;
94}
#define ast_log
Definition astobj2.c:42
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define LOG_ERROR
#define LANGUAGE_BUCKETS
The number of buckets to be used for storing language-keyed objects.
Definition sounds.c:46
#define ast_str_container_alloc(buckets)
Allocates a hash container for bare strings.
Definition strings.h:1365
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition strings.h:693
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
Definition strings.c:205
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981

References ao2_cleanup, ao2_ref, ast_config_AST_DATA_DIR, ast_free, ast_log, ast_str_buffer(), ast_str_container_add(), ast_str_container_alloc, ast_str_create, ast_str_reset(), ast_str_set(), LANGUAGE_BUCKETS, LOG_ERROR, NULL, and RAII_VAR.

Referenced by ast_sounds_get_index_for_file().

◆ handle_cli_sound_show()

static char * handle_cli_sound_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Show details about a sound available in the system.

Definition at line 193 of file sounds.c.

194{
195 int length;
196 struct ao2_iterator it_sounds;
197 char *filename;
198 struct ast_media_index *sounds_index;
199 struct ao2_container *sound_files;
200
201 switch (cmd) {
202 case CLI_INIT:
203 e->command = "core show sound";
204 e->usage =
205 "Usage: core show sound [soundid]\n"
206 " Shows information about the specified sound.\n";
207 return NULL;
208 case CLI_GENERATE:
209 if (a->pos != 3) {
210 return NULL;
211 }
212
213 sounds_index = ast_sounds_get_index();
214 if (!sounds_index) {
215 return NULL;
216 }
217
218 sound_files = ast_media_get_media(sounds_index);
219 ao2_ref(sounds_index, -1);
220 if (!sound_files) {
221 return NULL;
222 }
223
224 length = strlen(a->word);
225 it_sounds = ao2_iterator_init(sound_files, 0);
226 while ((filename = ao2_iterator_next(&it_sounds))) {
227 if (!strncasecmp(a->word, filename, length)) {
228 if (ast_cli_completion_add(ast_strdup(filename))) {
229 ao2_ref(filename, -1);
230 break;
231 }
232 }
233 ao2_ref(filename, -1);
234 }
235 ao2_iterator_destroy(&it_sounds);
236 ao2_ref(sound_files, -1);
237
238 return NULL;
239 }
240
241 if (a->argc == 4) {
242 struct ao2_container *variants;
243
244 sounds_index = ast_sounds_get_index_for_file(a->argv[3]);
245 if (!sounds_index) {
246 return NULL;
247 }
248
249 variants = ast_media_get_variants(sounds_index, a->argv[3]);
250
251 if (!variants || !ao2_container_count(variants)) {
252 ao2_ref(sounds_index, -1);
253 ao2_cleanup(variants);
254 ast_cli(a->fd, "ERROR: File %s not found in index\n", a->argv[3]);
255 return CLI_FAILURE;
256 }
257
258 ast_cli(a->fd, "Indexed Information for %s:\n", a->argv[3]);
259 ao2_callback_data(variants, OBJ_MULTIPLE | OBJ_NODATA, show_sound_info_cb, a, sounds_index);
260 ao2_ref(sounds_index, -1);
261 ao2_ref(variants, -1);
262
263 return CLI_SUCCESS;
264 }
265
266 return CLI_SHOWUSAGE;
267}
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_NODATA
Definition astobj2.h:1044
@ OBJ_MULTIPLE
Definition astobj2.h:1049
#define CLI_SHOWUSAGE
Definition cli.h:45
#define CLI_SUCCESS
Definition cli.h:44
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition main/cli.c:2737
void ast_cli(int fd, const char *fmt,...)
Definition clicompat.c:6
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
#define CLI_FAILURE
Definition cli.h:46
struct ao2_container * ast_media_get_media(struct ast_media_index *index)
Get the a container of all media available on the system.
struct ao2_container * ast_media_get_variants(struct ast_media_index *index, const char *filename)
Get the languages in which a media file is available.
struct ast_media_index * ast_sounds_get_index(void)
Get the sounds index.
Definition sounds.c:308
static int show_sound_info_cb(void *obj, void *arg, void *data, int flags)
Definition sounds.c:104
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177
static struct test_val a

References a, ao2_callback_data, ao2_cleanup, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), ast_cli_completion_add(), ast_media_get_media(), ast_media_get_variants(), ast_sounds_get_index(), ast_sounds_get_index_for_file(), ast_strdup, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, OBJ_MULTIPLE, OBJ_NODATA, show_sound_info_cb(), and ast_cli_entry::usage.

◆ handle_cli_sounds_show()

static char * handle_cli_sounds_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Show a list of sounds available on the system.

Definition at line 144 of file sounds.c.

145{
146 switch (cmd) {
147 case CLI_INIT:
148 e->command = "core show sounds";
149 e->usage =
150 "Usage: core show sounds\n"
151 " Shows a listing of sound files available on the system.\n";
152 return NULL;
153 case CLI_GENERATE:
154 return NULL;
155 }
156
157 if (a->argc == 3) {
158 struct ast_media_index *sounds_index = ast_sounds_get_index();
159 struct ao2_container *sound_files;
160 struct ao2_container *sorted;
161
162 if (!sounds_index) {
163 return CLI_FAILURE;
164 }
165
166 sound_files = ast_media_get_media(sounds_index);
167 ao2_ref(sounds_index, -1);
168 if (!sound_files) {
169 return CLI_FAILURE;
170 }
171
174 if (!sorted
175 || ao2_container_dup(sorted, sound_files, 0)) {
176 ao2_cleanup(sorted);
177 ao2_cleanup(sound_files);
178 return CLI_FAILURE;
179 }
180
181 ast_cli(a->fd, "Available audio files:\n");
183 ao2_ref(sorted, -1);
184 ao2_ref(sound_files, -1);
185
186 return CLI_SUCCESS;
187 }
188
189 return CLI_SHOWUSAGE;
190}
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition astobj2.h:1693
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
Definition astobj2.h:1349
static int show_sounds_cb(void *obj, void *arg, int flags)
Definition sounds.c:96
static int sound_sorter(const void *obj_left, const void *obj_right, int flags)
Definition sounds.c:138

References a, AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_callback, ao2_cleanup, ao2_container_alloc_rbtree, ao2_container_dup(), ao2_ref, ast_cli(), ast_media_get_media(), ast_sounds_get_index(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, NULL, OBJ_MULTIPLE, OBJ_NODATA, show_sounds_cb(), sound_sorter(), and ast_cli_entry::usage.

◆ load_module()

static int load_module ( void  )
static

Definition at line 282 of file sounds.c.

283{
284 int res;
285
287 if (res) {
289 }
290
292}
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition module.h:78
static struct ast_cli_entry cli_sounds[]
Struct for registering CLI commands.
Definition sounds.c:270
#define ARRAY_LEN(a)
Definition utils.h:706

References ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and cli_sounds.

◆ show_sound_info_cb()

static int show_sound_info_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 104 of file sounds.c.

105{
106 char *language = obj;
107 struct ast_cli_args *a = arg;
108 struct ast_format *format;
109 int formats_shown = 0;
110 struct ast_media_index *local_index = data;
111 struct ast_format_cap *cap;
112 const char *description = ast_media_get_description(local_index, a->argv[3], language);
113
114 ast_cli(a->fd, " Language %s:\n", language);
115 if (!ast_strlen_zero(description)) {
116 ast_cli(a->fd, " Description: %s\n", description);
117 }
118
119 cap = ast_media_get_format_cap(local_index, a->argv[3], language);
120 if (cap) {
121 int x;
122 for (x = 0; x < ast_format_cap_count(cap); x++) {
123 format = ast_format_cap_get_format(cap, x);
124 ast_cli(a->fd, " Format: %s\n", ast_format_get_name(format));
125 ao2_ref(format, -1);
126 formats_shown = 1;
127 }
128 ao2_ref(cap, -1);
129 }
130
131 if (!formats_shown) {
132 ast_cli(a->fd, " No Formats Available\n");
133 }
134
135 return 0;
136}
static char language[MAX_LANGUAGE]
Definition chan_iax2.c:348
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition format_cap.c:400
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition format_cap.c:395
const char * ast_media_get_description(struct ast_media_index *index, const char *filename, const char *variant)
Get the description for a media file.
struct ast_format_cap * ast_media_get_format_cap(struct ast_media_index *index, const char *filename, const char *variant)
Get the ast_format_cap for a media file.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54
Definition of a media format.
Definition format.c:43

References a, ao2_ref, ast_cli(), ast_format_cap_count(), ast_format_cap_get_format(), ast_format_get_name(), ast_media_get_description(), ast_media_get_format_cap(), ast_strlen_zero(), and language.

Referenced by handle_cli_sound_show().

◆ show_sounds_cb()

static int show_sounds_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 96 of file sounds.c.

97{
98 char *name = obj;
99 struct ast_cli_args *a = arg;
100 ast_cli(a->fd, "%s\n", name);
101 return 0;
102}
static const char name[]
Definition format_mp3.c:68

References a, ast_cli(), and name.

Referenced by handle_cli_sounds_show().

◆ sound_sorter()

static int sound_sorter ( const void *  obj_left,
const void *  obj_right,
int  flags 
)
static

Definition at line 138 of file sounds.c.

139{
140 return strcmp(obj_left, obj_right);
141}

Referenced by handle_cli_sounds_show().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 275 of file sounds.c.

276{
278
279 return 0;
280}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408

References ARRAY_LEN, ast_cli_unregister_multiple(), and cli_sounds.

◆ update_index_cb()

static int update_index_cb ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Callback to process an individual language directory or subdirectory.

Definition at line 295 of file sounds.c.

296{
297 char *lang = obj;
298 char *filename = data;
299 struct ast_media_index *index = arg;
300
301 if (ast_media_index_update_for_file(index, lang, filename)) {
302 return CMP_MATCH;
303 }
304
305 return 0;
306}
@ CMP_MATCH
Definition astobj2.h:1027
int ast_media_index_update_for_file(struct ast_media_index *index, const char *variant, const char *filename)
Update a media index for a specific sound file.
struct ao2_container * index

References ast_media_index_update_for_file(), CMP_MATCH, and ast_media_index::index.

Referenced by ast_sounds_get_index_for_file().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Sounds Index" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND + 1, }
static

Definition at line 354 of file sounds.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 354 of file sounds.c.

◆ cli_sounds

struct ast_cli_entry cli_sounds[]
static
Initial value:
= {
{ .handler = handle_cli_sounds_show , .summary = "Shows available sounds" ,},
{ .handler = handle_cli_sound_show , .summary = "Shows details about a specific sound" ,},
}
static char * handle_cli_sound_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show details about a sound available in the system.
Definition sounds.c:193
static char * handle_cli_sounds_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show a list of sounds available on the system.
Definition sounds.c:144

Struct for registering CLI commands.

Definition at line 270 of file sounds.c.

270 {
271 AST_CLI_DEFINE(handle_cli_sounds_show, "Shows available sounds"),
272 AST_CLI_DEFINE(handle_cli_sound_show, "Shows details about a specific sound"),
273};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by load_module(), and unload_module().