Mon Mar 19 11:30:49 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 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 1149 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().

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

int ast_indications_reload ( void   ) 

Reload indications module.

Provided by indications.c

Definition at line 1166 of file indications.c.

References load_indications().

01167 {
01168    return load_indications(1);
01169 }

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

References CMP_MATCH, CMP_STOP, and ast_tone_zone::country.

Referenced by ast_indications_init().

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

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

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

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

References ast_str_case_hash(), and ast_tone_zone::country.

Referenced by ast_indications_init().

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

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

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    ao2_iterator_destroy(&i);
00662 
00663    return res;
00664 }

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

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

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

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

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

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

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

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

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

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

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

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

static int is_valid_tone_zone ( struct ast_tone_zone zone  )  [static]

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

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

static int load_indications ( int  reload  )  [static]

load indications module

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

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

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

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

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

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

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

static void reset_tone_zone ( struct ast_tone_zone zone  )  [static]

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

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

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

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

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

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

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

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

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


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 1099 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 Mar 19 11:30:49 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7