#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 1149 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().
01150 { 01151 if (!(ast_tone_zones = ao2_container_alloc(NUM_TONE_ZONE_BUCKETS, 01152 ast_tone_zone_hash, ast_tone_zone_cmp))) { 01153 return -1; 01154 } 01155 01156 if (load_indications(0)) { 01157 return -1; 01158 } 01159 01160 ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications)); 01161 01162 return 0; 01163 }
int ast_indications_reload | ( | void | ) |
Reload indications module.
Provided by indications.c
Definition at line 1166 of file indications.c.
References load_indications().
01167 { 01168 return load_indications(1); 01169 }
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 1112 of file indications.c.
References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.
Referenced by ast_indications_init().
01113 { 01114 struct ast_tone_zone *zone = obj; 01115 struct ast_tone_zone *zone_arg = arg; 01116 01117 return (!strcasecmp(zone->country, zone_arg->country)) ? 01118 CMP_MATCH | CMP_STOP : 0; 01119 }
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 1121 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().
01122 { 01123 struct ast_data *data_zone_sound; 01124 struct ast_tone_zone_sound *s; 01125 01126 ast_data_add_structure(ast_tone_zone, tree, zone); 01127 01128 if (AST_LIST_EMPTY(&zone->tones)) { 01129 return 0; 01130 } 01131 01132 data_zone_sound = ast_data_add_node(tree, "tones"); 01133 if (!data_zone_sound) { 01134 return -1; 01135 } 01136 01137 ast_tone_zone_lock(zone); 01138 01139 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01140 ast_data_add_structure(ast_tone_zone_sound, data_zone_sound, s); 01141 } 01142 01143 ast_tone_zone_unlock(zone); 01144 01145 return 0; 01146 }
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 1105 of file indications.c.
References ast_str_case_hash(), and ast_tone_zone::country.
Referenced by ast_indications_init().
01106 { 01107 const struct ast_tone_zone *zone = obj; 01108 01109 return ast_str_case_hash(zone->country); 01110 }
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 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_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().
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 ao2_iterator_destroy(&i); 00662 00663 return res; 00664 }
static char* complete_indications | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 727 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().
00728 { 00729 char *res = NULL; 00730 int which = 0; 00731 size_t wordlen; 00732 struct ast_tone_zone_sound *ts; 00733 struct ast_tone_zone *tz, tmp_tz = { 00734 .nrringcadence = 0, 00735 }; 00736 00737 ast_copy_string(tmp_tz.country, a->argv[a->pos - 1], sizeof(tmp_tz.country)); 00738 00739 if (!(tz = ao2_find(ast_tone_zones, &tmp_tz, OBJ_POINTER))) { 00740 return NULL; 00741 } 00742 00743 wordlen = strlen(a->word); 00744 00745 ast_tone_zone_lock(tz); 00746 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00747 if (!strncasecmp(a->word, ts->name, wordlen) && ++which > a->n) { 00748 res = ast_strdup(ts->name); 00749 break; 00750 } 00751 } 00752 ast_tone_zone_unlock(tz); 00753 00754 tz = ast_tone_zone_unref(tz); 00755 00756 return res; 00757 }
static char* handle_cli_indication_add | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 666 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.
00667 { 00668 struct ast_tone_zone *tz; 00669 int created_country = 0; 00670 char *res = CLI_SUCCESS; 00671 00672 switch (cmd) { 00673 case CLI_INIT: 00674 e->command = "indication add"; 00675 e->usage = 00676 "Usage: indication add <country> <indication> \"<tonelist>\"\n" 00677 " Add the given indication to the country.\n"; 00678 return NULL; 00679 case CLI_GENERATE: 00680 if (a->pos == 2) { 00681 return complete_country(a); 00682 } else { 00683 return NULL; 00684 } 00685 } 00686 00687 if (a->argc != 5) { 00688 return CLI_SHOWUSAGE; 00689 } 00690 00691 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00692 /* country does not exist, create it */ 00693 ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n", a->argv[2]); 00694 00695 if (!(tz = ast_tone_zone_alloc())) { 00696 return CLI_FAILURE; 00697 } 00698 00699 ast_copy_string(tz->country, a->argv[2], sizeof(tz->country)); 00700 00701 if (ast_register_indication_country(tz)) { 00702 ast_log(LOG_WARNING, "Unable to register new country\n"); 00703 tz = ast_tone_zone_unref(tz); 00704 return CLI_FAILURE; 00705 } 00706 00707 created_country = 1; 00708 } 00709 00710 ast_tone_zone_lock(tz); 00711 00712 if (ast_register_indication(tz, a->argv[3], a->argv[4])) { 00713 ast_log(LOG_WARNING, "Unable to register indication %s/%s\n", a->argv[2], a->argv[3]); 00714 if (created_country) { 00715 ast_unregister_indication_country(a->argv[2]); 00716 } 00717 res = CLI_FAILURE; 00718 } 00719 00720 ast_tone_zone_unlock(tz); 00721 00722 tz = ast_tone_zone_unref(tz); 00723 00724 return res; 00725 }
static char* handle_cli_indication_remove | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 759 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.
00760 { 00761 struct ast_tone_zone *tz; 00762 char *res = CLI_SUCCESS; 00763 00764 switch (cmd) { 00765 case CLI_INIT: 00766 e->command = "indication remove"; 00767 e->usage = 00768 "Usage: indication remove <country> [indication]\n" 00769 " Remove the given indication from the country.\n"; 00770 return NULL; 00771 case CLI_GENERATE: 00772 if (a->pos == 2) { 00773 return complete_country(a); 00774 } else if (a->pos == 3) { 00775 return complete_indications(a); 00776 } 00777 } 00778 00779 if (a->argc != 3 && a->argc != 4) { 00780 return CLI_SHOWUSAGE; 00781 } 00782 00783 if (a->argc == 3) { 00784 /* remove entire country */ 00785 if (ast_unregister_indication_country(a->argv[2])) { 00786 ast_log(LOG_WARNING, "Unable to unregister indication country %s\n", a->argv[2]); 00787 return CLI_FAILURE; 00788 } 00789 00790 return CLI_SUCCESS; 00791 } 00792 00793 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00794 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n", a->argv[2], a->argv[3]); 00795 return CLI_FAILURE; 00796 } 00797 00798 if (ast_unregister_indication(tz, a->argv[3])) { 00799 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n", a->argv[2], a->argv[3]); 00800 res = CLI_FAILURE; 00801 } 00802 00803 tz = ast_tone_zone_unref(tz); 00804 00805 return res; 00806 }
static char* handle_cli_indication_show | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 808 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.
00809 { 00810 struct ast_tone_zone *tz = NULL; 00811 struct ast_str *buf; 00812 int found_country = 0; 00813 int i; 00814 00815 switch (cmd) { 00816 case CLI_INIT: 00817 e->command = "indication show"; 00818 e->usage = 00819 "Usage: indication show [<country> ...]\n" 00820 " Display either a condensed summary of all countries and indications, or a\n" 00821 " more verbose list of indications for the specified countries.\n"; 00822 return NULL; 00823 case CLI_GENERATE: 00824 return complete_country(a); 00825 } 00826 00827 if (a->argc == 2) { 00828 struct ao2_iterator iter; 00829 /* no arguments, show a list of countries */ 00830 ast_cli(a->fd, "Country Description\n"); 00831 ast_cli(a->fd, "===========================\n"); 00832 iter = ast_tone_zone_iterator_init(); 00833 while ((tz = ao2_iterator_next(&iter))) { 00834 ast_tone_zone_lock(tz); 00835 ast_cli(a->fd, "%-7.7s %s\n", tz->country, tz->description); 00836 ast_tone_zone_unlock(tz); 00837 tz = ast_tone_zone_unref(tz); 00838 } 00839 ao2_iterator_destroy(&iter); 00840 return CLI_SUCCESS; 00841 } 00842 00843 buf = ast_str_alloca(256); 00844 00845 for (i = 2; i < a->argc; i++) { 00846 struct ast_tone_zone zone_arg = { 00847 .nrringcadence = 0, 00848 }; 00849 struct ast_tone_zone_sound *ts; 00850 int j; 00851 00852 ast_copy_string(zone_arg.country, a->argv[i], sizeof(zone_arg.country)); 00853 00854 if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) { 00855 continue; 00856 } 00857 00858 if (!found_country) { 00859 found_country = 1; 00860 ast_cli(a->fd, "Country Indication PlayList\n"); 00861 ast_cli(a->fd, "=====================================\n"); 00862 } 00863 00864 ast_tone_zone_lock(tz); 00865 00866 ast_str_set(&buf, 0, "%-7.7s %-15.15s ", tz->country, "<ringcadence>"); 00867 for (j = 0; j < tz->nrringcadence; j++) { 00868 ast_str_append(&buf, 0, "%d%s", tz->ringcadence[j], 00869 (j == tz->nrringcadence - 1) ? "" : ","); 00870 } 00871 ast_str_append(&buf, 0, "\n"); 00872 ast_cli(a->fd, "%s", buf->str); 00873 00874 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00875 ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data); 00876 } 00877 00878 ast_tone_zone_unlock(tz); 00879 tz = ast_tone_zone_unref(tz); 00880 } 00881 00882 if (!found_country) { 00883 ast_cli(a->fd, "No countries matched your criteria.\n"); 00884 } 00885 00886 return CLI_SUCCESS; 00887 }
static int is_valid_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 889 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().
00890 { 00891 int res; 00892 00893 ast_tone_zone_lock(zone); 00894 res = (!ast_strlen_zero(zone->description) && !AST_LIST_EMPTY(&zone->tones)); 00895 ast_tone_zone_unlock(zone); 00896 00897 return res; 00898 }
static int load_indications | ( | int | reload | ) | [static] |
load indications module
Definition at line 1046 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().
01047 { 01048 struct ast_config *cfg; 01049 const char *cxt = NULL; 01050 const char *country = NULL; 01051 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 01052 int res = -1; 01053 01054 cfg = ast_config_load2(config, "indications", config_flags); 01055 01056 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) { 01057 ast_log(LOG_WARNING, "Can't find indications config file %s.\n", config); 01058 return 0; 01059 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 01060 return 0; 01061 } 01062 01063 /* Lock the container to prevent multiple simultaneous reloads */ 01064 ao2_lock(ast_tone_zones); 01065 01066 ao2_callback(ast_tone_zones, OBJ_NODATA, tone_zone_mark, NULL); 01067 01068 /* Use existing config to populate the Indication table */ 01069 while ((cxt = ast_category_browse(cfg, cxt))) { 01070 /* All categories but "general" are considered countries */ 01071 if (!strcasecmp(cxt, "general")) { 01072 continue; 01073 } 01074 01075 if (parse_tone_zone(cfg, cxt)) { 01076 goto return_cleanup; 01077 } 01078 } 01079 01080 ao2_callback(ast_tone_zones, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, 01081 prune_tone_zone, NULL); 01082 01083 /* determine which country is the default */ 01084 country = ast_variable_retrieve(cfg, "general", "country"); 01085 if (ast_strlen_zero(country) || ast_set_indication_country(country)) { 01086 ast_log(LOG_WARNING, "Unable to set the default country (for indication tones)\n"); 01087 } 01088 01089 res = 0; 01090 01091 return_cleanup: 01092 ao2_unlock(ast_tone_zones); 01093 ast_config_destroy(cfg); 01094 01095 return res; 01096 }
static int parse_tone_zone | ( | struct ast_config * | cfg, | |
const char * | country | |||
) | [static] |
Definition at line 959 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().
00960 { 00961 struct ast_variable *v; 00962 struct ast_tone_zone *zone; 00963 struct ast_tone_zone tmp_zone = { 00964 .nrringcadence = 0, 00965 }; 00966 int allocd = 0; 00967 00968 ast_copy_string(tmp_zone.country, country, sizeof(tmp_zone.country)); 00969 00970 if ((zone = ao2_find(ast_tone_zones, &tmp_zone, OBJ_POINTER))) { 00971 reset_tone_zone(zone); 00972 } else if ((zone = ast_tone_zone_alloc())) { 00973 allocd = 1; 00974 ast_copy_string(zone->country, country, sizeof(zone->country)); 00975 } else { 00976 return -1; 00977 } 00978 00979 ast_tone_zone_lock(zone); 00980 for (v = ast_variable_browse(cfg, country); v; v = v->next) { 00981 store_config_tone_zone(zone, v->name, v->value); 00982 } 00983 ast_tone_zone_unlock(zone); 00984 00985 if (allocd) { 00986 if (!is_valid_tone_zone(zone)) { 00987 ast_log(LOG_WARNING, "Indication country '%s' is invalid\n", country); 00988 } else if (ast_register_indication_country(zone)) { 00989 ast_log(LOG_WARNING, "Unable to register indication country '%s'.\n", 00990 country); 00991 } 00992 } 00993 00994 zone = ast_tone_zone_unref(zone); 00995 00996 return 0; 00997 }
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 1025 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().
01026 { 01027 struct ast_tone_zone *zone = obj; 01028 struct ast_tone_zone_sound *s; 01029 01030 ast_tone_zone_lock(zone); 01031 01032 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, s, entry) { 01033 if (s->killme) { 01034 AST_LIST_REMOVE_CURRENT(entry); 01035 s = ast_tone_zone_sound_unref(s); 01036 } 01037 } 01038 AST_LIST_TRAVERSE_SAFE_END; 01039 01040 ast_tone_zone_unlock(zone); 01041 01042 return zone->killme ? CMP_MATCH : 0; 01043 }
static void reset_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 944 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().
00945 { 00946 ast_tone_zone_lock(zone); 00947 00948 zone->killme = 0; 00949 00950 if (zone->nrringcadence) { 00951 zone->nrringcadence = 0; 00952 ast_free(zone->ringcadence); 00953 zone->ringcadence = NULL; 00954 } 00955 00956 ast_tone_zone_unlock(zone); 00957 }
static void store_config_tone_zone | ( | struct ast_tone_zone * | zone, | |
const char * | var, | |||
const char * | value | |||
) | [static] |
Definition at line 930 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().
00932 { 00933 CV_START(var, value); 00934 00935 CV_STR("description", zone->description); 00936 CV_F("ringcadence", store_tone_zone_ring_cadence(zone, value)); 00937 CV_F("ringcadance", store_tone_zone_ring_cadence(zone, value)); 00938 00939 ast_register_indication(zone, var, value); 00940 00941 CV_END; 00942 }
static void store_tone_zone_ring_cadence | ( | struct ast_tone_zone * | zone, | |
const char * | val | |||
) | [static] |
Definition at line 903 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().
00904 { 00905 char buf[1024]; 00906 char *ring, *c = buf; 00907 00908 ast_copy_string(buf, val, sizeof(buf)); 00909 00910 while ((ring = strsep(&c, ","))) { 00911 int *tmp, val; 00912 00913 ring = ast_strip(ring); 00914 00915 if (!isdigit(ring[0]) || (val = atoi(ring)) == -1) { 00916 ast_log(LOG_WARNING, "Invalid ringcadence given '%s'.\n", ring); 00917 continue; 00918 } 00919 00920 if (!(tmp = ast_realloc(zone->ringcadence, (zone->nrringcadence + 1) * sizeof(int)))) { 00921 return; 00922 } 00923 00924 zone->ringcadence = tmp; 00925 tmp[zone->nrringcadence] = val; 00926 zone->nrringcadence++; 00927 } 00928 }
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 1003 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().
01004 { 01005 struct ast_tone_zone *zone = obj; 01006 struct ast_tone_zone_sound *s; 01007 01008 ast_tone_zone_lock(zone); 01009 01010 zone->killme = 1; 01011 01012 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 01013 s->killme = 1; 01014 } 01015 01016 ast_tone_zone_unlock(zone); 01017 01018 return 0; 01019 }
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 1099 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().