Wed Aug 18 22:34:25 2010

Asterisk developer's documentation


indications.h File Reference

BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01. More...

#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_soundast_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_zoneast_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_zoneast_walk_indications (const struct tone_zone *cur)
 support for walking through a list of indications


Detailed Description

BSD Telephony Of Mexico "Tormenta" Tone Zone Support 2/22/01.

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.


Function Documentation

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 }

struct tone_zone* ast_walk_indications ( const struct tone_zone cur  ) 

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 }


Generated on Wed Aug 18 22:34:25 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7