Indication Tone Handling. More...
#include "asterisk.h"#include <math.h>#include "asterisk/lock.h"#include "asterisk/linkedlists.h"#include "asterisk/indications.h"#include "asterisk/frame.h"#include "asterisk/channel.h"#include "asterisk/utils.h"#include "asterisk/cli.h"#include "asterisk/module.h"#include "asterisk/astobj2.h"#include "asterisk/_private.h"
Go to the source code of this file.
Data Structures | |
| struct | playtones_def |
| struct | playtones_item |
| struct | playtones_state |
Defines | |
| #define | NUM_TONE_ZONE_BUCKETS 53 |
Functions | |
| struct ast_tone_zone_sound * | ast_get_indication_tone (const struct ast_tone_zone *_zone, const char *indication) |
| Locate a tone zone sound. | |
| struct ast_tone_zone * | ast_get_indication_zone (const char *country) |
| locate ast_tone_zone | |
| int | ast_indications_init (void) |
| Load indications module. | |
| int | ast_indications_reload (void) |
| Reload indications module. | |
| int | ast_playtones_start (struct ast_channel *chan, int vol, const char *playlst, int interruptible) |
| Start playing a list of tones on a channel. | |
| void | ast_playtones_stop (struct ast_channel *chan) |
| Stop playing tones on a channel. | |
| static int | ast_register_indication (struct ast_tone_zone *zone, const char *indication, const char *tonelist) |
| static int | ast_register_indication_country (struct ast_tone_zone *zone) |
| static int | ast_set_indication_country (const char *country) |
| static struct ast_tone_zone * | ast_tone_zone_alloc (void) |
| static int | ast_tone_zone_cmp (void *obj, void *arg, int flags) |
| int | ast_tone_zone_count (void) |
| Get the number of registered tone zones. | |
| static void | ast_tone_zone_destructor (void *obj) |
| deallocate the passed tone zone | |
| static int | ast_tone_zone_hash (const void *obj, const int flags) |
| struct ao2_iterator | ast_tone_zone_iterator_init (void) |
| Get an iterator for the available tone zones. | |
| int | ast_tone_zone_part_parse (const char *s, struct ast_tone_zone_part *tone_data) |
| Parse a tone part. | |
| static void | ast_tone_zone_sound_destructor (void *obj) |
| static int | ast_unregister_indication (struct ast_tone_zone *zone, const char *indication) |
| static int | ast_unregister_indication_country (const char *country) |
| static char * | complete_country (struct ast_cli_args *a) |
| static char * | complete_indications (struct ast_cli_args *a) |
| static char * | handle_cli_indication_add (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_indication_remove (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_indication_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static int | is_valid_tone_zone (struct ast_tone_zone *zone) |
| static int | load_indications (int reload) |
| load indications module | |
| static int | parse_tone_zone (struct ast_config *cfg, const char *country) |
| static void * | playtones_alloc (struct ast_channel *chan, void *params) |
| static int | playtones_generator (struct ast_channel *chan, void *data, int len, int samples) |
| static void | playtones_release (struct ast_channel *chan, void *params) |
| static int | prune_tone_zone (void *obj, void *arg, int flags) |
| static void | reset_tone_zone (struct ast_tone_zone *zone) |
| static void | store_config_tone_zone (struct ast_tone_zone *zone, const char *var, const char *value) |
| static void | store_tone_zone_ring_cadence (struct ast_tone_zone *zone, const char *val) |
| static int | tone_zone_mark (void *obj, void *arg, int flags) |
Variables | |
| static struct ao2_container * | ast_tone_zones |
| static struct ast_cli_entry | cli_indications [] |
| CLI entries for commands provided by this module. | |
| static const char | config [] = "indications.conf" |
| static struct ast_tone_zone * | default_tone_zone |
| static const int | midi_tohz [128] |
| static struct ast_generator | playtones |
Indication Tone Handling.
Definition in file indications.c.
| #define NUM_TONE_ZONE_BUCKETS 53 |
Definition at line 65 of file indications.c.
Referenced by ast_indications_init().
| struct ast_tone_zone_sound* ast_get_indication_tone | ( | const struct ast_tone_zone * | zone, | |
| const char * | indication | |||
| ) | [read] |
Locate a tone zone sound.
| zone | Zone to look in for a sound, if NULL, the default will be used | |
| indication | Sound to look for, such as "busy" |
Definition at line 452 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_zone_sound::name, and ast_tone_zone::tones.
Referenced by ast_app_dtget(), ast_indicate_data(), dialtone_indicate(), handle_playtones(), in_band_indication(), pbx_builtin_waitexten(), play_dialtone(), read_exec(), readexten_exec(), and skinny_transfer().
00453 { 00454 struct ast_tone_zone_sound *ts = NULL; 00455 /* _zone is const to the users of the API */ 00456 struct ast_tone_zone *zone = (struct ast_tone_zone *) _zone; 00457 00458 /* If no zone is specified, use the default */ 00459 if (!zone) { 00460 ao2_lock(ast_tone_zones); 00461 if (default_tone_zone) { 00462 zone = ast_tone_zone_ref(default_tone_zone); 00463 } 00464 ao2_unlock(ast_tone_zones); 00465 00466 if (!zone) { 00467 return NULL; 00468 } 00469 } 00470 00471 ast_tone_zone_lock(zone); 00472 00473 /* Look through list of tones in the zone searching for the right one */ 00474 AST_LIST_TRAVERSE(&zone->tones, ts, entry) { 00475 if (!strcasecmp(ts->name, indication)) { 00476 /* Increase ref count for the reference we will return */ 00477 ts = ast_tone_zone_sound_ref(ts); 00478 break; 00479 } 00480 } 00481 00482 ast_tone_zone_unlock(zone); 00483 00484 return ts; 00485 }
| struct ast_tone_zone* ast_get_indication_zone | ( | const char * | country | ) | [read] |
locate ast_tone_zone
| country | country to find. If NULL is provided, get the default. |
Definition at line 430 of file indications.c.
References ao2_find, ao2_lock(), ao2_unlock(), ast_copy_string(), ast_strlen_zero(), ast_tone_zone_ref(), ast_tone_zone::country, ast_tone_zone::nrringcadence, and OBJ_POINTER.
Referenced by ast_set_indication_country(), ast_var_indications(), build_device(), func_channel_write(), handle_cli_indication_add(), and handle_cli_indication_remove().
00431 { 00432 struct ast_tone_zone *tz = NULL; 00433 struct ast_tone_zone zone_arg = { 00434 .nrringcadence = 0, 00435 }; 00436 00437 if (ast_strlen_zero(country)) { 00438 ao2_lock(ast_tone_zones); 00439 if (default_tone_zone) { 00440 tz = ast_tone_zone_ref(default_tone_zone); 00441 } 00442 ao2_unlock(ast_tone_zones); 00443 00444 return tz; 00445 } 00446 00447 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country)); 00448 00449 return ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER); 00450 }
| int ast_indications_init | ( | void | ) |
Load indications module.
Provided by indications.c
Definition at line 1106 of file indications.c.
References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_tone_zone_cmp(), ast_tone_zone_hash(), load_indications(), and NUM_TONE_ZONE_BUCKETS.
Referenced by main().
01107 { 01108 if (!(ast_tone_zones = ao2_container_alloc(NUM_TONE_ZONE_BUCKETS, 01109 ast_tone_zone_hash, ast_tone_zone_cmp))) { 01110 return -1; 01111 } 01112 01113 if (load_indications(0)) { 01114 return -1; 01115 } 01116 01117 ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications)); 01118 01119 return 0; 01120 }
| int ast_indications_reload | ( | void | ) |
Reload indications module.
Provided by indications.c
Definition at line 1123 of file indications.c.
References load_indications().
01124 { 01125 return load_indications(1); 01126 }
| 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 301 of file indications.c.
References ast_activate_generator(), ast_free, ast_log(), ast_realloc, 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, ast_tone_zone_part::midinote, ast_tone_zone_part::modulate, playtones_item::modulate, playtones_def::nitems, playtones_def::reppos, s, ast_tone_zone_part::time, and playtones_def::vol.
Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_begin(), dialtone_indicate(), do_dtmf_local(), handle_playtones(), in_band_indication(), milliwatt_exec(), pbx_builtin_waitexten(), play_dialtone(), playtone(), read_exec(), readexten_exec(), send_digit_to_chan(), and skinny_transfer().
00302 { 00303 char *s, *data = ast_strdupa(playlst); 00304 struct playtones_def d = { vol, -1, 0, 1, NULL }; 00305 char *stringp; 00306 char *separator; 00307 static const float sample_rate = 8000.0; 00308 static const float max_sample_val = 32768.0; 00309 00310 if (vol < 1) { 00311 d.vol = 7219; /* Default to -8db */ 00312 } 00313 00314 d.interruptible = interruptible; 00315 00316 stringp = data; 00317 00318 /* check if the data is separated with '|' or with ',' by default */ 00319 if (strchr(stringp,'|')) { 00320 separator = "|"; 00321 } else { 00322 separator = ","; 00323 } 00324 00325 while ((s = strsep(&stringp, separator)) && !ast_strlen_zero(s)) { 00326 struct ast_tone_zone_part tone_data = { 00327 .time = 0, 00328 }; 00329 00330 s = ast_strip(s); 00331 00332 if (s[0]=='!') { 00333 s++; 00334 } else if (d.reppos == -1) { 00335 d.reppos = d.nitems; 00336 } 00337 00338 if (ast_tone_zone_part_parse(s, &tone_data)) { 00339 ast_log(LOG_ERROR, "Failed to parse tone part '%s'\n", s); 00340 continue; 00341 } 00342 00343 if (tone_data.midinote) { 00344 /* midi notes must be between 0 and 127 */ 00345 00346 if (tone_data.freq1 >= 0 && tone_data.freq1 <= 127) { 00347 tone_data.freq1 = midi_tohz[tone_data.freq1]; 00348 } else { 00349 tone_data.freq1 = 0; 00350 } 00351 00352 if (tone_data.freq2 >= 0 && tone_data.freq2 <= 127) { 00353 tone_data.freq2 = midi_tohz[tone_data.freq2]; 00354 } else { 00355 tone_data.freq2 = 0; 00356 } 00357 } 00358 00359 if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) { 00360 return -1; 00361 } 00362 00363 d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (tone_data.freq1 / sample_rate)) * max_sample_val; 00364 d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol; 00365 d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol; 00366 00367 d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (tone_data.freq2 / sample_rate)) * max_sample_val; 00368 d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol; 00369 d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol; 00370 00371 d.items[d.nitems].duration = tone_data.time; 00372 d.items[d.nitems].modulate = tone_data.modulate; 00373 00374 d.nitems++; 00375 } 00376 00377 if (!d.nitems) { 00378 ast_log(LOG_ERROR, "No valid tone parts\n"); 00379 return -1; 00380 } 00381 00382 if (ast_activate_generator(chan, &playtones, &d)) { 00383 ast_free(d.items); 00384 return -1; 00385 } 00386 00387 return 0; 00388 }
| void ast_playtones_stop | ( | struct ast_channel * | chan | ) |
Stop playing tones on a channel.
Stop the tones from playing
Definition at line 390 of file indications.c.
References ast_deactivate_generator().
Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_end(), disa_exec(), handle_stopplaytones(), pbx_builtin_waitexten(), playtone(), read_exec(), readexten_exec(), stop_indicate(), and unistim_indicate().
00391 { 00392 ast_deactivate_generator(chan); 00393 }
| static int ast_register_indication | ( | struct ast_tone_zone * | zone, | |
| const char * | indication, | |||
| const char * | tonelist | |||
| ) | [static] |
Definition at line 567 of file indications.c.
References ao2_alloc, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_strdup, ast_strlen_zero(), ast_tone_zone_sound_destructor(), ast_tone_zone_sound_unref(), ast_tone_zone_sound::data, 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().
00569 { 00570 struct ast_tone_zone_sound *ts; 00571 00572 if (ast_strlen_zero(indication) || ast_strlen_zero(tonelist)) { 00573 return -1; 00574 } 00575 00576 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) { 00577 if (!strcasecmp(indication, ts->name)) { 00578 AST_LIST_REMOVE_CURRENT(entry); 00579 ts = ast_tone_zone_sound_unref(ts); 00580 break; 00581 } 00582 } 00583 AST_LIST_TRAVERSE_SAFE_END; 00584 00585 if (!(ts = ao2_alloc(sizeof(*ts), ast_tone_zone_sound_destructor))) { 00586 return -1; 00587 } 00588 00589 if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) { 00590 ts = ast_tone_zone_sound_unref(ts); 00591 return -1; 00592 } 00593 00594 AST_LIST_INSERT_TAIL(&zone->tones, ts, entry); /* Inherit reference */ 00595 00596 return 0; 00597 }
| static int ast_register_indication_country | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 520 of file indications.c.
References ao2_link, ao2_lock(), ao2_unlock(), ast_tone_zone_ref(), ast_verb, and ast_tone_zone::country.
Referenced by handle_cli_indication_add(), and parse_tone_zone().
00521 { 00522 ao2_lock(ast_tone_zones); 00523 if (!default_tone_zone) { 00524 default_tone_zone = ast_tone_zone_ref(zone); 00525 } 00526 ao2_unlock(ast_tone_zones); 00527 00528 ao2_link(ast_tone_zones, zone); 00529 00530 ast_verb(3, "Registered indication country '%s'\n", zone->country); 00531 00532 return 0; 00533 }
| static int ast_set_indication_country | ( | const char * | country | ) | [static] |
Definition at line 406 of file indications.c.
References ao2_lock(), ao2_unlock(), ast_get_indication_zone(), ast_strlen_zero(), ast_tone_zone_ref(), ast_tone_zone_unref(), and ast_verb.
Referenced by load_indications().
00407 { 00408 struct ast_tone_zone *zone = NULL; 00409 00410 /* If no country is specified or we are unable to find the zone, then return not found */ 00411 if (ast_strlen_zero(country) || !(zone = ast_get_indication_zone(country))) { 00412 return -1; 00413 } 00414 00415 ast_verb(3, "Setting default indication country to '%s'\n", country); 00416 00417 ao2_lock(ast_tone_zones); 00418 if (default_tone_zone) { 00419 default_tone_zone = ast_tone_zone_unref(default_tone_zone); 00420 } 00421 default_tone_zone = ast_tone_zone_ref(zone); 00422 ao2_unlock(ast_tone_zones); 00423 00424 zone = ast_tone_zone_unref(zone); 00425 00426 return 0; 00427 }
| static struct ast_tone_zone* ast_tone_zone_alloc | ( | void | ) | [static, read] |
Definition at line 622 of file indications.c.
References ao2_alloc, and ast_tone_zone_destructor().
Referenced by handle_cli_indication_add(), and parse_tone_zone().
00623 { 00624 return ao2_alloc(sizeof(struct ast_tone_zone), ast_tone_zone_destructor); 00625 }
| static int ast_tone_zone_cmp | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1096 of file indications.c.
References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.
Referenced by ast_indications_init().
01097 { 01098 struct ast_tone_zone *zone = obj; 01099 struct ast_tone_zone *zone_arg = arg; 01100 01101 return (!strcasecmp(zone->country, zone_arg->country)) ? 01102 CMP_MATCH | CMP_STOP : 0; 01103 }
| int ast_tone_zone_count | ( | void | ) |
Get the number of registered tone zones.
Definition at line 395 of file indications.c.
References ao2_container_count().
00396 { 00397 return ao2_container_count(ast_tone_zones); 00398 }
| static void ast_tone_zone_destructor | ( | void * | obj | ) | [static] |
deallocate the passed tone zone
Definition at line 504 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().
00505 { 00506 struct ast_tone_zone *zone = obj; 00507 struct ast_tone_zone_sound *current; 00508 00509 while ((current = AST_LIST_REMOVE_HEAD(&zone->tones, entry))) { 00510 current = ast_tone_zone_sound_unref(current); 00511 } 00512 00513 if (zone->ringcadence) { 00514 ast_free(zone->ringcadence); 00515 zone->ringcadence = NULL; 00516 } 00517 }
| static int ast_tone_zone_hash | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1089 of file indications.c.
References ast_str_case_hash(), and ast_tone_zone::country.
Referenced by ast_indications_init().
01090 { 01091 const struct ast_tone_zone *zone = obj; 01092 01093 return ast_str_case_hash(zone->country); 01094 }
| struct ao2_iterator ast_tone_zone_iterator_init | ( | void | ) | [read] |
Get an iterator for the available tone zones.
Use ao2_iterator_next() to iterate the tone zones.
Definition at line 400 of file indications.c.
References ao2_iterator_init().
Referenced by ast_var_indications(), ast_var_indications_table(), and handle_cli_indication_show().
00401 { 00402 return ao2_iterator_init(ast_tone_zones, 0); 00403 }
| 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 244 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().
00245 { 00246 if (sscanf(s, "%30u+%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00247 &tone_data->time) == 3) { 00248 /* f1+f2/time format */ 00249 } else if (sscanf(s, "%30u+%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00250 /* f1+f2 format */ 00251 tone_data->time = 0; 00252 } else if (sscanf(s, "%30u*%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00253 &tone_data->time) == 3) { 00254 /* f1*f2/time format */ 00255 tone_data->modulate = 1; 00256 } else if (sscanf(s, "%30u*%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00257 /* f1*f2 format */ 00258 tone_data->time = 0; 00259 tone_data->modulate = 1; 00260 } else if (sscanf(s, "%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) { 00261 /* f1/time format */ 00262 tone_data->freq2 = 0; 00263 } else if (sscanf(s, "%30u", &tone_data->freq1) == 1) { 00264 /* f1 format */ 00265 tone_data->freq2 = 0; 00266 tone_data->time = 0; 00267 } else if (sscanf(s, "M%30u+M%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00268 &tone_data->time) == 3) { 00269 /* Mf1+Mf2/time format */ 00270 tone_data->midinote = 1; 00271 } else if (sscanf(s, "M%30u+M%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00272 /* Mf1+Mf2 format */ 00273 tone_data->time = 0; 00274 tone_data->midinote = 1; 00275 } else if (sscanf(s, "M%30u*M%30u/%30u", &tone_data->freq1, &tone_data->freq2, 00276 &tone_data->time) == 3) { 00277 /* Mf1*Mf2/time format */ 00278 tone_data->modulate = 1; 00279 tone_data->midinote = 1; 00280 } else if (sscanf(s, "M%30u*M%30u", &tone_data->freq1, &tone_data->freq2) == 2) { 00281 /* Mf1*Mf2 format */ 00282 tone_data->time = 0; 00283 tone_data->modulate = 1; 00284 tone_data->midinote = 1; 00285 } else if (sscanf(s, "M%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) { 00286 /* Mf1/time format */ 00287 tone_data->freq2 = -1; 00288 tone_data->midinote = 1; 00289 } else if (sscanf(s, "M%30u", &tone_data->freq1) == 1) { 00290 /* Mf1 format */ 00291 tone_data->freq2 = -1; 00292 tone_data->time = 0; 00293 tone_data->midinote = 1; 00294 } else { 00295 return -1; 00296 } 00297 00298 return 0; 00299 }
| static void ast_tone_zone_sound_destructor | ( | void * | obj | ) | [static] |
Definition at line 487 of file indications.c.
References ast_free, ast_tone_zone_sound::data, and ast_tone_zone_sound::name.
Referenced by ast_register_indication().
00488 { 00489 struct ast_tone_zone_sound *ts = obj; 00490 00491 /* Deconstify the 'const char *'s so the compiler doesn't complain. (but it's safe) */ 00492 if (ts->name) { 00493 ast_free((char *) ts->name); 00494 ts->name = NULL; 00495 } 00496 00497 if (ts->data) { 00498 ast_free((char *) ts->data); 00499 ts->data = NULL; 00500 } 00501 }
| static int ast_unregister_indication | ( | struct ast_tone_zone * | zone, | |
| const char * | indication | |||
| ) | [static] |
Definition at line 600 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().
00601 { 00602 struct ast_tone_zone_sound *ts; 00603 int res = -1; 00604 00605 ast_tone_zone_lock(zone); 00606 00607 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) { 00608 if (!strcasecmp(indication, ts->name)) { 00609 AST_LIST_REMOVE_CURRENT(entry); 00610 ts = ast_tone_zone_sound_unref(ts); 00611 res = 0; 00612 break; 00613 } 00614 } 00615 AST_LIST_TRAVERSE_SAFE_END; 00616 00617 ast_tone_zone_unlock(zone); 00618 00619 return res; 00620 }
| static int ast_unregister_indication_country | ( | const char * | country | ) | [static] |
Definition at line 536 of file indications.c.
References ao2_callback, ao2_find, ao2_lock(), ao2_unlink, ao2_unlock(), ast_copy_string(), ast_tone_zone_unref(), ast_tone_zone::country, ast_tone_zone::nrringcadence, and OBJ_POINTER.
Referenced by handle_cli_indication_add(), and handle_cli_indication_remove().
00537 { 00538 struct ast_tone_zone *tz = NULL; 00539 struct ast_tone_zone zone_arg = { 00540 .nrringcadence = 0, 00541 }; 00542 00543 ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country)); 00544 00545 if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) { 00546 return -1; 00547 } 00548 00549 ao2_lock(ast_tone_zones); 00550 if (default_tone_zone == tz) { 00551 ast_tone_zone_unref(default_tone_zone); 00552 /* Get a new default, punt to the first one we find */ 00553 default_tone_zone = ao2_callback(ast_tone_zones, 0, NULL, NULL); 00554 } 00555 ao2_unlock(ast_tone_zones); 00556 00557 ao2_unlink(ast_tone_zones, tz); 00558 00559 tz = ast_tone_zone_unref(tz); 00560 00561 return 0; 00562 }
| static char* complete_country | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 627 of file indications.c.
References ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_tone_zone_unref(), ast_tone_zone::country, ast_cli_args::n, and ast_cli_args::word.
Referenced by handle_cli_indication_add(), handle_cli_indication_remove(), and handle_cli_indication_show().
00628 { 00629 char *res = NULL; 00630 struct ao2_iterator i; 00631 int which = 0; 00632 size_t wordlen; 00633 struct ast_tone_zone *tz; 00634 00635 wordlen = strlen(a->word); 00636 00637 i = ao2_iterator_init(ast_tone_zones, 0); 00638 while ((tz = ao2_iterator_next(&i))) { 00639 if (!strncasecmp(a->word, tz->country, wordlen) && ++which > a->n) { 00640 res = ast_strdup(tz->country); 00641 } 00642 tz = ast_tone_zone_unref(tz); 00643 if (res) { 00644 break; 00645 } 00646 } 00647 00648 return res; 00649 }
| static char* complete_indications | ( | struct ast_cli_args * | a | ) | [static] |
Definition at line 712 of file indications.c.
References ao2_find, ast_cli_args::argv, ast_copy_string(), AST_LIST_TRAVERSE, ast_strdup, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_unref(), ast_tone_zone::country, ast_cli_args::n, ast_tone_zone_sound::name, OBJ_POINTER, ast_cli_args::pos, ast_tone_zone::tones, and ast_cli_args::word.
Referenced by handle_cli_indication_remove().
00713 { 00714 char *res = NULL; 00715 int which = 0; 00716 size_t wordlen; 00717 struct ast_tone_zone_sound *ts; 00718 struct ast_tone_zone *tz, tmp_tz = { 00719 .nrringcadence = 0, 00720 }; 00721 00722 ast_copy_string(tmp_tz.country, a->argv[a->pos - 1], sizeof(tmp_tz.country)); 00723 00724 if (!(tz = ao2_find(ast_tone_zones, &tmp_tz, OBJ_POINTER))) { 00725 return NULL; 00726 } 00727 00728 wordlen = strlen(a->word); 00729 00730 ast_tone_zone_lock(tz); 00731 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00732 if (!strncasecmp(a->word, ts->name, wordlen) && ++which > a->n) { 00733 res = ast_strdup(ts->name); 00734 break; 00735 } 00736 } 00737 ast_tone_zone_unlock(tz); 00738 00739 tz = ast_tone_zone_unref(tz); 00740 00741 return res; 00742 }
| static char* handle_cli_indication_add | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 651 of file indications.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_copy_string(), ast_get_indication_zone(), ast_log(), ast_register_indication(), ast_register_indication_country(), ast_tone_zone_alloc(), ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_unref(), ast_unregister_indication_country(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_country(), ast_tone_zone::country, LOG_NOTICE, LOG_WARNING, ast_cli_args::pos, and ast_cli_entry::usage.
00652 { 00653 struct ast_tone_zone *tz; 00654 int created_country = 0; 00655 char *res = CLI_SUCCESS; 00656 00657 switch (cmd) { 00658 case CLI_INIT: 00659 e->command = "indication add"; 00660 e->usage = 00661 "Usage: indication add <country> <indication> \"<tonelist>\"\n" 00662 " Add the given indication to the country.\n"; 00663 return NULL; 00664 case CLI_GENERATE: 00665 if (a->pos == 2) { 00666 return complete_country(a); 00667 } else { 00668 return NULL; 00669 } 00670 } 00671 00672 if (a->argc != 5) { 00673 return CLI_SHOWUSAGE; 00674 } 00675 00676 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00677 /* country does not exist, create it */ 00678 ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n", a->argv[2]); 00679 00680 if (!(tz = ast_tone_zone_alloc())) { 00681 return CLI_FAILURE; 00682 } 00683 00684 ast_copy_string(tz->country, a->argv[2], sizeof(tz->country)); 00685 00686 if (ast_register_indication_country(tz)) { 00687 ast_log(LOG_WARNING, "Unable to register new country\n"); 00688 tz = ast_tone_zone_unref(tz); 00689 return CLI_FAILURE; 00690 } 00691 00692 created_country = 1; 00693 } 00694 00695 ast_tone_zone_lock(tz); 00696 00697 if (ast_register_indication(tz, a->argv[3], a->argv[4])) { 00698 ast_log(LOG_WARNING, "Unable to register indication %s/%s\n", a->argv[2], a->argv[3]); 00699 if (created_country) { 00700 ast_unregister_indication_country(a->argv[2]); 00701 } 00702 res = CLI_FAILURE; 00703 } 00704 00705 ast_tone_zone_unlock(tz); 00706 00707 tz = ast_tone_zone_unref(tz); 00708 00709 return res; 00710 }
| static char* handle_cli_indication_remove | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 744 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, and ast_cli_entry::usage.
00745 { 00746 struct ast_tone_zone *tz; 00747 char *res = CLI_SUCCESS; 00748 00749 switch (cmd) { 00750 case CLI_INIT: 00751 e->command = "indication remove"; 00752 e->usage = 00753 "Usage: indication remove <country> [indication]\n" 00754 " Remove the given indication from the country.\n"; 00755 return NULL; 00756 case CLI_GENERATE: 00757 if (a->pos == 2) { 00758 return complete_country(a); 00759 } else if (a->pos == 3) { 00760 return complete_indications(a); 00761 } 00762 } 00763 00764 if (a->argc != 3 && a->argc != 4) { 00765 return CLI_SHOWUSAGE; 00766 } 00767 00768 if (a->argc == 3) { 00769 /* remove entire country */ 00770 if (ast_unregister_indication_country(a->argv[2])) { 00771 ast_log(LOG_WARNING, "Unable to unregister indication country %s\n", a->argv[2]); 00772 return CLI_FAILURE; 00773 } 00774 00775 return CLI_SUCCESS; 00776 } 00777 00778 if (!(tz = ast_get_indication_zone(a->argv[2]))) { 00779 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n", a->argv[2], a->argv[3]); 00780 return CLI_FAILURE; 00781 } 00782 00783 if (ast_unregister_indication(tz, a->argv[3])) { 00784 ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n", a->argv[2], a->argv[3]); 00785 res = CLI_FAILURE; 00786 } 00787 00788 tz = ast_tone_zone_unref(tz); 00789 00790 return res; 00791 }
| static char* handle_cli_indication_show | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 793 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(), buf, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, complete_country(), ast_tone_zone::country, ast_tone_zone_sound::data, ast_tone_zone::description, ast_tone_zone_sound::entry, ast_cli_args::fd, ast_tone_zone_sound::name, ast_tone_zone::nrringcadence, OBJ_POINTER, ast_tone_zone::ringcadence, ast_tone_zone::tones, and ast_cli_entry::usage.
00794 { 00795 struct ast_tone_zone *tz = NULL; 00796 struct ast_str *buf; 00797 int found_country = 0; 00798 int i; 00799 00800 switch (cmd) { 00801 case CLI_INIT: 00802 e->command = "indication show"; 00803 e->usage = 00804 "Usage: indication show [<country> ...]\n" 00805 " Display either a condensed summary of all countries and indications, or a\n" 00806 " more verbose list of indications for the specified countries.\n"; 00807 return NULL; 00808 case CLI_GENERATE: 00809 return complete_country(a); 00810 } 00811 00812 if (a->argc == 2) { 00813 struct ao2_iterator iter; 00814 /* no arguments, show a list of countries */ 00815 ast_cli(a->fd, "Country Description\n"); 00816 ast_cli(a->fd, "===========================\n"); 00817 iter = ast_tone_zone_iterator_init(); 00818 while ((tz = ao2_iterator_next(&iter))) { 00819 ast_tone_zone_lock(tz); 00820 ast_cli(a->fd, "%-7.7s %s\n", tz->country, tz->description); 00821 ast_tone_zone_unlock(tz); 00822 tz = ast_tone_zone_unref(tz); 00823 } 00824 return CLI_SUCCESS; 00825 } 00826 00827 buf = ast_str_alloca(256); 00828 00829 for (i = 2; i < a->argc; i++) { 00830 struct ast_tone_zone zone_arg = { 00831 .nrringcadence = 0, 00832 }; 00833 struct ast_tone_zone_sound *ts; 00834 int j; 00835 00836 ast_copy_string(zone_arg.country, a->argv[i], sizeof(zone_arg.country)); 00837 00838 if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) { 00839 continue; 00840 } 00841 00842 if (!found_country) { 00843 found_country = 1; 00844 ast_cli(a->fd, "Country Indication PlayList\n"); 00845 ast_cli(a->fd, "=====================================\n"); 00846 } 00847 00848 ast_tone_zone_lock(tz); 00849 00850 ast_str_set(&buf, 0, "%-7.7s %-15.15s ", tz->country, "<ringcadence>"); 00851 for (j = 0; j < tz->nrringcadence; j++) { 00852 ast_str_append(&buf, 0, "%d%s", tz->ringcadence[j], 00853 (j == tz->nrringcadence - 1) ? "" : ","); 00854 } 00855 ast_str_append(&buf, 0, "\n"); 00856 ast_cli(a->fd, "%s", buf->str); 00857 00858 AST_LIST_TRAVERSE(&tz->tones, ts, entry) { 00859 ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data); 00860 } 00861 00862 ast_tone_zone_unlock(tz); 00863 tz = ast_tone_zone_unref(tz); 00864 } 00865 00866 if (!found_country) { 00867 ast_cli(a->fd, "No countries matched your criteria.\n"); 00868 } 00869 00870 return CLI_SUCCESS; 00871 }
| static int is_valid_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 873 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().
00874 { 00875 int res; 00876 00877 ast_tone_zone_lock(zone); 00878 res = (!ast_strlen_zero(zone->description) && !AST_LIST_EMPTY(&zone->tones)); 00879 ast_tone_zone_unlock(zone); 00880 00881 return res; 00882 }
| static int load_indications | ( | int | reload | ) | [static] |
load indications module
Definition at line 1030 of file indications.c.
References ao2_callback, ao2_lock(), ao2_unlock(), ast_category_browse(), ast_config_destroy(), ast_config_load2(), ast_log(), ast_set_indication_country(), ast_strlen_zero(), ast_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, country, LOG_ERROR, 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().
01031 { 01032 struct ast_config *cfg; 01033 const char *cxt = NULL; 01034 const char *country = NULL; 01035 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 01036 int res = -1; 01037 01038 cfg = ast_config_load2(config, "indications", config_flags); 01039 01040 if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) { 01041 ast_log(LOG_ERROR, "Can't find indications config file %s.\n", config); 01042 return -1; 01043 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 01044 return 0; 01045 } 01046 01047 /* Lock the container to prevent multiple simultaneous reloads */ 01048 ao2_lock(ast_tone_zones); 01049 01050 ao2_callback(ast_tone_zones, OBJ_NODATA, tone_zone_mark, NULL); 01051 01052 /* Use existing config to populate the Indication table */ 01053 while ((cxt = ast_category_browse(cfg, cxt))) { 01054 /* All categories but "general" are considered countries */ 01055 if (!strcasecmp(cxt, "general")) { 01056 continue; 01057 } 01058 01059 if (parse_tone_zone(cfg, cxt)) { 01060 goto return_cleanup; 01061 } 01062 } 01063 01064 ao2_callback(ast_tone_zones, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, 01065 prune_tone_zone, NULL); 01066 01067 /* determine which country is the default */ 01068 country = ast_variable_retrieve(cfg, "general", "country"); 01069 if (ast_strlen_zero(country) || ast_set_indication_country(country)) { 01070 ast_log(LOG_WARNING, "Unable to set the default country (for indication tones)\n"); 01071 } 01072 01073 res = 0; 01074 01075 return_cleanup: 01076 ao2_unlock(ast_tone_zones); 01077 ast_config_destroy(cfg); 01078 01079 return res; 01080 }
| static int parse_tone_zone | ( | struct ast_config * | cfg, | |
| const char * | country | |||
| ) | [static] |
Definition at line 943 of file indications.c.
References ao2_find, ast_copy_string(), ast_log(), ast_register_indication_country(), ast_tone_zone_alloc(), ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_unref(), ast_variable_browse(), ast_tone_zone::country, is_valid_tone_zone(), LOG_WARNING, ast_variable::name, ast_variable::next, ast_tone_zone::nrringcadence, OBJ_POINTER, reset_tone_zone(), store_config_tone_zone(), and ast_variable::value.
Referenced by load_indications().
00944 { 00945 struct ast_variable *v; 00946 struct ast_tone_zone *zone; 00947 struct ast_tone_zone tmp_zone = { 00948 .nrringcadence = 0, 00949 }; 00950 int allocd = 0; 00951 00952 ast_copy_string(tmp_zone.country, country, sizeof(tmp_zone.country)); 00953 00954 if ((zone = ao2_find(ast_tone_zones, &tmp_zone, OBJ_POINTER))) { 00955 reset_tone_zone(zone); 00956 } else if ((zone = ast_tone_zone_alloc())) { 00957 allocd = 1; 00958 ast_copy_string(zone->country, country, sizeof(zone->country)); 00959 } else { 00960 return -1; 00961 } 00962 00963 ast_tone_zone_lock(zone); 00964 for (v = ast_variable_browse(cfg, country); v; v = v->next) { 00965 store_config_tone_zone(zone, v->name, v->value); 00966 } 00967 ast_tone_zone_unlock(zone); 00968 00969 if (allocd) { 00970 if (!is_valid_tone_zone(zone)) { 00971 ast_log(LOG_WARNING, "Indication country '%s' is invalid\n", country); 00972 } else if (ast_register_indication_country(zone)) { 00973 ast_log(LOG_WARNING, "Unable to register indication country '%s'.\n", 00974 country); 00975 } 00976 } 00977 00978 zone = ast_tone_zone_unref(zone); 00979 00980 return 0; 00981 }
| static void* playtones_alloc | ( | struct ast_channel * | chan, | |
| void * | params | |||
| ) | [static] |
Definition at line 127 of file indications.c.
References ast_calloc, ast_clear_flag, AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format(), playtones_def::interruptible, playtones_def::items, playtones_state::items, LOG_WARNING, ast_channel::name, playtones_def::nitems, playtones_state::nitems, playtones_state::oldnpos, playtones_state::origwfmt, pd, playtones_release(), ps, playtones_def::reppos, playtones_state::reppos, playtones_def::vol, playtones_state::vol, and ast_channel::writeformat.
00128 { 00129 struct playtones_def *pd = params; 00130 struct playtones_state *ps = NULL; 00131 00132 if (!(ps = ast_calloc(1, sizeof(*ps)))) { 00133 return NULL; 00134 } 00135 00136 ps->origwfmt = chan->writeformat; 00137 00138 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) { 00139 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name); 00140 playtones_release(NULL, ps); 00141 ps = NULL; 00142 } else { 00143 ps->vol = pd->vol; 00144 ps->reppos = pd->reppos; 00145 ps->nitems = pd->nitems; 00146 ps->items = pd->items; 00147 ps->oldnpos = -1; 00148 } 00149 00150 /* Let interrupts interrupt :) */ 00151 if (pd->interruptible) { 00152 ast_set_flag(chan, AST_FLAG_WRITE_INT); 00153 } else { 00154 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 00155 } 00156 00157 return ps; 00158 }
| static int playtones_generator | ( | struct ast_channel * | chan, | |
| void * | data, | |||
| int | len, | |||
| int | samples | |||
| ) | [static] |
Definition at line 160 of file indications.c.
References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), ast_frame::data, playtones_state::data, ast_frame::datalen, playtones_item::duration, playtones_state::f, playtones_item::fac1, playtones_item::fac2, ast_frame::frametype, playtones_item::init_v2_1, playtones_item::init_v2_2, playtones_item::init_v3_1, playtones_item::init_v3_2, playtones_state::items, LOG_WARNING, playtones_item::modulate, playtones_state::nitems, playtones_state::npos, ast_frame::offset, playtones_state::oldnpos, playtones_state::pos, ps, ast_frame::ptr, playtones_state::reppos, ast_frame::samples, ast_frame::subclass, playtones_state::v1_1, playtones_state::v1_2, playtones_state::v2_1, playtones_state::v2_2, playtones_state::v3_1, and playtones_state::v3_2.
00161 { 00162 struct playtones_state *ps = data; 00163 struct playtones_item *pi; 00164 int x; 00165 00166 /* we need to prepare a frame with 16 * timelen samples as we're 00167 * generating SLIN audio */ 00168 00169 len = samples * 2; 00170 if (len > sizeof(ps->data) / 2 - 1) { 00171 ast_log(LOG_WARNING, "Can't generate that much data!\n"); 00172 return -1; 00173 } 00174 00175 memset(&ps->f, 0, sizeof(ps->f)); 00176 00177 pi = &ps->items[ps->npos]; 00178 00179 if (ps->oldnpos != ps->npos) { 00180 /* Load new parameters */ 00181 ps->v1_1 = 0; 00182 ps->v2_1 = pi->init_v2_1; 00183 ps->v3_1 = pi->init_v3_1; 00184 ps->v1_2 = 0; 00185 ps->v2_2 = pi->init_v2_2; 00186 ps->v3_2 = pi->init_v3_2; 00187 ps->oldnpos = ps->npos; 00188 } 00189 00190 for (x = 0; x < samples; x++) { 00191 ps->v1_1 = ps->v2_1; 00192 ps->v2_1 = ps->v3_1; 00193 ps->v3_1 = (pi->fac1 * ps->v2_1 >> 15) - ps->v1_1; 00194 00195 ps->v1_2 = ps->v2_2; 00196 ps->v2_2 = ps->v3_2; 00197 ps->v3_2 = (pi->fac2 * ps->v2_2 >> 15) - ps->v1_2; 00198 if (pi->modulate) { 00199 int p; 00200 p = ps->v3_2 - 32768; 00201 if (p < 0) { 00202 p = -p; 00203 } 00204 p = ((p * 9) / 10) + 1; 00205 ps->data[x] = (ps->v3_1 * p) >> 15; 00206 } else { 00207 ps->data[x] = ps->v3_1 + ps->v3_2; 00208 } 00209 } 00210 00211 ps->f.frametype = AST_FRAME_VOICE; 00212 ps->f.subclass = AST_FORMAT_SLINEAR; 00213 ps->f.datalen = len; 00214 ps->f.samples = samples; 00215 ps->f.offset = AST_FRIENDLY_OFFSET; 00216 ps->f.data.ptr = ps->data; 00217 00218 if (ast_write(chan, &ps->f)) { 00219 return -1; 00220 } 00221 00222 ps->pos += x; 00223 00224 if (pi->duration && ps->pos >= pi->duration * 8) { /* item finished? */ 00225 ps->pos = 0; /* start new item */ 00226 ps->npos++; 00227 if (ps->npos >= ps->nitems) { /* last item? */ 00228 if (ps->reppos == -1) { /* repeat set? */ 00229 return -1; 00230 } 00231 ps->npos = ps->reppos; /* redo from top */ 00232 } 00233 } 00234 00235 return 0; 00236 }
| static void playtones_release | ( | struct ast_channel * | chan, | |
| void * | params | |||
| ) | [static] |
Definition at line 111 of file indications.c.
References ast_free, ast_set_write_format(), playtones_state::items, playtones_state::origwfmt, and ps.
Referenced by playtones_alloc().
00112 { 00113 struct playtones_state *ps = params; 00114 00115 if (chan) { 00116 ast_set_write_format(chan, ps->origwfmt); 00117 } 00118 00119 if (ps->items) { 00120 ast_free(ps->items); 00121 ps->items = NULL; 00122 } 00123 00124 ast_free(ps); 00125 }
| 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 1009 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, s, and ast_tone_zone::tones.
Referenced by load_indications().
01010 { 01011 struct ast_tone_zone *zone = obj; 01012 struct ast_tone_zone_sound *s; 01013 01014 ast_tone_zone_lock(zone); 01015 01016 AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, s, entry) { 01017 if (s->killme) { 01018 AST_LIST_REMOVE_CURRENT(entry); 01019 s = ast_tone_zone_sound_unref(s); 01020 } 01021 } 01022 AST_LIST_TRAVERSE_SAFE_END; 01023 01024 ast_tone_zone_unlock(zone); 01025 01026 return zone->killme ? CMP_MATCH : 0; 01027 }
| static void reset_tone_zone | ( | struct ast_tone_zone * | zone | ) | [static] |
Definition at line 928 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().
00929 { 00930 ast_tone_zone_lock(zone); 00931 00932 zone->killme = 0; 00933 00934 if (zone->nrringcadence) { 00935 zone->nrringcadence = 0; 00936 ast_free(zone->ringcadence); 00937 zone->ringcadence = NULL; 00938 } 00939 00940 ast_tone_zone_unlock(zone); 00941 }
| static void store_config_tone_zone | ( | struct ast_tone_zone * | zone, | |
| const char * | var, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 914 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().
00916 { 00917 CV_START(var, value); 00918 00919 CV_STR("description", zone->description); 00920 CV_F("ringcadence", store_tone_zone_ring_cadence(zone, value)); 00921 CV_F("ringcadance", store_tone_zone_ring_cadence(zone, value)); 00922 00923 ast_register_indication(zone, var, value); 00924 00925 CV_END; 00926 }
| static void store_tone_zone_ring_cadence | ( | struct ast_tone_zone * | zone, | |
| const char * | val | |||
| ) | [static] |
Definition at line 887 of file indications.c.
References ast_copy_string(), ast_log(), ast_realloc, ast_strip(), buf, LOG_WARNING, ast_tone_zone::nrringcadence, ring(), and ast_tone_zone::ringcadence.
Referenced by store_config_tone_zone().
00888 { 00889 char buf[1024]; 00890 char *ring, *c = buf; 00891 00892 ast_copy_string(buf, val, sizeof(buf)); 00893 00894 while ((ring = strsep(&c, ","))) { 00895 int *tmp, val; 00896 00897 ring = ast_strip(ring); 00898 00899 if (!isdigit(ring[0]) || (val = atoi(ring)) == -1) { 00900 ast_log(LOG_WARNING, "Invalid ringcadence given '%s'.\n", ring); 00901 continue; 00902 } 00903 00904 if (!(tmp = ast_realloc(zone->ringcadence, (zone->nrringcadence + 1) * sizeof(int)))) { 00905 return; 00906 } 00907 00908 zone->ringcadence = tmp; 00909 tmp[zone->nrringcadence] = val; 00910 zone->nrringcadence++; 00911 } 00912 }
| 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 987 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, s, and ast_tone_zone::tones.
Referenced by load_indications().
00988 { 00989 struct ast_tone_zone *zone = obj; 00990 struct ast_tone_zone_sound *s; 00991 00992 ast_tone_zone_lock(zone); 00993 00994 zone->killme = 1; 00995 00996 AST_LIST_TRAVERSE(&zone->tones, s, entry) { 00997 s->killme = 1; 00998 } 00999 01000 ast_tone_zone_unlock(zone); 01001 01002 return 0; 01003 }
struct ao2_container* ast_tone_zones [static] |
Definition at line 63 of file indications.c.
struct ast_cli_entry cli_indications[] [static] |
{
AST_CLI_DEFINE(handle_cli_indication_add, "Add the given indication to the country"),
AST_CLI_DEFINE(handle_cli_indication_remove, "Remove the given indication from the country"),
AST_CLI_DEFINE(handle_cli_indication_show, "Display a list of all countries/indications")
}
CLI entries for commands provided by this module.
Definition at line 1083 of file indications.c.
const char config[] = "indications.conf" [static] |
Definition at line 45 of file indications.c.
struct ast_tone_zone* default_tone_zone [static] |
Definition at line 70 of file indications.c.
const int midi_tohz[128] [static] |
Definition at line 47 of file indications.c.
struct ast_generator playtones [static] |
{
.alloc = playtones_alloc,
.release = playtones_release,
.generate = playtones_generator,
}
Definition at line 238 of file indications.c.
1.6.2