Mon Oct 8 12:39:23 2012

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/data.h"
#include "asterisk/_private.h"

Go to the source code of this file.

Data Structures

struct  playtones_def
struct  playtones_item
struct  playtones_state

Defines

#define DATA_EXPORT_TONE_ZONE(MEMBER)
#define DATA_EXPORT_TONE_ZONE_SOUND(MEMBER)
#define NUM_TONE_ZONE_BUCKETS   53

Functions

 AST_DATA_STRUCTURE (ast_tone_zone_sound, DATA_EXPORT_TONE_ZONE_SOUND)
 AST_DATA_STRUCTURE (ast_tone_zone, DATA_EXPORT_TONE_ZONE)
ast_tone_zone_soundast_get_indication_tone (const struct ast_tone_zone *_zone, const char *indication)
 Locate a tone zone sound.
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.
int ast_tone_zone_data_add_structure (struct ast_data *tree, struct ast_tone_zone *zone)
 Add a tone_zone structure to the data tree specified.
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)
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 DATA_EXPORT_TONE_ZONE ( MEMBER   ) 

Value:

Definition at line 49 of file indications.c.

#define DATA_EXPORT_TONE_ZONE_SOUND ( MEMBER   ) 

Value:

Definition at line 56 of file indications.c.

#define NUM_TONE_ZONE_BUCKETS   53

Definition at line 83 of file indications.c.

Referenced by ast_indications_init().


Function Documentation

AST_DATA_STRUCTURE ( ast_tone_zone_sound  ,
DATA_EXPORT_TONE_ZONE_SOUND   
)

AST_DATA_STRUCTURE ( ast_tone_zone  ,
DATA_EXPORT_TONE_ZONE   
)

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

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 470 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_zones, default_tone_zone, ast_tone_zone_sound::name, and ast_tone_zone::tones.

Referenced by ast_app_dtget(), ast_indicate_data(), dial_handle_playtones(), dialtone_indicate(), handle_playtones(), in_band_indication(), pbx_builtin_waitexten(), play_dialtone(), read_exec(), readexten_exec(), and skinny_transfer().

00471 {
00472    struct ast_tone_zone_sound *ts = NULL;
00473    /* _zone is const to the users of the API */
00474    struct ast_tone_zone *zone = (struct ast_tone_zone *) _zone;
00475 
00476    /* If no zone is specified, use the default */
00477    if (!zone) {
00478       ao2_lock(ast_tone_zones);
00479       if (default_tone_zone) {
00480          zone = ast_tone_zone_ref(default_tone_zone);
00481       }
00482       ao2_unlock(ast_tone_zones);
00483 
00484       if (!zone) {
00485          return NULL;
00486       }
00487    }
00488 
00489    ast_tone_zone_lock(zone);
00490 
00491    /* Look through list of tones in the zone searching for the right one */
00492    AST_LIST_TRAVERSE(&zone->tones, ts, entry) {
00493       if (!strcasecmp(ts->name, indication)) {
00494          /* Increase ref count for the reference we will return */
00495          ts = ast_tone_zone_sound_ref(ts);
00496          break;
00497       }
00498    }
00499 
00500    ast_tone_zone_unlock(zone);
00501 
00502    return ts;
00503 }

struct ast_tone_zone* ast_get_indication_zone ( const char *  country  ) 

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 448 of file indications.c.

References ao2_find, ao2_lock, ao2_unlock, ast_copy_string(), ast_strlen_zero(), ast_tone_zone_ref(), ast_tone_zones, ast_tone_zone::country, default_tone_zone, ast_tone_zone::nrringcadence, OBJ_POINTER, and tz.

Referenced by ast_set_indication_country(), ast_var_indications(), build_device(), func_channel_write_real(), handle_cli_indication_add(), and handle_cli_indication_remove().

00449 {
00450    struct ast_tone_zone *tz = NULL;
00451    struct ast_tone_zone zone_arg = {
00452       .nrringcadence = 0,
00453    };
00454 
00455    if (ast_strlen_zero(country)) {
00456       ao2_lock(ast_tone_zones);
00457       if (default_tone_zone) {
00458          tz = ast_tone_zone_ref(default_tone_zone);
00459       }
00460       ao2_unlock(ast_tone_zones);
00461 
00462       return tz;
00463    }
00464 
00465    ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country));
00466 
00467    return ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER);
00468 }

int ast_indications_init ( void   ) 

Load indications module.

Provided by indications.c

Definition at line 1153 of file indications.c.

References ao2_container_alloc, ARRAY_LEN, ast_cli_register_multiple(), ast_tone_zone_cmp(), ast_tone_zone_hash(), ast_tone_zones, cli_indications, load_indications(), and NUM_TONE_ZONE_BUCKETS.

Referenced by main().

01154 {
01155    if (!(ast_tone_zones = ao2_container_alloc(NUM_TONE_ZONE_BUCKETS,
01156          ast_tone_zone_hash, ast_tone_zone_cmp))) {
01157       return -1;
01158    }
01159 
01160    if (load_indications(0)) {
01161       return -1;
01162    }
01163 
01164    ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications));
01165 
01166    return 0;
01167 }

int ast_indications_reload ( void   ) 

Reload indications module.

Provided by indications.c

Definition at line 1170 of file indications.c.

References load_indications().

01171 {
01172    return load_indications(1);
01173 }

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 319 of file indications.c.

References ast_activate_generator(), ast_free, ast_log(), ast_realloc, ast_strdupa, 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, M_PI, ast_tone_zone_part::midinote, ast_tone_zone_part::modulate, playtones_item::modulate, playtones_def::nitems, playtones, playtones_def::reppos, strsep(), ast_tone_zone_part::time, and playtones_def::vol.

Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_begin(), dial_handle_playtones(), dialtone_indicate(), handle_playtones(), in_band_indication(), milliwatt_exec(), pbx_builtin_waitexten(), play_dialtone(), playtone(), read_exec(), readexten_exec(), receivefax_t38_init(), send_digit_to_chan(), sendfax_t38_init(), and skinny_transfer().

00320 {
00321    char *s, *data = ast_strdupa(playlst);
00322    struct playtones_def d = { vol, -1, 0, 1, NULL };
00323    char *stringp;
00324    char *separator;
00325    static const float sample_rate = 8000.0;
00326    static const float max_sample_val = 32768.0;
00327 
00328    if (vol < 1) {
00329       d.vol = 7219; /* Default to -8db */
00330    }
00331 
00332    d.interruptible = interruptible;
00333 
00334    stringp = data;
00335 
00336    /* check if the data is separated with '|' or with ',' by default */
00337    if (strchr(stringp,'|')) {
00338       separator = "|";
00339    } else {
00340       separator = ",";
00341    }
00342 
00343    while ((s = strsep(&stringp, separator)) && !ast_strlen_zero(s)) {
00344       struct ast_tone_zone_part tone_data = {
00345          .time = 0,
00346       };
00347 
00348       s = ast_strip(s);
00349 
00350       if (s[0]=='!') {
00351          s++;
00352       } else if (d.reppos == -1) {
00353          d.reppos = d.nitems;
00354       }
00355 
00356       if (ast_tone_zone_part_parse(s, &tone_data)) {
00357          ast_log(LOG_ERROR, "Failed to parse tone part '%s'\n", s);
00358          continue;
00359       }
00360 
00361       if (tone_data.midinote) {
00362          /* midi notes must be between 0 and 127 */
00363 
00364          if (tone_data.freq1 >= 0 && tone_data.freq1 <= 127) {
00365             tone_data.freq1 = midi_tohz[tone_data.freq1];
00366          } else {
00367             tone_data.freq1 = 0;
00368          }
00369 
00370          if (tone_data.freq2 >= 0 && tone_data.freq2 <= 127) {
00371             tone_data.freq2 = midi_tohz[tone_data.freq2];
00372          } else {
00373             tone_data.freq2 = 0;
00374          }
00375       }
00376 
00377       if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) {
00378          return -1;
00379       }
00380 
00381       d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (tone_data.freq1 / sample_rate)) * max_sample_val;
00382       d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol;
00383       d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol;
00384 
00385       d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (tone_data.freq2 / sample_rate)) * max_sample_val;
00386       d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol;
00387       d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol;
00388 
00389       d.items[d.nitems].duration = tone_data.time;
00390       d.items[d.nitems].modulate = tone_data.modulate;
00391 
00392       d.nitems++;
00393    }
00394 
00395    if (!d.nitems) {
00396       ast_log(LOG_ERROR, "No valid tone parts\n");
00397       return -1;
00398    }
00399 
00400    if (ast_activate_generator(chan, &playtones, &d)) {
00401       ast_free(d.items);
00402       return -1;
00403    }
00404 
00405    return 0;
00406 }

void ast_playtones_stop ( struct ast_channel chan  ) 

Stop playing tones on a channel.

Parameters:
chan the channel to stop tones on

Definition at line 408 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(), receivefax_t38_init(), sendfax_t38_init(), stop_indicate(), and unistim_indicate().

00409 {
00410    ast_deactivate_generator(chan);
00411 }

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 585 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::entry, ast_tone_zone_sound::name, and ast_tone_zone::tones.

Referenced by handle_cli_indication_add(), and store_config_tone_zone().

00587 {
00588    struct ast_tone_zone_sound *ts;
00589 
00590    if (ast_strlen_zero(indication) || ast_strlen_zero(tonelist)) {
00591       return -1;
00592    }
00593 
00594    AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) {
00595       if (!strcasecmp(indication, ts->name)) {
00596          AST_LIST_REMOVE_CURRENT(entry);
00597          ts = ast_tone_zone_sound_unref(ts);
00598          break;
00599       }
00600    }
00601    AST_LIST_TRAVERSE_SAFE_END;
00602 
00603    if (!(ts = ao2_alloc(sizeof(*ts), ast_tone_zone_sound_destructor))) {
00604       return -1;
00605    }
00606 
00607    if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) {
00608       ts = ast_tone_zone_sound_unref(ts);
00609       return -1;
00610    }
00611 
00612    AST_LIST_INSERT_TAIL(&zone->tones, ts, entry); /* Inherit reference */
00613 
00614    return 0;
00615 }

static int ast_register_indication_country ( struct ast_tone_zone zone  )  [static]

Definition at line 538 of file indications.c.

References ao2_link, ao2_lock, ao2_unlock, ast_tone_zone_ref(), ast_tone_zones, ast_verb, ast_tone_zone::country, and default_tone_zone.

Referenced by handle_cli_indication_add(), and parse_tone_zone().

00539 {
00540    ao2_lock(ast_tone_zones);
00541    if (!default_tone_zone) {
00542       default_tone_zone = ast_tone_zone_ref(zone);
00543    }
00544    ao2_unlock(ast_tone_zones);
00545 
00546    ao2_link(ast_tone_zones, zone);
00547 
00548    ast_verb(3, "Registered indication country '%s'\n", zone->country);
00549 
00550    return 0;
00551 }

static int ast_set_indication_country ( const char *  country  )  [static]

Definition at line 424 of file indications.c.

References ao2_lock, ao2_unlock, ast_get_indication_zone(), ast_strlen_zero(), ast_tone_zone_ref(), ast_tone_zone_unref(), ast_tone_zones, ast_verb, and default_tone_zone.

Referenced by load_indications().

00425 {
00426    struct ast_tone_zone *zone = NULL;
00427 
00428    /* If no country is specified or we are unable to find the zone, then return not found */
00429    if (ast_strlen_zero(country) || !(zone = ast_get_indication_zone(country))) {
00430       return -1;
00431    }
00432 
00433    ast_verb(3, "Setting default indication country to '%s'\n", country);
00434 
00435    ao2_lock(ast_tone_zones);
00436    if (default_tone_zone) {
00437       default_tone_zone = ast_tone_zone_unref(default_tone_zone);
00438    }
00439    default_tone_zone = ast_tone_zone_ref(zone);
00440    ao2_unlock(ast_tone_zones);
00441 
00442    zone = ast_tone_zone_unref(zone);
00443 
00444    return 0;
00445 }

static struct ast_tone_zone* ast_tone_zone_alloc ( void   )  [static]

Definition at line 640 of file indications.c.

References ao2_alloc, and ast_tone_zone_destructor().

Referenced by handle_cli_indication_add(), and parse_tone_zone().

00641 {
00642    return ao2_alloc(sizeof(struct ast_tone_zone), ast_tone_zone_destructor);
00643 }

static int ast_tone_zone_cmp ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1116 of file indications.c.

References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.

Referenced by ast_indications_init().

01117 {
01118    struct ast_tone_zone *zone = obj;
01119    struct ast_tone_zone *zone_arg = arg;
01120 
01121    return (!strcasecmp(zone->country, zone_arg->country)) ?
01122          CMP_MATCH | CMP_STOP : 0;
01123 }

int ast_tone_zone_count ( void   ) 

Get the number of registered tone zones.

Returns:
the total number of registered tone zones

Definition at line 413 of file indications.c.

References ao2_container_count(), and ast_tone_zones.

00414 {
00415    return ao2_container_count(ast_tone_zones);
00416 }

int ast_tone_zone_data_add_structure ( struct ast_data tree,
struct ast_tone_zone zone 
)

Add a tone_zone structure to the data tree specified.

Return values:
<0 on error.
0 on success.

Definition at line 1125 of file indications.c.

References ast_data_add_node(), ast_data_add_structure, AST_LIST_EMPTY, AST_LIST_TRAVERSE, ast_tone_zone_lock, ast_tone_zone_unlock, ast_tone_zone_sound::entry, and ast_tone_zone::tones.

Referenced by ast_channel_data_add_structure().

01126 {
01127    struct ast_data *data_zone_sound;
01128    struct ast_tone_zone_sound *s;
01129 
01130    ast_data_add_structure(ast_tone_zone, tree, zone);
01131 
01132    if (AST_LIST_EMPTY(&zone->tones)) {
01133       return 0;
01134    }
01135 
01136    data_zone_sound = ast_data_add_node(tree, "tones");
01137    if (!data_zone_sound) {
01138       return -1;
01139    }
01140 
01141    ast_tone_zone_lock(zone);
01142 
01143    AST_LIST_TRAVERSE(&zone->tones, s, entry) {
01144       ast_data_add_structure(ast_tone_zone_sound, data_zone_sound, s);
01145    }
01146 
01147    ast_tone_zone_unlock(zone);
01148 
01149    return 0;
01150 }

static void ast_tone_zone_destructor ( void *  obj  )  [static]

deallocate the passed tone zone

Definition at line 522 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().

00523 {
00524    struct ast_tone_zone *zone = obj;
00525    struct ast_tone_zone_sound *current;
00526 
00527    while ((current = AST_LIST_REMOVE_HEAD(&zone->tones, entry))) {
00528       current = ast_tone_zone_sound_unref(current);
00529    }
00530 
00531    if (zone->ringcadence) {
00532       ast_free(zone->ringcadence);
00533       zone->ringcadence = NULL;
00534    }
00535 }

static int ast_tone_zone_hash ( const void *  obj,
const int  flags 
) [static]

Definition at line 1109 of file indications.c.

References ast_str_case_hash(), and ast_tone_zone::country.

Referenced by ast_indications_init().

01110 {
01111    const struct ast_tone_zone *zone = obj;
01112 
01113    return ast_str_case_hash(zone->country);
01114 }

struct ao2_iterator ast_tone_zone_iterator_init ( void   ) 

Get an iterator for the available tone zones.

Note:
Use ao2_iterator_next() to iterate the tone zones.

Use ao2_iterator_destroy() to clean up.

Returns:
an initialized iterator

Definition at line 418 of file indications.c.

References ao2_iterator_init(), and ast_tone_zones.

Referenced by ast_var_indications(), ast_var_indications_table(), and handle_cli_indication_show().

00419 {
00420    return ao2_iterator_init(ast_tone_zones, 0);
00421 }

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 262 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().

00263 {
00264    if (sscanf(s, "%30u+%30u/%30u", &tone_data->freq1, &tone_data->freq2, 
00265          &tone_data->time) == 3) {
00266       /* f1+f2/time format */
00267    } else if (sscanf(s, "%30u+%30u", &tone_data->freq1, &tone_data->freq2) == 2) {
00268       /* f1+f2 format */
00269       tone_data->time = 0;
00270    } else if (sscanf(s, "%30u*%30u/%30u", &tone_data->freq1, &tone_data->freq2, 
00271          &tone_data->time) == 3) {
00272       /* f1*f2/time format */
00273       tone_data->modulate = 1;
00274    } else if (sscanf(s, "%30u*%30u", &tone_data->freq1, &tone_data->freq2) == 2) {
00275       /* f1*f2 format */
00276       tone_data->time = 0;
00277       tone_data->modulate = 1;
00278    } else if (sscanf(s, "%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) {
00279       /* f1/time format */
00280       tone_data->freq2 = 0;
00281    } else if (sscanf(s, "%30u", &tone_data->freq1) == 1) {
00282       /* f1 format */
00283       tone_data->freq2 = 0;
00284       tone_data->time = 0;
00285    } else if (sscanf(s, "M%30u+M%30u/%30u", &tone_data->freq1, &tone_data->freq2, 
00286          &tone_data->time) == 3) {
00287       /* Mf1+Mf2/time format */
00288       tone_data->midinote = 1;
00289    } else if (sscanf(s, "M%30u+M%30u", &tone_data->freq1, &tone_data->freq2) == 2) {
00290       /* Mf1+Mf2 format */
00291       tone_data->time = 0;
00292       tone_data->midinote = 1;
00293    } else if (sscanf(s, "M%30u*M%30u/%30u", &tone_data->freq1, &tone_data->freq2, 
00294          &tone_data->time) == 3) {
00295       /* Mf1*Mf2/time format */
00296       tone_data->modulate = 1;
00297       tone_data->midinote = 1;
00298    } else if (sscanf(s, "M%30u*M%30u", &tone_data->freq1, &tone_data->freq2) == 2) {
00299       /* Mf1*Mf2 format */
00300       tone_data->time = 0;
00301       tone_data->modulate = 1;
00302       tone_data->midinote = 1;
00303    } else if (sscanf(s, "M%30u/%30u", &tone_data->freq1, &tone_data->time) == 2) {
00304       /* Mf1/time format */
00305       tone_data->freq2 = -1;
00306       tone_data->midinote = 1;
00307    } else if (sscanf(s, "M%30u", &tone_data->freq1) == 1) {
00308       /* Mf1 format */
00309       tone_data->freq2 = -1;
00310       tone_data->time = 0;
00311       tone_data->midinote = 1;
00312    } else {
00313       return -1;
00314    }
00315 
00316    return 0;
00317 }

static void ast_tone_zone_sound_destructor ( void *  obj  )  [static]

Definition at line 505 of file indications.c.

References ast_free, ast_tone_zone_sound::data, and ast_tone_zone_sound::name.

Referenced by ast_register_indication().

00506 {
00507    struct ast_tone_zone_sound *ts = obj;
00508 
00509    /* Deconstify the 'const char *'s so the compiler doesn't complain. (but it's safe) */
00510    if (ts->name) {
00511       ast_free((char *) ts->name);
00512       ts->name = NULL;
00513    }
00514 
00515    if (ts->data) {
00516       ast_free((char *) ts->data);
00517       ts->data = NULL;
00518    }
00519 }

static int ast_unregister_indication ( struct ast_tone_zone zone,
const char *  indication 
) [static]

Definition at line 618 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().

00619 {
00620    struct ast_tone_zone_sound *ts;
00621    int res = -1;
00622 
00623    ast_tone_zone_lock(zone);
00624 
00625    AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, entry) {
00626       if (!strcasecmp(indication, ts->name)) {
00627          AST_LIST_REMOVE_CURRENT(entry);
00628          ts = ast_tone_zone_sound_unref(ts);
00629          res = 0;
00630          break;
00631       }
00632    }
00633    AST_LIST_TRAVERSE_SAFE_END;
00634 
00635    ast_tone_zone_unlock(zone);
00636 
00637    return res;
00638 }

static int ast_unregister_indication_country ( const char *  country  )  [static]

Definition at line 554 of file indications.c.

References ao2_callback, ao2_find, ao2_lock, ao2_unlink, ao2_unlock, ast_copy_string(), ast_tone_zone_unref(), ast_tone_zones, ast_tone_zone::country, default_tone_zone, ast_tone_zone::nrringcadence, OBJ_POINTER, and tz.

Referenced by handle_cli_indication_add(), and handle_cli_indication_remove().

00555 {
00556    struct ast_tone_zone *tz = NULL;
00557    struct ast_tone_zone zone_arg = {
00558       .nrringcadence = 0,
00559    };
00560 
00561    ast_copy_string(zone_arg.country, country, sizeof(zone_arg.country));
00562 
00563    if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) {
00564       return -1;
00565    }
00566 
00567    ao2_lock(ast_tone_zones);
00568    if (default_tone_zone == tz) {
00569       ast_tone_zone_unref(default_tone_zone);
00570       /* Get a new default, punt to the first one we find */
00571       default_tone_zone = ao2_callback(ast_tone_zones, 0, NULL, NULL);
00572    }
00573    ao2_unlock(ast_tone_zones);
00574 
00575    ao2_unlink(ast_tone_zones, tz);
00576 
00577    tz = ast_tone_zone_unref(tz);
00578 
00579    return 0;
00580 }

static char* complete_country ( struct ast_cli_args a  )  [static]

Definition at line 645 of file indications.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_tone_zone_unref(), ast_tone_zones, ast_cli_args::n, tz, and ast_cli_args::word.

Referenced by handle_cli_indication_add(), handle_cli_indication_remove(), and handle_cli_indication_show().

00646 {
00647    char *res = NULL;
00648    struct ao2_iterator i;
00649    int which = 0;
00650    size_t wordlen;
00651    struct ast_tone_zone *tz;
00652 
00653    wordlen = strlen(a->word);
00654 
00655    i = ao2_iterator_init(ast_tone_zones, 0);
00656    while ((tz = ao2_iterator_next(&i))) {
00657       if (!strncasecmp(a->word, tz->country, wordlen) && ++which > a->n) {
00658          res = ast_strdup(tz->country);
00659       }
00660       tz = ast_tone_zone_unref(tz);
00661       if (res) {
00662          break;
00663       }
00664    }
00665    ao2_iterator_destroy(&i);
00666 
00667    return res;
00668 }

static char* complete_indications ( struct ast_cli_args a  )  [static]

Definition at line 731 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_zones, ast_tone_zone::country, ast_cli_args::n, ast_tone_zone_sound::name, OBJ_POINTER, ast_cli_args::pos, tz, and ast_cli_args::word.

Referenced by handle_cli_indication_remove().

00732 {
00733    char *res = NULL;
00734    int which = 0;
00735    size_t wordlen;
00736    struct ast_tone_zone_sound *ts;
00737    struct ast_tone_zone *tz, tmp_tz = {
00738       .nrringcadence = 0,
00739    };
00740 
00741    ast_copy_string(tmp_tz.country, a->argv[a->pos - 1], sizeof(tmp_tz.country));
00742 
00743    if (!(tz = ao2_find(ast_tone_zones, &tmp_tz, OBJ_POINTER))) {
00744       return NULL;
00745    }
00746 
00747    wordlen = strlen(a->word);
00748 
00749    ast_tone_zone_lock(tz);
00750    AST_LIST_TRAVERSE(&tz->tones, ts, entry) {
00751       if (!strncasecmp(a->word, ts->name, wordlen) && ++which > a->n) {
00752          res = ast_strdup(ts->name);
00753          break;
00754       }
00755    }
00756    ast_tone_zone_unlock(tz);
00757 
00758    tz = ast_tone_zone_unref(tz);
00759 
00760    return res;
00761 }

static char* handle_cli_indication_add ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 670 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(), LOG_NOTICE, LOG_WARNING, ast_cli_args::pos, tz, and ast_cli_entry::usage.

00671 {
00672    struct ast_tone_zone *tz;
00673    int created_country = 0;
00674    char *res = CLI_SUCCESS;
00675 
00676    switch (cmd) {
00677    case CLI_INIT:
00678       e->command = "indication add";
00679       e->usage =
00680          "Usage: indication add <country> <indication> \"<tonelist>\"\n"
00681          "       Add the given indication to the country.\n";
00682       return NULL;
00683    case CLI_GENERATE:
00684       if (a->pos == 2) {
00685          return complete_country(a);
00686       } else {
00687          return NULL;
00688       }
00689    }
00690 
00691    if (a->argc != 5) {
00692       return CLI_SHOWUSAGE;
00693    }
00694 
00695    if (!(tz = ast_get_indication_zone(a->argv[2]))) {
00696       /* country does not exist, create it */
00697       ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n", a->argv[2]);
00698 
00699       if (!(tz = ast_tone_zone_alloc())) {
00700          return CLI_FAILURE;
00701       }
00702 
00703       ast_copy_string(tz->country, a->argv[2], sizeof(tz->country));
00704 
00705       if (ast_register_indication_country(tz)) {
00706          ast_log(LOG_WARNING, "Unable to register new country\n");
00707          tz = ast_tone_zone_unref(tz);
00708          return CLI_FAILURE;
00709       }
00710 
00711       created_country = 1;
00712    }
00713 
00714    ast_tone_zone_lock(tz);
00715 
00716    if (ast_register_indication(tz, a->argv[3], a->argv[4])) {
00717       ast_log(LOG_WARNING, "Unable to register indication %s/%s\n", a->argv[2], a->argv[3]);
00718       if (created_country) {
00719          ast_unregister_indication_country(a->argv[2]);
00720       }
00721       res = CLI_FAILURE;
00722    }
00723 
00724    ast_tone_zone_unlock(tz);
00725 
00726    tz = ast_tone_zone_unref(tz);
00727 
00728    return res;
00729 }

static char* handle_cli_indication_remove ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 763 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, tz, and ast_cli_entry::usage.

00764 {
00765    struct ast_tone_zone *tz;
00766    char *res = CLI_SUCCESS;
00767 
00768    switch (cmd) {
00769    case CLI_INIT:
00770       e->command = "indication remove";
00771       e->usage =
00772          "Usage: indication remove <country> [indication]\n"
00773          "       Remove the given indication from the country.\n";
00774       return NULL;
00775    case CLI_GENERATE:
00776       if (a->pos == 2) {
00777          return complete_country(a);
00778       } else if (a->pos == 3) {
00779          return complete_indications(a);
00780       }
00781    }
00782 
00783    if (a->argc != 3 && a->argc != 4) {
00784       return CLI_SHOWUSAGE;
00785    }
00786 
00787    if (a->argc == 3) {
00788       /* remove entire country */
00789       if (ast_unregister_indication_country(a->argv[2])) {
00790          ast_log(LOG_WARNING, "Unable to unregister indication country %s\n", a->argv[2]);
00791          return CLI_FAILURE;
00792       }
00793 
00794       return CLI_SUCCESS;
00795    }
00796 
00797    if (!(tz = ast_get_indication_zone(a->argv[2]))) {
00798       ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n", a->argv[2], a->argv[3]);
00799       return CLI_FAILURE;
00800    }
00801 
00802    if (ast_unregister_indication(tz, a->argv[3])) {
00803       ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n", a->argv[2], a->argv[3]);
00804       res = CLI_FAILURE;
00805    }
00806 
00807    tz = ast_tone_zone_unref(tz);
00808 
00809    return res;
00810 }

static char* handle_cli_indication_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 812 of file indications.c.

References ao2_find, ao2_iterator_destroy(), 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(), ast_tone_zones, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, complete_country(), ast_tone_zone_sound::data, ast_tone_zone_sound::entry, ast_cli_args::fd, ast_tone_zone_sound::name, OBJ_POINTER, tz, and ast_cli_entry::usage.

00813 {
00814    struct ast_tone_zone *tz = NULL;
00815    struct ast_str *buf;
00816    int found_country = 0;
00817    int i;
00818 
00819    switch (cmd) {
00820    case CLI_INIT:
00821       e->command = "indication show";
00822       e->usage =
00823          "Usage: indication show [<country> ...]\n"
00824          "       Display either a condensed summary of all countries and indications, or a\n"
00825          "       more verbose list of indications for the specified countries.\n";
00826       return NULL;
00827    case CLI_GENERATE:
00828       return complete_country(a);
00829    }
00830 
00831    if (a->argc == 2) {
00832       struct ao2_iterator iter;
00833       /* no arguments, show a list of countries */
00834       ast_cli(a->fd, "Country   Description\n");
00835       ast_cli(a->fd, "===========================\n");
00836       iter = ast_tone_zone_iterator_init();
00837       while ((tz = ao2_iterator_next(&iter))) {
00838          ast_tone_zone_lock(tz);
00839          ast_cli(a->fd, "%-7.7s  %s\n", tz->country, tz->description);
00840          ast_tone_zone_unlock(tz);
00841          tz = ast_tone_zone_unref(tz);
00842       }
00843       ao2_iterator_destroy(&iter);
00844       return CLI_SUCCESS;
00845    }
00846 
00847    buf = ast_str_alloca(256);
00848 
00849    for (i = 2; i < a->argc; i++) {
00850       struct ast_tone_zone zone_arg = {
00851          .nrringcadence = 0,
00852       };
00853       struct ast_tone_zone_sound *ts;
00854       int j;
00855 
00856       ast_copy_string(zone_arg.country, a->argv[i], sizeof(zone_arg.country));
00857 
00858       if (!(tz = ao2_find(ast_tone_zones, &zone_arg, OBJ_POINTER))) {
00859          continue;
00860       }
00861 
00862       if (!found_country) {
00863          found_country = 1;
00864          ast_cli(a->fd, "Country Indication      PlayList\n");
00865          ast_cli(a->fd, "=====================================\n");
00866       }
00867 
00868       ast_tone_zone_lock(tz);
00869 
00870       ast_str_set(&buf, 0, "%-7.7s %-15.15s ", tz->country, "<ringcadence>");
00871       for (j = 0; j < tz->nrringcadence; j++) {
00872          ast_str_append(&buf, 0, "%d%s", tz->ringcadence[j],
00873                (j == tz->nrringcadence - 1) ? "" : ",");
00874       }
00875       ast_str_append(&buf, 0, "\n");
00876       ast_cli(a->fd, "%s", buf->str);
00877 
00878       AST_LIST_TRAVERSE(&tz->tones, ts, entry) {
00879          ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data);
00880       }
00881 
00882       ast_tone_zone_unlock(tz);
00883       tz = ast_tone_zone_unref(tz);
00884    }
00885 
00886    if (!found_country) {
00887       ast_cli(a->fd, "No countries matched your criteria.\n");
00888    }
00889 
00890    return CLI_SUCCESS;
00891 }

static int is_valid_tone_zone ( struct ast_tone_zone zone  )  [static]

Definition at line 893 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().

00894 {
00895    int res;
00896 
00897    ast_tone_zone_lock(zone);
00898    res = (!ast_strlen_zero(zone->description) && !AST_LIST_EMPTY(&zone->tones));
00899    ast_tone_zone_unlock(zone);
00900 
00901    return res;
00902 }

static int load_indications ( int  reload  )  [static]

load indications module

Definition at line 1050 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_tone_zones, ast_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, country, 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().

01051 {
01052    struct ast_config *cfg;
01053    const char *cxt = NULL;
01054    const char *country = NULL;
01055    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
01056    int res = -1;
01057 
01058    cfg = ast_config_load2(config, "indications", config_flags);
01059 
01060    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
01061       ast_log(LOG_WARNING, "Can't find indications config file %s.\n", config);
01062       return 0;
01063    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
01064       return 0;
01065    }
01066 
01067    /* Lock the container to prevent multiple simultaneous reloads */
01068    ao2_lock(ast_tone_zones);
01069 
01070    ao2_callback(ast_tone_zones, OBJ_NODATA, tone_zone_mark, NULL);
01071 
01072    /* Use existing config to populate the Indication table */
01073    while ((cxt = ast_category_browse(cfg, cxt))) {
01074       /* All categories but "general" are considered countries */
01075       if (!strcasecmp(cxt, "general")) {
01076          continue;
01077       }
01078 
01079       if (parse_tone_zone(cfg, cxt)) {
01080          goto return_cleanup;
01081       }
01082    }
01083 
01084    ao2_callback(ast_tone_zones, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK,
01085          prune_tone_zone, NULL);
01086 
01087    /* determine which country is the default */
01088    country = ast_variable_retrieve(cfg, "general", "country");
01089    if (ast_strlen_zero(country) || ast_set_indication_country(country)) {
01090       ast_log(LOG_WARNING, "Unable to set the default country (for indication tones)\n");
01091    }
01092 
01093    res = 0;
01094 
01095 return_cleanup:
01096    ao2_unlock(ast_tone_zones);
01097    ast_config_destroy(cfg);
01098 
01099    return res;
01100 }

static int parse_tone_zone ( struct ast_config cfg,
const char *  country 
) [static]

Definition at line 963 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_tone_zones, 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().

00964 {
00965    struct ast_variable *v;
00966    struct ast_tone_zone *zone;
00967    struct ast_tone_zone tmp_zone = {
00968       .nrringcadence = 0,
00969    };
00970    int allocd = 0;
00971 
00972    ast_copy_string(tmp_zone.country, country, sizeof(tmp_zone.country));
00973 
00974    if ((zone = ao2_find(ast_tone_zones, &tmp_zone, OBJ_POINTER))) {
00975       reset_tone_zone(zone);
00976    } else if ((zone = ast_tone_zone_alloc())) {
00977       allocd = 1;
00978       ast_copy_string(zone->country, country, sizeof(zone->country));
00979    } else {
00980       return -1;
00981    }
00982 
00983    ast_tone_zone_lock(zone);
00984    for (v = ast_variable_browse(cfg, country); v; v = v->next) {
00985       store_config_tone_zone(zone, v->name, v->value);
00986    }
00987    ast_tone_zone_unlock(zone);
00988 
00989    if (allocd) {
00990       if (!is_valid_tone_zone(zone)) {
00991          ast_log(LOG_WARNING, "Indication country '%s' is invalid\n", country);
00992       } else if (ast_register_indication_country(zone)) {
00993          ast_log(LOG_WARNING, "Unable to register indication country '%s'.\n",
00994                country);
00995       }
00996    }
00997 
00998    zone = ast_tone_zone_unref(zone);
00999 
01000    return 0;
01001 }

static void* playtones_alloc ( struct ast_channel chan,
void *  params 
) [static]

Definition at line 145 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, LOG_WARNING, ast_channel::name, playtones_def::nitems, playtones_release(), playtones_def::reppos, playtones_def::vol, and ast_channel::writeformat.

00146 {
00147    struct playtones_def *pd = params;
00148    struct playtones_state *ps = NULL;
00149 
00150    if (!(ps = ast_calloc(1, sizeof(*ps)))) {
00151       return NULL;
00152    }
00153 
00154    ps->origwfmt = chan->writeformat;
00155 
00156    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
00157       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
00158       playtones_release(NULL, ps);
00159       ps = NULL;
00160    } else {
00161       ps->vol = pd->vol;
00162       ps->reppos = pd->reppos;
00163       ps->nitems = pd->nitems;
00164       ps->items = pd->items;
00165       ps->oldnpos = -1;
00166    }
00167 
00168    /* Let interrupts interrupt :) */
00169    if (pd->interruptible) {
00170       ast_set_flag(chan, AST_FLAG_WRITE_INT);
00171    } else {
00172       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
00173    }
00174 
00175    return ps;
00176 }

static int playtones_generator ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
) [static]

Definition at line 178 of file indications.c.

References ast_log(), playtones_state::data, playtones_state::f, playtones_item::fac1, playtones_item::fac2, 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::npos, playtones_state::oldnpos, 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.

00179 {
00180    struct playtones_state *ps = data;
00181    struct playtones_item *pi;
00182    int x;
00183 
00184    /* we need to prepare a frame with 16 * timelen samples as we're
00185     * generating SLIN audio */
00186 
00187    len = samples * 2;
00188    if (len > sizeof(ps->data) / 2 - 1) {
00189       ast_log(LOG_WARNING, "Can't generate that much data!\n");
00190       return -1;
00191    }
00192 
00193    memset(&ps->f, 0, sizeof(ps->f));
00194 
00195    pi = &ps->items[ps->npos];
00196 
00197    if (ps->oldnpos != ps->npos) {
00198       /* Load new parameters */
00199       ps->v1_1 = 0;
00200       ps->v2_1 = pi->init_v2_1;
00201       ps->v3_1 = pi->init_v3_1;
00202       ps->v1_2 = 0;
00203       ps->v2_2 = pi->init_v2_2;
00204       ps->v3_2 = pi->init_v3_2;
00205       ps->oldnpos = ps->npos;
00206    }
00207 
00208    for (x = 0; x < samples; x++) {
00209       ps->v1_1 = ps->v2_1;
00210       ps->v2_1 = ps->v3_1;
00211       ps->v3_1 = (pi->fac1 * ps->v2_1 >> 15) - ps->v1_1;
00212 
00213       ps->v1_2 = ps->v2_2;
00214       ps->v2_2 = ps->v3_2;
00215       ps->v3_2 = (pi->fac2 * ps->v2_2 >> 15) - ps->v1_2;
00216       if (pi->modulate) {
00217          int p;
00218          p = ps->v3_2 - 32768;
00219          if (p < 0) {
00220             p = -p;
00221          }
00222          p = ((p * 9) / 10) + 1;
00223          ps->data[x] = (ps->v3_1 * p) >> 15;
00224       } else {
00225          ps->data[x] = ps->v3_1 + ps->v3_2;
00226       }
00227    }
00228 
00229    ps->f.frametype = AST_FRAME_VOICE;
00230    ps->f.subclass.codec = AST_FORMAT_SLINEAR;
00231    ps->f.datalen = len;
00232    ps->f.samples = samples;
00233    ps->f.offset = AST_FRIENDLY_OFFSET;
00234    ps->f.data.ptr = ps->data;
00235 
00236    if (ast_write(chan, &ps->f)) {
00237       return -1;
00238    }
00239 
00240    ps->pos += x;
00241 
00242    if (pi->duration && ps->pos >= pi->duration * 8) { /* item finished? */
00243       ps->pos = 0;               /* start new item */
00244       ps->npos++;
00245       if (ps->npos >= ps->nitems) {       /* last item? */
00246          if (ps->reppos == -1) {       /* repeat set? */
00247             return -1;
00248          }
00249          ps->npos = ps->reppos;        /* redo from top */
00250       }
00251    }
00252 
00253    return 0;
00254 }

static void playtones_release ( struct ast_channel chan,
void *  params 
) [static]

Definition at line 129 of file indications.c.

References ast_free, ast_set_write_format(), playtones_state::items, and playtones_state::origwfmt.

Referenced by playtones_alloc().

00130 {
00131    struct playtones_state *ps = params;
00132 
00133    if (chan) {
00134       ast_set_write_format(chan, ps->origwfmt);
00135    }
00136 
00137    if (ps->items) {
00138       ast_free(ps->items);
00139       ps->items = NULL;
00140    }
00141 
00142    ast_free(ps);
00143 }

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 1029 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, and ast_tone_zone::tones.

Referenced by load_indications().

01030 {
01031    struct ast_tone_zone *zone = obj;
01032    struct ast_tone_zone_sound *s;
01033 
01034    ast_tone_zone_lock(zone);
01035 
01036    AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, s, entry) {
01037       if (s->killme) {
01038          AST_LIST_REMOVE_CURRENT(entry);
01039          s = ast_tone_zone_sound_unref(s);
01040       }
01041    }
01042    AST_LIST_TRAVERSE_SAFE_END;
01043 
01044    ast_tone_zone_unlock(zone);
01045 
01046    return zone->killme ? CMP_MATCH : 0;
01047 }

static void reset_tone_zone ( struct ast_tone_zone zone  )  [static]

Definition at line 948 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().

00949 {
00950    ast_tone_zone_lock(zone);
00951 
00952    zone->killme = 0;
00953 
00954    if (zone->nrringcadence) {
00955       zone->nrringcadence = 0;
00956       ast_free(zone->ringcadence);
00957       zone->ringcadence = NULL;
00958    }
00959 
00960    ast_tone_zone_unlock(zone);
00961 }

static void store_config_tone_zone ( struct ast_tone_zone zone,
const char *  var,
const char *  value 
) [static]

Definition at line 934 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().

00936 {
00937    CV_START(var, value);
00938 
00939    CV_STR("description", zone->description);
00940    CV_F("ringcadence", store_tone_zone_ring_cadence(zone, value));
00941    CV_F("ringcadance", store_tone_zone_ring_cadence(zone, value));
00942 
00943    ast_register_indication(zone, var, value);
00944 
00945    CV_END;
00946 }

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 907 of file indications.c.

References ast_copy_string(), ast_log(), ast_realloc, ast_strip(), LOG_WARNING, ast_tone_zone::nrringcadence, ast_tone_zone::ringcadence, and strsep().

Referenced by store_config_tone_zone().

00908 {
00909    char buf[1024];
00910    char *ring, *c = buf;
00911 
00912    ast_copy_string(buf, val, sizeof(buf));
00913 
00914    while ((ring = strsep(&c, ","))) {
00915       int *tmp, val;
00916 
00917       ring = ast_strip(ring);
00918 
00919       if (!isdigit(ring[0]) || (val = atoi(ring)) == -1) {
00920          ast_log(LOG_WARNING, "Invalid ringcadence given '%s'.\n", ring);
00921          continue;
00922       }
00923 
00924       if (!(tmp = ast_realloc(zone->ringcadence, (zone->nrringcadence + 1) * sizeof(int)))) {
00925          return;
00926       }
00927 
00928       zone->ringcadence = tmp;
00929       tmp[zone->nrringcadence] = val;
00930       zone->nrringcadence++;
00931    }
00932 }

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 1007 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, and ast_tone_zone::tones.

Referenced by load_indications().

01008 {
01009    struct ast_tone_zone *zone = obj;
01010    struct ast_tone_zone_sound *s;
01011 
01012    ast_tone_zone_lock(zone);
01013 
01014    zone->killme = 1;
01015 
01016    AST_LIST_TRAVERSE(&zone->tones, s, entry) {
01017       s->killme = 1;
01018    }
01019 
01020    ast_tone_zone_unlock(zone);
01021 
01022    return 0;
01023 }


Variable Documentation

struct ao2_container* ast_tone_zones [static]

Definition at line 81 of file indications.c.

Referenced by ast_get_indication_tone(), ast_get_indication_zone(), ast_indications_init(), ast_register_indication_country(), ast_set_indication_country(), ast_tone_zone_count(), ast_tone_zone_iterator_init(), ast_unregister_indication_country(), complete_country(), complete_indications(), handle_cli_indication_show(), load_indications(), and parse_tone_zone().

struct ast_cli_entry cli_indications[] [static]

Initial value:

 {
   { .handler =  handle_cli_indication_add , .summary =  "Add the given indication to the country" ,__VA_ARGS__ },
   { .handler =  handle_cli_indication_remove , .summary =  "Remove the given indication from the country" ,__VA_ARGS__ },
   { .handler =  handle_cli_indication_show , .summary =  "Display a list of all countries/indications" ,__VA_ARGS__ }
}
CLI entries for commands provided by this module.

Definition at line 1103 of file indications.c.

Referenced by ast_indications_init().

const char config[] = "indications.conf" [static]

Definition at line 63 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 88 of file indications.c.

Referenced by ast_get_indication_tone(), ast_get_indication_zone(), ast_register_indication_country(), ast_set_indication_country(), and ast_unregister_indication_country().

const int midi_tohz[128] [static]

Definition at line 65 of file indications.c.

struct ast_generator playtones [static]

Initial value:

 {
   .alloc     = playtones_alloc,
   .release   = playtones_release,
   .generate  = playtones_generator,
}

Definition at line 256 of file indications.c.

Referenced by ast_playtones_start().


Generated on Mon Oct 8 12:39:23 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7