Fri Nov 12 12:04:22 2010

Asterisk developer's documentation


indications.c File Reference

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"
Include dependency graph for indications.c:

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_soundast_get_indication_tone (const struct ast_tone_zone *_zone, const char *indication)
 Locate a tone zone sound.
struct ast_tone_zoneast_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_zoneast_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_containerast_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_zonedefault_tone_zone
static const int midi_tohz [128]
static struct ast_generator playtones

Detailed Description

Indication Tone Handling.

Author:
Pauline Middelink <middelink@polyware.nl>
Russell Bryant <russell@digium.com>

Definition in file indications.c.


Define Documentation

#define NUM_TONE_ZONE_BUCKETS   53

Definition at line 65 of file indications.c.

Referenced by ast_indications_init().


Function Documentation

struct ast_tone_zone_sound* ast_get_indication_tone ( const struct ast_tone_zone zone,
const char *  indication 
) [read]

Locate a tone zone sound.

Parameters:
zone Zone to look in for a sound, if NULL, the default will be used
indication Sound to look for, such as "busy"
Returns:
a reference to the specified sound if it exists, NULL if not

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

Parameters:
country country to find. If NULL is provided, get the default.
Returns:
a reference to the specified country if found or NULL if not found

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.

Parameters:
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
Return values:
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]
Note:
called with the tone zone locked

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.

Returns:
the total 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.

Returns:
an initialized iterator

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.

Parameters:
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.
Return values:
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]
Note:
This is called with the tone zone locked.

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 }


Variable Documentation

struct ao2_container* ast_tone_zones [static]

Definition at line 63 of file indications.c.

struct ast_cli_entry cli_indications[] [static]
Initial value:
 {
   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]
Note:
Access to this is protected by locking the ast_tone_zones container

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]
Initial value:
 {
   .alloc     = playtones_alloc,
   .release   = playtones_release,
   .generate  = playtones_generator,
}

Definition at line 238 of file indications.c.


Generated by  doxygen 1.6.2