Mon Jun 27 16:51:15 2011

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

#define DATA_EXPORT_TONE_ZONE_SOUND ( MEMBER   ) 

Value:

Definition at line 52 of file indications.c.

#define NUM_TONE_ZONE_BUCKETS   53

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

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

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

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

int ast_indications_init ( void   ) 

Load indications module.

Provided by indications.c

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

01148 {
01149    if (!(ast_tone_zones = ao2_container_alloc(NUM_TONE_ZONE_BUCKETS,
01150          ast_tone_zone_hash, ast_tone_zone_cmp))) {
01151       return -1;
01152    }
01153 
01154    if (load_indications(0)) {
01155       return -1;
01156    }
01157 
01158    ast_cli_register_multiple(cli_indications, ARRAY_LEN(cli_indications));
01159 
01160    return 0;
01161 }

int ast_indications_reload ( void   ) 

Reload indications module.

Provided by indications.c

Definition at line 1164 of file indications.c.

References load_indications().

01165 {
01166    return load_indications(1);
01167 }

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 315 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.

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

void ast_playtones_stop ( struct ast_channel chan  ) 

Stop playing tones on a channel.

Stop the tones from playing

Definition at line 404 of file indications.c.

References ast_deactivate_generator().

00405 {
00406    ast_deactivate_generator(chan);
00407 }

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

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

static int ast_register_indication_country ( struct ast_tone_zone zone  )  [static]

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

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

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

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

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

static struct ast_tone_zone* ast_tone_zone_alloc ( void   )  [static]

Definition at line 636 of file indications.c.

References ao2_alloc, and ast_tone_zone_destructor().

Referenced by handle_cli_indication_add(), and parse_tone_zone().

00637 {
00638    return ao2_alloc(sizeof(struct ast_tone_zone), ast_tone_zone_destructor);
00639 }

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

Definition at line 1110 of file indications.c.

References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.

Referenced by ast_indications_init().

01111 {
01112    struct ast_tone_zone *zone = obj;
01113    struct ast_tone_zone *zone_arg = arg;
01114 
01115    return (!strcasecmp(zone->country, zone_arg->country)) ?
01116          CMP_MATCH | CMP_STOP : 0;
01117 }

int ast_tone_zone_count ( void   ) 

Get the number of registered tone zones.

Returns:
the total number of registered tone zones

Definition at line 409 of file indications.c.

References ao2_container_count(), and ast_tone_zones.

00410 {
00411    return ao2_container_count(ast_tone_zones);
00412 }

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

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

static void ast_tone_zone_destructor ( void *  obj  )  [static]

deallocate the passed tone zone

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

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

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

Definition at line 1103 of file indications.c.

References ast_str_case_hash(), and ast_tone_zone::country.

Referenced by ast_indications_init().

01104 {
01105    const struct ast_tone_zone *zone = obj;
01106 
01107    return ast_str_case_hash(zone->country);
01108 }

struct ao2_iterator ast_tone_zone_iterator_init ( void   ) 

Get an iterator for the available tone zones.

Use ao2_iterator_next() to iterate the tone zones.

Returns:
an initialized iterator

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

00415 {
00416    return ao2_iterator_init(ast_tone_zones, 0);
00417 }

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

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

static void ast_tone_zone_sound_destructor ( void *  obj  )  [static]

Definition at line 501 of file indications.c.

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

Referenced by ast_register_indication().

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

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

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

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

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

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

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

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

Definition at line 641 of file indications.c.

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

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

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

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

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

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

Definition at line 665 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.

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

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

Definition at line 758 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.

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

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

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

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

static int is_valid_tone_zone ( struct ast_tone_zone zone  )  [static]

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

00888 {
00889    int res;
00890 
00891    ast_tone_zone_lock(zone);
00892    res = (!ast_strlen_zero(zone->description) && !AST_LIST_EMPTY(&zone->tones));
00893    ast_tone_zone_unlock(zone);
00894 
00895    return res;
00896 }

static int load_indications ( int  reload  )  [static]

load indications module

Definition at line 1044 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_flags, 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().

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

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

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

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

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

Definition at line 141 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(), LOG_WARNING, ast_channel::name, pd, playtones_release(), ps, and ast_channel::writeformat.

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

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

Definition at line 174 of file indications.c.

References ast_log(), 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, LOG_WARNING, playtones_item::modulate, and ps.

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

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

Definition at line 125 of file indications.c.

References ast_free, ast_set_write_format(), and ps.

Referenced by playtones_alloc().

00126 {
00127    struct playtones_state *ps = params;
00128 
00129    if (chan) {
00130       ast_set_write_format(chan, ps->origwfmt);
00131    }
00132 
00133    if (ps->items) {
00134       ast_free(ps->items);
00135       ps->items = NULL;
00136    }
00137 
00138    ast_free(ps);
00139 }

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

01024 {
01025    struct ast_tone_zone *zone = obj;
01026    struct ast_tone_zone_sound *s;
01027 
01028    ast_tone_zone_lock(zone);
01029 
01030    AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, s, entry) {
01031       if (s->killme) {
01032          AST_LIST_REMOVE_CURRENT(entry);
01033          s = ast_tone_zone_sound_unref(s);
01034       }
01035    }
01036    AST_LIST_TRAVERSE_SAFE_END;
01037 
01038    ast_tone_zone_unlock(zone);
01039 
01040    return zone->killme ? CMP_MATCH : 0;
01041 }

static void reset_tone_zone ( struct ast_tone_zone zone  )  [static]

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

00943 {
00944    ast_tone_zone_lock(zone);
00945 
00946    zone->killme = 0;
00947 
00948    if (zone->nrringcadence) {
00949       zone->nrringcadence = 0;
00950       ast_free(zone->ringcadence);
00951       zone->ringcadence = NULL;
00952    }
00953 
00954    ast_tone_zone_unlock(zone);
00955 }

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

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

00930 {
00931    CV_START(var, value);
00932 
00933    CV_STR("description", zone->description);
00934    CV_F("ringcadence", store_tone_zone_ring_cadence(zone, value));
00935    CV_F("ringcadance", store_tone_zone_ring_cadence(zone, value));
00936 
00937    ast_register_indication(zone, var, value);
00938 
00939    CV_END;
00940 }

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

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

Referenced by store_config_tone_zone().

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

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

01002 {
01003    struct ast_tone_zone *zone = obj;
01004    struct ast_tone_zone_sound *s;
01005 
01006    ast_tone_zone_lock(zone);
01007 
01008    zone->killme = 1;
01009 
01010    AST_LIST_TRAVERSE(&zone->tones, s, entry) {
01011       s->killme = 1;
01012    }
01013 
01014    ast_tone_zone_unlock(zone);
01015 
01016    return 0;
01017 }


Variable Documentation

struct ao2_container* ast_tone_zones [static]

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

Referenced by ast_indications_init().

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

Definition at line 59 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 84 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 61 of file indications.c.

struct ast_generator playtones [static]

Initial value:

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

Definition at line 252 of file indications.c.

Referenced by ast_playtones_start().


Generated on Mon Jun 27 16:51:15 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7