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,.
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.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#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)
char * strsep(char **str, const char *delims)
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.
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)
@ CONFIG_FLAG_FILEUNCHANGED
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.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
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.
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
union ast_frame::@226 data
enum ast_frame_type frametype
void *(* alloc)(struct ast_channel *chan, void *params)
Support for dynamic strings.
A description of a part of a tone.
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.
struct ast_tone_zone::@234 tones
A list of tones for this locale.
char country[MAX_TONEZONE_COUNTRY]
Country code that this set of tones is for.
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)