Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Functions | Variables
indications.c File Reference

Indication Tone Handling. More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/frame.h"
#include "asterisk/format_cache.h"
#include "asterisk/channel.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/_private.h"
Include dependency graph for indications.c:

Go to the source code of this file.

Data Structures

struct  playtones_def
 
struct  playtones_item
 
struct  playtones_state
 

Macros

#define NUM_TONE_ZONE_BUCKETS   53
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_tone_zone_soundast_get_indication_tone (const struct ast_tone_zone *_zone, const char *indication)
 Locate a tone zone sound. More...
 
struct ast_tone_zoneast_get_indication_zone (const char *country)
 locate ast_tone_zone, given the country. if country == NULL, use the default country More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
int ast_playtones_start (struct ast_channel *chan, int vol, const char *playlst, int interruptible)
 Start playing a list of tones on a channel. More...
 
void ast_playtones_stop (struct ast_channel *chan)
 Stop playing tones on a channel. More...
 
static int ast_register_indication (struct ast_tone_zone *zone, const char *indication, const char *tonelist)
 
static int ast_register_indication_country (struct ast_tone_zone *zone)
 add a new country, if country exists, it will be replaced. More...
 
static int ast_set_indication_country (const char *country)
 Set global indication country If no country is specified or we are unable to find the zone, then return not found. More...
 
static struct ast_tone_zoneast_tone_zone_alloc (void)
 
static int ast_tone_zone_cmp (void *obj, void *arg, int flags)
 
int ast_tone_zone_count (void)
 Get the number of registered tone zones. More...
 
static void ast_tone_zone_destructor (void *obj)
 deallocate the passed tone zone More...
 
static int ast_tone_zone_hash (const void *obj, const int flags)
 
struct ao2_iterator ast_tone_zone_iterator_init (void)
 Get an iterator for the available tone zones. More...
 
int ast_tone_zone_part_parse (const char *s, struct ast_tone_zone_part *tone_data)
 Parse a tone part. More...
 
static void ast_tone_zone_sound_destructor (void *obj)
 
static int ast_unregister_indication (struct ast_tone_zone *zone, const char *indication)
 remove an existing country's indication. Both country and indication must exist More...
 
static int ast_unregister_indication_country (const char *country)
 remove an existing country and all its indications, country must exist. More...
 
static char * complete_country (struct ast_cli_args *a)
 
static char * complete_indications (struct ast_cli_args *a)
 
static char * handle_cli_indication_add (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_indication_remove (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_indication_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int is_valid_tone_zone (struct ast_tone_zone *zone)
 
static int load_indications (int reload)
 load indications module More...
 
static int load_module (void)
 Load indications module. More...
 
static int parse_tone_zone (struct ast_config *cfg, const char *country)
 
static void * playtones_alloc (struct ast_channel *chan, void *params)
 
static int playtones_generator (struct ast_channel *chan, void *data, int len, int samples)
 
static void playtones_release (struct ast_channel *chan, void *params)
 
static int prune_tone_zone (void *obj, void *arg, int flags)
 Prune tones no longer in the configuration, and have the tone zone unlinked if it is no longer in the configuration at all. More...
 
static int reload_module (void)
 Reload indications module. More...
 
static void reset_tone_zone (struct ast_tone_zone *zone)
 
static void store_config_tone_zone (struct ast_tone_zone *zone, const char *var, const char *value)
 
static void store_tone_zone_ring_cadence (struct ast_tone_zone *zone, const char *val)
 
static int tone_zone_mark (void *obj, void *arg, int flags)
 Mark the zone and its tones before parsing configuration. We will use this to know what to remove after configuration is parsed. More...
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Indication Tone Handling" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ao2_containerast_tone_zones
 
static struct ast_cli_entry cli_indications []
 CLI entries for commands provided by this module. More...
 
static const char config [] = "indications.conf"
 
static struct ast_tone_zonedefault_tone_zone
 
static const int midi_tohz [128]
 
static struct ast_generator playtones
 

Detailed Description

Indication Tone Handling.

Author
Pauline Middelink midde.nosp@m.link.nosp@m.@poly.nosp@m.ware.nosp@m..nl
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com

Definition in file indications.c.

Macro Definition Documentation

◆ NUM_TONE_ZONE_BUCKETS

#define NUM_TONE_ZONE_BUCKETS   53

Definition at line 68 of file indications.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1190 of file indications.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1190 of file indications.c.

◆ ast_get_indication_tone()

struct ast_tone_zone_sound * ast_get_indication_tone ( const struct ast_tone_zone zone,
const char *  indication 
)

Locate a tone zone sound.

Parameters
zoneZone to look in for a sound, if NULL, the default will be used
indicationSound to look for, such as "busy"
Returns
a reference to the specified sound if it exists, NULL if not

Definition at line 461 of file indications.c.

462{
463 struct ast_tone_zone_sound *ts = NULL;
464 /* _zone is const to the users of the API */
465 struct ast_tone_zone *zone = (struct ast_tone_zone *) _zone;
466
467 /* If no zone is specified, use the default */
468 if (!zone) {
470 if (default_tone_zone) {
472 }
474
475 if (!zone) {
476 return NULL;
477 }
478 }
479
480 ast_tone_zone_lock(zone);
481
482 /* Look through list of tones in the zone searching for the right one */
483 AST_LIST_TRAVERSE(&zone->tones, ts, entry) {
484 if (!strcasecmp(ts->name, indication)) {
485 /* Increase ref count for the reference we will return */
487 break;
488 }
489 }
490
492
493 if (!_zone)
494 zone = ast_tone_zone_unref(zone);
495
496 return ts;
497}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
static struct ao2_container * ast_tone_zones
Definition: indications.c:66
static struct ast_tone_zone * default_tone_zone
Definition: indications.c:73
#define ast_tone_zone_unlock(tz)
Unlock an ast_tone_zone.
Definition: indications.h:193
static struct ast_tone_zone * ast_tone_zone_unref(struct ast_tone_zone *tz)
Release a reference to an ast_tone_zone.
Definition: indications.h:205
#define ast_tone_zone_lock(tz)
Lock an ast_tone_zone.
Definition: indications.h:188
static struct ast_tone_zone_sound * ast_tone_zone_sound_ref(struct ast_tone_zone_sound *ts)
Increase the reference count on an ast_tone_zone_sound.
Definition: indications.h:238
static struct ast_tone_zone * ast_tone_zone_ref(struct ast_tone_zone *tz)
Increase the reference count on an ast_tone_zone.
Definition: indications.h:216
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define NULL
Definition: resample.c:96
Description of a tone.
Definition: indications.h:35
const char * name
Name of the tone. For example, "busy".
Definition: indications.h:37
A set of tones for a given locale.
Definition: indications.h:74
struct ast_tone_zone::@234 tones
A list of tones for this locale.
Definition: search.h:40

References ao2_lock, ao2_unlock, AST_LIST_TRAVERSE, ast_tone_zone_lock, ast_tone_zone_ref(), ast_tone_zone_sound_ref(), ast_tone_zone_unlock, ast_tone_zone_unref(), ast_tone_zones, default_tone_zone, ast_tone_zone_sound::name, NULL, and ast_tone_zone::tones.

Referenced by ast_app_dtget(), ast_control_tone(), dial_handle_playtones(), handle_playtones(), in_band_indication(), indicate_data_internal(), pbx_builtin_waitexten(), play_dialtone(), read_exec(), readexten_exec(), and send_dial_tone().

◆ ast_get_indication_zone()

struct ast_tone_zone * ast_get_indication_zone ( const char *  country)

locate ast_tone_zone, given the country. if country == NULL, use the default country

locate ast_tone_zone

Definition at line 439 of file indications.c.

440{
441 struct ast_tone_zone *tz = NULL;
442 struct ast_tone_zone zone_arg = {
443 .nrringcadence = 0,
444 };
445
448 if (default_tone_zone) {
450 }
452
453 return tz;
454 }
455
456 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country));
457
458 return ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER);
459}
#define OBJ_POINTER
Definition: astobj2.h:1150
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
static char * tz
Definition: cdr_pgsql.c:71
static char country[80]
Definition: pbx_dundi.c:205
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
unsigned int nrringcadence
Number of ring cadence elements in the ringcadence array.
Definition: indications.h:84
char country[MAX_TONEZONE_COUNTRY]
Country code that this set of tones is for.
Definition: indications.h:76

References ao2_find, ao2_lock, ao2_unlock, ast_copy_string(), ast_strlen_zero(), ast_tone_zone_ref(), ast_tone_zones, country, ast_tone_zone::country, default_tone_zone, ast_tone_zone::nrringcadence, NULL, OBJ_POINTER, and tz.

Referenced by ast_control_tone(), ast_set_indication_country(), ast_var_indications(), build_device(), chan_pjsip_new(), func_channel_write_real(), handle_cli_indication_add(), and handle_cli_indication_remove().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1190 of file indications.c.

◆ ast_playtones_start()

int ast_playtones_start ( struct ast_channel chan,
int  vol,
const char *  tonelist,
int  interruptible 
)

Start playing a list of tones on a channel.

Parameters
chanthe channel to play tones on
volvolume
tonelistthe list of tones to play, comma separated
interruptiblewhether or not this tone can be interrupted
Return values
0success
non-zerofailure

Definition at line 302 of file indications.c.

303{
304 char *s, *data = ast_strdupa(playlst);
305 struct playtones_def d = { vol, -1, 0, 1, NULL };
306 char *stringp;
307 char *separator;
308 static const float sample_rate = 8000.0;
309 static const float max_sample_val = 32768.0;
310
311 if (vol < 1) {
312 d.vol = 7219; /* Default to -8db */
313 }
314
315 d.interruptible = interruptible;
316
317 stringp = data;
318
319 /* check if the data is separated with '|' or with ',' by default */
320 if (strchr(stringp,'|')) {
321 separator = "|";
322 } else {
323 separator = ",";
324 }
325
326 while ((s = strsep(&stringp, separator)) && !ast_strlen_zero(s)) {
327 struct playtones_item *new_items;
328 struct ast_tone_zone_part tone_data = {
329 .time = 0,
330 };
331
332 s = ast_strip(s);
333 if (s[0]=='!') {
334 s++;
335 } else if (d.reppos == -1) {
336 d.reppos = d.nitems;
337 }
338
339 if (ast_tone_zone_part_parse(s, &tone_data)) {
340 ast_log(LOG_ERROR, "Failed to parse tone part '%s'\n", s);
341 continue;
342 }
343
344 if (tone_data.midinote) {
345 /* midi notes must be between 0 and 127 */
346 if (tone_data.freq1 <= 127) {
347 tone_data.freq1 = midi_tohz[tone_data.freq1];
348 } else {
349 tone_data.freq1 = 0;
350 }
351
352 if (tone_data.freq2 <= 127) {
353 tone_data.freq2 = midi_tohz[tone_data.freq2];
354 } else {
355 tone_data.freq2 = 0;
356 }
357 }
358
359 new_items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items));
360 if (!new_items) {
361 ast_free(d.items);
362 return -1;
363 }
364 d.items = new_items;
365
366 d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (tone_data.freq1 / sample_rate)) * max_sample_val;
367 d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol;
368 d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol;
369
370 d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (tone_data.freq2 / sample_rate)) * max_sample_val;
371 d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol;
372 d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol;
373
374 d.items[d.nitems].duration = tone_data.time;
375 d.items[d.nitems].modulate = tone_data.modulate;
376
377 d.nitems++;
378 }
379
380 if (!d.nitems) {
381 ast_log(LOG_ERROR, "No valid tone parts\n");
382 return -1;
383 }
384
385 if (ast_activate_generator(chan, &playtones, &d)) {
386 ast_free(d.items);
387 return -1;
388 }
389
390 return 0;
391}
#define ast_free(a)
Definition: astmm.h:180
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:226
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
unsigned int cos
Definition: chan_iax2.c:356
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
Definition: channel.c:2951
char * strsep(char **str, const char *delims)
#define LOG_ERROR
int ast_tone_zone_part_parse(const char *s, struct ast_tone_zone_part *tone_data)
Parse a tone part.
Definition: indications.c:245
static const int midi_tohz[128]
Definition: indications.c:50
static struct ast_generator playtones
Definition: indications.c:239
#define M_PI
Definition: resample.c:83
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
A description of a part of a tone.
Definition: indications.h:109
unsigned int modulate
Definition: indications.h:113
unsigned int freq2
Definition: indications.h:111
unsigned int time
Definition: indications.h:112
unsigned int midinote
Definition: indications.h:114
unsigned int freq1
Definition: indications.h:110
static struct test_val d

References ast_activate_generator(), ast_free, ast_log, ast_realloc, ast_strdupa, ast_strip(), ast_strlen_zero(), ast_tone_zone_part_parse(), cos, d, ast_tone_zone_part::freq1, ast_tone_zone_part::freq2, playtones_def::interruptible, LOG_ERROR, M_PI, midi_tohz, ast_tone_zone_part::midinote, ast_tone_zone_part::modulate, NULL, playtones, strsep(), ast_tone_zone_part::time, and playtones_def::vol.

Referenced by ast_app_dtget(), ast_control_tone(), ast_senddigit_begin(), ast_senddigit_mf_begin(), control_tone_frame_response(), dial_handle_playtones(), handle_playtones(), in_band_indication(), indicate_data_internal(), mf_stream(), milliwatt_exec(), pbx_builtin_waitexten(), play_dialtone(), playtone(), read_exec(), readexten_exec(), receivefax_t38_init(), send_tone_burst(), sendfax_t38_init(), and sf_stream().

◆ ast_playtones_stop()

void ast_playtones_stop ( struct ast_channel chan)

Stop playing tones on a channel.

Parameters
chanthe channel to stop tones on

Definition at line 393 of file indications.c.

394{
396}
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:2893

References ast_deactivate_generator().

Referenced by ast_app_dtget(), ast_senddigit_end(), ast_senddigit_mf_end(), control_tone_frame_response(), disa_exec(), handle_stopplaytones(), indicate_data_internal(), pbx_builtin_waitexten(), playtone(), read_exec(), readexten_exec(), receivefax_t38_init(), send_tone_burst(), sendfax_t38_init(), and unistim_indicate().

◆ ast_register_indication()

static int ast_register_indication ( struct ast_tone_zone zone,
const char *  indication,
const char *  tonelist 
)
static
Note
called with the tone zone locked

Definition at line 579 of file indications.c.

581{
582 struct ast_tone_zone_sound *ts;
583
584 if (ast_strlen_zero(indication) || ast_strlen_zero(tonelist)) {
585 return -1;
586 }
587
589 if (!strcasecmp(indication, ts->name)) {
592 break;
593 }
594 }
596
599 if (!ts) {
600 return -1;
601 }
602
603 if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) {
605 return -1;
606 }
607
608 AST_LIST_INSERT_TAIL(&zone->tones, ts, entry); /* Inherit reference */
609
610 return 0;
611}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static void ast_tone_zone_sound_destructor(void *obj)
Definition: indications.c:499
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
Definition: indications.h:227
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
const char * data
Description of a tone.
Definition: indications.h:52

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_strdup, ast_strlen_zero(), ast_tone_zone_sound_destructor(), ast_tone_zone_sound_unref(), ast_tone_zone_sound::data, ast_tone_zone_sound::name, and ast_tone_zone::tones.

Referenced by handle_cli_indication_add(), and store_config_tone_zone().

◆ ast_register_indication_country()

static int ast_register_indication_country ( struct ast_tone_zone zone)
static

add a new country, if country exists, it will be replaced.

Definition at line 532 of file indications.c.

533{
535 if (!default_tone_zone) {
537 }
539
541
542 ast_verb(5, "Registered indication country '%s'\n", zone->country);
543
544 return 0;
545}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define ast_verb(level,...)

References ao2_link, ao2_lock, ao2_unlock, ast_tone_zone_ref(), ast_tone_zones, ast_verb, ast_tone_zone::country, and default_tone_zone.

Referenced by handle_cli_indication_add(), and parse_tone_zone().

◆ ast_set_indication_country()

static int ast_set_indication_country ( const char *  country)
static

Set global indication country If no country is specified or we are unable to find the zone, then return not found.

Definition at line 410 of file indications.c.

411{
412 struct ast_tone_zone *zone = NULL;
413
415 ast_log(LOG_WARNING, "Failed to get indication zone, country not set\n");
416 return -1;
417 }
418
419 if (!(zone = ast_get_indication_zone(country))) {
420 ast_log(LOG_WARNING, "Failed to get indication zone: %s\n", country);
421 return -1;
422 }
423
424 ast_log(LOG_NOTICE, "Setting default indication country to '%s'\n", country);
425
427 if (default_tone_zone) {
429 }
432
433 zone = ast_tone_zone_unref(zone);
434
435 return 0;
436}
#define LOG_NOTICE
#define LOG_WARNING
struct ast_tone_zone * ast_get_indication_zone(const char *country)
locate ast_tone_zone, given the country. if country == NULL, use the default country
Definition: indications.c:439

References ao2_lock, ao2_unlock, ast_get_indication_zone(), ast_log, ast_strlen_zero(), ast_tone_zone_ref(), ast_tone_zone_unref(), ast_tone_zones, country, default_tone_zone, LOG_NOTICE, LOG_WARNING, and NULL.

Referenced by load_indications().

◆ ast_tone_zone_alloc()

static struct ast_tone_zone * ast_tone_zone_alloc ( void  )
static

Definition at line 636 of file indications.c.

637{
638 return ao2_alloc(sizeof(struct ast_tone_zone), ast_tone_zone_destructor);
639}
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void ast_tone_zone_destructor(void *obj)
deallocate the passed tone zone
Definition: indications.c:516

References ao2_alloc, and ast_tone_zone_destructor().

Referenced by handle_cli_indication_add(), and parse_tone_zone().

◆ ast_tone_zone_cmp()

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

Definition at line 1131 of file indications.c.

1132{
1133 struct ast_tone_zone *zone = obj;
1134 struct ast_tone_zone *zone_arg = arg;
1135
1136 return (!strcasecmp(zone->country, zone_arg->country)) ?
1137 CMP_MATCH | CMP_STOP : 0;
1138}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028

References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.

Referenced by load_module().

◆ ast_tone_zone_count()

int ast_tone_zone_count ( void  )

Get the number of registered tone zones.

Returns
the total number of registered tone zones

Definition at line 398 of file indications.c.

399{
401}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.

References ao2_container_count(), and ast_tone_zones.

◆ ast_tone_zone_destructor()

static void ast_tone_zone_destructor ( void *  obj)
static

deallocate the passed tone zone

Definition at line 516 of file indications.c.

517{
518 struct ast_tone_zone *zone = obj;
520
521 while ((current = AST_LIST_REMOVE_HEAD(&zone->tones, entry))) {
523 }
524
525 if (zone->ringcadence) {
526 ast_free(zone->ringcadence);
527 zone->ringcadence = NULL;
528 }
529}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
size_t current
Definition: main/cli.c:113
int * ringcadence
Array of ring cadence parts.
Definition: indications.h:91

References ast_free, AST_LIST_REMOVE_HEAD, ast_tone_zone_sound_unref(), current, NULL, ast_tone_zone::ringcadence, and ast_tone_zone::tones.

Referenced by ast_tone_zone_alloc().

◆ ast_tone_zone_hash()

static int ast_tone_zone_hash ( const void *  obj,
const int  flags 
)
static

Definition at line 1124 of file indications.c.

1125{
1126 const struct ast_tone_zone *zone = obj;
1127
1128 return ast_str_case_hash(zone->country);
1129}
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1303

References ast_str_case_hash(), and ast_tone_zone::country.

Referenced by load_module().

◆ ast_tone_zone_iterator_init()

struct ao2_iterator ast_tone_zone_iterator_init ( void  )

Get an iterator for the available tone zones.

Note
Use ao2_iterator_next() to iterate the tone zones.
Use ao2_iterator_destroy() to clean up.
Returns
an initialized iterator

Definition at line 403 of file indications.c.

404{
406}
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

References ao2_iterator_init(), and ast_tone_zones.

Referenced by ast_var_indications(), ast_var_indications_table(), and handle_cli_indication_show().

◆ ast_tone_zone_part_parse()

int ast_tone_zone_part_parse ( const char *  s,
struct ast_tone_zone_part tone_data 
)

Parse a tone part.

Parameters
sThe part of a tone to parse. This should be in the form described for the data part of ast_tone_zone_sound. '!' should be removed if present.
tone_dataAn output parameter that contains the result of the parsing.
Return values
0success
-1failure, and the contents of tone_data are undefined

Definition at line 245 of file indications.c.

246{
247 if (sscanf(s, "%30u+%30u/%30u", &tone_data->freq1, &tone_data->freq2,
248 &tone_data->time) == 3) {
249 /* f1+f2/time format */
250 } else if (sscanf(s, "%30u+%30u", &tone_data->freq1, &tone_data->freq2) == 2) {
251 /* f1+f2 format */
252 tone_data->time = 0;
253 } else if (sscanf(s, "%30u*%30u/%30u", &tone_data->freq1, &tone_data->freq2,
254 &tone_data->time) == 3) {
255 /* f1*f2/time format */
256 tone_data->modulate = 1;
257 } else if (sscanf(s, "%30u*%30u", &tone_data->freq1, &tone_data->freq2) == 2) {
258 /* f1*f2 format */
259 tone_data->time = 0;
260 tone_data->modulate = 1;
261 } else if (sscanf(s, "%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) {
262 /* f1/time format */
263 tone_data->freq2 = 0;
264 } else if (sscanf(s, "%30u", &tone_data->freq1) == 1) {
265 /* f1 format */
266 tone_data->freq2 = 0;
267 tone_data->time = 0;
268 } else if (sscanf(s, "M%30u+M%30u/%30u", &tone_data->freq1, &tone_data->freq2,
269 &tone_data->time) == 3) {
270 /* Mf1+Mf2/time format */
271 tone_data->midinote = 1;
272 } else if (sscanf(s, "M%30u+M%30u", &tone_data->freq1, &tone_data->freq2) == 2) {
273 /* Mf1+Mf2 format */
274 tone_data->time = 0;
275 tone_data->midinote = 1;
276 } else if (sscanf(s, "M%30u*M%30u/%30u", &tone_data->freq1, &tone_data->freq2,
277 &tone_data->time) == 3) {
278 /* Mf1*Mf2/time format */
279 tone_data->modulate = 1;
280 tone_data->midinote = 1;
281 } else if (sscanf(s, "M%30u*M%30u", &tone_data->freq1, &tone_data->freq2) == 2) {
282 /* Mf1*Mf2 format */
283 tone_data->time = 0;
284 tone_data->modulate = 1;
285 tone_data->midinote = 1;
286 } else if (sscanf(s, "M%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) {
287 /* Mf1/time format */
288 tone_data->freq2 = -1;
289 tone_data->midinote = 1;
290 } else if (sscanf(s, "M%30u", &tone_data->freq1) == 1) {
291 /* Mf1 format */
292 tone_data->freq2 = -1;
293 tone_data->time = 0;
294 tone_data->midinote = 1;
295 } else {
296 return -1;
297 }
298
299 return 0;
300}

References ast_tone_zone_part::freq1, ast_tone_zone_part::freq2, ast_tone_zone_part::midinote, ast_tone_zone_part::modulate, and ast_tone_zone_part::time.

Referenced by ast_playtones_start(), and send_dial_tone().

◆ ast_tone_zone_sound_destructor()

static void ast_tone_zone_sound_destructor ( void *  obj)
static

Definition at line 499 of file indications.c.

500{
501 struct ast_tone_zone_sound *ts = obj;
502
503 /* Deconstify the 'const char *'s so the compiler doesn't complain. (but it's safe) */
504 if (ts->name) {
505 ast_free((char *) ts->name);
506 ts->name = NULL;
507 }
508
509 if (ts->data) {
510 ast_free((char *) ts->data);
511 ts->data = NULL;
512 }
513}

References ast_free, ast_tone_zone_sound::data, ast_tone_zone_sound::name, and NULL.

Referenced by ast_register_indication().

◆ ast_unregister_indication()

static int ast_unregister_indication ( struct ast_tone_zone zone,
const char *  indication 
)
static

remove an existing country's indication. Both country and indication must exist

Definition at line 614 of file indications.c.

615{
616 struct ast_tone_zone_sound *ts;
617 int res = -1;
618
619 ast_tone_zone_lock(zone);
620
622 if (!strcasecmp(indication, ts->name)) {
625 res = 0;
626 break;
627 }
628 }
630
632
633 return res;
634}

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_tone_zone_lock, ast_tone_zone_sound_unref(), ast_tone_zone_unlock, ast_tone_zone_sound::name, and ast_tone_zone::tones.

Referenced by handle_cli_indication_remove().

◆ ast_unregister_indication_country()

static int ast_unregister_indication_country ( const char *  country)
static

remove an existing country and all its indications, country must exist.

Definition at line 548 of file indications.c.

549{
550 struct ast_tone_zone *tz = NULL;
551 struct ast_tone_zone zone_arg = {
552 .nrringcadence = 0,
553 };
554
555 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country));
556
559 if (!tz) {
561 return -1;
562 }
563
564 if (default_tone_zone == tz) {
566 /* Get a new default, punt to the first one we find */
568 }
570
572
573 return 0;
574}
#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
@ OBJ_UNLINK
Definition: astobj2.h:1039

References ao2_callback, ao2_find, ao2_lock, ao2_unlock, ast_copy_string(), ast_tone_zone_unref(), ast_tone_zones, country, ast_tone_zone::country, default_tone_zone, ast_tone_zone::nrringcadence, NULL, OBJ_POINTER, OBJ_UNLINK, and tz.

Referenced by handle_cli_indication_add(), and handle_cli_indication_remove().

◆ complete_country()

static char * complete_country ( struct ast_cli_args a)
static

Definition at line 641 of file indications.c.

642{
643 struct ao2_iterator i;
644 size_t wordlen;
645 struct ast_tone_zone *tz;
646
647 wordlen = strlen(a->word);
648
650 while ((tz = ao2_iterator_next(&i))) {
651 if (!strncasecmp(a->word, tz->country, wordlen)) {
652 if (ast_cli_completion_add(ast_strdup(tz->country))) {
654 break;
655 }
656 }
658 }
660
661 return NULL;
662}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2756
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
static struct test_val a

References a, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_completion_add(), ast_strdup, ast_tone_zone_unref(), ast_tone_zones, NULL, and tz.

Referenced by handle_cli_indication_add(), handle_cli_indication_remove(), and handle_cli_indication_show().

◆ complete_indications()

static char * complete_indications ( struct ast_cli_args a)
static

Definition at line 729 of file indications.c.

730{
731 size_t wordlen;
732 struct ast_tone_zone_sound *ts;
733 struct ast_tone_zone *tz;
734 struct ast_tone_zone tmp_tz = {
735 .nrringcadence = 0,
736 };
737
738 ast_copy_string(tmp_tz.country, a->argv[a->pos - 1], sizeof(tmp_tz.country));
739
741 if (!tz) {
742 return NULL;
743 }
744
745 wordlen = strlen(a->word);
746
748 AST_LIST_TRAVERSE(&tz->tones, ts, entry) {
749 if (!strncasecmp(a->word, ts->name, wordlen)) {
751 break;
752 }
753 }
754 }
756
758
759 return NULL;
760}

References a, ao2_find, ast_cli_completion_add(), ast_copy_string(), AST_LIST_TRAVERSE, ast_strdup, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_unref(), ast_tone_zones, ast_tone_zone::country, ast_tone_zone_sound::name, ast_tone_zone::nrringcadence, NULL, OBJ_POINTER, and tz.

Referenced by handle_cli_indication_remove().

◆ handle_cli_indication_add()

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

Definition at line 664 of file indications.c.

665{
666 struct ast_tone_zone *tz;
667 int created_country = 0;
668 char *res = CLI_SUCCESS;
669
670 switch (cmd) {
671 case CLI_INIT:
672 e->command = "indication add";
673 e->usage =
674 "Usage: indication add <country> <indication> \"<tonelist>\"\n"
675 " Add the given indication to the country.\n";
676 return NULL;
677 case CLI_GENERATE:
678 if (a->pos == 2) {
679 return complete_country(a);
680 } else {
681 return NULL;
682 }
683 }
684
685 if (a->argc != 5) {
686 return CLI_SHOWUSAGE;
687 }
688
689 if (!(tz = ast_get_indication_zone(a->argv[2]))) {
690 /* country does not exist, create it */
691 ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n", a->argv[2]);
692
693 if (!(tz = ast_tone_zone_alloc())) {
694 return CLI_FAILURE;
695 }
696
697 ast_copy_string(tz->country, a->argv[2], sizeof(tz->country));
698
700 ast_log(LOG_WARNING, "Unable to register new country\n");
702 return CLI_FAILURE;
703 }
704
705 created_country = 1;
706 }
707
709
710 if (ast_register_indication(tz, a->argv[3], a->argv[4])) {
711 if (ast_strlen_zero(a->argv[3])) {
712 ast_log(LOG_WARNING, "Unable to register indication %s\n", a->argv[2]);
713 } else {
714 ast_log(LOG_WARNING, "Unable to register indication %s/%s\n", a->argv[2], a->argv[3]);
715 }
716 if (created_country) {
718 }
719 res = CLI_FAILURE;
720 }
721
723
725
726 return res;
727}
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define CLI_FAILURE
Definition: cli.h:46
static int ast_register_indication_country(struct ast_tone_zone *zone)
add a new country, if country exists, it will be replaced.
Definition: indications.c:532
static char * complete_country(struct ast_cli_args *a)
Definition: indications.c:641
static int ast_register_indication(struct ast_tone_zone *zone, const char *indication, const char *tonelist)
Definition: indications.c:579
static struct ast_tone_zone * ast_tone_zone_alloc(void)
Definition: indications.c:636
static int ast_unregister_indication_country(const char *country)
remove an existing country and all its indications, country must exist.
Definition: indications.c:548
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177

References a, ast_copy_string(), ast_get_indication_zone(), ast_log, ast_register_indication(), ast_register_indication_country(), ast_strlen_zero(), ast_tone_zone_alloc(), ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_unref(), ast_unregister_indication_country(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_country(), LOG_NOTICE, LOG_WARNING, NULL, tz, and ast_cli_entry::usage.

◆ handle_cli_indication_remove()

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

Definition at line 762 of file indications.c.

763{
764 struct ast_tone_zone *tz;
765 char *res = CLI_SUCCESS;
766
767 switch (cmd) {
768 case CLI_INIT:
769 e->command = "indication remove";
770 e->usage =
771 "Usage: indication remove <country> [indication]\n"
772 " Remove the given indication from the country.\n";
773 return NULL;
774 case CLI_GENERATE:
775 if (a->pos == 2) {
776 return complete_country(a);
777 }
778 if (a->pos == 3) {
779 return complete_indications(a);
780 }
781 return NULL;
782 }
783
784 if (a->argc != 3 && a->argc != 4) {
785 return CLI_SHOWUSAGE;
786 }
787
788 if (a->argc == 3) {
789 /* remove entire country */
790 if (ast_unregister_indication_country(a->argv[2])) {
791 ast_log(LOG_WARNING, "Unable to unregister indication country %s\n", a->argv[2]);
792 return CLI_FAILURE;
793 }
794
795 return CLI_SUCCESS;
796 }
797
798 if (!(tz = ast_get_indication_zone(a->argv[2]))) {
799 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n", a->argv[2], a->argv[3]);
800 return CLI_FAILURE;
801 }
802
803 if (ast_unregister_indication(tz, a->argv[3])) {
804 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n", a->argv[2], a->argv[3]);
805 res = CLI_FAILURE;
806 }
807
809
810 return res;
811}
static int ast_unregister_indication(struct ast_tone_zone *zone, const char *indication)
remove an existing country's indication. Both country and indication must exist
Definition: indications.c:614
static char * complete_indications(struct ast_cli_args *a)
Definition: indications.c:729

References a, ast_get_indication_zone(), ast_log, ast_tone_zone_unref(), ast_unregister_indication(), ast_unregister_indication_country(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_country(), complete_indications(), LOG_WARNING, NULL, tz, and ast_cli_entry::usage.

◆ handle_cli_indication_show()

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

Definition at line 813 of file indications.c.

814{
815 struct ast_tone_zone *tz = NULL;
816 struct ast_str *buf;
817 int found_country = 0;
818 int i;
819
820 switch (cmd) {
821 case CLI_INIT:
822 e->command = "indication show";
823 e->usage =
824 "Usage: indication show [<country> ...]\n"
825 " Display either a condensed summary of all countries and indications, or a\n"
826 " more verbose list of indications for the specified countries.\n";
827 return NULL;
828 case CLI_GENERATE:
829 return complete_country(a);
830 }
831
832 if (a->argc == 2) {
833 struct ao2_iterator iter;
834 /* no arguments, show a list of countries */
835 ast_cli(a->fd, "Country Description\n");
836 ast_cli(a->fd, "===========================\n");
838 while ((tz = ao2_iterator_next(&iter))) {
840 ast_cli(a->fd, "%-7.7s %s\n", tz->country, tz->description);
843 }
845
847 if (default_tone_zone) {
848 ast_cli(a->fd, "===========================\n");
850 ast_cli(a->fd, "Default tone zone: %s\n", tz->country);
852 }
854 return CLI_SUCCESS;
855 }
856
857 buf = ast_str_alloca(256);
858
859 for (i = 2; i < a->argc; i++) {
860 struct ast_tone_zone zone_arg = {
861 .nrringcadence = 0,
862 };
863 struct ast_tone_zone_sound *ts;
864 int j;
865
866 ast_copy_string(zone_arg.country, a->argv[i], sizeof(zone_arg.country));
867
868 if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) {
869 continue;
870 }
871
872 if (!found_country) {
873 found_country = 1;
874 ast_cli(a->fd, "Country Indication PlayList\n");
875 ast_cli(a->fd, "=====================================\n");
876 }
877
879
880 ast_str_set(&buf, 0, "%-7.7s %-15.15s ", tz->country, "<ringcadence>");
881 for (j = 0; j < tz->nrringcadence; j++) {
882 ast_str_append(&buf, 0, "%d%s", tz->ringcadence[j],
883 (j == tz->nrringcadence - 1) ? "" : ",");
884 }
885 ast_str_append(&buf, 0, "\n");
886 ast_cli(a->fd, "%s", ast_str_buffer(buf));
887
888 AST_LIST_TRAVERSE(&tz->tones, ts, entry) {
889 ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data);
890 }
891
894 }
895
896 if (!found_country) {
897 ast_cli(a->fd, "No countries matched your criteria.\n");
898 }
899
900 return CLI_SUCCESS;
901}
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ao2_iterator ast_tone_zone_iterator_init(void)
Get an iterator for the available tone zones.
Definition: indications.c:403
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_alloca(init_len)
Definition: strings.h:848
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
Support for dynamic strings.
Definition: strings.h:623

References a, ao2_find, ao2_iterator_destroy(), ao2_iterator_next, ao2_lock, ao2_unlock, ast_cli(), ast_copy_string(), AST_LIST_TRAVERSE, ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_tone_zone_iterator_init(), ast_tone_zone_lock, ast_tone_zone_ref(), ast_tone_zone_unlock, ast_tone_zone_unref(), ast_tone_zones, buf, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, complete_country(), ast_tone_zone::country, ast_tone_zone_sound::data, default_tone_zone, ast_tone_zone_sound::name, ast_tone_zone::nrringcadence, NULL, OBJ_POINTER, tz, and ast_cli_entry::usage.

◆ is_valid_tone_zone()

static int is_valid_tone_zone ( struct ast_tone_zone zone)
static

Definition at line 903 of file indications.c.

904{
905 int res;
906
907 ast_tone_zone_lock(zone);
908 res = (!ast_strlen_zero(zone->description) && !AST_LIST_EMPTY(&zone->tones));
910
911 return res;
912}
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
char description[40]
Text description of the given country.
Definition: indications.h:82

References AST_LIST_EMPTY, ast_strlen_zero(), ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone::description, and ast_tone_zone::tones.

Referenced by parse_tone_zone().

◆ load_indications()

static int load_indications ( int  reload)
static

load indications module

Definition at line 1060 of file indications.c.

1061{
1062 struct ast_config *cfg;
1063 const char *cxt = NULL;
1064 const char *country = NULL;
1065 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1066 int res = -1;
1067
1068 cfg = ast_config_load2(config, "indications", config_flags);
1069
1071 ast_log(LOG_WARNING, "Can't find indications config file %s.\n", config);
1072 return 0;
1073 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
1074 return 0;
1075 }
1076
1077 /* Lock the container to prevent multiple simultaneous reloads */
1079
1081
1082 /* Use existing config to populate the Indication table */
1083 while ((cxt = ast_category_browse(cfg, cxt))) {
1084 /* All categories but "general" are considered countries */
1085 if (!strcasecmp(cxt, "general")) {
1086 continue;
1087 }
1088
1089 if (parse_tone_zone(cfg, cxt)) {
1090 goto return_cleanup;
1091 }
1092 }
1093
1096
1097 /* determine which country is the default */
1098 country = ast_variable_retrieve(cfg, "general", "country");
1099 if (!ast_strlen_zero(country)) {
1100 ast_log(LOG_NOTICE, "Default country for indication tones: %s\n", country);
1102 ast_log(LOG_WARNING, "Unable to set the default country (for indication tones)\n");
1103 }
1104 } else {
1105 ast_log(LOG_WARNING, "Missing default country (for indication tones)\n");
1106 }
1107
1108 res = 0;
1109
1110return_cleanup:
1112 ast_config_destroy(cfg);
1113
1114 return res;
1115}
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: main/config.c:3321
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3326
#define CONFIG_STATUS_FILEMISSING
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:783
@ CONFIG_FLAG_FILEUNCHANGED
static int prune_tone_zone(void *obj, void *arg, int flags)
Prune tones no longer in the configuration, and have the tone zone unlinked if it is no longer in the...
Definition: indications.c:1039
static int tone_zone_mark(void *obj, void *arg, int flags)
Mark the zone and its tones before parsing configuration. We will use this to know what to remove aft...
Definition: indications.c:1017
static int parse_tone_zone(struct ast_config *cfg, const char *country)
Definition: indications.c:973
static const char config[]
Definition: indications.c:48
static int ast_set_indication_country(const char *country)
Set global indication country If no country is specified or we are unable to find the zone,...
Definition: indications.c:410
static int reload(void)
Structure used to handle boolean flags.
Definition: utils.h:199

References ao2_callback, ao2_lock, ao2_unlock, ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_log, ast_set_indication_country(), ast_strlen_zero(), ast_tone_zones, ast_variable_retrieve(), config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, country, LOG_NOTICE, LOG_WARNING, NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, parse_tone_zone(), prune_tone_zone(), reload(), and tone_zone_mark().

Referenced by load_module(), and reload_module().

◆ load_module()

static int load_module ( void  )
static

Load indications module.

Definition at line 1160 of file indications.c.

1161{
1164 if (!ast_tone_zones) {
1166 }
1167
1168 if (load_indications(0)) {
1170 }
1171
1173
1175}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static int load_indications(int reload)
load indications module
Definition: indications.c:1060
#define NUM_TONE_ZONE_BUCKETS
Definition: indications.c:68
static struct ast_cli_entry cli_indications[]
CLI entries for commands provided by this module.
Definition: indications.c:1118
static int ast_tone_zone_hash(const void *obj, const int flags)
Definition: indications.c:1124
static int ast_tone_zone_cmp(void *obj, void *arg, int flags)
Definition: indications.c:1131
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
#define ARRAY_LEN(a)
Definition: utils.h:666

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_tone_zone_cmp(), ast_tone_zone_hash(), ast_tone_zones, cli_indications, load_indications(), NULL, and NUM_TONE_ZONE_BUCKETS.

◆ parse_tone_zone()

static int parse_tone_zone ( struct ast_config cfg,
const char *  country 
)
static

Definition at line 973 of file indications.c.

974{
975 struct ast_variable *v;
976 struct ast_tone_zone *zone;
977 struct ast_tone_zone tmp_zone = {
978 .nrringcadence = 0,
979 };
980 int allocd = 0;
981
982 ast_copy_string(tmp_zone.country, country, sizeof(tmp_zone.country));
983
984 if ((zone = ao2_find(ast_tone_zones, &tmp_zone, OBJ_POINTER))) {
985 reset_tone_zone(zone);
986 } else if ((zone = ast_tone_zone_alloc())) {
987 allocd = 1;
988 ast_copy_string(zone->country, country, sizeof(zone->country));
989 } else {
990 return -1;
991 }
992
993 ast_tone_zone_lock(zone);
994 for (v = ast_variable_browse(cfg, country); v; v = v->next) {
995 store_config_tone_zone(zone, v->name, v->value);
996 }
998
999 if (allocd) {
1000 if (!is_valid_tone_zone(zone)) {
1001 ast_log(LOG_WARNING, "Indication country '%s' is invalid\n", country);
1002 } else if (ast_register_indication_country(zone)) {
1003 ast_log(LOG_WARNING, "Unable to register indication country '%s'.\n",
1004 country);
1005 }
1006 }
1007
1008 zone = ast_tone_zone_unref(zone);
1009
1010 return 0;
1011}
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
static void store_config_tone_zone(struct ast_tone_zone *zone, const char *var, const char *value)
Definition: indications.c:945
static int is_valid_tone_zone(struct ast_tone_zone *zone)
Definition: indications.c:903
static void reset_tone_zone(struct ast_tone_zone *zone)
Definition: indications.c:958
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next

References ao2_find, ast_copy_string(), ast_log, ast_register_indication_country(), ast_tone_zone_alloc(), ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_unref(), ast_tone_zones, ast_variable_browse(), country, ast_tone_zone::country, is_valid_tone_zone(), LOG_WARNING, ast_variable::name, ast_variable::next, ast_tone_zone::nrringcadence, OBJ_POINTER, reset_tone_zone(), store_config_tone_zone(), and ast_variable::value.

Referenced by load_indications().

◆ playtones_alloc()

static void * playtones_alloc ( struct ast_channel chan,
void *  params 
)
static

Definition at line 128 of file indications.c.

129{
130 struct playtones_def *pd = params;
131 struct playtones_state *ps = NULL;
132
133 if (!(ps = ast_calloc(1, sizeof(*ps)))) {
134 return NULL;
135 }
136
138
140 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", ast_channel_name(chan));
142 ps = NULL;
143 } else {
144 ps->vol = pd->vol;
145 ps->reppos = pd->reppos;
146 ps->nitems = pd->nitems;
147 ps->items = pd->items;
148 ps->oldnpos = -1;
149 }
150
151 /* Let interrupts interrupt :) */
152 if (pd->interruptible) {
154 } else {
156 }
157
158 return ps;
159}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5803
@ AST_FLAG_WRITE_INT
Definition: channel.h:983
struct ast_format * ast_format_slin
Built-in cached signed linear 8kHz format.
Definition: format_cache.c:41
static void playtones_release(struct ast_channel *chan, void *params)
Definition: indications.c:114
struct playtones_item * items
Definition: indications.c:91
struct ast_format * origwfmt
Definition: indications.c:108
struct playtones_item * items
Definition: indications.c:104
#define ast_clear_flag(p, flag)
Definition: utils.h:77
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ao2_bump, ast_calloc, ast_channel_flags(), ast_channel_name(), ast_channel_writeformat(), ast_clear_flag, AST_FLAG_WRITE_INT, ast_format_slin, ast_log, ast_set_flag, ast_set_write_format(), playtones_def::interruptible, playtones_def::items, playtones_state::items, LOG_WARNING, playtones_def::nitems, playtones_state::nitems, NULL, playtones_state::oldnpos, playtones_state::origwfmt, playtones_release(), playtones_def::reppos, playtones_state::reppos, playtones_def::vol, and playtones_state::vol.

◆ playtones_generator()

static int playtones_generator ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
)
static

Definition at line 161 of file indications.c.

162{
163 struct playtones_state *ps = data;
164 struct playtones_item *pi;
165 int x;
166
167 /* we need to prepare a frame with 16 * timelen samples as we're
168 * generating SLIN audio */
169
170 len = samples * 2;
171 if (len > sizeof(ps->data) / 2 - 1) {
172 ast_log(LOG_WARNING, "Can't generate that much data!\n");
173 return -1;
174 }
175
176 memset(&ps->f, 0, sizeof(ps->f));
177
178 pi = &ps->items[ps->npos];
179
180 if (ps->oldnpos != ps->npos) {
181 /* Load new parameters */
182 ps->v1_1 = 0;
183 ps->v2_1 = pi->init_v2_1;
184 ps->v3_1 = pi->init_v3_1;
185 ps->v1_2 = 0;
186 ps->v2_2 = pi->init_v2_2;
187 ps->v3_2 = pi->init_v3_2;
188 ps->oldnpos = ps->npos;
189 }
190
191 for (x = 0; x < samples; x++) {
192 ps->v1_1 = ps->v2_1;
193 ps->v2_1 = ps->v3_1;
194 ps->v3_1 = (pi->fac1 * ps->v2_1 >> 15) - ps->v1_1;
195
196 ps->v1_2 = ps->v2_2;
197 ps->v2_2 = ps->v3_2;
198 ps->v3_2 = (pi->fac2 * ps->v2_2 >> 15) - ps->v1_2;
199 if (pi->modulate) {
200 int p;
201 p = ps->v3_2 - 32768;
202 if (p < 0) {
203 p = -p;
204 }
205 p = ((p * 9) / 10) + 1;
206 ps->data[x] = (ps->v3_1 * p) >> 15;
207 } else {
208 ps->data[x] = ps->v3_1 + ps->v3_2;
209 }
210 }
211
214 ps->f.datalen = len;
215 ps->f.samples = samples;
217 ps->f.data.ptr = ps->data;
218
219 if (ast_write(chan, &ps->f)) {
220 return -1;
221 }
222
223 ps->pos += x;
224
225 if (pi->duration && ps->pos >= pi->duration * 8) { /* item finished? */
226 ps->pos = 0; /* start new item */
227 ps->npos++;
228 if (ps->npos >= ps->nitems) { /* last item? */
229 if (ps->reppos == -1) { /* repeat set? */
230 return -1;
231 }
232 ps->npos = ps->reppos; /* redo from top */
233 }
234 }
235
236 return 0;
237}
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5144
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
@ AST_FRAME_VOICE
struct ast_format * format
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype
struct ast_frame f
Definition: indications.c:109
short data[4000]
Definition: indications.c:111

References ast_format_slin, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log, ast_write(), ast_frame::data, playtones_state::data, ast_frame::datalen, playtones_item::duration, playtones_state::f, playtones_item::fac1, playtones_item::fac2, ast_frame_subclass::format, ast_frame::frametype, playtones_item::init_v2_1, playtones_item::init_v2_2, playtones_item::init_v3_1, playtones_item::init_v3_2, playtones_state::items, len(), LOG_WARNING, playtones_item::modulate, playtones_state::nitems, playtones_state::npos, ast_frame::offset, playtones_state::oldnpos, playtones_state::pos, ast_frame::ptr, playtones_state::reppos, ast_frame::samples, ast_frame::subclass, playtones_state::v1_1, playtones_state::v1_2, playtones_state::v2_1, playtones_state::v2_2, playtones_state::v3_1, and playtones_state::v3_2.

◆ playtones_release()

static void playtones_release ( struct ast_channel chan,
void *  params 
)
static

Definition at line 114 of file indications.c.

115{
116 struct playtones_state *ps = params;
117
118 if (chan) {
120 }
121
123 ast_free(ps->items);
124
125 ast_free(ps);
126}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934

References ao2_cleanup, ast_free, ast_set_write_format(), playtones_state::items, and playtones_state::origwfmt.

Referenced by playtones_alloc().

◆ prune_tone_zone()

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

Prune tones no longer in the configuration, and have the tone zone unlinked if it is no longer in the configuration at all.

Definition at line 1039 of file indications.c.

1040{
1041 struct ast_tone_zone *zone = obj;
1042 struct ast_tone_zone_sound *s;
1043
1044 ast_tone_zone_lock(zone);
1045
1047 if (s->killme) {
1050 }
1051 }
1053
1055
1056 return zone->killme ? CMP_MATCH : 0;
1057}
unsigned int killme
Definition: indications.h:59
unsigned int killme
Definition: indications.h:98

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_tone_zone_lock, ast_tone_zone_sound_unref(), ast_tone_zone_unlock, CMP_MATCH, ast_tone_zone_sound::killme, ast_tone_zone::killme, and ast_tone_zone::tones.

Referenced by load_indications().

◆ reload_module()

static int reload_module ( void  )
static

Reload indications module.

Definition at line 1178 of file indications.c.

1179{
1180 return load_indications(1);
1181}

References load_indications().

◆ reset_tone_zone()

static void reset_tone_zone ( struct ast_tone_zone zone)
static

Definition at line 958 of file indications.c.

959{
960 ast_tone_zone_lock(zone);
961
962 zone->killme = 0;
963
964 if (zone->nrringcadence) {
965 zone->nrringcadence = 0;
966 ast_free(zone->ringcadence);
967 zone->ringcadence = NULL;
968 }
969
971}

References ast_free, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone::killme, ast_tone_zone::nrringcadence, NULL, and ast_tone_zone::ringcadence.

Referenced by parse_tone_zone().

◆ store_config_tone_zone()

static void store_config_tone_zone ( struct ast_tone_zone zone,
const char *  var,
const char *  value 
)
static

Definition at line 945 of file indications.c.

947{
949
950 CV_STR("description", zone->description);
951 CV_F("ringcadence", store_tone_zone_ring_cadence(zone, value));
952
954
955 CV_END;
956}
#define var
Definition: ast_expr2f.c:605
#define CV_START(__in_var, __in_val)
the macro to open a block for variable parsing
#define CV_END
close a variable parsing block
#define CV_STR(__x, __dst)
#define CV_F(__pattern, __body)
call a generic function if the name matches.
static void store_tone_zone_ring_cadence(struct ast_tone_zone *zone, const char *val)
Definition: indications.c:918
int value
Definition: syslog.c:37

References ast_register_indication(), CV_END, CV_F, CV_START, CV_STR, ast_tone_zone::description, store_tone_zone_ring_cadence(), value, and var.

Referenced by parse_tone_zone().

◆ store_tone_zone_ring_cadence()

static void store_tone_zone_ring_cadence ( struct ast_tone_zone zone,
const char *  val 
)
static
Note
This is called with the tone zone locked.

Definition at line 918 of file indications.c.

919{
920 char buf[1024];
921 char *ring, *c = buf;
922
923 ast_copy_string(buf, val, sizeof(buf));
924
925 while ((ring = strsep(&c, ","))) {
926 int *tmp, value;
927
928 ring = ast_strip(ring);
929
930 if (!isdigit(ring[0]) || (value = atoi(ring)) == -1) {
931 ast_log(LOG_WARNING, "Invalid ringcadence given '%s'.\n", ring);
932 continue;
933 }
934
935 if (!(tmp = ast_realloc(zone->ringcadence, (zone->nrringcadence + 1) * sizeof(int)))) {
936 return;
937 }
938
939 zone->ringcadence = tmp;
940 tmp[zone->nrringcadence] = value;
941 zone->nrringcadence++;
942 }
943}
static int tmp()
Definition: bt_open.c:389
Definition: ast_expr2.c:325
static struct test_val c

References ast_copy_string(), ast_log, ast_realloc, ast_strip(), buf, c, LOG_WARNING, ast_tone_zone::nrringcadence, ast_tone_zone::ringcadence, strsep(), tmp(), and value.

Referenced by store_config_tone_zone().

◆ tone_zone_mark()

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

Mark the zone and its tones before parsing configuration. We will use this to know what to remove after configuration is parsed.

Definition at line 1017 of file indications.c.

1018{
1019 struct ast_tone_zone *zone = obj;
1020 struct ast_tone_zone_sound *s;
1021
1022 ast_tone_zone_lock(zone);
1023
1024 zone->killme = 1;
1025
1026 AST_LIST_TRAVERSE(&zone->tones, s, entry) {
1027 s->killme = 1;
1028 }
1029
1031
1032 return 0;
1033}

References AST_LIST_TRAVERSE, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_sound::killme, ast_tone_zone::killme, and ast_tone_zone::tones.

Referenced by load_indications().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1144 of file indications.c.

1145{
1147 if (default_tone_zone) {
1150 }
1151 if (ast_tone_zones) {
1154 }
1155
1156 return 0;
1157}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30

References ao2_ref, ARRAY_LEN, ast_cli_unregister_multiple(), ast_tone_zone_unref(), ast_tone_zones, cli_indications, default_tone_zone, and NULL.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Indication Tone Handling" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
static

Definition at line 1190 of file indications.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1190 of file indications.c.

◆ ast_tone_zones

struct ao2_container* ast_tone_zones
static

◆ cli_indications

struct ast_cli_entry cli_indications[]
static
Initial value:
= {
{ .handler = handle_cli_indication_add , .summary = "Add the given indication to the country" ,},
{ .handler = handle_cli_indication_remove , .summary = "Remove the given indication from the country" ,},
{ .handler = handle_cli_indication_show , .summary = "Display a list of all countries/indications" ,}
}
static char * handle_cli_indication_remove(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: indications.c:762
static char * handle_cli_indication_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: indications.c:813
static char * handle_cli_indication_add(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: indications.c:664

CLI entries for commands provided by this module.

Definition at line 1118 of file indications.c.

Referenced by load_module(), and unload_module().

◆ config

const char config[] = "indications.conf"
static

Definition at line 48 of file indications.c.

Referenced by load_indications().

◆ default_tone_zone

struct ast_tone_zone* default_tone_zone
static

◆ midi_tohz

const int midi_tohz[128]
static

Definition at line 50 of file indications.c.

Referenced by ast_playtones_start().

◆ playtones

struct ast_generator playtones
static
Initial value:
= {
.alloc = playtones_alloc,
.release = playtones_release,
.generate = playtones_generator,
}
static void * playtones_alloc(struct ast_channel *chan, void *params)
Definition: indications.c:128
static int playtones_generator(struct ast_channel *chan, void *data, int len, int samples)
Definition: indications.c:161

Definition at line 239 of file indications.c.

Referenced by ast_playtones_start().