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/channel.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/data.h"
#include "asterisk/_private.h"
Go to the source code of this file.
Data Structures | |
struct | playtones_def |
struct | playtones_item |
struct | playtones_state |
Defines | |
#define | DATA_EXPORT_TONE_ZONE(MEMBER) |
#define | DATA_EXPORT_TONE_ZONE_SOUND(MEMBER) |
#define | NUM_TONE_ZONE_BUCKETS 53 |
Functions | |
AST_DATA_STRUCTURE (ast_tone_zone_sound, DATA_EXPORT_TONE_ZONE_SOUND) | |
AST_DATA_STRUCTURE (ast_tone_zone, DATA_EXPORT_TONE_ZONE) | |
struct ast_tone_zone_sound * | ast_get_indication_tone (const struct ast_tone_zone *_zone, const char *indication) |
Locate a tone zone sound. | |
struct ast_tone_zone * | ast_get_indication_zone (const char *country) |
locate ast_tone_zone | |
int | ast_indications_init (void) |
Load indications module. | |
int | ast_indications_reload (void) |
Reload indications module. | |
int | ast_playtones_start (struct ast_channel *chan, int vol, const char *playlst, int interruptible) |
Start playing a list of tones on a channel. | |
void | ast_playtones_stop (struct ast_channel *chan) |
Stop playing tones on a channel. | |
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) |
static int | ast_set_indication_country (const char *country) |
static struct ast_tone_zone * | ast_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. | |
int | ast_tone_zone_data_add_structure (struct ast_data *tree, struct ast_tone_zone *zone) |
Add a tone_zone structure to the data tree specified. | |
static void | ast_tone_zone_destructor (void *obj) |
deallocate the passed tone zone | |
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. | |
int | ast_tone_zone_part_parse (const char *s, struct ast_tone_zone_part *tone_data) |
Parse a tone part. | |
static void | ast_tone_zone_sound_destructor (void *obj) |
static int | ast_unregister_indication (struct ast_tone_zone *zone, const char *indication) |
static int | ast_unregister_indication_country (const char *country) |
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 void | indications_shutdown (void) |
static int | is_valid_tone_zone (struct ast_tone_zone *zone) |
static int | load_indications (int reload) |
load indications module | |
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) |
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) |
Variables | |
static struct ao2_container * | ast_tone_zones |
static struct ast_cli_entry | cli_indications [] |
CLI entries for commands provided by this module. | |
static const char | config [] = "indications.conf" |
static struct ast_tone_zone * | default_tone_zone |
static const int | midi_tohz [128] |
static struct ast_generator | playtones |
Indication Tone Handling.
Definition in file indications.c.
#define DATA_EXPORT_TONE_ZONE | ( | MEMBER | ) |
MEMBER(ast_tone_zone, country, AST_DATA_STRING) \ MEMBER(ast_tone_zone, description, AST_DATA_STRING) \ MEMBER(ast_tone_zone, nrringcadence, AST_DATA_UNSIGNED_INTEGER)
Definition at line 49 of file indications.c.
#define DATA_EXPORT_TONE_ZONE_SOUND | ( | MEMBER | ) |
MEMBER(ast_tone_zone_sound, name, AST_DATA_STRING) \ MEMBER(ast_tone_zone_sound, data, AST_DATA_STRING)
Definition at line 56 of file indications.c.
#define NUM_TONE_ZONE_BUCKETS 53 |
Definition at line 83 of file indications.c.
Referenced by ast_indications_init().
AST_DATA_STRUCTURE | ( | ast_tone_zone_sound | , | |
DATA_EXPORT_TONE_ZONE_SOUND | ||||
) |
AST_DATA_STRUCTURE | ( | ast_tone_zone | , | |
DATA_EXPORT_TONE_ZONE | ||||
) |
struct ast_tone_zone_sound* ast_get_indication_tone | ( | const struct ast_tone_zone * | zone, | |
const char * | indication | |||
) | [read] |
Locate a tone zone sound.
zone | Zone to look in for a sound, if NULL, the default will be used | |
indication | Sound to look for, such as "busy" |
Definition at line 473 of file indications.c.
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, and ast_tone_zone_sound::name.
Referenced by ast_app_dtget(), ast_indicate_data(), dial_handle_playtones(), dialtone_indicate(), handle_playtones(), in_band_indication(), pbx_builtin_waitexten(), play_dialtone(), read_exec(), readexten_exec(), and skinny_transfer().
00474 { 00475 struct ast_tone_zone_sound *ts = NULL; 00476 /* _zone is const to the users of the API */ 00477 struct ast_tone_zone *zone = (struct ast_tone_zone *) _zone; 00478 00479 /* If no zone is specified, use the default */ 00480 if (!zone) { 00481 ao2_lock(ast_tone_zones); 00482 if (default_tone_zone) { 00483 zone = ast_tone_zone_ref(default_tone_zone); 00484 } 00485 ao2_unlock(ast_tone_zones); 00486 00487 if (!zone) { 00488 return NULL; 00489 } 00490 } 00491 00492 ast_tone_zone_lock(zone); 00493 00494 /* Look through list of tones in the zone searching for the right one */ 00495 AST_LIST_TRAVERSE(&zone->tones, ts, entry) { 00496 if (!strcasecmp(ts->name, indication)) { 00497 /* Increase ref count for the reference we will return */ 00498 ts = ast_tone_zone_sound_ref(ts); 00499 break; 00500 } 00501 } 00502 00503 ast_tone_zone_unlock(zone); 00504 00505 return ts; 00506 }
struct ast_tone_zone* ast_get_indication_zone | ( | const char * | country | ) | [read] |
locate ast_tone_zone
country | country to find. If NULL is provided, get the default. |
Definition at line 451 of file indications.c.
References ao2_find, ao2_lock, ao2_unlock, ast_copy_string(), ast_strlen_zero(), ast_tone_zone_ref(), ast_tone_zone::country, ast_tone_zone::nrringcadence, OBJ_POINTER, and tz.
Referenced by ast_set_indication_country(), ast_var_indications(), build_device(), func_channel_write_real(), handle_cli_indication_add(), and handle_cli_indication_remove().
00452 { 00453 struct ast_tone_zone *tz = NULL; 00454 struct ast_tone_zone zone_arg = { 00455 .nrringcadence = 0, 00456 }; 00457 00458 if (ast_strlen_zero(country)) { 00459 ao2_lock(ast_tone_zones); 00460 if (default_tone_zone) { 00461 tz = ast_tone_zone_ref(default_tone_zone); 00462 } 00463 ao2_unlock(ast_tone_zones); 00464 00465 return tz; 00466 } 00467 00468 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country)); 00469 00470 return ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER); 00471 }
int ast_indications_init | ( | void | ) |
Load indications module.
Provided by indications.c
Definition at line 1169 of file indications.c.
References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_register_atexit(), ast_tone_zone_cmp(), ast_tone_zone_hash(), indications_shutdown(), load_indications(), and NUM_TONE_ZONE_BUCKETS.
Referenced by main().
01170 { 01171 if (!(ast_tone_zones = ao2_container_alloc(NUM_TONE_ZONE_BUCKETS, 01172 ast_tone_zone_hash, ast_tone_zone_cmp))) { 01173 return -1; 01174 } 01175 01176 if (load_indications(0)) { 01177 indications_shutdown(); 01178 return -1; 01179 } 01180 01181 ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications)); 01182 01183 ast_register_atexit(indications_shutdown); 01184 return 0; 01185 }
int ast_indications_reload | ( | void | ) |
Reload indications module.
Provided by indications.c
Definition at line 1188 of file indications.c.
References load_indications().
01189 { 01190 return load_indications(1); 01191 }
int ast_playtones_start | ( | struct ast_channel * | chan, | |
int | vol, | |||
const char * | tonelist, | |||
int | interruptible | |||
) |
Start playing a list of tones on a channel.
chan | the channel to play tones on | |
vol | volume | |
tonelist | the list of tones to play, comma separated | |
interruptible | whether or not this tone can be interrupted |
0 | success | |
non-zero | failure |
Definition at line 319 of file indications.c.
References ast_activate_generator(), ast_free, ast_log(), ast_realloc, ast_strdupa, ast_strip(), ast_strlen_zero(), ast_tone_zone_part_parse(), cos, playtones_item::duration, playtones_item::fac1, playtones_item::fac2, ast_tone_zone_part::freq1, ast_tone_zone_part::freq2, playtones_item::init_v2_1, playtones_item::init_v2_2, playtones_item::init_v3_1, playtones_item::init_v3_2, playtones_def::interruptible, playtones_def::items, LOG_ERROR, M_PI, ast_tone_zone_part::midinote, ast_tone_zone_part::modulate, playtones_item::modulate, playtones_def::nitems, playtones_def::reppos, ast_tone_zone_part::time, and playtones_def::vol.
Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_begin(), dial_handle_playtones(), dialtone_indicate(), handle_playtones(), in_band_indication(), milliwatt_exec(), pbx_builtin_waitexten(), play_dialtone(), playtone(), read_exec(), readexten_exec(), receivefax_t38_init(), send_digit_to_chan(), sendfax_t38_init(), and skinny_transfer().
00320 { 00321 char *s, *data = ast_strdupa(playlst); 00322 struct playtones_def d = { vol, -1, 0, 1, NULL }; 00323 char *stringp; 00324 char *separator; 00325 static const float sample_rate = 8000.0; 00326 static const float max_sample_val = 32768.0; 00327 00328 if (vol < 1) { 00329 d.vol = 7219; /* Default to -8db */ 00330 } 00331 00332 d.interruptible = interruptible; 00333 00334 stringp = data; 00335 00336 /* check if the data is separated with '|' or with ',' by default */ 00337 if (strchr(stringp,'|')) { 00338 separator = "|"; 00339 } else { 00340 separator = ","; 00341 } 00342 00343 while ((s = strsep(&stringp, separator)) && !ast_strlen_zero(s)) { 00344 struct playtones_item *new_items; 00345 struct ast_tone_zone_part tone_data = { 00346 .time = 0, 00347 }; 00348 00349 s = ast_strip(s); 00350 if (s[0]=='!') { 00351 s++; 00352 } else if (d.reppos == -1) { 00353 d.reppos = d.nitems; 00354 } 00355 00356 if (ast_tone_zone_part_parse(s, &tone_data)) { 00357 ast_log(LOG_ERROR, "Failed to parse tone part '%s'\n", s); 00358 continue; 00359 } 00360 00361 if (tone_data.midinote) { 00362 /* midi notes must be between 0 and 127 */ 00363 00364 if (tone_data.freq1 >= 0 && tone_data.freq1 <= 127) { 00365 tone_data.freq1 = midi_tohz[tone_data.freq1]; 00366 } else { 00367 tone_data.freq1 = 0; 00368 } 00369 00370 if (tone_data.freq2 >= 0 && tone_data.freq2 <= 127) { 00371 tone_data.freq2 = midi_tohz[tone_data.freq2]; 00372 } else { 00373 tone_data.freq2 = 0; 00374 } 00375 } 00376 00377 new_items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)); 00378 if (!new_items) { 00379 ast_free(d.items); 00380 return -1; 00381 } 00382 d.items = new_items; 00383 00384 d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (tone_data.freq1 / sample_rate)) * max_sample_val; 00385 d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol; 00386 d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol; 00387 00388 d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (tone_data.freq2 / sample_rate)) * max_sample_val; 00389 d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol; 00390 d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol; 00391 00392 d.items[d.nitems].duration = tone_data.time; 00393 d.items[d.nitems].modulate = tone_data.modulate; 00394 00395 d.nitems++; 00396 } 00397 00398 if (!d.nitems) { 00399 ast_log(LOG_ERROR, "No valid tone parts\n"); 00400 return -1; 00401 } 00402 00403 if (ast_activate_generator(chan, &playtones, &d)) { 00404 ast_free(d.items); 00405 return -1; 00406 } 00407 00408 return 0; 00409 }
void ast_playtones_stop | ( | struct ast_channel * | chan | ) |
Stop playing tones on a channel.
chan | the channel to stop tones on |
Definition at line 411 of file indications.c.
References ast_deactivate_generator().
Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_end(), disa_exec(), handle_stopplaytones(), pbx_builtin_waitexten(), playtone(), read_exec(), readexten_exec(), receivefax_t38_init(), sendfax_t38_init(), stop_indicate(), and unistim_indicate().
00412 { 00413 ast_deactivate_generator(chan); 00414 }
static int ast_register_indication | ( | struct ast_tone_zone * | zone, | |
const char * | indication, | |||
const char * | tonelist | |||
) | [static] |
Definition at line 588 of file indications.c.
References ao2_alloc, 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, and ast_tone_zone_sound::name.
Referenced by handle_cli_indication_add(), and store_config_tone_zone().
00590 { 00591 struct ast_tone_zone_sound *ts; 00592 00593 if (ast_strlen_zero(indication) || ast_strlen_zero(tonelist)) { 00594 return -1; 00595 } 00596 00597 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) { 00598 if (!strcasecmp(indication, ts->name)) { 00599 AST_LIST_REMOVE_CURRENT(entry); 00600 ts = ast_tone_zone_sound_unref(ts); 00601 break; 00602 } 00603 } 00604 AST_LIST_TRAVERSE_SAFE_END; 00605 00606 if (!(ts = ao2_alloc(sizeof(*ts), ast_tone_zone_sound_destructor))) { 00607 return -1; 00608 } 00609 00610 if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) { 00611 ts = ast_tone_zone_sound_unref(ts); 00612 return -1; 00613 } 00614 00615 AST_LIST_INSERT_TAIL(&zone->tones, ts, entry); /* Inherit reference */ 00616 00617 return 0; 00618 }
static int ast_register_indication_country | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 541 of file indications.c.
References ao2_link, ao2_lock, ao2_unlock, ast_tone_zone_ref(), ast_verb, and ast_tone_zone::country.
Referenced by handle_cli_indication_add(), and parse_tone_zone().
00542 { 00543 ao2_lock(ast_tone_zones); 00544 if (!default_tone_zone) { 00545 default_tone_zone = ast_tone_zone_ref(zone); 00546 } 00547 ao2_unlock(ast_tone_zones); 00548 00549 ao2_link(ast_tone_zones, zone); 00550 00551 ast_verb(3, "Registered indication country '%s'\n", zone->country); 00552 00553 return 0; 00554 }
static int ast_set_indication_country | ( | const char * | country | ) | [static] |
Definition at line 427 of file indications.c.
References ao2_lock, ao2_unlock, ast_get_indication_zone(), ast_strlen_zero(), ast_tone_zone_ref(), ast_tone_zone_unref(), and ast_verb.
Referenced by load_indications().
00428 { 00429 struct ast_tone_zone *zone = NULL; 00430 00431 /* If no country is specified or we are unable to find the zone, then return not found */ 00432 if (ast_strlen_zero(country) || !(zone = ast_get_indication_zone(country))) { 00433 return -1; 00434 } 00435 00436 ast_verb(3, "Setting default indication country to '%s'\n", country); 00437 00438 ao2_lock(ast_tone_zones); 00439 if (default_tone_zone) { 00440 default_tone_zone = ast_tone_zone_unref(default_tone_zone); 00441 } 00442 default_tone_zone = ast_tone_zone_ref(zone); 00443 ao2_unlock(ast_tone_zones); 00444 00445 zone = ast_tone_zone_unref(zone); 00446 00447 return 0; 00448 }
static struct ast_tone_zone* ast_tone_zone_alloc | ( | void | ) | [static, read] |
Definition at line 643 of file indications.c.
References ao2_alloc, and ast_tone_zone_destructor().
Referenced by handle_cli_indication_add(), and parse_tone_zone().
00644 { 00645 return ao2_alloc(sizeof(struct ast_tone_zone), ast_tone_zone_destructor); 00646 }
static int ast_tone_zone_cmp | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1118 of file indications.c.
References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.
Referenced by ast_indications_init().
01119 { 01120 struct ast_tone_zone *zone = obj; 01121 struct ast_tone_zone *zone_arg = arg; 01122 01123 return (!strcasecmp(zone->country, zone_arg->country)) ? 01124 CMP_MATCH | CMP_STOP : 0; 01125 }
int ast_tone_zone_count | ( | void | ) |
Get the number of registered tone zones.
Definition at line 416 of file indications.c.
References ao2_container_count().
00417 { 00418 return ao2_container_count(ast_tone_zones); 00419 }
int ast_tone_zone_data_add_structure | ( | struct ast_data * | tree, | |
struct ast_tone_zone * | zone | |||
) |
Add a tone_zone structure to the data tree specified.
<0 | on error. | |
0 | on success. |
Definition at line 1127 of file indications.c.
References ast_data_add_node(), ast_data_add_structure, AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_tone_zone_lock, and ast_tone_zone_unlock.
Referenced by ast_channel_data_add_structure().
01128 { 01129 struct ast_data *data_zone_sound; 01130 struct ast_tone_zone_sound *s; 01131 01132 ast_data_add_structure(ast_tone_zone, tree, zone); 01133 01134 if (AST_LIST_EMPTY(&zone->tones)) { 01135 return 0; 01136 } 01137 01138 data_zone_sound = ast_data_add_node(tree, "tones"); 01139 if (!data_zone_sound) { 01140 return -1; 01141 } 01142 01143 ast_tone_zone_lock(zone); 01144 01145 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01146 ast_data_add_structure(ast_tone_zone_sound, data_zone_sound, s); 01147 } 01148 01149 ast_tone_zone_unlock(zone); 01150 01151 return 0; 01152 }
static void ast_tone_zone_destructor | ( | void * | obj | ) | [static] |
deallocate the passed tone zone
Definition at line 525 of file indications.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_tone_zone_sound_unref(), and ast_tone_zone::ringcadence.
Referenced by ast_tone_zone_alloc().
00526 { 00527 struct ast_tone_zone *zone = obj; 00528 struct ast_tone_zone_sound *current; 00529 00530 while ((current = AST_LIST_REMOVE_HEAD(&zone->tones, entry))) { 00531 current = ast_tone_zone_sound_unref(current); 00532 } 00533 00534 if (zone->ringcadence) { 00535 ast_free(zone->ringcadence); 00536 zone->ringcadence = NULL; 00537 } 00538 }
static int ast_tone_zone_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1111 of file indications.c.
References ast_str_case_hash(), and ast_tone_zone::country.
Referenced by ast_indications_init().
01112 { 01113 const struct ast_tone_zone *zone = obj; 01114 01115 return ast_str_case_hash(zone->country); 01116 }
struct ao2_iterator ast_tone_zone_iterator_init | ( | void | ) | [read] |
Get an iterator for the available tone zones.
Definition at line 421 of file indications.c.
References ao2_iterator_init().
Referenced by ast_var_indications(), ast_var_indications_table(), and handle_cli_indication_show().
00422 { 00423 return ao2_iterator_init(ast_tone_zones, 0); 00424 }
int ast_tone_zone_part_parse | ( | const char * | s, | |
struct ast_tone_zone_part * | tone_data | |||
) |
Parse a tone part.
s | The 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_data | An output parameter that contains the result of the parsing. |
0 | success | |
-1 | failure, and the contents of tone_data are undefined |
Definition at line 262 of file indications.c.
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().
00263 { 00264 if (sscanf(s, "%30u+%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00265 &tone_data->time) == 3) { 00266 /* f1+f2/time format */ 00267 } else if (sscanf(s, "%30u+%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00268 /* f1+f2 format */ 00269 tone_data->time = 0; 00270 } else if (sscanf(s, "%30u*%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00271 &tone_data->time) == 3) { 00272 /* f1*f2/time format */ 00273 tone_data->modulate = 1; 00274 } else if (sscanf(s, "%30u*%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00275 /* f1*f2 format */ 00276 tone_data->time = 0; 00277 tone_data->modulate = 1; 00278 } else if (sscanf(s, "%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) { 00279 /* f1/time format */ 00280 tone_data->freq2 = 0; 00281 } else if (sscanf(s, "%30u", &tone_data->freq1) == 1) { 00282 /* f1 format */ 00283 tone_data->freq2 = 0; 00284 tone_data->time = 0; 00285 } else if (sscanf(s, "M%30u+M%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00286 &tone_data->time) == 3) { 00287 /* Mf1+Mf2/time format */ 00288 tone_data->midinote = 1; 00289 } else if (sscanf(s, "M%30u+M%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00290 /* Mf1+Mf2 format */ 00291 tone_data->time = 0; 00292 tone_data->midinote = 1; 00293 } else if (sscanf(s, "M%30u*M%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00294 &tone_data->time) == 3) { 00295 /* Mf1*Mf2/time format */ 00296 tone_data->modulate = 1; 00297 tone_data->midinote = 1; 00298 } else if (sscanf(s, "M%30u*M%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00299 /* Mf1*Mf2 format */ 00300 tone_data->time = 0; 00301 tone_data->modulate = 1; 00302 tone_data->midinote = 1; 00303 } else if (sscanf(s, "M%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) { 00304 /* Mf1/time format */ 00305 tone_data->freq2 = -1; 00306 tone_data->midinote = 1; 00307 } else if (sscanf(s, "M%30u", &tone_data->freq1) == 1) { 00308 /* Mf1 format */ 00309 tone_data->freq2 = -1; 00310 tone_data->time = 0; 00311 tone_data->midinote = 1; 00312 } else { 00313 return -1; 00314 } 00315 00316 return 0; 00317 }
static void ast_tone_zone_sound_destructor | ( | void * | obj | ) | [static] |
Definition at line 508 of file indications.c.
References ast_free, ast_tone_zone_sound::data, and ast_tone_zone_sound::name.
Referenced by ast_register_indication().
00509 { 00510 struct ast_tone_zone_sound *ts = obj; 00511 00512 /* Deconstify the 'const char *'s so the compiler doesn't complain. (but it's safe) */ 00513 if (ts->name) { 00514 ast_free((char *) ts->name); 00515 ts->name = NULL; 00516 } 00517 00518 if (ts->data) { 00519 ast_free((char *) ts->data); 00520 ts->data = NULL; 00521 } 00522 }
static int ast_unregister_indication | ( | struct ast_tone_zone * | zone, | |
const char * | indication | |||
) | [static] |
Definition at line 621 of file indications.c.
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, and ast_tone_zone_sound::name.
Referenced by handle_cli_indication_remove().
00622 { 00623 struct ast_tone_zone_sound *ts; 00624 int res = -1; 00625 00626 ast_tone_zone_lock(zone); 00627 00628 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) { 00629 if (!strcasecmp(indication, ts->name)) { 00630 AST_LIST_REMOVE_CURRENT(entry); 00631 ts = ast_tone_zone_sound_unref(ts); 00632 res = 0; 00633 break; 00634 } 00635 } 00636 AST_LIST_TRAVERSE_SAFE_END; 00637 00638 ast_tone_zone_unlock(zone); 00639 00640 return res; 00641 }
static int ast_unregister_indication_country | ( | const char * | country | ) | [static] |
Definition at line 557 of file indications.c.
References ao2_callback, ao2_find, ao2_lock, ao2_unlock, ast_copy_string(), ast_tone_zone_unref(), ast_tone_zone::country, ast_tone_zone::nrringcadence, OBJ_POINTER, OBJ_UNLINK, and tz.
Referenced by handle_cli_indication_add(), and handle_cli_indication_remove().
00558 { 00559 struct ast_tone_zone *tz = NULL; 00560 struct ast_tone_zone zone_arg = { 00561 .nrringcadence = 0, 00562 }; 00563 00564 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country)); 00565 00566 ao2_lock(ast_tone_zones); 00567 tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER | OBJ_UNLINK); 00568 if (!tz) { 00569 ao2_unlock(ast_tone_zones); 00570 return -1; 00571 } 00572 00573 if (default_tone_zone == tz) { 00574 ast_tone_zone_unref(default_tone_zone); 00575 /* Get a new default, punt to the first one we find */ 00576 default_tone_zone = ao2_callback(ast_tone_zones, 0, NULL, NULL); 00577 } 00578 ao2_unlock(ast_tone_zones); 00579 00580 tz = ast_tone_zone_unref(tz); 00581 00582 return 0; 00583 }
static char* complete_country | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 648 of file indications.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_tone_zone_unref(), ast_tone_zone::country, ast_cli_args::n, tz, and ast_cli_args::word.
Referenced by handle_cli_indication_add(), handle_cli_indication_remove(), and handle_cli_indication_show().
00649 { 00650 char *res = NULL; 00651 struct ao2_iterator i; 00652 int which = 0; 00653 size_t wordlen; 00654 struct ast_tone_zone *tz; 00655 00656 wordlen = strlen(a->word); 00657 00658 i = ao2_iterator_init(ast_tone_zones, 0); 00659 while ((tz = ao2_iterator_next(&i))) { 00660 if (!strncasecmp(a->word, tz->country, wordlen) && ++which > a->n) { 00661 res = ast_strdup(tz->country); 00662 } 00663 tz = ast_tone_zone_unref(tz); 00664 if (res) { 00665 break; 00666 } 00667 } 00668 ao2_iterator_destroy(&i); 00669 00670 return res; 00671 }
static char* complete_indications | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 734 of file indications.c.
References ao2_find, ast_cli_args::argv, ast_copy_string(), AST_LIST_TRAVERSE, ast_strdup, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_unref(), ast_tone_zone::country, ast_cli_args::n, ast_tone_zone_sound::name, OBJ_POINTER, ast_cli_args::pos, tz, and ast_cli_args::word.
Referenced by handle_cli_indication_remove().
00735 { 00736 char *res = NULL; 00737 int which = 0; 00738 size_t wordlen; 00739 struct ast_tone_zone_sound *ts; 00740 struct ast_tone_zone *tz, tmp_tz = { 00741 .nrringcadence = 0, 00742 }; 00743 00744 ast_copy_string(tmp_tz.country, a->argv[a->pos - 1], sizeof(tmp_tz.country)); 00745 00746 if (!(tz = ao2_find(ast_tone_zones, &tmp_tz, OBJ_POINTER))) { 00747 return NULL; 00748 } 00749 00750 wordlen = strlen(a->word); 00751 00752 ast_tone_zone_lock(tz); 00753 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00754 if (!strncasecmp(a->word, ts->name, wordlen) && ++which > a->n) { 00755 res = ast_strdup(ts->name); 00756 break; 00757 } 00758 } 00759 ast_tone_zone_unlock(tz); 00760 00761 tz = ast_tone_zone_unref(tz); 00762 00763 return res; 00764 }
static char* handle_cli_indication_add | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 673 of file indications.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_copy_string(), ast_get_indication_zone(), ast_log(), ast_register_indication(), ast_register_indication_country(), 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(), ast_tone_zone::country, LOG_NOTICE, LOG_WARNING, ast_cli_args::pos, tz, and ast_cli_entry::usage.
00674 { 00675 struct ast_tone_zone *tz; 00676 int created_country = 0; 00677 char *res = CLI_SUCCESS; 00678 00679 switch (cmd) { 00680 case CLI_INIT: 00681 e->command = "indication add"; 00682 e->usage = 00683 "Usage: indication add <country> <indication> \"<tonelist>\"\n" 00684 " Add the given indication to the country.\n"; 00685 return NULL; 00686 case CLI_GENERATE: 00687 if (a->pos == 2) { 00688 return complete_country(a); 00689 } else { 00690 return NULL; 00691 } 00692 } 00693 00694 if (a->argc != 5) { 00695 return CLI_SHOWUSAGE; 00696 } 00697 00698 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00699 /* country does not exist, create it */ 00700 ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n", a->argv[2]); 00701 00702 if (!(tz = ast_tone_zone_alloc())) { 00703 return CLI_FAILURE; 00704 } 00705 00706 ast_copy_string(tz->country, a->argv[2], sizeof(tz->country)); 00707 00708 if (ast_register_indication_country(tz)) { 00709 ast_log(LOG_WARNING, "Unable to register new country\n"); 00710 tz = ast_tone_zone_unref(tz); 00711 return CLI_FAILURE; 00712 } 00713 00714 created_country = 1; 00715 } 00716 00717 ast_tone_zone_lock(tz); 00718 00719 if (ast_register_indication(tz, a->argv[3], a->argv[4])) { 00720 ast_log(LOG_WARNING, "Unable to register indication %s/%s\n", a->argv[2], a->argv[3]); 00721 if (created_country) { 00722 ast_unregister_indication_country(a->argv[2]); 00723 } 00724 res = CLI_FAILURE; 00725 } 00726 00727 ast_tone_zone_unlock(tz); 00728 00729 tz = ast_tone_zone_unref(tz); 00730 00731 return res; 00732 }
static char* handle_cli_indication_remove | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 766 of file indications.c.
References ast_cli_args::argc, ast_cli_args::argv, 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, ast_cli_args::pos, tz, and ast_cli_entry::usage.
00767 { 00768 struct ast_tone_zone *tz; 00769 char *res = CLI_SUCCESS; 00770 00771 switch (cmd) { 00772 case CLI_INIT: 00773 e->command = "indication remove"; 00774 e->usage = 00775 "Usage: indication remove <country> [indication]\n" 00776 " Remove the given indication from the country.\n"; 00777 return NULL; 00778 case CLI_GENERATE: 00779 if (a->pos == 2) { 00780 return complete_country(a); 00781 } else if (a->pos == 3) { 00782 return complete_indications(a); 00783 } 00784 } 00785 00786 if (a->argc != 3 && a->argc != 4) { 00787 return CLI_SHOWUSAGE; 00788 } 00789 00790 if (a->argc == 3) { 00791 /* remove entire country */ 00792 if (ast_unregister_indication_country(a->argv[2])) { 00793 ast_log(LOG_WARNING, "Unable to unregister indication country %s\n", a->argv[2]); 00794 return CLI_FAILURE; 00795 } 00796 00797 return CLI_SUCCESS; 00798 } 00799 00800 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00801 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n", a->argv[2], a->argv[3]); 00802 return CLI_FAILURE; 00803 } 00804 00805 if (ast_unregister_indication(tz, a->argv[3])) { 00806 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n", a->argv[2], a->argv[3]); 00807 res = CLI_FAILURE; 00808 } 00809 00810 tz = ast_tone_zone_unref(tz); 00811 00812 return res; 00813 }
static char* handle_cli_indication_show | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 815 of file indications.c.
References ao2_find, ao2_iterator_destroy(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, 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_unlock, ast_tone_zone_unref(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, complete_country(), ast_tone_zone::country, ast_tone_zone_sound::data, ast_tone_zone::description, ast_cli_args::fd, ast_tone_zone_sound::name, ast_tone_zone::nrringcadence, OBJ_POINTER, ast_tone_zone::ringcadence, tz, and ast_cli_entry::usage.
00816 { 00817 struct ast_tone_zone *tz = NULL; 00818 struct ast_str *buf; 00819 int found_country = 0; 00820 int i; 00821 00822 switch (cmd) { 00823 case CLI_INIT: 00824 e->command = "indication show"; 00825 e->usage = 00826 "Usage: indication show [<country> ...]\n" 00827 " Display either a condensed summary of all countries and indications, or a\n" 00828 " more verbose list of indications for the specified countries.\n"; 00829 return NULL; 00830 case CLI_GENERATE: 00831 return complete_country(a); 00832 } 00833 00834 if (a->argc == 2) { 00835 struct ao2_iterator iter; 00836 /* no arguments, show a list of countries */ 00837 ast_cli(a->fd, "Country Description\n"); 00838 ast_cli(a->fd, "===========================\n"); 00839 iter = ast_tone_zone_iterator_init(); 00840 while ((tz = ao2_iterator_next(&iter))) { 00841 ast_tone_zone_lock(tz); 00842 ast_cli(a->fd, "%-7.7s %s\n", tz->country, tz->description); 00843 ast_tone_zone_unlock(tz); 00844 tz = ast_tone_zone_unref(tz); 00845 } 00846 ao2_iterator_destroy(&iter); 00847 return CLI_SUCCESS; 00848 } 00849 00850 buf = ast_str_alloca(256); 00851 00852 for (i = 2; i < a->argc; i++) { 00853 struct ast_tone_zone zone_arg = { 00854 .nrringcadence = 0, 00855 }; 00856 struct ast_tone_zone_sound *ts; 00857 int j; 00858 00859 ast_copy_string(zone_arg.country, a->argv[i], sizeof(zone_arg.country)); 00860 00861 if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) { 00862 continue; 00863 } 00864 00865 if (!found_country) { 00866 found_country = 1; 00867 ast_cli(a->fd, "Country Indication PlayList\n"); 00868 ast_cli(a->fd, "=====================================\n"); 00869 } 00870 00871 ast_tone_zone_lock(tz); 00872 00873 ast_str_set(&buf, 0, "%-7.7s %-15.15s ", tz->country, "<ringcadence>"); 00874 for (j = 0; j < tz->nrringcadence; j++) { 00875 ast_str_append(&buf, 0, "%d%s", tz->ringcadence[j], 00876 (j == tz->nrringcadence - 1) ? "" : ","); 00877 } 00878 ast_str_append(&buf, 0, "\n"); 00879 ast_cli(a->fd, "%s", ast_str_buffer(buf)); 00880 00881 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00882 ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data); 00883 } 00884 00885 ast_tone_zone_unlock(tz); 00886 tz = ast_tone_zone_unref(tz); 00887 } 00888 00889 if (!found_country) { 00890 ast_cli(a->fd, "No countries matched your criteria.\n"); 00891 } 00892 00893 return CLI_SUCCESS; 00894 }
static void indications_shutdown | ( | void | ) | [static] |
Definition at line 1155 of file indications.c.
References ao2_ref, ARRAY_LEN, ast_cli_unregister_multiple(), and ast_tone_zone_unref().
Referenced by ast_indications_init().
01156 { 01157 ast_cli_unregister_multiple(cli_indications, ARRAY_LEN(cli_indications)); 01158 if (default_tone_zone) { 01159 ast_tone_zone_unref(default_tone_zone); 01160 default_tone_zone = NULL; 01161 } 01162 if (ast_tone_zones) { 01163 ao2_ref(ast_tone_zones, -1); 01164 ast_tone_zones = NULL; 01165 } 01166 }
static int is_valid_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 896 of file indications.c.
References AST_LIST_EMPTY, ast_strlen_zero(), ast_tone_zone_lock, ast_tone_zone_unlock, and ast_tone_zone::description.
Referenced by parse_tone_zone().
00897 { 00898 int res; 00899 00900 ast_tone_zone_lock(zone); 00901 res = (!ast_strlen_zero(zone->description) && !AST_LIST_EMPTY(&zone->tones)); 00902 ast_tone_zone_unlock(zone); 00903 00904 return res; 00905 }
static int load_indications | ( | int | reload | ) | [static] |
load indications module
Definition at line 1052 of file indications.c.
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_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, country, LOG_WARNING, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, parse_tone_zone(), prune_tone_zone(), and tone_zone_mark().
Referenced by ast_indications_init(), and ast_indications_reload().
01053 { 01054 struct ast_config *cfg; 01055 const char *cxt = NULL; 01056 const char *country = NULL; 01057 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 01058 int res = -1; 01059 01060 cfg = ast_config_load2(config, "indications", config_flags); 01061 01062 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) { 01063 ast_log(LOG_WARNING, "Can't find indications config file %s.\n", config); 01064 return 0; 01065 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 01066 return 0; 01067 } 01068 01069 /* Lock the container to prevent multiple simultaneous reloads */ 01070 ao2_lock(ast_tone_zones); 01071 01072 ao2_callback(ast_tone_zones, OBJ_NODATA, tone_zone_mark, NULL); 01073 01074 /* Use existing config to populate the Indication table */ 01075 while ((cxt = ast_category_browse(cfg, cxt))) { 01076 /* All categories but "general" are considered countries */ 01077 if (!strcasecmp(cxt, "general")) { 01078 continue; 01079 } 01080 01081 if (parse_tone_zone(cfg, cxt)) { 01082 goto return_cleanup; 01083 } 01084 } 01085 01086 ao2_callback(ast_tone_zones, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, 01087 prune_tone_zone, NULL); 01088 01089 /* determine which country is the default */ 01090 country = ast_variable_retrieve(cfg, "general", "country"); 01091 if (ast_strlen_zero(country) || ast_set_indication_country(country)) { 01092 ast_log(LOG_WARNING, "Unable to set the default country (for indication tones)\n"); 01093 } 01094 01095 res = 0; 01096 01097 return_cleanup: 01098 ao2_unlock(ast_tone_zones); 01099 ast_config_destroy(cfg); 01100 01101 return res; 01102 }
static int parse_tone_zone | ( | struct ast_config * | cfg, | |
const char * | country | |||
) | [static] |
Definition at line 965 of file indications.c.
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_variable_browse(), 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().
00966 { 00967 struct ast_variable *v; 00968 struct ast_tone_zone *zone; 00969 struct ast_tone_zone tmp_zone = { 00970 .nrringcadence = 0, 00971 }; 00972 int allocd = 0; 00973 00974 ast_copy_string(tmp_zone.country, country, sizeof(tmp_zone.country)); 00975 00976 if ((zone = ao2_find(ast_tone_zones, &tmp_zone, OBJ_POINTER))) { 00977 reset_tone_zone(zone); 00978 } else if ((zone = ast_tone_zone_alloc())) { 00979 allocd = 1; 00980 ast_copy_string(zone->country, country, sizeof(zone->country)); 00981 } else { 00982 return -1; 00983 } 00984 00985 ast_tone_zone_lock(zone); 00986 for (v = ast_variable_browse(cfg, country); v; v = v->next) { 00987 store_config_tone_zone(zone, v->name, v->value); 00988 } 00989 ast_tone_zone_unlock(zone); 00990 00991 if (allocd) { 00992 if (!is_valid_tone_zone(zone)) { 00993 ast_log(LOG_WARNING, "Indication country '%s' is invalid\n", country); 00994 } else if (ast_register_indication_country(zone)) { 00995 ast_log(LOG_WARNING, "Unable to register indication country '%s'.\n", 00996 country); 00997 } 00998 } 00999 01000 zone = ast_tone_zone_unref(zone); 01001 01002 return 0; 01003 }
static void* playtones_alloc | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 145 of file indications.c.
References ast_calloc, ast_clear_flag, AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, 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, playtones_state::oldnpos, playtones_state::origwfmt, playtones_release(), playtones_def::reppos, playtones_state::reppos, playtones_def::vol, playtones_state::vol, and ast_channel::writeformat.
00146 { 00147 struct playtones_def *pd = params; 00148 struct playtones_state *ps = NULL; 00149 00150 if (!(ps = ast_calloc(1, sizeof(*ps)))) { 00151 return NULL; 00152 } 00153 00154 ps->origwfmt = chan->writeformat; 00155 00156 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 00157 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 00158 playtones_release(NULL, ps); 00159 ps = NULL; 00160 } else { 00161 ps->vol = pd->vol; 00162 ps->reppos = pd->reppos; 00163 ps->nitems = pd->nitems; 00164 ps->items = pd->items; 00165 ps->oldnpos = -1; 00166 } 00167 00168 /* Let interrupts interrupt :) */ 00169 if (pd->interruptible) { 00170 ast_set_flag(chan, AST_FLAG_WRITE_INT); 00171 } else { 00172 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 00173 } 00174 00175 return ps; 00176 }
static int playtones_generator | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | len, | |||
int | samples | |||
) | [static] |
Definition at line 178 of file indications.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), ast_frame_subclass::codec, ast_frame::data, playtones_state::data, ast_frame::datalen, playtones_item::duration, playtones_state::f, playtones_item::fac1, playtones_item::fac2, 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, 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.
00179 { 00180 struct playtones_state *ps = data; 00181 struct playtones_item *pi; 00182 int x; 00183 00184 /* we need to prepare a frame with 16 * timelen samples as we're 00185 * generating SLIN audio */ 00186 00187 len = samples * 2; 00188 if (len > sizeof(ps->data) / 2 - 1) { 00189 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 00190 return -1; 00191 } 00192 00193 memset(&ps->f, 0, sizeof(ps->f)); 00194 00195 pi = &ps->items[ps->npos]; 00196 00197 if (ps->oldnpos != ps->npos) { 00198 /* Load new parameters */ 00199 ps->v1_1 = 0; 00200 ps->v2_1 = pi->init_v2_1; 00201 ps->v3_1 = pi->init_v3_1; 00202 ps->v1_2 = 0; 00203 ps->v2_2 = pi->init_v2_2; 00204 ps->v3_2 = pi->init_v3_2; 00205 ps->oldnpos = ps->npos; 00206 } 00207 00208 for (x = 0; x < samples; x++) { 00209 ps->v1_1 = ps->v2_1; 00210 ps->v2_1 = ps->v3_1; 00211 ps->v3_1 = (pi->fac1 * ps->v2_1 >> 15) - ps->v1_1; 00212 00213 ps->v1_2 = ps->v2_2; 00214 ps->v2_2 = ps->v3_2; 00215 ps->v3_2 = (pi->fac2 * ps->v2_2 >> 15) - ps->v1_2; 00216 if (pi->modulate) { 00217 int p; 00218 p = ps->v3_2 - 32768; 00219 if (p < 0) { 00220 p = -p; 00221 } 00222 p = ((p * 9) / 10) + 1; 00223 ps->data[x] = (ps->v3_1 * p) >> 15; 00224 } else { 00225 ps->data[x] = ps->v3_1 + ps->v3_2; 00226 } 00227 } 00228 00229 ps->f.frametype = AST_FRAME_VOICE; 00230 ps->f.subclass.codec = AST_FORMAT_SLINEAR; 00231 ps->f.datalen = len; 00232 ps->f.samples = samples; 00233 ps->f.offset = AST_FRIENDLY_OFFSET; 00234 ps->f.data.ptr = ps->data; 00235 00236 if (ast_write(chan, &ps->f)) { 00237 return -1; 00238 } 00239 00240 ps->pos += x; 00241 00242 if (pi->duration && ps->pos >= pi->duration * 8) { /* item finished? */ 00243 ps->pos = 0; /* start new item */ 00244 ps->npos++; 00245 if (ps->npos >= ps->nitems) { /* last item? */ 00246 if (ps->reppos == -1) { /* repeat set? */ 00247 return -1; 00248 } 00249 ps->npos = ps->reppos; /* redo from top */ 00250 } 00251 } 00252 00253 return 0; 00254 }
static void playtones_release | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 129 of file indications.c.
References ast_free, ast_set_write_format(), playtones_state::items, and playtones_state::origwfmt.
Referenced by playtones_alloc().
00130 { 00131 struct playtones_state *ps = params; 00132 00133 if (chan) { 00134 ast_set_write_format(chan, ps->origwfmt); 00135 } 00136 00137 if (ps->items) { 00138 ast_free(ps->items); 00139 ps->items = NULL; 00140 } 00141 00142 ast_free(ps); 00143 }
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 1031 of file indications.c.
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::killme, and ast_tone_zone_sound::killme.
Referenced by load_indications().
01032 { 01033 struct ast_tone_zone *zone = obj; 01034 struct ast_tone_zone_sound *s; 01035 01036 ast_tone_zone_lock(zone); 01037 01038 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, s, entry) { 01039 if (s->killme) { 01040 AST_LIST_REMOVE_CURRENT(entry); 01041 s = ast_tone_zone_sound_unref(s); 01042 } 01043 } 01044 AST_LIST_TRAVERSE_SAFE_END; 01045 01046 ast_tone_zone_unlock(zone); 01047 01048 return zone->killme ? CMP_MATCH : 0; 01049 }
static void reset_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 950 of file indications.c.
References ast_free, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone::killme, ast_tone_zone::nrringcadence, and ast_tone_zone::ringcadence.
Referenced by parse_tone_zone().
00951 { 00952 ast_tone_zone_lock(zone); 00953 00954 zone->killme = 0; 00955 00956 if (zone->nrringcadence) { 00957 zone->nrringcadence = 0; 00958 ast_free(zone->ringcadence); 00959 zone->ringcadence = NULL; 00960 } 00961 00962 ast_tone_zone_unlock(zone); 00963 }
static void store_config_tone_zone | ( | struct ast_tone_zone * | zone, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Definition at line 937 of file indications.c.
References ast_register_indication(), CV_END, CV_F, CV_START, CV_STR, ast_tone_zone::description, and store_tone_zone_ring_cadence().
Referenced by parse_tone_zone().
00939 { 00940 CV_START(var, value); 00941 00942 CV_STR("description", zone->description); 00943 CV_F("ringcadence", store_tone_zone_ring_cadence(zone, value)); 00944 00945 ast_register_indication(zone, var, value); 00946 00947 CV_END; 00948 }
static void store_tone_zone_ring_cadence | ( | struct ast_tone_zone * | zone, | |
const char * | val | |||
) | [static] |
Definition at line 910 of file indications.c.
References ast_copy_string(), ast_log(), ast_realloc, ast_strip(), LOG_WARNING, ast_tone_zone::nrringcadence, and ast_tone_zone::ringcadence.
Referenced by store_config_tone_zone().
00911 { 00912 char buf[1024]; 00913 char *ring, *c = buf; 00914 00915 ast_copy_string(buf, val, sizeof(buf)); 00916 00917 while ((ring = strsep(&c, ","))) { 00918 int *tmp, val; 00919 00920 ring = ast_strip(ring); 00921 00922 if (!isdigit(ring[0]) || (val = atoi(ring)) == -1) { 00923 ast_log(LOG_WARNING, "Invalid ringcadence given '%s'.\n", ring); 00924 continue; 00925 } 00926 00927 if (!(tmp = ast_realloc(zone->ringcadence, (zone->nrringcadence + 1) * sizeof(int)))) { 00928 return; 00929 } 00930 00931 zone->ringcadence = tmp; 00932 tmp[zone->nrringcadence] = val; 00933 zone->nrringcadence++; 00934 } 00935 }
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 1009 of file indications.c.
References AST_LIST_TRAVERSE, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_sound::killme, and ast_tone_zone::killme.
Referenced by load_indications().
01010 { 01011 struct ast_tone_zone *zone = obj; 01012 struct ast_tone_zone_sound *s; 01013 01014 ast_tone_zone_lock(zone); 01015 01016 zone->killme = 1; 01017 01018 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01019 s->killme = 1; 01020 } 01021 01022 ast_tone_zone_unlock(zone); 01023 01024 return 0; 01025 }
struct ao2_container* ast_tone_zones [static] |
Definition at line 81 of file indications.c.
struct ast_cli_entry cli_indications[] [static] |
{ AST_CLI_DEFINE(handle_cli_indication_add, "Add the given indication to the country"), AST_CLI_DEFINE(handle_cli_indication_remove, "Remove the given indication from the country"), AST_CLI_DEFINE(handle_cli_indication_show, "Display a list of all countries/indications") }
CLI entries for commands provided by this module.
Definition at line 1105 of file indications.c.
const char config[] = "indications.conf" [static] |
Definition at line 63 of file indications.c.
struct ast_tone_zone* default_tone_zone [static] |
Definition at line 88 of file indications.c.
const int midi_tohz[128] [static] |
Definition at line 65 of file indications.c.
struct ast_generator playtones [static] |
{ .alloc = playtones_alloc, .release = playtones_release, .generate = playtones_generator, }
Definition at line 256 of file indications.c.