Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:34 2007

Asterisk developer's documentation :: Codename Pineapple


indications.h File Reference


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.

#include "asterisk/lock.h"

Include dependency graph for indications.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ind_tone_zone
struct  ind_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

ind_tone_zone_soundast_get_indication_tone (const struct ind_tone_zone *zone, const char *indication)
 locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone
ind_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 ind_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 ind_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 ind_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
ind_tone_zoneast_walk_indications (const struct ind_tone_zone *cur)
 support for walking through a list of indications


Function Documentation

struct ind_tone_zone_sound* ast_get_indication_tone const struct ind_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 423 of file indications.c.

References AST_LIST_FIRST, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, current_tonezone, ind_tone_zone_sound::name, ind_tone_zone_sound::next, and ind_tone_zone::tones.

Referenced by ast_app_dtget(), ast_indicate_data(), dialtone_indicate(), and handle_playtones().

00424 {
00425    struct ind_tone_zone_sound *ts = NULL;
00426 
00427    AST_RWLIST_RDLOCK(&tone_zones);
00428 
00429    /* If no zone is already specified we need to try to pick one */
00430    if (!zone) {
00431       if (current_tonezone) {
00432          zone = current_tonezone;
00433       } else if (!(zone = AST_LIST_FIRST(&tone_zones))) {
00434          /* No zone has been found ;( */
00435          AST_RWLIST_UNLOCK(&tone_zones);
00436          return NULL;
00437       }
00438    }
00439 
00440    /* Look through list of tones in the zone searching for the right one */
00441    for (ts = zone->tones; ts; ts = ts->next) {
00442       if (!strcasecmp(ts->name, indication))
00443          break;
00444    }
00445 
00446    AST_RWLIST_UNLOCK(&tone_zones);
00447 
00448    return ts;
00449 }

struct ind_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 385 of file indications.c.

References ind_tone_zone::alias, AST_LIST_FIRST, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ind_tone_zone::country, current_tonezone, and LOG_NOTICE.

Referenced by ast_set_indication_country(), handle_add_indication(), and handle_remove_indication().

00386 {
00387    struct ind_tone_zone *tz = NULL;
00388    int alias_loop = 0;
00389 
00390    AST_RWLIST_RDLOCK(&tone_zones);
00391 
00392    if (!country) {
00393       if (current_tonezone)
00394          tz = current_tonezone;
00395       else
00396          tz = AST_LIST_FIRST(&tone_zones);
00397    } else {
00398       do {
00399          AST_RWLIST_TRAVERSE(&tone_zones, tz, list) {
00400             if (!strcasecmp(tz->country, country))
00401                break;
00402          }
00403          if (!tz)
00404             break;
00405          /* If this is an alias then we have to search yet again otherwise we have found the zonezone */
00406          if (tz->alias && tz->alias[0])
00407             country = tz->alias;
00408          else
00409             break;
00410       } while ((++alias_loop < 20) && tz);
00411    }
00412 
00413    AST_RWLIST_UNLOCK(&tone_zones);
00414 
00415    /* If we reached the maximum loops to find the proper country via alias, print out a notice */
00416    if (alias_loop == 20)
00417       ast_log(LOG_NOTICE, "Alias loop for '%s' is bonkers\n", country);
00418 
00419    return tz;
00420 }

int ast_playtones_start struct ast_channel chan,
int  vol,
const char *  tonelist,
int  interruptible
 

Start a tone-list going.

Definition at line 220 of file indications.c.

References ast_activate_generator(), ast_log(), ast_realloc, ast_strdupa, playtones_item::duration, playtones_item::fac1, playtones_item::fac2, free, 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_WARNING, midi_tohz, playtones_item::modulate, playtones_def::nitems, playtones, playtones_def::reppos, s, strsep(), and playtones_def::vol.

Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_begin(), dialtone_indicate(), handle_playtones(), and send_digit_to_chan().

00221 {
00222    char *s, *data = ast_strdupa(playlst); /* cute */
00223    struct playtones_def d = { vol, -1, 0, 1, NULL};
00224    char *stringp;
00225    char *separator;
00226    
00227    if (vol < 1)
00228       d.vol = 7219; /* Default to -8db */
00229 
00230    d.interruptible = interruptible;
00231    
00232    stringp=data;
00233    /* the stringp/data is not null here */
00234    /* check if the data is separated with '|' or with ',' by default */
00235    if (strchr(stringp,'|'))
00236       separator = "|";
00237    else
00238       separator = ",";
00239    s = strsep(&stringp,separator);
00240    while (s && *s) {
00241       int freq1, freq2, time, modulate=0, midinote=0;
00242 
00243       if (s[0]=='!')
00244          s++;
00245       else if (d.reppos == -1)
00246          d.reppos = d.nitems;
00247       if (sscanf(s, "%d+%d/%d", &freq1, &freq2, &time) == 3) {
00248          /* f1+f2/time format */
00249       } else if (sscanf(s, "%d+%d", &freq1, &freq2) == 2) {
00250          /* f1+f2 format */
00251          time = 0;
00252       } else if (sscanf(s, "%d*%d/%d", &freq1, &freq2, &time) == 3) {
00253          /* f1*f2/time format */
00254          modulate = 1;
00255       } else if (sscanf(s, "%d*%d", &freq1, &freq2) == 2) {
00256          /* f1*f2 format */
00257          time = 0;
00258          modulate = 1;
00259       } else if (sscanf(s, "%d/%d", &freq1, &time) == 2) {
00260          /* f1/time format */
00261          freq2 = 0;
00262       } else if (sscanf(s, "%d", &freq1) == 1) {
00263          /* f1 format */
00264          freq2 = 0;
00265          time = 0;
00266       } else if (sscanf(s, "M%d+M%d/%d", &freq1, &freq2, &time) == 3) {
00267          /* Mf1+Mf2/time format */
00268          midinote = 1;
00269       } else if (sscanf(s, "M%d+M%d", &freq1, &freq2) == 2) {
00270          /* Mf1+Mf2 format */
00271          time = 0;
00272          midinote = 1;
00273       } else if (sscanf(s, "M%d*M%d/%d", &freq1, &freq2, &time) == 3) {
00274          /* Mf1*Mf2/time format */
00275          modulate = 1;
00276          midinote = 1;
00277       } else if (sscanf(s, "M%d*M%d", &freq1, &freq2) == 2) {
00278          /* Mf1*Mf2 format */
00279          time = 0;
00280          modulate = 1;
00281          midinote = 1;
00282       } else if (sscanf(s, "M%d/%d", &freq1, &time) == 2) {
00283          /* Mf1/time format */
00284          freq2 = -1;
00285          midinote = 1;
00286       } else if (sscanf(s, "M%d", &freq1) == 1) {
00287          /* Mf1 format */
00288          freq2 = -1;
00289          time = 0;
00290          midinote = 1;
00291       } else {
00292          ast_log(LOG_WARNING,"%s: tone component '%s' of '%s' is no good\n",chan->name,s,playlst);
00293          return -1;
00294       }
00295 
00296       if (midinote) {
00297          /* midi notes must be between 0 and 127 */
00298          if ((freq1 >= 0) && (freq1 <= 127))
00299             freq1 = midi_tohz[freq1];
00300          else
00301             freq1 = 0;
00302 
00303          if ((freq2 >= 0) && (freq2 <= 127))
00304             freq2 = midi_tohz[freq2];
00305          else
00306             freq2 = 0;
00307       }
00308 
00309       if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) {
00310          return -1;
00311       }
00312       d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0;
00313       d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * d.vol;
00314       d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * d.vol;
00315 
00316       d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0;
00317       d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * d.vol;
00318       d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * d.vol;
00319       d.items[d.nitems].duration = time;
00320       d.items[d.nitems].modulate = modulate;
00321       d.nitems++;
00322 
00323       s = strsep(&stringp,separator);
00324    }
00325 
00326    if (ast_activate_generator(chan, &playtones, &d)) {
00327       free(d.items);
00328       return -1;
00329    }
00330    return 0;
00331 }

void ast_playtones_stop struct ast_channel chan  ) 
 

Stop the tones from playing.

Definition at line 333 of file indications.c.

References ast_deactivate_generator().

Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_end(), handle_stopplaytones(), and stop_indicate().

00334 {
00335    ast_deactivate_generator(chan);
00336 }

int ast_register_indication struct ind_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 534 of file indications.c.

References ind_tone_zone::alias, ast_malloc, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdup, ind_tone_zone_sound::data, free, ind_tone_zone_sound::name, ind_tone_zone_sound::next, and ind_tone_zone::tones.

Referenced by handle_add_indication().

00535 {
00536    struct ind_tone_zone_sound *ts, *ps;
00537 
00538    /* is it an alias? stop */
00539    if (zone->alias[0])
00540       return -1;
00541 
00542    AST_RWLIST_WRLOCK(&tone_zones);
00543    for (ps=NULL,ts=zone->tones; ts; ps=ts,ts=ts->next) {
00544       if (strcasecmp(indication,ts->name)==0) {
00545          /* indication already there, replace */
00546          free((void*)ts->name);
00547          free((void*)ts->data);
00548          break;
00549       }
00550    }
00551    if (!ts) {
00552       /* not there, we have to add */
00553       if (!(ts = ast_malloc(sizeof(*ts)))) {
00554          AST_RWLIST_UNLOCK(&tone_zones);
00555          return -2;
00556       }
00557       ts->next = NULL;
00558    }
00559    if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) {
00560       AST_RWLIST_UNLOCK(&tone_zones);
00561       return -2;
00562    }
00563    if (ps)
00564       ps->next = ts;
00565    else
00566       zone->tones = ts;
00567    AST_RWLIST_UNLOCK(&tone_zones);
00568    return 0;
00569 }

int ast_register_indication_country struct ind_tone_zone country  ) 
 

add a new country, if country exists, it will be replaced.

Definition at line 471 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_verbose(), ind_tone_zone::country, current_tonezone, free_zone(), option_verbose, and VERBOSE_PREFIX_3.

Referenced by handle_add_indication(), and ind_load_module().

00472 {
00473    struct ind_tone_zone *tz = NULL;
00474 
00475    AST_RWLIST_WRLOCK(&tone_zones);
00476    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&tone_zones, tz, list) {
00477       /* If this is not the same zone, then just continue to the next entry */
00478       if (strcasecmp(zone->country, tz->country))
00479          continue;
00480       /* If this zone we are going to remove is the current default then make the new zone the default */
00481       if (tz == current_tonezone)
00482          current_tonezone = zone;
00483       /* Remove from the linked list */
00484       AST_RWLIST_REMOVE_CURRENT(&tone_zones, list);
00485       /* Finally free the zone itself */
00486       free_zone(tz);
00487       break;
00488    }
00489    AST_RWLIST_TRAVERSE_SAFE_END
00490 
00491    /* Add zone to the list */
00492    AST_RWLIST_INSERT_TAIL(&tone_zones, zone, list);
00493 
00494    /* It's all over. */
00495    AST_RWLIST_UNLOCK(&tone_zones);
00496 
00497    if (option_verbose > 2)
00498       ast_verbose(VERBOSE_PREFIX_3 "Registered indication country '%s'\n", zone->country);
00499 
00500    return 0;
00501 }

int ast_set_indication_country const char *  country  ) 
 

set the default tone country

Definition at line 364 of file indications.c.

References ast_get_indication_zone(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), current_tonezone, option_verbose, and VERBOSE_PREFIX_3.

Referenced by ind_load_module().

00365 {
00366    struct ind_tone_zone *zone = NULL;
00367 
00368    /* If no country is specified or we are unable to find the zone, then return not found */
00369    if (!country || !(zone = ast_get_indication_zone(country)))
00370       return 1;
00371    
00372    if (option_verbose > 2)
00373       ast_verbose(VERBOSE_PREFIX_3 "Setting default indication country to '%s'\n", country);
00374 
00375    /* Protect the current tonezone using the tone_zones lock as well */
00376    AST_RWLIST_WRLOCK(&tone_zones);
00377    current_tonezone = zone;
00378    AST_RWLIST_UNLOCK(&tone_zones);
00379 
00380    /* Zone was found */
00381    return 0;
00382 }

int ast_unregister_indication struct ind_tone_zone zone,
const char *  indication
 

remove an existing tone_zone's indication. tone_zone must exist

Definition at line 572 of file indications.c.

References ind_tone_zone::alias, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ind_tone_zone_sound::data, free, ind_tone_zone_sound::name, ind_tone_zone_sound::next, and ind_tone_zone::tones.

Referenced by handle_remove_indication().

00573 {
00574    struct ind_tone_zone_sound *ts,*ps = NULL, *tmp;
00575    int res = -1;
00576 
00577    /* is it an alias? stop */
00578    if (zone->alias[0])
00579       return -1;
00580 
00581    AST_RWLIST_WRLOCK(&tone_zones);
00582    ts = zone->tones;
00583    while (ts) {
00584       if (strcasecmp(indication,ts->name)==0) {
00585          /* indication found */
00586          tmp = ts->next;
00587          if (ps)
00588             ps->next = tmp;
00589          else
00590             zone->tones = tmp;
00591          free((void*)ts->name);
00592          free((void*)ts->data);
00593          free(ts);
00594          ts = tmp;
00595          res = 0;
00596       }
00597       else {
00598          /* next zone please */
00599          ps = ts;
00600          ts = ts->next;
00601       }
00602    }
00603    /* indication not found, goodbye */
00604    AST_RWLIST_UNLOCK(&tone_zones);
00605    return res;
00606 }

int ast_unregister_indication_country const char *  country  ) 
 

remove an existing country and all its indications, country must exist

Definition at line 505 of file indications.c.

References ind_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_verbose(), ind_tone_zone::country, current_tonezone, free_zone(), LOG_NOTICE, option_verbose, and VERBOSE_PREFIX_3.

Referenced by handle_add_indication(), handle_remove_indication(), reload(), and unload_module().

00506 {
00507    struct ind_tone_zone *tz = NULL;
00508    int res = -1;
00509 
00510    AST_RWLIST_WRLOCK(&tone_zones);
00511    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&tone_zones, tz, list) {
00512       if (country && (strcasecmp(country, tz->country) && strcasecmp(country, tz->alias)))
00513          continue;
00514       /* If this tonezone is the current default then unset it */
00515       if (tz == current_tonezone) {
00516          ast_log(LOG_NOTICE,"Removed default indication country '%s'\n", tz->country);
00517          current_tonezone = NULL;
00518       }
00519       /* Remove from the list */
00520       AST_RWLIST_REMOVE_CURRENT(&tone_zones, list);
00521       if (option_verbose > 2)
00522          ast_verbose(VERBOSE_PREFIX_3 "Unregistered indication country '%s'\n", tz->country);
00523       free_zone(tz);
00524       res = 0;
00525    }
00526    AST_RWLIST_TRAVERSE_SAFE_END
00527    AST_RWLIST_UNLOCK(&tone_zones);
00528 
00529    return res;
00530 }

struct ind_tone_zone* ast_walk_indications const struct ind_tone_zone cur  ) 
 

support for walking through a list of indications

Definition at line 343 of file indications.c.

References AST_RWLIST_FIRST, AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, and AST_RWLIST_UNLOCK.

Referenced by handle_show_indications().

00344 {
00345    struct ind_tone_zone *tz = NULL;
00346 
00347    AST_RWLIST_RDLOCK(&tone_zones);
00348    /* If cur is not NULL, then we have to iterate through - otherwise just return the first entry */
00349    if (cur) {
00350       AST_RWLIST_TRAVERSE(&tone_zones, tz, list) {
00351          if (tz == cur)
00352             break;
00353       }
00354       tz = AST_RWLIST_NEXT(tz, list);
00355    } else {
00356       tz = AST_RWLIST_FIRST(&tone_zones);
00357    }
00358    AST_RWLIST_UNLOCK(&tone_zones);
00359 
00360    return tz;
00361 }


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen