#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) | |
ast_tone_zone_sound * | ast_get_indication_tone (const struct ast_tone_zone *_zone, const char *indication) |
Locate a tone zone sound. | |
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) |
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 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 |
Russell Bryant <russell@digium.com>
Definition in file indications.c.
#define DATA_EXPORT_TONE_ZONE | ( | MEMBER | ) |
Value:
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 | ) |
Value:
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 |
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.
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, ast_tone_zones, default_tone_zone, ast_tone_zone_sound::name, and ast_tone_zone::tones.
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 | ) |
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_zones, ast_tone_zone::country, default_tone_zone, 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 1153 of file indications.c.
References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_tone_zone_cmp(), ast_tone_zone_hash(), ast_tone_zones, cli_indications, load_indications(), and NUM_TONE_ZONE_BUCKETS.
Referenced by main().
01154 { 01155 if (!(ast_tone_zones = ao2_container_alloc(NUM_TONE_ZONE_BUCKETS, 01156 ast_tone_zone_hash, ast_tone_zone_cmp))) { 01157 return -1; 01158 } 01159 01160 if (load_indications(0)) { 01161 return -1; 01162 } 01163 01164 ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications)); 01165 01166 return 0; 01167 }
int ast_indications_reload | ( | void | ) |
Reload indications module.
Provided by indications.c
Definition at line 1170 of file indications.c.
References load_indications().
01171 { 01172 return load_indications(1); 01173 }
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, playtones_def::reppos, strsep(), 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::entry, ast_tone_zone_sound::name, and ast_tone_zone::tones.
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_tone_zones, ast_verb, ast_tone_zone::country, and default_tone_zone.
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(), ast_tone_zones, ast_verb, and default_tone_zone.
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] |
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 1116 of file indications.c.
References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.
Referenced by ast_indications_init().
01117 { 01118 struct ast_tone_zone *zone = obj; 01119 struct ast_tone_zone *zone_arg = arg; 01120 01121 return (!strcasecmp(zone->country, zone_arg->country)) ? 01122 CMP_MATCH | CMP_STOP : 0; 01123 }
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(), and ast_tone_zones.
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 1125 of file indications.c.
References ast_data_add_node(), ast_data_add_structure, AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_sound::entry, and ast_tone_zone::tones.
Referenced by ast_channel_data_add_structure().
01126 { 01127 struct ast_data *data_zone_sound; 01128 struct ast_tone_zone_sound *s; 01129 01130 ast_data_add_structure(ast_tone_zone, tree, zone); 01131 01132 if (AST_LIST_EMPTY(&zone->tones)) { 01133 return 0; 01134 } 01135 01136 data_zone_sound = ast_data_add_node(tree, "tones"); 01137 if (!data_zone_sound) { 01138 return -1; 01139 } 01140 01141 ast_tone_zone_lock(zone); 01142 01143 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01144 ast_data_add_structure(ast_tone_zone_sound, data_zone_sound, s); 01145 } 01146 01147 ast_tone_zone_unlock(zone); 01148 01149 return 0; 01150 }
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(), ast_tone_zone_sound::entry, ast_tone_zone::ringcadence, and ast_tone_zone::tones.
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 1109 of file indications.c.
References ast_str_case_hash(), and ast_tone_zone::country.
Referenced by ast_indications_init().
01110 { 01111 const struct ast_tone_zone *zone = obj; 01112 01113 return ast_str_case_hash(zone->country); 01114 }
struct ao2_iterator ast_tone_zone_iterator_init | ( | void | ) |
Get an iterator for the available tone zones.
Use ao2_iterator_destroy() to clean up.
Definition at line 418 of file indications.c.
References ao2_iterator_init(), and ast_tone_zones.
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, ast_tone_zone_sound::entry, ast_tone_zone_sound::name, and ast_tone_zone::tones.
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_unlink, ao2_unlock, ast_copy_string(), ast_tone_zone_unref(), ast_tone_zones, ast_tone_zone::country, default_tone_zone, ast_tone_zone::nrringcadence, OBJ_POINTER, 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 if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) { 00564 return -1; 00565 } 00566 00567 ao2_lock(ast_tone_zones); 00568 if (default_tone_zone == tz) { 00569 ast_tone_zone_unref(default_tone_zone); 00570 /* Get a new default, punt to the first one we find */ 00571 default_tone_zone = ao2_callback(ast_tone_zones, 0, NULL, NULL); 00572 } 00573 ao2_unlock(ast_tone_zones); 00574 00575 ao2_unlink(ast_tone_zones, tz); 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_zones, 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_zones, 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(), 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_set(), ast_tone_zone_iterator_init(), ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_unref(), ast_tone_zones, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, complete_country(), ast_tone_zone_sound::data, ast_tone_zone_sound::entry, ast_cli_args::fd, ast_tone_zone_sound::name, OBJ_POINTER, 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", buf->str); 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 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, ast_tone_zone::description, and ast_tone_zone::tones.
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 1050 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_tone_zones, 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().
01051 { 01052 struct ast_config *cfg; 01053 const char *cxt = NULL; 01054 const char *country = NULL; 01055 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 01056 int res = -1; 01057 01058 cfg = ast_config_load2(config, "indications", config_flags); 01059 01060 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) { 01061 ast_log(LOG_WARNING, "Can't find indications config file %s.\n", config); 01062 return 0; 01063 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 01064 return 0; 01065 } 01066 01067 /* Lock the container to prevent multiple simultaneous reloads */ 01068 ao2_lock(ast_tone_zones); 01069 01070 ao2_callback(ast_tone_zones, OBJ_NODATA, tone_zone_mark, NULL); 01071 01072 /* Use existing config to populate the Indication table */ 01073 while ((cxt = ast_category_browse(cfg, cxt))) { 01074 /* All categories but "general" are considered countries */ 01075 if (!strcasecmp(cxt, "general")) { 01076 continue; 01077 } 01078 01079 if (parse_tone_zone(cfg, cxt)) { 01080 goto return_cleanup; 01081 } 01082 } 01083 01084 ao2_callback(ast_tone_zones, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, 01085 prune_tone_zone, NULL); 01086 01087 /* determine which country is the default */ 01088 country = ast_variable_retrieve(cfg, "general", "country"); 01089 if (ast_strlen_zero(country) || ast_set_indication_country(country)) { 01090 ast_log(LOG_WARNING, "Unable to set the default country (for indication tones)\n"); 01091 } 01092 01093 res = 0; 01094 01095 return_cleanup: 01096 ao2_unlock(ast_tone_zones); 01097 ast_config_destroy(cfg); 01098 01099 return res; 01100 }
static int parse_tone_zone | ( | struct ast_config * | cfg, | |
const char * | country | |||
) | [static] |
Definition at line 963 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_tone_zones, 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().
00964 { 00965 struct ast_variable *v; 00966 struct ast_tone_zone *zone; 00967 struct ast_tone_zone tmp_zone = { 00968 .nrringcadence = 0, 00969 }; 00970 int allocd = 0; 00971 00972 ast_copy_string(tmp_zone.country, country, sizeof(tmp_zone.country)); 00973 00974 if ((zone = ao2_find(ast_tone_zones, &tmp_zone, OBJ_POINTER))) { 00975 reset_tone_zone(zone); 00976 } else if ((zone = ast_tone_zone_alloc())) { 00977 allocd = 1; 00978 ast_copy_string(zone->country, country, sizeof(zone->country)); 00979 } else { 00980 return -1; 00981 } 00982 00983 ast_tone_zone_lock(zone); 00984 for (v = ast_variable_browse(cfg, country); v; v = v->next) { 00985 store_config_tone_zone(zone, v->name, v->value); 00986 } 00987 ast_tone_zone_unlock(zone); 00988 00989 if (allocd) { 00990 if (!is_valid_tone_zone(zone)) { 00991 ast_log(LOG_WARNING, "Indication country '%s' is invalid\n", country); 00992 } else if (ast_register_indication_country(zone)) { 00993 ast_log(LOG_WARNING, "Unable to register indication country '%s'.\n", 00994 country); 00995 } 00996 } 00997 00998 zone = ast_tone_zone_unref(zone); 00999 01000 return 0; 01001 }
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, LOG_WARNING, ast_channel::name, playtones_def::nitems, playtones_release(), playtones_def::reppos, playtones_def::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_log(), playtones_state::data, playtones_state::f, playtones_item::fac1, playtones_item::fac2, 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::npos, playtones_state::oldnpos, 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 1029 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_sound::entry, ast_tone_zone::killme, ast_tone_zone_sound::killme, and ast_tone_zone::tones.
Referenced by load_indications().
01030 { 01031 struct ast_tone_zone *zone = obj; 01032 struct ast_tone_zone_sound *s; 01033 01034 ast_tone_zone_lock(zone); 01035 01036 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, s, entry) { 01037 if (s->killme) { 01038 AST_LIST_REMOVE_CURRENT(entry); 01039 s = ast_tone_zone_sound_unref(s); 01040 } 01041 } 01042 AST_LIST_TRAVERSE_SAFE_END; 01043 01044 ast_tone_zone_unlock(zone); 01045 01046 return zone->killme ? CMP_MATCH : 0; 01047 }
static void reset_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 948 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().
00949 { 00950 ast_tone_zone_lock(zone); 00951 00952 zone->killme = 0; 00953 00954 if (zone->nrringcadence) { 00955 zone->nrringcadence = 0; 00956 ast_free(zone->ringcadence); 00957 zone->ringcadence = NULL; 00958 } 00959 00960 ast_tone_zone_unlock(zone); 00961 }
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 CV_F("ringcadance", store_tone_zone_ring_cadence(zone, value)); 00942 00943 ast_register_indication(zone, var, value); 00944 00945 CV_END; 00946 }
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, ast_tone_zone::ringcadence, and strsep().
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 1007 of file indications.c.
References AST_LIST_TRAVERSE, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_sound::entry, ast_tone_zone_sound::killme, ast_tone_zone::killme, and ast_tone_zone::tones.
Referenced by load_indications().
01008 { 01009 struct ast_tone_zone *zone = obj; 01010 struct ast_tone_zone_sound *s; 01011 01012 ast_tone_zone_lock(zone); 01013 01014 zone->killme = 1; 01015 01016 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01017 s->killme = 1; 01018 } 01019 01020 ast_tone_zone_unlock(zone); 01021 01022 return 0; 01023 }
struct ao2_container* ast_tone_zones [static] |
Definition at line 81 of file indications.c.
Referenced by ast_get_indication_tone(), ast_get_indication_zone(), ast_indications_init(), ast_register_indication_country(), ast_set_indication_country(), ast_tone_zone_count(), ast_tone_zone_iterator_init(), ast_unregister_indication_country(), complete_country(), complete_indications(), handle_cli_indication_show(), load_indications(), and parse_tone_zone().
struct ast_cli_entry cli_indications[] [static] |
Initial value:
{ { .handler = handle_cli_indication_add , .summary = "Add the given indication to the country" ,__VA_ARGS__ }, { .handler = handle_cli_indication_remove , .summary = "Remove the given indication from the country" ,__VA_ARGS__ }, { .handler = handle_cli_indication_show , .summary = "Display a list of all countries/indications" ,__VA_ARGS__ } }
Definition at line 1103 of file indications.c.
Referenced by ast_indications_init().
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.
Referenced by ast_get_indication_tone(), ast_get_indication_zone(), ast_register_indication_country(), ast_set_indication_country(), and ast_unregister_indication_country().
const int midi_tohz[128] [static] |
Definition at line 65 of file indications.c.
struct ast_generator playtones [static] |
Initial value:
{ .alloc = playtones_alloc, .release = playtones_release, .generate = playtones_generator, }
Definition at line 256 of file indications.c.
Referenced by ast_playtones_start().