#include "asterisk/lock.h"
Go to the source code of this file.
Data Structures | |
struct | tone_zone |
struct | tone_zone_sound |
Description is a series of tones of the format: [!]freq1[+freq2][/duration] separated by commas. There are no spaces. The sequence is repeated back to the first tone description not preceeded by !. Duration is specified in milliseconds. More... | |
Functions | |
tone_zone_sound * | ast_get_indication_tone (const struct tone_zone *zone, const char *indication) |
locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone | |
tone_zone * | ast_get_indication_zone (const char *country) |
locate tone_zone, given the country. if country == NULL, use the default country | |
int | ast_playtones_start (struct ast_channel *chan, int vol, const char *tonelist, int interruptible) |
Start a tone-list going. | |
void | ast_playtones_stop (struct ast_channel *chan) |
Stop the tones from playing. | |
int | ast_register_indication (struct tone_zone *zone, const char *indication, const char *tonelist) |
add a new indication to a tone_zone. tone_zone must exist. if the indication already exists, it will be replaced. | |
int | ast_register_indication_country (struct tone_zone *country) |
add a new country, if country exists, it will be replaced. | |
int | ast_set_indication_country (const char *country) |
set the default tone country | |
int | ast_unregister_indication (struct tone_zone *zone, const char *indication) |
remove an existing tone_zone's indication. tone_zone must exist | |
int | ast_unregister_indication_country (const char *country) |
remove an existing country and all its indications, country must exist | |
tone_zone * | ast_walk_indications (const struct tone_zone *cur) |
support for walking through a list of indications |
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Primary Author: Pauline Middelink <middelink@polyware.nl>
Definition in file indications.h.
struct tone_zone_sound* ast_get_indication_tone | ( | const struct tone_zone * | zone, | |
const char * | indication | |||
) |
locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone
Definition at line 414 of file indications.c.
References AST_LIST_FIRST, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, current_tonezone, tone_zone_sound::name, tone_zone_sound::next, and 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().
00415 { 00416 struct tone_zone_sound *ts = NULL; 00417 00418 AST_RWLIST_RDLOCK(&tone_zones); 00419 00420 /* If no zone is already specified we need to try to pick one */ 00421 if (!zone) { 00422 if (current_tonezone) { 00423 zone = current_tonezone; 00424 } else if (!(zone = AST_LIST_FIRST(&tone_zones))) { 00425 /* No zone has been found ;( */ 00426 AST_RWLIST_UNLOCK(&tone_zones); 00427 return NULL; 00428 } 00429 } 00430 00431 /* Look through list of tones in the zone searching for the right one */ 00432 for (ts = zone->tones; ts; ts = ts->next) { 00433 if (!strcasecmp(ts->name, indication)) 00434 break; 00435 } 00436 00437 AST_RWLIST_UNLOCK(&tone_zones); 00438 00439 return ts; 00440 }
struct tone_zone* ast_get_indication_zone | ( | const char * | country | ) |
locate tone_zone, given the country. if country == NULL, use the default country
Definition at line 379 of file indications.c.
References tone_zone::alias, AST_LIST_FIRST, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), tone_zone::country, current_tonezone, and LOG_NOTICE.
Referenced by ast_set_indication_country(), build_device(), func_channel_write(), handle_cli_indication_add(), and handle_cli_indication_remove().
00380 { 00381 struct tone_zone *tz = NULL; 00382 int alias_loop = 0; 00383 00384 AST_RWLIST_RDLOCK(&tone_zones); 00385 00386 if (ast_strlen_zero(country)) { 00387 tz = current_tonezone ? current_tonezone : AST_LIST_FIRST(&tone_zones); 00388 } else { 00389 do { 00390 AST_RWLIST_TRAVERSE(&tone_zones, tz, list) { 00391 if (!strcasecmp(tz->country, country)) 00392 break; 00393 } 00394 if (!tz) 00395 break; 00396 /* If this is an alias then we have to search yet again otherwise we have found the zonezone */ 00397 if (tz->alias && tz->alias[0]) 00398 country = tz->alias; 00399 else 00400 break; 00401 } while ((++alias_loop < 20) && tz); 00402 } 00403 00404 AST_RWLIST_UNLOCK(&tone_zones); 00405 00406 /* If we reached the maximum loops to find the proper country via alias, print out a notice */ 00407 if (alias_loop == 20) 00408 ast_log(LOG_NOTICE, "Alias loop for '%s' is bonkers\n", country); 00409 00410 return tz; 00411 }
int ast_playtones_start | ( | struct ast_channel * | chan, | |
int | vol, | |||
const char * | tonelist, | |||
int | interruptible | |||
) |
Start a tone-list going.
Definition at line 215 of file indications.c.
00216 { 00217 char *s, *data = ast_strdupa(playlst); /* cute */ 00218 struct playtones_def d = { vol, -1, 0, 1, NULL}; 00219 char *stringp; 00220 char *separator; 00221 00222 if (vol < 1) 00223 d.vol = 7219; /* Default to -8db */ 00224 00225 d.interruptible = interruptible; 00226 00227 stringp=data; 00228 /* the stringp/data is not null here */ 00229 /* check if the data is separated with '|' or with ',' by default */ 00230 if (strchr(stringp,'|')) 00231 separator = "|"; 00232 else 00233 separator = ","; 00234 s = strsep(&stringp,separator); 00235 while (s && *s) { 00236 int freq1, freq2, duration, modulate = 0, midinote = 0; 00237 00238 if (s[0]=='!') 00239 s++; 00240 else if (d.reppos == -1) 00241 d.reppos = d.nitems; 00242 if (sscanf(s, "%30d+%30d/%30d", &freq1, &freq2, &duration) == 3) { 00243 /* f1+f2/time format */ 00244 } else if (sscanf(s, "%30d+%30d", &freq1, &freq2) == 2) { 00245 /* f1+f2 format */ 00246 duration = 0; 00247 } else if (sscanf(s, "%30d*%30d/%30d", &freq1, &freq2, &duration) == 3) { 00248 /* f1*f2/time format */ 00249 modulate = 1; 00250 } else if (sscanf(s, "%30d*%30d", &freq1, &freq2) == 2) { 00251 /* f1*f2 format */ 00252 duration = 0; 00253 modulate = 1; 00254 } else if (sscanf(s, "%30d/%30d", &freq1, &duration) == 2) { 00255 /* f1/time format */ 00256 freq2 = 0; 00257 } else if (sscanf(s, "%30d", &freq1) == 1) { 00258 /* f1 format */ 00259 freq2 = 0; 00260 duration = 0; 00261 } else if (sscanf(s, "M%30d+M%30d/%30d", &freq1, &freq2, &duration) == 3) { 00262 /* Mf1+Mf2/time format */ 00263 midinote = 1; 00264 } else if (sscanf(s, "M%30d+M%30d", &freq1, &freq2) == 2) { 00265 /* Mf1+Mf2 format */ 00266 duration = 0; 00267 midinote = 1; 00268 } else if (sscanf(s, "M%30d*M%30d/%30d", &freq1, &freq2, &duration) == 3) { 00269 /* Mf1*Mf2/time format */ 00270 modulate = 1; 00271 midinote = 1; 00272 } else if (sscanf(s, "M%30d*M%30d", &freq1, &freq2) == 2) { 00273 /* Mf1*Mf2 format */ 00274 duration = 0; 00275 modulate = 1; 00276 midinote = 1; 00277 } else if (sscanf(s, "M%30d/%30d", &freq1, &duration) == 2) { 00278 /* Mf1/time format */ 00279 freq2 = -1; 00280 midinote = 1; 00281 } else if (sscanf(s, "M%30d", &freq1) == 1) { 00282 /* Mf1 format */ 00283 freq2 = -1; 00284 duration = 0; 00285 midinote = 1; 00286 } else { 00287 ast_log(LOG_WARNING,"%s: tone component '%s' of '%s' is no good\n",chan->name,s,playlst); 00288 return -1; 00289 } 00290 00291 if (midinote) { 00292 /* midi notes must be between 0 and 127 */ 00293 if ((freq1 >= 0) && (freq1 <= 127)) 00294 freq1 = midi_tohz[freq1]; 00295 else 00296 freq1 = 0; 00297 00298 if ((freq2 >= 0) && (freq2 <= 127)) 00299 freq2 = midi_tohz[freq2]; 00300 else 00301 freq2 = 0; 00302 } 00303 00304 if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) { 00305 return -1; 00306 } 00307 d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0; 00308 d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * d.vol; 00309 d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * d.vol; 00310 00311 d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0; 00312 d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * d.vol; 00313 d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * d.vol; 00314 d.items[d.nitems].duration = duration; 00315 d.items[d.nitems].modulate = modulate; 00316 d.nitems++; 00317 00318 s = strsep(&stringp,separator); 00319 } 00320 00321 if (ast_activate_generator(chan, &playtones, &d)) { 00322 ast_free(d.items); 00323 return -1; 00324 } 00325 return 0; 00326 }
void ast_playtones_stop | ( | struct ast_channel * | chan | ) |
Stop the tones from playing.
Definition at line 328 of file indications.c.
00329 { 00330 ast_deactivate_generator(chan); 00331 }
int ast_register_indication | ( | struct tone_zone * | zone, | |
const char * | indication, | |||
const char * | tonelist | |||
) |
add a new indication to a tone_zone. tone_zone must exist. if the indication already exists, it will be replaced.
Definition at line 523 of file indications.c.
References tone_zone::alias, ast_free, ast_malloc, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, tone_zone_sound::data, tone_zone_sound::name, tone_zone_sound::next, ps, and tone_zone::tones.
Referenced by handle_cli_indication_add().
00524 { 00525 struct tone_zone_sound *ts, *ps; 00526 00527 /* is it an alias? stop */ 00528 if (zone->alias[0]) 00529 return -1; 00530 00531 AST_RWLIST_WRLOCK(&tone_zones); 00532 for (ps=NULL,ts=zone->tones; ts; ps=ts,ts=ts->next) { 00533 if (!strcasecmp(indication,ts->name)) { 00534 /* indication already there, replace */ 00535 ast_free((void*)ts->name); 00536 ast_free((void*)ts->data); 00537 break; 00538 } 00539 } 00540 if (!ts) { 00541 /* not there, we have to add */ 00542 if (!(ts = ast_malloc(sizeof(*ts)))) { 00543 AST_RWLIST_UNLOCK(&tone_zones); 00544 return -2; 00545 } 00546 ts->next = NULL; 00547 } 00548 if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) { 00549 AST_RWLIST_UNLOCK(&tone_zones); 00550 return -2; 00551 } 00552 if (ps) 00553 ps->next = ts; 00554 else 00555 zone->tones = ts; 00556 AST_RWLIST_UNLOCK(&tone_zones); 00557 return 0; 00558 }
int ast_register_indication_country | ( | struct tone_zone * | country | ) |
add a new country, if country exists, it will be replaced.
Definition at line 462 of file indications.c.
References AST_RWLIST_INSERT_TAIL, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, tone_zone::country, current_tonezone, and free_zone().
Referenced by handle_cli_indication_add(), and ind_load_module().
00463 { 00464 struct tone_zone *tz = NULL; 00465 00466 AST_RWLIST_WRLOCK(&tone_zones); 00467 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&tone_zones, tz, list) { 00468 /* If this is not the same zone, then just continue to the next entry */ 00469 if (strcasecmp(zone->country, tz->country)) 00470 continue; 00471 /* If this zone we are going to remove is the current default then make the new zone the default */ 00472 if (tz == current_tonezone) 00473 current_tonezone = zone; 00474 /* Remove from the linked list */ 00475 AST_RWLIST_REMOVE_CURRENT(list); 00476 /* Finally free the zone itself */ 00477 free_zone(tz); 00478 break; 00479 } 00480 AST_RWLIST_TRAVERSE_SAFE_END; 00481 00482 /* Add zone to the list */ 00483 AST_RWLIST_INSERT_TAIL(&tone_zones, zone, list); 00484 00485 /* It's all over. */ 00486 AST_RWLIST_UNLOCK(&tone_zones); 00487 00488 ast_verb(3, "Registered indication country '%s'\n", zone->country); 00489 00490 return 0; 00491 }
int ast_set_indication_country | ( | const char * | country | ) |
set the default tone country
Definition at line 359 of file indications.c.
References ast_get_indication_zone(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, and current_tonezone.
Referenced by ind_load_module().
00360 { 00361 struct tone_zone *zone = NULL; 00362 00363 /* If no country is specified or we are unable to find the zone, then return not found */ 00364 if (!country || !(zone = ast_get_indication_zone(country))) 00365 return 1; 00366 00367 ast_verb(3, "Setting default indication country to '%s'\n", country); 00368 00369 /* Protect the current tonezone using the tone_zones lock as well */ 00370 AST_RWLIST_WRLOCK(&tone_zones); 00371 current_tonezone = zone; 00372 AST_RWLIST_UNLOCK(&tone_zones); 00373 00374 /* Zone was found */ 00375 return 0; 00376 }
int ast_unregister_indication | ( | struct tone_zone * | zone, | |
const char * | indication | |||
) |
remove an existing tone_zone's indication. tone_zone must exist
Definition at line 561 of file indications.c.
References tone_zone::alias, ast_free, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, tone_zone_sound::data, tone_zone_sound::name, tone_zone_sound::next, ps, and tone_zone::tones.
Referenced by handle_cli_indication_remove().
00562 { 00563 struct tone_zone_sound *ts,*ps = NULL, *tmp; 00564 int res = -1; 00565 00566 /* is it an alias? stop */ 00567 if (zone->alias[0]) 00568 return -1; 00569 00570 AST_RWLIST_WRLOCK(&tone_zones); 00571 ts = zone->tones; 00572 while (ts) { 00573 if (!strcasecmp(indication,ts->name)) { 00574 /* indication found */ 00575 tmp = ts->next; 00576 if (ps) 00577 ps->next = tmp; 00578 else 00579 zone->tones = tmp; 00580 ast_free((void*)ts->name); 00581 ast_free((void*)ts->data); 00582 ast_free(ts); 00583 ts = tmp; 00584 res = 0; 00585 } 00586 else { 00587 /* next zone please */ 00588 ps = ts; 00589 ts = ts->next; 00590 } 00591 } 00592 /* indication not found, goodbye */ 00593 AST_RWLIST_UNLOCK(&tone_zones); 00594 return res; 00595 }
int ast_unregister_indication_country | ( | const char * | country | ) |
remove an existing country and all its indications, country must exist
Definition at line 495 of file indications.c.
References tone_zone::alias, ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, tone_zone::country, current_tonezone, free_zone(), and LOG_NOTICE.
Referenced by handle_cli_indication_add(), handle_cli_indication_remove(), ind_load_module(), and unload_module().
00496 { 00497 struct tone_zone *tz = NULL; 00498 int res = -1; 00499 00500 AST_RWLIST_WRLOCK(&tone_zones); 00501 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&tone_zones, tz, list) { 00502 if (country && (strcasecmp(country, tz->country) && strcasecmp(country, tz->alias))) 00503 continue; 00504 /* If this tonezone is the current default then unset it */ 00505 if (tz == current_tonezone) { 00506 ast_log(LOG_NOTICE,"Removed default indication country '%s'\n", tz->country); 00507 current_tonezone = NULL; 00508 } 00509 /* Remove from the list */ 00510 AST_RWLIST_REMOVE_CURRENT(list); 00511 ast_verb(3, "Unregistered indication country '%s'\n", tz->country); 00512 free_zone(tz); 00513 res = 0; 00514 } 00515 AST_RWLIST_TRAVERSE_SAFE_END; 00516 AST_RWLIST_UNLOCK(&tone_zones); 00517 00518 return res; 00519 }
support for walking through a list of indications
Definition at line 338 of file indications.c.
References AST_RWLIST_FIRST, AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.
Referenced by handle_cli_indication_show().
00339 { 00340 struct tone_zone *tz = NULL; 00341 00342 AST_RWLIST_RDLOCK(&tone_zones); 00343 /* If cur is not NULL, then we have to iterate through - otherwise just return the first entry */ 00344 if (cur) { 00345 AST_RWLIST_TRAVERSE(&tone_zones, tz, list) { 00346 if (tz == cur) 00347 break; 00348 } 00349 tz = AST_RWLIST_NEXT(tz, list); 00350 } else { 00351 tz = AST_RWLIST_FIRST(&tone_zones); 00352 } 00353 AST_RWLIST_UNLOCK(&tone_zones); 00354 00355 return tz; 00356 }