#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 45 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 52 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 466 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().
00467 { 00468 struct ast_tone_zone_sound *ts = NULL; 00469 /* _zone is const to the users of the API */ 00470 struct ast_tone_zone *zone = (struct ast_tone_zone *) _zone; 00471 00472 /* If no zone is specified, use the default */ 00473 if (!zone) { 00474 ao2_lock(ast_tone_zones); 00475 if (default_tone_zone) { 00476 zone = ast_tone_zone_ref(default_tone_zone); 00477 } 00478 ao2_unlock(ast_tone_zones); 00479 00480 if (!zone) { 00481 return NULL; 00482 } 00483 } 00484 00485 ast_tone_zone_lock(zone); 00486 00487 /* Look through list of tones in the zone searching for the right one */ 00488 AST_LIST_TRAVERSE(&zone->tones, ts, entry) { 00489 if (!strcasecmp(ts->name, indication)) { 00490 /* Increase ref count for the reference we will return */ 00491 ts = ast_tone_zone_sound_ref(ts); 00492 break; 00493 } 00494 } 00495 00496 ast_tone_zone_unlock(zone); 00497 00498 return ts; 00499 }
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 444 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().
00445 { 00446 struct ast_tone_zone *tz = NULL; 00447 struct ast_tone_zone zone_arg = { 00448 .nrringcadence = 0, 00449 }; 00450 00451 if (ast_strlen_zero(country)) { 00452 ao2_lock(ast_tone_zones); 00453 if (default_tone_zone) { 00454 tz = ast_tone_zone_ref(default_tone_zone); 00455 } 00456 ao2_unlock(ast_tone_zones); 00457 00458 return tz; 00459 } 00460 00461 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country)); 00462 00463 return ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER); 00464 }
int ast_indications_init | ( | void | ) |
Load indications module.
Provided by indications.c
Definition at line 1147 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().
01148 { 01149 if (!(ast_tone_zones = ao2_container_alloc(NUM_TONE_ZONE_BUCKETS, 01150 ast_tone_zone_hash, ast_tone_zone_cmp))) { 01151 return -1; 01152 } 01153 01154 if (load_indications(0)) { 01155 return -1; 01156 } 01157 01158 ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications)); 01159 01160 return 0; 01161 }
int ast_indications_reload | ( | void | ) |
Reload indications module.
Provided by indications.c
Definition at line 1164 of file indications.c.
References load_indications().
01165 { 01166 return load_indications(1); 01167 }
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 315 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.
00316 { 00317 char *s, *data = ast_strdupa(playlst); 00318 struct playtones_def d = { vol, -1, 0, 1, NULL }; 00319 char *stringp; 00320 char *separator; 00321 static const float sample_rate = 8000.0; 00322 static const float max_sample_val = 32768.0; 00323 00324 if (vol < 1) { 00325 d.vol = 7219; /* Default to -8db */ 00326 } 00327 00328 d.interruptible = interruptible; 00329 00330 stringp = data; 00331 00332 /* check if the data is separated with '|' or with ',' by default */ 00333 if (strchr(stringp,'|')) { 00334 separator = "|"; 00335 } else { 00336 separator = ","; 00337 } 00338 00339 while ((s = strsep(&stringp, separator)) && !ast_strlen_zero(s)) { 00340 struct ast_tone_zone_part tone_data = { 00341 .time = 0, 00342 }; 00343 00344 s = ast_strip(s); 00345 00346 if (s[0]=='!') { 00347 s++; 00348 } else if (d.reppos == -1) { 00349 d.reppos = d.nitems; 00350 } 00351 00352 if (ast_tone_zone_part_parse(s, &tone_data)) { 00353 ast_log(LOG_ERROR, "Failed to parse tone part '%s'\n", s); 00354 continue; 00355 } 00356 00357 if (tone_data.midinote) { 00358 /* midi notes must be between 0 and 127 */ 00359 00360 if (tone_data.freq1 >= 0 && tone_data.freq1 <= 127) { 00361 tone_data.freq1 = midi_tohz[tone_data.freq1]; 00362 } else { 00363 tone_data.freq1 = 0; 00364 } 00365 00366 if (tone_data.freq2 >= 0 && tone_data.freq2 <= 127) { 00367 tone_data.freq2 = midi_tohz[tone_data.freq2]; 00368 } else { 00369 tone_data.freq2 = 0; 00370 } 00371 } 00372 00373 if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) { 00374 return -1; 00375 } 00376 00377 d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (tone_data.freq1 / sample_rate)) * max_sample_val; 00378 d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol; 00379 d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol; 00380 00381 d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (tone_data.freq2 / sample_rate)) * max_sample_val; 00382 d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol; 00383 d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol; 00384 00385 d.items[d.nitems].duration = tone_data.time; 00386 d.items[d.nitems].modulate = tone_data.modulate; 00387 00388 d.nitems++; 00389 } 00390 00391 if (!d.nitems) { 00392 ast_log(LOG_ERROR, "No valid tone parts\n"); 00393 return -1; 00394 } 00395 00396 if (ast_activate_generator(chan, &playtones, &d)) { 00397 ast_free(d.items); 00398 return -1; 00399 } 00400 00401 return 0; 00402 }
void ast_playtones_stop | ( | struct ast_channel * | chan | ) |
Stop playing tones on a channel.
Stop the tones from playing
Definition at line 404 of file indications.c.
References ast_deactivate_generator().
00405 { 00406 ast_deactivate_generator(chan); 00407 }
static int ast_register_indication | ( | struct ast_tone_zone * | zone, | |
const char * | indication, | |||
const char * | tonelist | |||
) | [static] |
Definition at line 581 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().
00583 { 00584 struct ast_tone_zone_sound *ts; 00585 00586 if (ast_strlen_zero(indication) || ast_strlen_zero(tonelist)) { 00587 return -1; 00588 } 00589 00590 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) { 00591 if (!strcasecmp(indication, ts->name)) { 00592 AST_LIST_REMOVE_CURRENT(entry); 00593 ts = ast_tone_zone_sound_unref(ts); 00594 break; 00595 } 00596 } 00597 AST_LIST_TRAVERSE_SAFE_END; 00598 00599 if (!(ts = ao2_alloc(sizeof(*ts), ast_tone_zone_sound_destructor))) { 00600 return -1; 00601 } 00602 00603 if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) { 00604 ts = ast_tone_zone_sound_unref(ts); 00605 return -1; 00606 } 00607 00608 AST_LIST_INSERT_TAIL(&zone->tones, ts, entry); /* Inherit reference */ 00609 00610 return 0; 00611 }
static int ast_register_indication_country | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 534 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().
00535 { 00536 ao2_lock(ast_tone_zones); 00537 if (!default_tone_zone) { 00538 default_tone_zone = ast_tone_zone_ref(zone); 00539 } 00540 ao2_unlock(ast_tone_zones); 00541 00542 ao2_link(ast_tone_zones, zone); 00543 00544 ast_verb(3, "Registered indication country '%s'\n", zone->country); 00545 00546 return 0; 00547 }
static int ast_set_indication_country | ( | const char * | country | ) | [static] |
Definition at line 420 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().
00421 { 00422 struct ast_tone_zone *zone = NULL; 00423 00424 /* If no country is specified or we are unable to find the zone, then return not found */ 00425 if (ast_strlen_zero(country) || !(zone = ast_get_indication_zone(country))) { 00426 return -1; 00427 } 00428 00429 ast_verb(3, "Setting default indication country to '%s'\n", country); 00430 00431 ao2_lock(ast_tone_zones); 00432 if (default_tone_zone) { 00433 default_tone_zone = ast_tone_zone_unref(default_tone_zone); 00434 } 00435 default_tone_zone = ast_tone_zone_ref(zone); 00436 ao2_unlock(ast_tone_zones); 00437 00438 zone = ast_tone_zone_unref(zone); 00439 00440 return 0; 00441 }
static struct ast_tone_zone* ast_tone_zone_alloc | ( | void | ) | [static] |
Definition at line 636 of file indications.c.
References ao2_alloc, and ast_tone_zone_destructor().
Referenced by handle_cli_indication_add(), and parse_tone_zone().
00637 { 00638 return ao2_alloc(sizeof(struct ast_tone_zone), ast_tone_zone_destructor); 00639 }
static int ast_tone_zone_cmp | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1110 of file indications.c.
References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.
Referenced by ast_indications_init().
01111 { 01112 struct ast_tone_zone *zone = obj; 01113 struct ast_tone_zone *zone_arg = arg; 01114 01115 return (!strcasecmp(zone->country, zone_arg->country)) ? 01116 CMP_MATCH | CMP_STOP : 0; 01117 }
int ast_tone_zone_count | ( | void | ) |
Get the number of registered tone zones.
Definition at line 409 of file indications.c.
References ao2_container_count(), and ast_tone_zones.
00410 { 00411 return ao2_container_count(ast_tone_zones); 00412 }
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 1119 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().
01120 { 01121 struct ast_data *data_zone_sound; 01122 struct ast_tone_zone_sound *s; 01123 01124 ast_data_add_structure(ast_tone_zone, tree, zone); 01125 01126 if (AST_LIST_EMPTY(&zone->tones)) { 01127 return 0; 01128 } 01129 01130 data_zone_sound = ast_data_add_node(tree, "tones"); 01131 if (!data_zone_sound) { 01132 return -1; 01133 } 01134 01135 ast_tone_zone_lock(zone); 01136 01137 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01138 ast_data_add_structure(ast_tone_zone_sound, data_zone_sound, s); 01139 } 01140 01141 ast_tone_zone_unlock(zone); 01142 01143 return 0; 01144 }
static void ast_tone_zone_destructor | ( | void * | obj | ) | [static] |
deallocate the passed tone zone
Definition at line 518 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().
00519 { 00520 struct ast_tone_zone *zone = obj; 00521 struct ast_tone_zone_sound *current; 00522 00523 while ((current = AST_LIST_REMOVE_HEAD(&zone->tones, entry))) { 00524 current = ast_tone_zone_sound_unref(current); 00525 } 00526 00527 if (zone->ringcadence) { 00528 ast_free(zone->ringcadence); 00529 zone->ringcadence = NULL; 00530 } 00531 }
static int ast_tone_zone_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1103 of file indications.c.
References ast_str_case_hash(), and ast_tone_zone::country.
Referenced by ast_indications_init().
01104 { 01105 const struct ast_tone_zone *zone = obj; 01106 01107 return ast_str_case_hash(zone->country); 01108 }
struct ao2_iterator ast_tone_zone_iterator_init | ( | void | ) |
Get an iterator for the available tone zones.
Use ao2_iterator_next() to iterate the tone zones.
Definition at line 414 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().
00415 { 00416 return ao2_iterator_init(ast_tone_zones, 0); 00417 }
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 258 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().
00259 { 00260 if (sscanf(s, "%30u+%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00261 &tone_data->time) == 3) { 00262 /* f1+f2/time format */ 00263 } else if (sscanf(s, "%30u+%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00264 /* f1+f2 format */ 00265 tone_data->time = 0; 00266 } else if (sscanf(s, "%30u*%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00267 &tone_data->time) == 3) { 00268 /* f1*f2/time format */ 00269 tone_data->modulate = 1; 00270 } else if (sscanf(s, "%30u*%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00271 /* f1*f2 format */ 00272 tone_data->time = 0; 00273 tone_data->modulate = 1; 00274 } else if (sscanf(s, "%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) { 00275 /* f1/time format */ 00276 tone_data->freq2 = 0; 00277 } else if (sscanf(s, "%30u", &tone_data->freq1) == 1) { 00278 /* f1 format */ 00279 tone_data->freq2 = 0; 00280 tone_data->time = 0; 00281 } else if (sscanf(s, "M%30u+M%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00282 &tone_data->time) == 3) { 00283 /* Mf1+Mf2/time format */ 00284 tone_data->midinote = 1; 00285 } else if (sscanf(s, "M%30u+M%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00286 /* Mf1+Mf2 format */ 00287 tone_data->time = 0; 00288 tone_data->midinote = 1; 00289 } else if (sscanf(s, "M%30u*M%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00290 &tone_data->time) == 3) { 00291 /* Mf1*Mf2/time format */ 00292 tone_data->modulate = 1; 00293 tone_data->midinote = 1; 00294 } else if (sscanf(s, "M%30u*M%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00295 /* Mf1*Mf2 format */ 00296 tone_data->time = 0; 00297 tone_data->modulate = 1; 00298 tone_data->midinote = 1; 00299 } else if (sscanf(s, "M%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) { 00300 /* Mf1/time format */ 00301 tone_data->freq2 = -1; 00302 tone_data->midinote = 1; 00303 } else if (sscanf(s, "M%30u", &tone_data->freq1) == 1) { 00304 /* Mf1 format */ 00305 tone_data->freq2 = -1; 00306 tone_data->time = 0; 00307 tone_data->midinote = 1; 00308 } else { 00309 return -1; 00310 } 00311 00312 return 0; 00313 }
static void ast_tone_zone_sound_destructor | ( | void * | obj | ) | [static] |
Definition at line 501 of file indications.c.
References ast_free, ast_tone_zone_sound::data, and ast_tone_zone_sound::name.
Referenced by ast_register_indication().
00502 { 00503 struct ast_tone_zone_sound *ts = obj; 00504 00505 /* Deconstify the 'const char *'s so the compiler doesn't complain. (but it's safe) */ 00506 if (ts->name) { 00507 ast_free((char *) ts->name); 00508 ts->name = NULL; 00509 } 00510 00511 if (ts->data) { 00512 ast_free((char *) ts->data); 00513 ts->data = NULL; 00514 } 00515 }
static int ast_unregister_indication | ( | struct ast_tone_zone * | zone, | |
const char * | indication | |||
) | [static] |
Definition at line 614 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().
00615 { 00616 struct ast_tone_zone_sound *ts; 00617 int res = -1; 00618 00619 ast_tone_zone_lock(zone); 00620 00621 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) { 00622 if (!strcasecmp(indication, ts->name)) { 00623 AST_LIST_REMOVE_CURRENT(entry); 00624 ts = ast_tone_zone_sound_unref(ts); 00625 res = 0; 00626 break; 00627 } 00628 } 00629 AST_LIST_TRAVERSE_SAFE_END; 00630 00631 ast_tone_zone_unlock(zone); 00632 00633 return res; 00634 }
static int ast_unregister_indication_country | ( | const char * | country | ) | [static] |
Definition at line 550 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().
00551 { 00552 struct ast_tone_zone *tz = NULL; 00553 struct ast_tone_zone zone_arg = { 00554 .nrringcadence = 0, 00555 }; 00556 00557 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country)); 00558 00559 if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) { 00560 return -1; 00561 } 00562 00563 ao2_lock(ast_tone_zones); 00564 if (default_tone_zone == tz) { 00565 ast_tone_zone_unref(default_tone_zone); 00566 /* Get a new default, punt to the first one we find */ 00567 default_tone_zone = ao2_callback(ast_tone_zones, 0, NULL, NULL); 00568 } 00569 ao2_unlock(ast_tone_zones); 00570 00571 ao2_unlink(ast_tone_zones, tz); 00572 00573 tz = ast_tone_zone_unref(tz); 00574 00575 return 0; 00576 }
static char* complete_country | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 641 of file indications.c.
References 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().
00642 { 00643 char *res = NULL; 00644 struct ao2_iterator i; 00645 int which = 0; 00646 size_t wordlen; 00647 struct ast_tone_zone *tz; 00648 00649 wordlen = strlen(a->word); 00650 00651 i = ao2_iterator_init(ast_tone_zones, 0); 00652 while ((tz = ao2_iterator_next(&i))) { 00653 if (!strncasecmp(a->word, tz->country, wordlen) && ++which > a->n) { 00654 res = ast_strdup(tz->country); 00655 } 00656 tz = ast_tone_zone_unref(tz); 00657 if (res) { 00658 break; 00659 } 00660 } 00661 00662 return res; 00663 }
static char* complete_indications | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 726 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().
00727 { 00728 char *res = NULL; 00729 int which = 0; 00730 size_t wordlen; 00731 struct ast_tone_zone_sound *ts; 00732 struct ast_tone_zone *tz, tmp_tz = { 00733 .nrringcadence = 0, 00734 }; 00735 00736 ast_copy_string(tmp_tz.country, a->argv[a->pos - 1], sizeof(tmp_tz.country)); 00737 00738 if (!(tz = ao2_find(ast_tone_zones, &tmp_tz, OBJ_POINTER))) { 00739 return NULL; 00740 } 00741 00742 wordlen = strlen(a->word); 00743 00744 ast_tone_zone_lock(tz); 00745 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00746 if (!strncasecmp(a->word, ts->name, wordlen) && ++which > a->n) { 00747 res = ast_strdup(ts->name); 00748 break; 00749 } 00750 } 00751 ast_tone_zone_unlock(tz); 00752 00753 tz = ast_tone_zone_unref(tz); 00754 00755 return res; 00756 }
static char* handle_cli_indication_add | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 665 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.
00666 { 00667 struct ast_tone_zone *tz; 00668 int created_country = 0; 00669 char *res = CLI_SUCCESS; 00670 00671 switch (cmd) { 00672 case CLI_INIT: 00673 e->command = "indication add"; 00674 e->usage = 00675 "Usage: indication add <country> <indication> \"<tonelist>\"\n" 00676 " Add the given indication to the country.\n"; 00677 return NULL; 00678 case CLI_GENERATE: 00679 if (a->pos == 2) { 00680 return complete_country(a); 00681 } else { 00682 return NULL; 00683 } 00684 } 00685 00686 if (a->argc != 5) { 00687 return CLI_SHOWUSAGE; 00688 } 00689 00690 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00691 /* country does not exist, create it */ 00692 ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n", a->argv[2]); 00693 00694 if (!(tz = ast_tone_zone_alloc())) { 00695 return CLI_FAILURE; 00696 } 00697 00698 ast_copy_string(tz->country, a->argv[2], sizeof(tz->country)); 00699 00700 if (ast_register_indication_country(tz)) { 00701 ast_log(LOG_WARNING, "Unable to register new country\n"); 00702 tz = ast_tone_zone_unref(tz); 00703 return CLI_FAILURE; 00704 } 00705 00706 created_country = 1; 00707 } 00708 00709 ast_tone_zone_lock(tz); 00710 00711 if (ast_register_indication(tz, a->argv[3], a->argv[4])) { 00712 ast_log(LOG_WARNING, "Unable to register indication %s/%s\n", a->argv[2], a->argv[3]); 00713 if (created_country) { 00714 ast_unregister_indication_country(a->argv[2]); 00715 } 00716 res = CLI_FAILURE; 00717 } 00718 00719 ast_tone_zone_unlock(tz); 00720 00721 tz = ast_tone_zone_unref(tz); 00722 00723 return res; 00724 }
static char* handle_cli_indication_remove | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 758 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.
00759 { 00760 struct ast_tone_zone *tz; 00761 char *res = CLI_SUCCESS; 00762 00763 switch (cmd) { 00764 case CLI_INIT: 00765 e->command = "indication remove"; 00766 e->usage = 00767 "Usage: indication remove <country> [indication]\n" 00768 " Remove the given indication from the country.\n"; 00769 return NULL; 00770 case CLI_GENERATE: 00771 if (a->pos == 2) { 00772 return complete_country(a); 00773 } else if (a->pos == 3) { 00774 return complete_indications(a); 00775 } 00776 } 00777 00778 if (a->argc != 3 && a->argc != 4) { 00779 return CLI_SHOWUSAGE; 00780 } 00781 00782 if (a->argc == 3) { 00783 /* remove entire country */ 00784 if (ast_unregister_indication_country(a->argv[2])) { 00785 ast_log(LOG_WARNING, "Unable to unregister indication country %s\n", a->argv[2]); 00786 return CLI_FAILURE; 00787 } 00788 00789 return CLI_SUCCESS; 00790 } 00791 00792 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00793 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n", a->argv[2], a->argv[3]); 00794 return CLI_FAILURE; 00795 } 00796 00797 if (ast_unregister_indication(tz, a->argv[3])) { 00798 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n", a->argv[2], a->argv[3]); 00799 res = CLI_FAILURE; 00800 } 00801 00802 tz = ast_tone_zone_unref(tz); 00803 00804 return res; 00805 }
static char* handle_cli_indication_show | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 807 of file indications.c.
References ao2_find, 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.
00808 { 00809 struct ast_tone_zone *tz = NULL; 00810 struct ast_str *buf; 00811 int found_country = 0; 00812 int i; 00813 00814 switch (cmd) { 00815 case CLI_INIT: 00816 e->command = "indication show"; 00817 e->usage = 00818 "Usage: indication show [<country> ...]\n" 00819 " Display either a condensed summary of all countries and indications, or a\n" 00820 " more verbose list of indications for the specified countries.\n"; 00821 return NULL; 00822 case CLI_GENERATE: 00823 return complete_country(a); 00824 } 00825 00826 if (a->argc == 2) { 00827 struct ao2_iterator iter; 00828 /* no arguments, show a list of countries */ 00829 ast_cli(a->fd, "Country Description\n"); 00830 ast_cli(a->fd, "===========================\n"); 00831 iter = ast_tone_zone_iterator_init(); 00832 while ((tz = ao2_iterator_next(&iter))) { 00833 ast_tone_zone_lock(tz); 00834 ast_cli(a->fd, "%-7.7s %s\n", tz->country, tz->description); 00835 ast_tone_zone_unlock(tz); 00836 tz = ast_tone_zone_unref(tz); 00837 } 00838 return CLI_SUCCESS; 00839 } 00840 00841 buf = ast_str_alloca(256); 00842 00843 for (i = 2; i < a->argc; i++) { 00844 struct ast_tone_zone zone_arg = { 00845 .nrringcadence = 0, 00846 }; 00847 struct ast_tone_zone_sound *ts; 00848 int j; 00849 00850 ast_copy_string(zone_arg.country, a->argv[i], sizeof(zone_arg.country)); 00851 00852 if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) { 00853 continue; 00854 } 00855 00856 if (!found_country) { 00857 found_country = 1; 00858 ast_cli(a->fd, "Country Indication PlayList\n"); 00859 ast_cli(a->fd, "=====================================\n"); 00860 } 00861 00862 ast_tone_zone_lock(tz); 00863 00864 ast_str_set(&buf, 0, "%-7.7s %-15.15s ", tz->country, "<ringcadence>"); 00865 for (j = 0; j < tz->nrringcadence; j++) { 00866 ast_str_append(&buf, 0, "%d%s", tz->ringcadence[j], 00867 (j == tz->nrringcadence - 1) ? "" : ","); 00868 } 00869 ast_str_append(&buf, 0, "\n"); 00870 ast_cli(a->fd, "%s", buf->str); 00871 00872 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00873 ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data); 00874 } 00875 00876 ast_tone_zone_unlock(tz); 00877 tz = ast_tone_zone_unref(tz); 00878 } 00879 00880 if (!found_country) { 00881 ast_cli(a->fd, "No countries matched your criteria.\n"); 00882 } 00883 00884 return CLI_SUCCESS; 00885 }
static int is_valid_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 887 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().
00888 { 00889 int res; 00890 00891 ast_tone_zone_lock(zone); 00892 res = (!ast_strlen_zero(zone->description) && !AST_LIST_EMPTY(&zone->tones)); 00893 ast_tone_zone_unlock(zone); 00894 00895 return res; 00896 }
static int load_indications | ( | int | reload | ) | [static] |
load indications module
Definition at line 1044 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_flags, 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().
01045 { 01046 struct ast_config *cfg; 01047 const char *cxt = NULL; 01048 const char *country = NULL; 01049 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 01050 int res = -1; 01051 01052 cfg = ast_config_load2(config, "indications", config_flags); 01053 01054 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) { 01055 ast_log(LOG_WARNING, "Can't find indications config file %s.\n", config); 01056 return 0; 01057 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 01058 return 0; 01059 } 01060 01061 /* Lock the container to prevent multiple simultaneous reloads */ 01062 ao2_lock(ast_tone_zones); 01063 01064 ao2_callback(ast_tone_zones, OBJ_NODATA, tone_zone_mark, NULL); 01065 01066 /* Use existing config to populate the Indication table */ 01067 while ((cxt = ast_category_browse(cfg, cxt))) { 01068 /* All categories but "general" are considered countries */ 01069 if (!strcasecmp(cxt, "general")) { 01070 continue; 01071 } 01072 01073 if (parse_tone_zone(cfg, cxt)) { 01074 goto return_cleanup; 01075 } 01076 } 01077 01078 ao2_callback(ast_tone_zones, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, 01079 prune_tone_zone, NULL); 01080 01081 /* determine which country is the default */ 01082 country = ast_variable_retrieve(cfg, "general", "country"); 01083 if (ast_strlen_zero(country) || ast_set_indication_country(country)) { 01084 ast_log(LOG_WARNING, "Unable to set the default country (for indication tones)\n"); 01085 } 01086 01087 res = 0; 01088 01089 return_cleanup: 01090 ao2_unlock(ast_tone_zones); 01091 ast_config_destroy(cfg); 01092 01093 return res; 01094 }
static int parse_tone_zone | ( | struct ast_config * | cfg, | |
const char * | country | |||
) | [static] |
Definition at line 957 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().
00958 { 00959 struct ast_variable *v; 00960 struct ast_tone_zone *zone; 00961 struct ast_tone_zone tmp_zone = { 00962 .nrringcadence = 0, 00963 }; 00964 int allocd = 0; 00965 00966 ast_copy_string(tmp_zone.country, country, sizeof(tmp_zone.country)); 00967 00968 if ((zone = ao2_find(ast_tone_zones, &tmp_zone, OBJ_POINTER))) { 00969 reset_tone_zone(zone); 00970 } else if ((zone = ast_tone_zone_alloc())) { 00971 allocd = 1; 00972 ast_copy_string(zone->country, country, sizeof(zone->country)); 00973 } else { 00974 return -1; 00975 } 00976 00977 ast_tone_zone_lock(zone); 00978 for (v = ast_variable_browse(cfg, country); v; v = v->next) { 00979 store_config_tone_zone(zone, v->name, v->value); 00980 } 00981 ast_tone_zone_unlock(zone); 00982 00983 if (allocd) { 00984 if (!is_valid_tone_zone(zone)) { 00985 ast_log(LOG_WARNING, "Indication country '%s' is invalid\n", country); 00986 } else if (ast_register_indication_country(zone)) { 00987 ast_log(LOG_WARNING, "Unable to register indication country '%s'.\n", 00988 country); 00989 } 00990 } 00991 00992 zone = ast_tone_zone_unref(zone); 00993 00994 return 0; 00995 }
static void* playtones_alloc | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 141 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(), LOG_WARNING, ast_channel::name, pd, playtones_release(), ps, and ast_channel::writeformat.
00142 { 00143 struct playtones_def *pd = params; 00144 struct playtones_state *ps = NULL; 00145 00146 if (!(ps = ast_calloc(1, sizeof(*ps)))) { 00147 return NULL; 00148 } 00149 00150 ps->origwfmt = chan->writeformat; 00151 00152 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 00153 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 00154 playtones_release(NULL, ps); 00155 ps = NULL; 00156 } else { 00157 ps->vol = pd->vol; 00158 ps->reppos = pd->reppos; 00159 ps->nitems = pd->nitems; 00160 ps->items = pd->items; 00161 ps->oldnpos = -1; 00162 } 00163 00164 /* Let interrupts interrupt :) */ 00165 if (pd->interruptible) { 00166 ast_set_flag(chan, AST_FLAG_WRITE_INT); 00167 } else { 00168 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 00169 } 00170 00171 return ps; 00172 }
static int playtones_generator | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | len, | |||
int | samples | |||
) | [static] |
Definition at line 174 of file indications.c.
References ast_log(), 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, LOG_WARNING, playtones_item::modulate, and ps.
00175 { 00176 struct playtones_state *ps = data; 00177 struct playtones_item *pi; 00178 int x; 00179 00180 /* we need to prepare a frame with 16 * timelen samples as we're 00181 * generating SLIN audio */ 00182 00183 len = samples * 2; 00184 if (len > sizeof(ps->data) / 2 - 1) { 00185 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 00186 return -1; 00187 } 00188 00189 memset(&ps->f, 0, sizeof(ps->f)); 00190 00191 pi = &ps->items[ps->npos]; 00192 00193 if (ps->oldnpos != ps->npos) { 00194 /* Load new parameters */ 00195 ps->v1_1 = 0; 00196 ps->v2_1 = pi->init_v2_1; 00197 ps->v3_1 = pi->init_v3_1; 00198 ps->v1_2 = 0; 00199 ps->v2_2 = pi->init_v2_2; 00200 ps->v3_2 = pi->init_v3_2; 00201 ps->oldnpos = ps->npos; 00202 } 00203 00204 for (x = 0; x < samples; x++) { 00205 ps->v1_1 = ps->v2_1; 00206 ps->v2_1 = ps->v3_1; 00207 ps->v3_1 = (pi->fac1 * ps->v2_1 >> 15) - ps->v1_1; 00208 00209 ps->v1_2 = ps->v2_2; 00210 ps->v2_2 = ps->v3_2; 00211 ps->v3_2 = (pi->fac2 * ps->v2_2 >> 15) - ps->v1_2; 00212 if (pi->modulate) { 00213 int p; 00214 p = ps->v3_2 - 32768; 00215 if (p < 0) { 00216 p = -p; 00217 } 00218 p = ((p * 9) / 10) + 1; 00219 ps->data[x] = (ps->v3_1 * p) >> 15; 00220 } else { 00221 ps->data[x] = ps->v3_1 + ps->v3_2; 00222 } 00223 } 00224 00225 ps->f.frametype = AST_FRAME_VOICE; 00226 ps->f.subclass.codec = AST_FORMAT_SLINEAR; 00227 ps->f.datalen = len; 00228 ps->f.samples = samples; 00229 ps->f.offset = AST_FRIENDLY_OFFSET; 00230 ps->f.data.ptr = ps->data; 00231 00232 if (ast_write(chan, &ps->f)) { 00233 return -1; 00234 } 00235 00236 ps->pos += x; 00237 00238 if (pi->duration && ps->pos >= pi->duration * 8) { /* item finished? */ 00239 ps->pos = 0; /* start new item */ 00240 ps->npos++; 00241 if (ps->npos >= ps->nitems) { /* last item? */ 00242 if (ps->reppos == -1) { /* repeat set? */ 00243 return -1; 00244 } 00245 ps->npos = ps->reppos; /* redo from top */ 00246 } 00247 } 00248 00249 return 0; 00250 }
static void playtones_release | ( | struct ast_channel * | chan, | |
void * | params | |||
) | [static] |
Definition at line 125 of file indications.c.
References ast_free, ast_set_write_format(), and ps.
Referenced by playtones_alloc().
00126 { 00127 struct playtones_state *ps = params; 00128 00129 if (chan) { 00130 ast_set_write_format(chan, ps->origwfmt); 00131 } 00132 00133 if (ps->items) { 00134 ast_free(ps->items); 00135 ps->items = NULL; 00136 } 00137 00138 ast_free(ps); 00139 }
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 1023 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().
01024 { 01025 struct ast_tone_zone *zone = obj; 01026 struct ast_tone_zone_sound *s; 01027 01028 ast_tone_zone_lock(zone); 01029 01030 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, s, entry) { 01031 if (s->killme) { 01032 AST_LIST_REMOVE_CURRENT(entry); 01033 s = ast_tone_zone_sound_unref(s); 01034 } 01035 } 01036 AST_LIST_TRAVERSE_SAFE_END; 01037 01038 ast_tone_zone_unlock(zone); 01039 01040 return zone->killme ? CMP_MATCH : 0; 01041 }
static void reset_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 942 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().
00943 { 00944 ast_tone_zone_lock(zone); 00945 00946 zone->killme = 0; 00947 00948 if (zone->nrringcadence) { 00949 zone->nrringcadence = 0; 00950 ast_free(zone->ringcadence); 00951 zone->ringcadence = NULL; 00952 } 00953 00954 ast_tone_zone_unlock(zone); 00955 }
static void store_config_tone_zone | ( | struct ast_tone_zone * | zone, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Definition at line 928 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().
00930 { 00931 CV_START(var, value); 00932 00933 CV_STR("description", zone->description); 00934 CV_F("ringcadence", store_tone_zone_ring_cadence(zone, value)); 00935 CV_F("ringcadance", store_tone_zone_ring_cadence(zone, value)); 00936 00937 ast_register_indication(zone, var, value); 00938 00939 CV_END; 00940 }
static void store_tone_zone_ring_cadence | ( | struct ast_tone_zone * | zone, | |
const char * | val | |||
) | [static] |
Definition at line 901 of file indications.c.
References ast_copy_string(), ast_log(), ast_realloc, ast_strip(), LOG_WARNING, ast_tone_zone::nrringcadence, ring(), ast_tone_zone::ringcadence, and strsep().
Referenced by store_config_tone_zone().
00902 { 00903 char buf[1024]; 00904 char *ring, *c = buf; 00905 00906 ast_copy_string(buf, val, sizeof(buf)); 00907 00908 while ((ring = strsep(&c, ","))) { 00909 int *tmp, val; 00910 00911 ring = ast_strip(ring); 00912 00913 if (!isdigit(ring[0]) || (val = atoi(ring)) == -1) { 00914 ast_log(LOG_WARNING, "Invalid ringcadence given '%s'.\n", ring); 00915 continue; 00916 } 00917 00918 if (!(tmp = ast_realloc(zone->ringcadence, (zone->nrringcadence + 1) * sizeof(int)))) { 00919 return; 00920 } 00921 00922 zone->ringcadence = tmp; 00923 tmp[zone->nrringcadence] = val; 00924 zone->nrringcadence++; 00925 } 00926 }
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 1001 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().
01002 { 01003 struct ast_tone_zone *zone = obj; 01004 struct ast_tone_zone_sound *s; 01005 01006 ast_tone_zone_lock(zone); 01007 01008 zone->killme = 1; 01009 01010 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01011 s->killme = 1; 01012 } 01013 01014 ast_tone_zone_unlock(zone); 01015 01016 return 0; 01017 }
struct ao2_container* ast_tone_zones [static] |
Definition at line 77 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 1097 of file indications.c.
Referenced by ast_indications_init().
const char config[] = "indications.conf" [static] |
Definition at line 59 of file indications.c.
struct ast_tone_zone* default_tone_zone [static] |
Definition at line 84 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 61 of file indications.c.
struct ast_generator playtones [static] |
Initial value:
{ .alloc = playtones_alloc, .release = playtones_release, .generate = playtones_generator, }
Definition at line 252 of file indications.c.
Referenced by ast_playtones_start().