48static const char config[] = 
"indications.conf";
 
   51    8,     8,     9,     9,     10,    10,    11,    12,    12,    13,
 
   52    14,    15,    16,    17,    18,    19,    20,    21,    23,    24,
 
   53    25,    27,    29,    30,    32,    34,    36,    38,    41,    43,
 
   54    46,    48,    51,    55,    58,    61,    65,    69,    73,    77,
 
   55    82,    87,    92,    97,    103,   110,   116,   123,   130,   138,
 
   56    146,   155,   164,   174,   184,   195,   207,   220,   233,   246,
 
   57    261,   277,   293,   311,   329,   349,   369,   391,   415,   440,
 
   58    466,   493,   523,   554,   587,   622,   659,   698,   739,   783,
 
   59    830,   880,   932,   987,   1046,  1108,  1174,  1244,  1318,  1396,
 
   60    1479,  1567,  1661,  1760,  1864,  1975,  2093,  2217,  2349,  2489,
 
   61    2637,  2793,  2959,  3135,  3322,  3520,  3729,  3951,  4186,  4434,
 
   62    4698,  4978,  5274,  5587,  5919,  6271,  6644,  7040,  7458,  7902,
 
   63    8372,  8869,  9397,  9956,  10548, 11175, 11839, 12543
 
 
   68#define NUM_TONE_ZONE_BUCKETS 53 
  171    if (
len > 
sizeof(ps->
data) / 2 - 1) {
 
  176    memset(&ps->
f, 0, 
sizeof(ps->
f));
 
  191    for (x = 0; x < samples; x++) {
 
  201            p = ps->
v3_2 - 32768;
 
  205            p = ((p * 9) / 10) + 1;
 
 
  247    if (sscanf(s, 
"%30u+%30u/%30u", &tone_data->
freq1, &tone_data->
freq2,
 
  248            &tone_data->
time) == 3) {
 
  250    } 
else if (sscanf(s, 
"%30u+%30u", &tone_data->
freq1, &tone_data->
freq2) == 2) {
 
  253    } 
else if (sscanf(s, 
"%30u*%30u/%30u", &tone_data->
freq1, &tone_data->
freq2,
 
  254            &tone_data->
time) == 3) {
 
  257    } 
else if (sscanf(s, 
"%30u*%30u", &tone_data->
freq1, &tone_data->
freq2) == 2) {
 
  261    } 
else if (sscanf(s, 
"%30u/%30u", &tone_data->
freq1, &tone_data->
time) == 2) {
 
  263        tone_data->
freq2 = 0;
 
  264    } 
else if (sscanf(s, 
"%30u", &tone_data->
freq1) == 1) {
 
  266        tone_data->
freq2 = 0;
 
  268    } 
else if (sscanf(s, 
"M%30u+M%30u/%30u", &tone_data->
freq1, &tone_data->
freq2,
 
  269            &tone_data->
time) == 3) {
 
  272    } 
else if (sscanf(s, 
"M%30u+M%30u", &tone_data->
freq1, &tone_data->
freq2) == 2) {
 
  276    } 
else if (sscanf(s, 
"M%30u*M%30u/%30u", &tone_data->
freq1, &tone_data->
freq2,
 
  277            &tone_data->
time) == 3) {
 
  281    } 
else if (sscanf(s, 
"M%30u*M%30u", &tone_data->
freq1, &tone_data->
freq2) == 2) {
 
  286    } 
else if (sscanf(s, 
"M%30u/%30u", &tone_data->
freq1, &tone_data->
time) == 2) {
 
  288        tone_data->
freq2 = -1;
 
  290    } 
else if (sscanf(s, 
"M%30u", &tone_data->
freq1) == 1) {
 
  292        tone_data->
freq2 = -1;
 
 
  308    static const float sample_rate = 8000.0;
 
  309    static const float max_sample_val = 32768.0;
 
  320    if (strchr(stringp,
'|')) {
 
  335        } 
else if (
d.reppos == -1) {
 
  346            if (tone_data.
freq1 <= 127) {
 
  352            if (tone_data.
freq2 <= 127) {
 
  359        new_items = 
ast_realloc(
d.items, (
d.nitems + 1) * 
sizeof(*
d.items));
 
  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;
 
  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;
 
  374        d.items[
d.nitems].duration = tone_data.
time;
 
  375        d.items[
d.nitems].modulate = tone_data.
modulate;
 
 
  484        if (!strcasecmp(ts->
name, indication)) {
 
 
  580        const char *tonelist)
 
  589        if (!strcasecmp(indication, ts->
name)) {
 
 
  622        if (!strcasecmp(indication, ts->
name)) {
 
 
  647    wordlen = strlen(
a->word);
 
  651        if (!strncasecmp(
a->word, 
tz->country, wordlen)) {
 
 
  667    int created_country = 0;
 
  674            "Usage: indication add <country> <indication> \"<tonelist>\"\n" 
  675            "       Add the given indication to the country.\n";
 
  716        if (created_country) {
 
 
  745    wordlen = strlen(
a->word);
 
  749        if (!strncasecmp(
a->word, ts->
name, wordlen)) {
 
 
  769        e->
command = 
"indication remove";
 
  771            "Usage: indication remove <country> [indication]\n" 
  772            "       Remove the given indication from the country.\n";
 
  784    if (
a->argc != 3 && 
a->argc != 4) {
 
  799        ast_log(
LOG_WARNING, 
"Unable to unregister indication %s/%s, country does not exists\n", 
a->argv[2], 
a->argv[3]);
 
 
  817    int found_country = 0;
 
  822        e->
command = 
"indication show";
 
  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";
 
  835        ast_cli(
a->fd, 
"Country   Description\n");
 
  836        ast_cli(
a->fd, 
"===========================\n");
 
  840            ast_cli(
a->fd, 
"%-7.7s  %s\n", 
tz->country, 
tz->description);
 
  848            ast_cli(
a->fd, 
"===========================\n");
 
  850            ast_cli(
a->fd, 
"Default tone zone: %s\n", 
tz->country);
 
  859    for (i = 2; i < 
a->argc; i++) {
 
  872        if (!found_country) {
 
  874            ast_cli(
a->fd, 
"Country Indication      PlayList\n");
 
  875            ast_cli(
a->fd, 
"=====================================\n");
 
  881        for (j = 0; j < 
tz->nrringcadence; j++) {
 
  883                    (j == 
tz->nrringcadence - 1) ? 
"" : 
",");
 
  896    if (!found_country) {
 
  897        ast_cli(
a->fd, 
"No countries matched your criteria.\n");
 
 
  921    char *ring, *
c = 
buf;
 
  925    while ((ring = 
strsep(&
c, 
","))) {
 
  930        if (!isdigit(ring[0]) || (
value = atoi(ring)) == -1) {
 
 
 1063    const char *cxt = 
NULL;
 
 1085        if (!strcasecmp(cxt, 
"general")) {
 
 1090            goto return_cleanup;
 
 
 1189    .
requires = 
"extconfig",
 
Prototypes for public functions only of internal interest,.
void ast_cli_unregister_multiple(void)
char * strsep(char **str, const char *delims)
Asterisk main include file. File version handling, generic pbx functions.
#define ast_realloc(p, len)
A wrapper for realloc()
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_alloc(data_size, destructor_fn)
#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.
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
void ast_deactivate_generator(struct ast_channel *chan)
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.
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.
Standard Command Line Interface.
#define AST_CLI_DEFINE(fn, txt,...)
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
#define CV_START(__in_var, __in_val)
the macro to open a block for variable parsing
#define CONFIG_STATUS_FILEMISSING
#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.
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
@ CONFIG_FLAG_FILEUNCHANGED
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Asterisk internal frame definitions.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define ast_verb(level,...)
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...
static char * handle_cli_indication_remove(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int ast_register_indication_country(struct ast_tone_zone *zone)
add a new country, if country exists, it will be replaced.
static int load_indications(int reload)
load indications module
static char * complete_country(struct ast_cli_args *a)
static int ast_register_indication(struct ast_tone_zone *zone, const char *indication, const char *tonelist)
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...
static struct ast_tone_zone * ast_tone_zone_alloc(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.
#define NUM_TONE_ZONE_BUCKETS
static char * handle_cli_indication_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void ast_tone_zone_sound_destructor(void *obj)
static struct ast_cli_entry cli_indications[]
CLI entries for commands provided by this module.
int ast_tone_zone_part_parse(const char *s, struct ast_tone_zone_part *tone_data)
Parse a tone part.
static void * playtones_alloc(struct ast_channel *chan, void *params)
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *_zone, const char *indication)
Locate a tone zone sound.
struct ao2_iterator ast_tone_zone_iterator_init(void)
Get an iterator for the available tone zones.
static int ast_unregister_indication_country(const char *country)
remove an existing country and all its indications, country must exist.
static void store_config_tone_zone(struct ast_tone_zone *zone, const char *var, const char *value)
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
static void store_tone_zone_ring_cadence(struct ast_tone_zone *zone, const char *val)
static int reload_module(void)
Reload indications module.
static char * complete_indications(struct ast_cli_args *a)
static int parse_tone_zone(struct ast_config *cfg, const char *country)
static char * handle_cli_indication_add(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int is_valid_tone_zone(struct ast_tone_zone *zone)
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
static const char config[]
static int playtones_generator(struct ast_channel *chan, void *data, int len, int samples)
static const int midi_tohz[128]
static struct ao2_container * ast_tone_zones
static int ast_tone_zone_hash(const void *obj, const int flags)
static void reset_tone_zone(struct ast_tone_zone *zone)
static struct ast_generator playtones
static int load_module(void)
Load indications module.
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
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,...
static int unload_module(void)
static void playtones_release(struct ast_channel *chan, void *params)
static struct ast_tone_zone * default_tone_zone
int ast_tone_zone_count(void)
Get the number of registered tone zones.
static int ast_tone_zone_cmp(void *obj, void *arg, int flags)
static void ast_tone_zone_destructor(void *obj)
deallocate the passed tone zone
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.
#define ast_tone_zone_unlock(tz)
Unlock an ast_tone_zone.
static struct ast_tone_zone * ast_tone_zone_unref(struct ast_tone_zone *tz)
Release a reference to an ast_tone_zone.
#define ast_tone_zone_lock(tz)
Lock an ast_tone_zone.
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.
static struct ast_tone_zone * ast_tone_zone_ref(struct ast_tone_zone *tz)
Increase the reference count on an ast_tone_zone.
A set of macros to manage forward-linked lists.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Asterisk locking-related definitions:
Asterisk module definitions.
@ AST_MODFLAG_GLOBAL_SYMBOLS
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
@ AST_MODULE_LOAD_SUCCESS
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_alloca(init_len)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Main Channel structure associated with a channel.
descriptor for a cli entry.
Structure used to handle boolean flags.
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
union ast_frame::@239 data
void *(* alloc)(struct ast_channel *chan, void *params)
Support for dynamic strings.
A description of a part of a tone.
struct ast_tone_zone_sound::@242 entry
Linked list fields for including in the list on an ast_tone_zone.
const char * data
Description of a tone.
const char * name
Name of the tone. For example, "busy".
A set of tones for a given locale.
unsigned int nrringcadence
Number of ring cadence elements in the ringcadence array.
char description[40]
Text description of the given country.
char country[MAX_TONEZONE_COUNTRY]
Country code that this set of tones is for.
struct ast_tone_zone::@247 tones
A list of tones for this locale.
int * ringcadence
Array of ring cadence parts.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
struct playtones_item * items
unsigned char offset[AST_FRIENDLY_OFFSET]
struct ast_format * origwfmt
struct playtones_item * items
#define ast_clear_flag(p, flag)
#define ast_set_flag(p, flag)