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 470 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().
00471 { 00472 struct ast_tone_zone_sound *ts = NULL; 00473 /* _zone is const to the users of the API */ 00474 struct ast_tone_zone *zone = (struct ast_tone_zone *) _zone; 00475 00476 /* If no zone is specified, use the default */ 00477 if (!zone) { 00478 ao2_lock(ast_tone_zones); 00479 if (default_tone_zone) { 00480 zone = ast_tone_zone_ref(default_tone_zone); 00481 } 00482 ao2_unlock(ast_tone_zones); 00483 00484 if (!zone) { 00485 return NULL; 00486 } 00487 } 00488 00489 ast_tone_zone_lock(zone); 00490 00491 /* Look through list of tones in the zone searching for the right one */ 00492 AST_LIST_TRAVERSE(&zone->tones, ts, entry) { 00493 if (!strcasecmp(ts->name, indication)) { 00494 /* Increase ref count for the reference we will return */ 00495 ts = ast_tone_zone_sound_ref(ts); 00496 break; 00497 } 00498 } 00499 00500 ast_tone_zone_unlock(zone); 00501 00502 return ts; 00503 }
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 448 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().
00449 { 00450 struct ast_tone_zone *tz = NULL; 00451 struct ast_tone_zone zone_arg = { 00452 .nrringcadence = 0, 00453 }; 00454 00455 if (ast_strlen_zero(country)) { 00456 ao2_lock(ast_tone_zones); 00457 if (default_tone_zone) { 00458 tz = ast_tone_zone_ref(default_tone_zone); 00459 } 00460 ao2_unlock(ast_tone_zones); 00461 00462 return tz; 00463 } 00464 00465 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country)); 00466 00467 return ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER); 00468 }
int ast_indications_init | ( | void | ) |
Load indications module.
Provided by indications.c
Definition at line 1166 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().
01167 { 01168 if (!(ast_tone_zones = ao2_container_alloc(NUM_TONE_ZONE_BUCKETS, 01169 ast_tone_zone_hash, ast_tone_zone_cmp))) { 01170 return -1; 01171 } 01172 01173 if (load_indications(0)) { 01174 indications_shutdown(); 01175 return -1; 01176 } 01177 01178 ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications)); 01179 01180 ast_register_atexit(indications_shutdown); 01181 return 0; 01182 }
int ast_indications_reload | ( | void | ) |
Reload indications module.
Provided by indications.c
Definition at line 1185 of file indications.c.
References load_indications().
01186 { 01187 return load_indications(1); 01188 }
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 ast_tone_zone_part tone_data = { 00345 .time = 0, 00346 }; 00347 00348 s = ast_strip(s); 00349 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 if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) { 00378 return -1; 00379 } 00380 00381 d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (tone_data.freq1 / sample_rate)) * max_sample_val; 00382 d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol; 00383 d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol; 00384 00385 d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (tone_data.freq2 / sample_rate)) * max_sample_val; 00386 d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol; 00387 d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol; 00388 00389 d.items[d.nitems].duration = tone_data.time; 00390 d.items[d.nitems].modulate = tone_data.modulate; 00391 00392 d.nitems++; 00393 } 00394 00395 if (!d.nitems) { 00396 ast_log(LOG_ERROR, "No valid tone parts\n"); 00397 return -1; 00398 } 00399 00400 if (ast_activate_generator(chan, &playtones, &d)) { 00401 ast_free(d.items); 00402 return -1; 00403 } 00404 00405 return 0; 00406 }
void ast_playtones_stop | ( | struct ast_channel * | chan | ) |
Stop playing tones on a channel.
chan | the channel to stop tones on |
Definition at line 408 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().
00409 { 00410 ast_deactivate_generator(chan); 00411 }
static int ast_register_indication | ( | struct ast_tone_zone * | zone, | |
const char * | indication, | |||
const char * | tonelist | |||
) | [static] |
Definition at line 585 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().
00587 { 00588 struct ast_tone_zone_sound *ts; 00589 00590 if (ast_strlen_zero(indication) || ast_strlen_zero(tonelist)) { 00591 return -1; 00592 } 00593 00594 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) { 00595 if (!strcasecmp(indication, ts->name)) { 00596 AST_LIST_REMOVE_CURRENT(entry); 00597 ts = ast_tone_zone_sound_unref(ts); 00598 break; 00599 } 00600 } 00601 AST_LIST_TRAVERSE_SAFE_END; 00602 00603 if (!(ts = ao2_alloc(sizeof(*ts), ast_tone_zone_sound_destructor))) { 00604 return -1; 00605 } 00606 00607 if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) { 00608 ts = ast_tone_zone_sound_unref(ts); 00609 return -1; 00610 } 00611 00612 AST_LIST_INSERT_TAIL(&zone->tones, ts, entry); /* Inherit reference */ 00613 00614 return 0; 00615 }
static int ast_register_indication_country | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 538 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().
00539 { 00540 ao2_lock(ast_tone_zones); 00541 if (!default_tone_zone) { 00542 default_tone_zone = ast_tone_zone_ref(zone); 00543 } 00544 ao2_unlock(ast_tone_zones); 00545 00546 ao2_link(ast_tone_zones, zone); 00547 00548 ast_verb(3, "Registered indication country '%s'\n", zone->country); 00549 00550 return 0; 00551 }
static int ast_set_indication_country | ( | const char * | country | ) | [static] |
Definition at line 424 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().
00425 { 00426 struct ast_tone_zone *zone = NULL; 00427 00428 /* If no country is specified or we are unable to find the zone, then return not found */ 00429 if (ast_strlen_zero(country) || !(zone = ast_get_indication_zone(country))) { 00430 return -1; 00431 } 00432 00433 ast_verb(3, "Setting default indication country to '%s'\n", country); 00434 00435 ao2_lock(ast_tone_zones); 00436 if (default_tone_zone) { 00437 default_tone_zone = ast_tone_zone_unref(default_tone_zone); 00438 } 00439 default_tone_zone = ast_tone_zone_ref(zone); 00440 ao2_unlock(ast_tone_zones); 00441 00442 zone = ast_tone_zone_unref(zone); 00443 00444 return 0; 00445 }
static struct ast_tone_zone* ast_tone_zone_alloc | ( | void | ) | [static, read] |
Definition at line 640 of file indications.c.
References ao2_alloc, and ast_tone_zone_destructor().
Referenced by handle_cli_indication_add(), and parse_tone_zone().
00641 { 00642 return ao2_alloc(sizeof(struct ast_tone_zone), ast_tone_zone_destructor); 00643 }
static int ast_tone_zone_cmp | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1115 of file indications.c.
References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.
Referenced by ast_indications_init().
01116 { 01117 struct ast_tone_zone *zone = obj; 01118 struct ast_tone_zone *zone_arg = arg; 01119 01120 return (!strcasecmp(zone->country, zone_arg->country)) ? 01121 CMP_MATCH | CMP_STOP : 0; 01122 }
int ast_tone_zone_count | ( | void | ) |
Get the number of registered tone zones.
Definition at line 413 of file indications.c.
References ao2_container_count().
00414 { 00415 return ao2_container_count(ast_tone_zones); 00416 }
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 1124 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().
01125 { 01126 struct ast_data *data_zone_sound; 01127 struct ast_tone_zone_sound *s; 01128 01129 ast_data_add_structure(ast_tone_zone, tree, zone); 01130 01131 if (AST_LIST_EMPTY(&zone->tones)) { 01132 return 0; 01133 } 01134 01135 data_zone_sound = ast_data_add_node(tree, "tones"); 01136 if (!data_zone_sound) { 01137 return -1; 01138 } 01139 01140 ast_tone_zone_lock(zone); 01141 01142 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01143 ast_data_add_structure(ast_tone_zone_sound, data_zone_sound, s); 01144 } 01145 01146 ast_tone_zone_unlock(zone); 01147 01148 return 0; 01149 }
static void ast_tone_zone_destructor | ( | void * | obj | ) | [static] |
deallocate the passed tone zone
Definition at line 522 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().
00523 { 00524 struct ast_tone_zone *zone = obj; 00525 struct ast_tone_zone_sound *current; 00526 00527 while ((current = AST_LIST_REMOVE_HEAD(&zone->tones, entry))) { 00528 current = ast_tone_zone_sound_unref(current); 00529 } 00530 00531 if (zone->ringcadence) { 00532 ast_free(zone->ringcadence); 00533 zone->ringcadence = NULL; 00534 } 00535 }
static int ast_tone_zone_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1108 of file indications.c.
References ast_str_case_hash(), and ast_tone_zone::country.
Referenced by ast_indications_init().
01109 { 01110 const struct ast_tone_zone *zone = obj; 01111 01112 return ast_str_case_hash(zone->country); 01113 }
struct ao2_iterator ast_tone_zone_iterator_init | ( | void | ) | [read] |
Get an iterator for the available tone zones.
Definition at line 418 of file indications.c.
References ao2_iterator_init().
Referenced by ast_var_indications(), ast_var_indications_table(), and handle_cli_indication_show().
00419 { 00420 return ao2_iterator_init(ast_tone_zones, 0); 00421 }
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 505 of file indications.c.
References ast_free, ast_tone_zone_sound::data, and ast_tone_zone_sound::name.
Referenced by ast_register_indication().
00506 { 00507 struct ast_tone_zone_sound *ts = obj; 00508 00509 /* Deconstify the 'const char *'s so the compiler doesn't complain. (but it's safe) */ 00510 if (ts->name) { 00511 ast_free((char *) ts->name); 00512 ts->name = NULL; 00513 } 00514 00515 if (ts->data) { 00516 ast_free((char *) ts->data); 00517 ts->data = NULL; 00518 } 00519 }
static int ast_unregister_indication | ( | struct ast_tone_zone * | zone, | |
const char * | indication | |||
) | [static] |
Definition at line 618 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().
00619 { 00620 struct ast_tone_zone_sound *ts; 00621 int res = -1; 00622 00623 ast_tone_zone_lock(zone); 00624 00625 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) { 00626 if (!strcasecmp(indication, ts->name)) { 00627 AST_LIST_REMOVE_CURRENT(entry); 00628 ts = ast_tone_zone_sound_unref(ts); 00629 res = 0; 00630 break; 00631 } 00632 } 00633 AST_LIST_TRAVERSE_SAFE_END; 00634 00635 ast_tone_zone_unlock(zone); 00636 00637 return res; 00638 }
static int ast_unregister_indication_country | ( | const char * | country | ) | [static] |
Definition at line 554 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().
00555 { 00556 struct ast_tone_zone *tz = NULL; 00557 struct ast_tone_zone zone_arg = { 00558 .nrringcadence = 0, 00559 }; 00560 00561 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country)); 00562 00563 ao2_lock(ast_tone_zones); 00564 tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER | OBJ_UNLINK); 00565 if (!tz) { 00566 ao2_unlock(ast_tone_zones); 00567 return -1; 00568 } 00569 00570 if (default_tone_zone == tz) { 00571 ast_tone_zone_unref(default_tone_zone); 00572 /* Get a new default, punt to the first one we find */ 00573 default_tone_zone = ao2_callback(ast_tone_zones, 0, NULL, NULL); 00574 } 00575 ao2_unlock(ast_tone_zones); 00576 00577 tz = ast_tone_zone_unref(tz); 00578 00579 return 0; 00580 }
static char* complete_country | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 645 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().
00646 { 00647 char *res = NULL; 00648 struct ao2_iterator i; 00649 int which = 0; 00650 size_t wordlen; 00651 struct ast_tone_zone *tz; 00652 00653 wordlen = strlen(a->word); 00654 00655 i = ao2_iterator_init(ast_tone_zones, 0); 00656 while ((tz = ao2_iterator_next(&i))) { 00657 if (!strncasecmp(a->word, tz->country, wordlen) && ++which > a->n) { 00658 res = ast_strdup(tz->country); 00659 } 00660 tz = ast_tone_zone_unref(tz); 00661 if (res) { 00662 break; 00663 } 00664 } 00665 ao2_iterator_destroy(&i); 00666 00667 return res; 00668 }
static char* complete_indications | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 731 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().
00732 { 00733 char *res = NULL; 00734 int which = 0; 00735 size_t wordlen; 00736 struct ast_tone_zone_sound *ts; 00737 struct ast_tone_zone *tz, tmp_tz = { 00738 .nrringcadence = 0, 00739 }; 00740 00741 ast_copy_string(tmp_tz.country, a->argv[a->pos - 1], sizeof(tmp_tz.country)); 00742 00743 if (!(tz = ao2_find(ast_tone_zones, &tmp_tz, OBJ_POINTER))) { 00744 return NULL; 00745 } 00746 00747 wordlen = strlen(a->word); 00748 00749 ast_tone_zone_lock(tz); 00750 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00751 if (!strncasecmp(a->word, ts->name, wordlen) && ++which > a->n) { 00752 res = ast_strdup(ts->name); 00753 break; 00754 } 00755 } 00756 ast_tone_zone_unlock(tz); 00757 00758 tz = ast_tone_zone_unref(tz); 00759 00760 return res; 00761 }
static char* handle_cli_indication_add | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 670 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.
00671 { 00672 struct ast_tone_zone *tz; 00673 int created_country = 0; 00674 char *res = CLI_SUCCESS; 00675 00676 switch (cmd) { 00677 case CLI_INIT: 00678 e->command = "indication add"; 00679 e->usage = 00680 "Usage: indication add <country> <indication> \"<tonelist>\"\n" 00681 " Add the given indication to the country.\n"; 00682 return NULL; 00683 case CLI_GENERATE: 00684 if (a->pos == 2) { 00685 return complete_country(a); 00686 } else { 00687 return NULL; 00688 } 00689 } 00690 00691 if (a->argc != 5) { 00692 return CLI_SHOWUSAGE; 00693 } 00694 00695 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00696 /* country does not exist, create it */ 00697 ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n", a->argv[2]); 00698 00699 if (!(tz = ast_tone_zone_alloc())) { 00700 return CLI_FAILURE; 00701 } 00702 00703 ast_copy_string(tz->country, a->argv[2], sizeof(tz->country)); 00704 00705 if (ast_register_indication_country(tz)) { 00706 ast_log(LOG_WARNING, "Unable to register new country\n"); 00707 tz = ast_tone_zone_unref(tz); 00708 return CLI_FAILURE; 00709 } 00710 00711 created_country = 1; 00712 } 00713 00714 ast_tone_zone_lock(tz); 00715 00716 if (ast_register_indication(tz, a->argv[3], a->argv[4])) { 00717 ast_log(LOG_WARNING, "Unable to register indication %s/%s\n", a->argv[2], a->argv[3]); 00718 if (created_country) { 00719 ast_unregister_indication_country(a->argv[2]); 00720 } 00721 res = CLI_FAILURE; 00722 } 00723 00724 ast_tone_zone_unlock(tz); 00725 00726 tz = ast_tone_zone_unref(tz); 00727 00728 return res; 00729 }
static char* handle_cli_indication_remove | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 763 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.
00764 { 00765 struct ast_tone_zone *tz; 00766 char *res = CLI_SUCCESS; 00767 00768 switch (cmd) { 00769 case CLI_INIT: 00770 e->command = "indication remove"; 00771 e->usage = 00772 "Usage: indication remove <country> [indication]\n" 00773 " Remove the given indication from the country.\n"; 00774 return NULL; 00775 case CLI_GENERATE: 00776 if (a->pos == 2) { 00777 return complete_country(a); 00778 } else if (a->pos == 3) { 00779 return complete_indications(a); 00780 } 00781 } 00782 00783 if (a->argc != 3 && a->argc != 4) { 00784 return CLI_SHOWUSAGE; 00785 } 00786 00787 if (a->argc == 3) { 00788 /* remove entire country */ 00789 if (ast_unregister_indication_country(a->argv[2])) { 00790 ast_log(LOG_WARNING, "Unable to unregister indication country %s\n", a->argv[2]); 00791 return CLI_FAILURE; 00792 } 00793 00794 return CLI_SUCCESS; 00795 } 00796 00797 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00798 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n", a->argv[2], a->argv[3]); 00799 return CLI_FAILURE; 00800 } 00801 00802 if (ast_unregister_indication(tz, a->argv[3])) { 00803 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n", a->argv[2], a->argv[3]); 00804 res = CLI_FAILURE; 00805 } 00806 00807 tz = ast_tone_zone_unref(tz); 00808 00809 return res; 00810 }
static char* handle_cli_indication_show | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 812 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.
00813 { 00814 struct ast_tone_zone *tz = NULL; 00815 struct ast_str *buf; 00816 int found_country = 0; 00817 int i; 00818 00819 switch (cmd) { 00820 case CLI_INIT: 00821 e->command = "indication show"; 00822 e->usage = 00823 "Usage: indication show [<country> ...]\n" 00824 " Display either a condensed summary of all countries and indications, or a\n" 00825 " more verbose list of indications for the specified countries.\n"; 00826 return NULL; 00827 case CLI_GENERATE: 00828 return complete_country(a); 00829 } 00830 00831 if (a->argc == 2) { 00832 struct ao2_iterator iter; 00833 /* no arguments, show a list of countries */ 00834 ast_cli(a->fd, "Country Description\n"); 00835 ast_cli(a->fd, "===========================\n"); 00836 iter = ast_tone_zone_iterator_init(); 00837 while ((tz = ao2_iterator_next(&iter))) { 00838 ast_tone_zone_lock(tz); 00839 ast_cli(a->fd, "%-7.7s %s\n", tz->country, tz->description); 00840 ast_tone_zone_unlock(tz); 00841 tz = ast_tone_zone_unref(tz); 00842 } 00843 ao2_iterator_destroy(&iter); 00844 return CLI_SUCCESS; 00845 } 00846 00847 buf = ast_str_alloca(256); 00848 00849 for (i = 2; i < a->argc; i++) { 00850 struct ast_tone_zone zone_arg = { 00851 .nrringcadence = 0, 00852 }; 00853 struct ast_tone_zone_sound *ts; 00854 int j; 00855 00856 ast_copy_string(zone_arg.country, a->argv[i], sizeof(zone_arg.country)); 00857 00858 if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) { 00859 continue; 00860 } 00861 00862 if (!found_country) { 00863 found_country = 1; 00864 ast_cli(a->fd, "Country Indication PlayList\n"); 00865 ast_cli(a->fd, "=====================================\n"); 00866 } 00867 00868 ast_tone_zone_lock(tz); 00869 00870 ast_str_set(&buf, 0, "%-7.7s %-15.15s ", tz->country, "<ringcadence>"); 00871 for (j = 0; j < tz->nrringcadence; j++) { 00872 ast_str_append(&buf, 0, "%d%s", tz->ringcadence[j], 00873 (j == tz->nrringcadence - 1) ? "" : ","); 00874 } 00875 ast_str_append(&buf, 0, "\n"); 00876 ast_cli(a->fd, "%s", ast_str_buffer(buf)); 00877 00878 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00879 ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data); 00880 } 00881 00882 ast_tone_zone_unlock(tz); 00883 tz = ast_tone_zone_unref(tz); 00884 } 00885 00886 if (!found_country) { 00887 ast_cli(a->fd, "No countries matched your criteria.\n"); 00888 } 00889 00890 return CLI_SUCCESS; 00891 }
static void indications_shutdown | ( | void | ) | [static] |
Definition at line 1152 of file indications.c.
References ao2_ref, ARRAY_LEN, ast_cli_unregister_multiple(), and ast_tone_zone_unref().
Referenced by ast_indications_init().
01153 { 01154 ast_cli_unregister_multiple(cli_indications, ARRAY_LEN(cli_indications)); 01155 if (default_tone_zone) { 01156 ast_tone_zone_unref(default_tone_zone); 01157 default_tone_zone = NULL; 01158 } 01159 if (ast_tone_zones) { 01160 ao2_ref(ast_tone_zones, -1); 01161 ast_tone_zones = NULL; 01162 } 01163 }
static int is_valid_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 893 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().
00894 { 00895 int res; 00896 00897 ast_tone_zone_lock(zone); 00898 res = (!ast_strlen_zero(zone->description) && !AST_LIST_EMPTY(&zone->tones)); 00899 ast_tone_zone_unlock(zone); 00900 00901 return res; 00902 }
static int load_indications | ( | int | reload | ) | [static] |
load indications module
Definition at line 1049 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().
01050 { 01051 struct ast_config *cfg; 01052 const char *cxt = NULL; 01053 const char *country = NULL; 01054 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 01055 int res = -1; 01056 01057 cfg = ast_config_load2(config, "indications", config_flags); 01058 01059 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) { 01060 ast_log(LOG_WARNING, "Can't find indications config file %s.\n", config); 01061 return 0; 01062 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 01063 return 0; 01064 } 01065 01066 /* Lock the container to prevent multiple simultaneous reloads */ 01067 ao2_lock(ast_tone_zones); 01068 01069 ao2_callback(ast_tone_zones, OBJ_NODATA, tone_zone_mark, NULL); 01070 01071 /* Use existing config to populate the Indication table */ 01072 while ((cxt = ast_category_browse(cfg, cxt))) { 01073 /* All categories but "general" are considered countries */ 01074 if (!strcasecmp(cxt, "general")) { 01075 continue; 01076 } 01077 01078 if (parse_tone_zone(cfg, cxt)) { 01079 goto return_cleanup; 01080 } 01081 } 01082 01083 ao2_callback(ast_tone_zones, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, 01084 prune_tone_zone, NULL); 01085 01086 /* determine which country is the default */ 01087 country = ast_variable_retrieve(cfg, "general", "country"); 01088 if (ast_strlen_zero(country) || ast_set_indication_country(country)) { 01089 ast_log(LOG_WARNING, "Unable to set the default country (for indication tones)\n"); 01090 } 01091 01092 res = 0; 01093 01094 return_cleanup: 01095 ao2_unlock(ast_tone_zones); 01096 ast_config_destroy(cfg); 01097 01098 return res; 01099 }
static int parse_tone_zone | ( | struct ast_config * | cfg, | |
const char * | country | |||
) | [static] |
Definition at line 962 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().
00963 { 00964 struct ast_variable *v; 00965 struct ast_tone_zone *zone; 00966 struct ast_tone_zone tmp_zone = { 00967 .nrringcadence = 0, 00968 }; 00969 int allocd = 0; 00970 00971 ast_copy_string(tmp_zone.country, country, sizeof(tmp_zone.country)); 00972 00973 if ((zone = ao2_find(ast_tone_zones, &tmp_zone, OBJ_POINTER))) { 00974 reset_tone_zone(zone); 00975 } else if ((zone = ast_tone_zone_alloc())) { 00976 allocd = 1; 00977 ast_copy_string(zone->country, country, sizeof(zone->country)); 00978 } else { 00979 return -1; 00980 } 00981 00982 ast_tone_zone_lock(zone); 00983 for (v = ast_variable_browse(cfg, country); v; v = v->next) { 00984 store_config_tone_zone(zone, v->name, v->value); 00985 } 00986 ast_tone_zone_unlock(zone); 00987 00988 if (allocd) { 00989 if (!is_valid_tone_zone(zone)) { 00990 ast_log(LOG_WARNING, "Indication country '%s' is invalid\n", country); 00991 } else if (ast_register_indication_country(zone)) { 00992 ast_log(LOG_WARNING, "Unable to register indication country '%s'.\n", 00993 country); 00994 } 00995 } 00996 00997 zone = ast_tone_zone_unref(zone); 00998 00999 return 0; 01000 }
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 1028 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().
01029 { 01030 struct ast_tone_zone *zone = obj; 01031 struct ast_tone_zone_sound *s; 01032 01033 ast_tone_zone_lock(zone); 01034 01035 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, s, entry) { 01036 if (s->killme) { 01037 AST_LIST_REMOVE_CURRENT(entry); 01038 s = ast_tone_zone_sound_unref(s); 01039 } 01040 } 01041 AST_LIST_TRAVERSE_SAFE_END; 01042 01043 ast_tone_zone_unlock(zone); 01044 01045 return zone->killme ? CMP_MATCH : 0; 01046 }
static void reset_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 947 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().
00948 { 00949 ast_tone_zone_lock(zone); 00950 00951 zone->killme = 0; 00952 00953 if (zone->nrringcadence) { 00954 zone->nrringcadence = 0; 00955 ast_free(zone->ringcadence); 00956 zone->ringcadence = NULL; 00957 } 00958 00959 ast_tone_zone_unlock(zone); 00960 }
static void store_config_tone_zone | ( | struct ast_tone_zone * | zone, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Definition at line 934 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().
00936 { 00937 CV_START(var, value); 00938 00939 CV_STR("description", zone->description); 00940 CV_F("ringcadence", store_tone_zone_ring_cadence(zone, value)); 00941 00942 ast_register_indication(zone, var, value); 00943 00944 CV_END; 00945 }
static void store_tone_zone_ring_cadence | ( | struct ast_tone_zone * | zone, | |
const char * | val | |||
) | [static] |
Definition at line 907 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().
00908 { 00909 char buf[1024]; 00910 char *ring, *c = buf; 00911 00912 ast_copy_string(buf, val, sizeof(buf)); 00913 00914 while ((ring = strsep(&c, ","))) { 00915 int *tmp, val; 00916 00917 ring = ast_strip(ring); 00918 00919 if (!isdigit(ring[0]) || (val = atoi(ring)) == -1) { 00920 ast_log(LOG_WARNING, "Invalid ringcadence given '%s'.\n", ring); 00921 continue; 00922 } 00923 00924 if (!(tmp = ast_realloc(zone->ringcadence, (zone->nrringcadence + 1) * sizeof(int)))) { 00925 return; 00926 } 00927 00928 zone->ringcadence = tmp; 00929 tmp[zone->nrringcadence] = val; 00930 zone->nrringcadence++; 00931 } 00932 }
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 1006 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().
01007 { 01008 struct ast_tone_zone *zone = obj; 01009 struct ast_tone_zone_sound *s; 01010 01011 ast_tone_zone_lock(zone); 01012 01013 zone->killme = 1; 01014 01015 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01016 s->killme = 1; 01017 } 01018 01019 ast_tone_zone_unlock(zone); 01020 01021 return 0; 01022 }
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 1102 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.