Fri Jun 19 12:10:48 2009

Asterisk developer's documentation


res_indications.c File Reference

Load the indications. More...

#include "asterisk.h"
#include <ctype.h>
#include <sys/stat.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/indications.h"
#include "asterisk/utils.h"

Go to the source code of this file.

Functions

static void __reg_module (void)
static void __unreg_module (void)
static void free_zone (struct tone_zone *zone)
static char * handle_cli_indication_add (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Add a country to indication.
static char * handle_cli_indication_remove (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Remove a country from indication.
static char * handle_cli_indication_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show the current indications.
static int handle_playtones (struct ast_channel *chan, void *data)
 play tone for indication country
static int handle_stopplaytones (struct ast_channel *chan, void *data)
 Stop tones playing.
static int ind_load_module (int reload)
 load indications module
static int load_module (void)
 Load indications module.
static int reload (void)
 Reload indications module.
static int unload_module (void)
 Unload indicators module.

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Region-specific tones" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_cli_entry cli_indications []
 CLI entries for commands provided by this module.
static const char config [] = "indications.conf"
char * playtones_desc


Detailed Description

Load the indications.

Author:
Pauline Middelink <middelink@polyware.nl>
Load the country specific dialtones into the asterisk PBX.

Definition in file res_indications.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 441 of file res_indications.c.

static void __unreg_module ( void   )  [static]

Definition at line 441 of file res_indications.c.

static void free_zone ( struct tone_zone zone  )  [inline, static]

Definition at line 253 of file res_indications.c.

References ast_free, tone_zone_sound::data, tone_zone_sound::name, tone_zone_sound::next, tone_zone::ringcadence, and tone_zone::tones.

00254 {
00255    while (zone->tones) {
00256       struct tone_zone_sound *tmp = zone->tones->next;
00257       ast_free((void *)zone->tones->name);
00258       ast_free((void *)zone->tones->data);
00259       ast_free(zone->tones);
00260       zone->tones = tmp;
00261    }
00262 
00263    if (zone->ringcadence)
00264       ast_free(zone->ringcadence);
00265 
00266    ast_free(zone);
00267 }

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

Add a country to indication.

Parameters:
e the ast_cli_entry for this CLI command
cmd the reason we are being called
a the arguments being passed to us

Definition at line 66 of file res_indications.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_calloc, ast_copy_string(), ast_free, ast_get_indication_zone(), ast_log(), ast_register_indication(), ast_register_indication_country(), ast_unregister_indication_country(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, LOG_NOTICE, LOG_WARNING, and ast_cli_entry::usage.

00067 {
00068    struct tone_zone *tz;
00069    int created_country = 0;
00070 
00071    switch (cmd) {
00072    case CLI_INIT:
00073       e->command = "indication add";
00074       e->usage =
00075          "Usage: indication add <country> <indication> \"<tonelist>\"\n"
00076          "       Add the given indication to the country.\n";
00077       return NULL;
00078    case CLI_GENERATE:
00079       return NULL;
00080    }
00081 
00082    if (a->argc != 5)
00083       return CLI_SHOWUSAGE;
00084 
00085    tz = ast_get_indication_zone(a->argv[2]);
00086    if (!tz) {
00087       /* country does not exist, create it */
00088       ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n", a->argv[2]);
00089       
00090       if (!(tz = ast_calloc(1, sizeof(*tz)))) {
00091          return CLI_FAILURE;
00092       }
00093       ast_copy_string(tz->country, a->argv[2], sizeof(tz->country));
00094       if (ast_register_indication_country(tz)) {
00095          ast_log(LOG_WARNING, "Unable to register new country\n");
00096          ast_free(tz);
00097          return CLI_FAILURE;
00098       }
00099       created_country = 1;
00100    }
00101    if (ast_register_indication(tz, a->argv[3], a->argv[4])) {
00102       ast_log(LOG_WARNING, "Unable to register indication %s/%s\n", a->argv[2], a->argv[3]);
00103       if (created_country)
00104          ast_unregister_indication_country(a->argv[2]);
00105       return CLI_FAILURE;
00106    }
00107    return CLI_SUCCESS;
00108 }

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

Remove a country from indication.

Parameters:
e the ast_cli_entry for this CLI command
cmd the reason we are being called
a the arguments being passed to us

Definition at line 116 of file res_indications.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_get_indication_zone(), ast_log(), ast_unregister_indication(), ast_unregister_indication_country(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, LOG_WARNING, and ast_cli_entry::usage.

00117 {
00118    struct tone_zone *tz;
00119 
00120    switch (cmd) {
00121    case CLI_INIT:
00122       e->command = "indication remove";
00123       e->usage =
00124          "Usage: indication remove <country> <indication>\n"
00125          "       Remove the given indication from the country.\n";
00126       return NULL;
00127    case CLI_GENERATE:
00128       return NULL;
00129    }
00130 
00131    if (a->argc != 3 && a->argc != 4)
00132       return CLI_SHOWUSAGE;
00133 
00134    if (a->argc == 3) {
00135       /* remove entiry country */
00136       if (ast_unregister_indication_country(a->argv[2])) {
00137          ast_log(LOG_WARNING, "Unable to unregister indication country %s\n", a->argv[2]);
00138          return CLI_FAILURE;
00139       }
00140       return CLI_SUCCESS;
00141    }
00142 
00143    tz = ast_get_indication_zone(a->argv[2]);
00144    if (!tz) {
00145       ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n", a->argv[2], a->argv[3]);
00146       return CLI_FAILURE;
00147    }
00148    if (ast_unregister_indication(tz, a->argv[3])) {
00149       ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n", a->argv[2], a->argv[3]);
00150       return CLI_FAILURE;
00151    }
00152    return CLI_SUCCESS;
00153 }

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

Show the current indications.

Parameters:
e the ast_cli_entry for this CLI command
cmd the reason we are being called
a the arguments being passed to us

Definition at line 161 of file res_indications.c.

References tone_zone::alias, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_walk_indications(), buf, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, tone_zone::country, tone_zone::description, ast_cli_args::fd, tone_zone_sound::next, tone_zone::nrringcadence, tone_zone::ringcadence, tone_zone::tones, and ast_cli_entry::usage.

00162 {
00163    struct tone_zone *tz = NULL;
00164    char buf[256];
00165    int found_country = 0;
00166 
00167    switch (cmd) {
00168    case CLI_INIT:
00169       e->command = "indication show";
00170       e->usage =
00171          "Usage: indication show [<country> ...]\n"
00172          "       Display either a condensed for of all country/indications, or the\n"
00173          "       indications for the specified countries.\n";
00174       return NULL;
00175    case CLI_GENERATE:
00176       return NULL;
00177    }
00178 
00179    if (a->argc == 2) {
00180       /* no arguments, show a list of countries */
00181       ast_cli(a->fd, "Country Alias   Description\n");
00182       ast_cli(a->fd, "===========================\n");
00183       while ((tz = ast_walk_indications(tz)))
00184          ast_cli(a->fd, "%-7.7s %-7.7s %s\n", tz->country, tz->alias, tz->description);
00185       return CLI_SUCCESS;
00186    }
00187    /* there was a request for specific country(ies), lets humor them */
00188    while ((tz = ast_walk_indications(tz))) {
00189       int i, j;
00190       for (i = 2; i < a->argc; i++) {
00191          if (strcasecmp(tz->country, a->argv[i]) == 0 && !tz->alias[0]) {
00192             struct tone_zone_sound* ts;
00193             if (!found_country) {
00194                found_country = 1;
00195                ast_cli(a->fd, "Country Indication      PlayList\n");
00196                ast_cli(a->fd, "=====================================\n");
00197             }
00198             j = snprintf(buf, sizeof(buf), "%-7.7s %-15.15s ", tz->country, "<ringcadence>");
00199             for (i = 0; i < tz->nrringcadence; i++) {
00200                j += snprintf(buf + j, sizeof(buf) - j, "%d,", tz->ringcadence[i]);
00201             }
00202             if (tz->nrringcadence)
00203                j--;
00204             ast_copy_string(buf + j, "\n", sizeof(buf) - j);
00205             ast_cli(a->fd, "%s", buf);
00206             for (ts = tz->tones; ts; ts = ts->next)
00207                ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data);
00208             break;
00209          }
00210       }
00211    }
00212    if (!found_country)
00213       ast_cli(a->fd, "No countries matched your criteria.\n");
00214    return CLI_SUCCESS;
00215 }

static int handle_playtones ( struct ast_channel chan,
void *  data 
) [static]

play tone for indication country

Parameters:
chan ast_channel to play the sounds back to
data contains tone to play

Definition at line 222 of file res_indications.c.

References ast_get_indication_tone(), ast_log(), ast_playtones_start(), chan, tone_zone_sound::data, LOG_NOTICE, and ast_channel::zone.

Referenced by load_module().

00223 {
00224    struct tone_zone_sound *ts;
00225    int res;
00226 
00227    if (!data || !((char*)data)[0]) {
00228       ast_log(LOG_NOTICE,"Nothing to play\n");
00229       return -1;
00230    }
00231    ts = ast_get_indication_tone(chan->zone, (const char*)data);
00232    if (ts && ts->data[0])
00233       res = ast_playtones_start(chan, 0, ts->data, 0);
00234    else
00235       res = ast_playtones_start(chan, 0, (const char*)data, 0);
00236    if (res)
00237       ast_log(LOG_NOTICE,"Unable to start playtones\n");
00238    return res;
00239 }

static int handle_stopplaytones ( struct ast_channel chan,
void *  data 
) [static]

Stop tones playing.

Parameters:
chan 
data 

Definition at line 246 of file res_indications.c.

References ast_playtones_stop(), and chan.

Referenced by load_module().

00247 {
00248    ast_playtones_stop(chan);
00249    return 0;
00250 }

static int ind_load_module ( int  reload  )  [static]

load indications module

Definition at line 270 of file res_indications.c.

References ast_calloc, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_log(), ast_malloc, ast_realloc, ast_register_indication_country(), ast_set_indication_country(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_unregister_indication_country(), ast_variable_browse(), ast_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEUNCHANGED, country, free_zone(), ast_variable::lineno, LOG_NOTICE, LOG_WARNING, tone_zone_sound::name, ast_variable::name, ast_variable::next, tone_zone_sound::next, ps, ring(), strsep(), tone_zone::tones, and ast_variable::value.

Referenced by load_module(), and reload().

00271 {
00272    struct ast_config *cfg;
00273    struct ast_variable *v;
00274    char *cxt;
00275    char *c;
00276    struct tone_zone *tones;
00277    const char *country = NULL;
00278    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
00279 
00280    /* that the following cast is needed, is yuk! */
00281    /* yup, checked it out. It is NOT written to. */
00282    cfg = ast_config_load((char *)config, config_flags);
00283    if (!cfg)
00284       return -1;
00285    else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
00286       return 0;
00287 
00288    if (reload)
00289       ast_unregister_indication_country(NULL);
00290 
00291    /* Use existing config to populate the Indication table */
00292    cxt = ast_category_browse(cfg, NULL);
00293    while(cxt) {
00294       /* All categories but "general" are considered countries */
00295       if (!strcasecmp(cxt, "general")) {
00296          cxt = ast_category_browse(cfg, cxt);
00297          continue;
00298       }     
00299       if (!(tones = ast_calloc(1, sizeof(*tones)))) {
00300          ast_config_destroy(cfg);
00301          return -1;
00302       }
00303       ast_copy_string(tones->country,cxt,sizeof(tones->country));
00304 
00305       v = ast_variable_browse(cfg, cxt);
00306       while(v) {
00307          if (!strcasecmp(v->name, "description")) {
00308             ast_copy_string(tones->description, v->value, sizeof(tones->description));
00309          } else if ((!strcasecmp(v->name,"ringcadence"))||(!strcasecmp(v->name,"ringcadance"))) {
00310             char *ring,*rings = ast_strdupa(v->value);
00311             c = rings;
00312             ring = strsep(&c,",");
00313             while (ring) {
00314                int *tmp, val;
00315                if (!isdigit(ring[0]) || (val=atoi(ring))==-1) {
00316                   ast_log(LOG_WARNING,"Invalid ringcadence given '%s' at line %d.\n",ring,v->lineno);
00317                   ring = strsep(&c,",");
00318                   continue;
00319                }              
00320                if (!(tmp = ast_realloc(tones->ringcadence, (tones->nrringcadence + 1) * sizeof(int)))) {
00321                   ast_config_destroy(cfg);
00322                   free_zone(tones);
00323                   return -1;
00324                }
00325                tones->ringcadence = tmp;
00326                tmp[tones->nrringcadence] = val;
00327                tones->nrringcadence++;
00328                /* next item */
00329                ring = strsep(&c,",");
00330             }
00331          } else if (!strcasecmp(v->name,"alias")) {
00332             char *countries = ast_strdupa(v->value);
00333             c = countries;
00334             country = strsep(&c,",");
00335             while (country) {
00336                struct tone_zone* azone;
00337                if (!(azone = ast_calloc(1, sizeof(*azone)))) {
00338                   ast_config_destroy(cfg);
00339                   free_zone(tones);
00340                   return -1;
00341                }
00342                ast_copy_string(azone->country, country, sizeof(azone->country));
00343                ast_copy_string(azone->alias, cxt, sizeof(azone->alias));
00344                if (ast_register_indication_country(azone)) {
00345                   ast_log(LOG_WARNING, "Unable to register indication alias at line %d.\n",v->lineno);
00346                   free_zone(tones);
00347                }
00348                /* next item */
00349                country = strsep(&c,",");
00350             }
00351          } else {
00352             /* add tone to country */
00353             struct tone_zone_sound *ps,*ts;
00354             for (ps=NULL,ts=tones->tones; ts; ps=ts, ts=ts->next) {
00355                if (strcasecmp(v->name,ts->name)==0) {
00356                   /* already there */
00357                   ast_log(LOG_NOTICE,"Duplicate entry '%s', skipped.\n",v->name);
00358                   goto out;
00359                }
00360             }
00361             /* not there, add it to the back */          
00362             if (!(ts = ast_malloc(sizeof(*ts)))) {
00363                ast_config_destroy(cfg);
00364                return -1;
00365             }
00366             ts->next = NULL;
00367             ts->name = ast_strdup(v->name);
00368             ts->data = ast_strdup(v->value);
00369             if (ps)
00370                ps->next = ts;
00371             else
00372                tones->tones = ts;
00373          }
00374 out:        v = v->next;
00375       }
00376       if (tones->description[0] || tones->alias[0] || tones->tones) {
00377          if (ast_register_indication_country(tones)) {
00378             ast_log(LOG_WARNING, "Unable to register indication at line %d.\n",v->lineno);
00379             free_zone(tones);
00380          }
00381       } else {
00382          free_zone(tones);
00383       }
00384 
00385       cxt = ast_category_browse(cfg, cxt);
00386    }
00387 
00388    /* determine which country is the default */
00389    country = ast_variable_retrieve(cfg,"general","country");
00390    if (ast_strlen_zero(country) || ast_set_indication_country(country)) {
00391       ast_log(LOG_WARNING,"Unable to set the default country (for indication tones)\n");
00392    }
00393 
00394    ast_config_destroy(cfg);
00395    return 0;
00396 }

static int load_module ( void   )  [static]

Load indications module.

Definition at line 420 of file res_indications.c.

References ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_application, cli_indications, handle_playtones(), handle_stopplaytones(), and ind_load_module().

00421 {
00422    if (ind_load_module(0))
00423       return AST_MODULE_LOAD_DECLINE; 
00424    ast_cli_register_multiple(cli_indications, sizeof(cli_indications) / sizeof(struct ast_cli_entry));
00425    ast_register_application("PlayTones", handle_playtones, "Play a tone list", playtones_desc);
00426    ast_register_application("StopPlayTones", handle_stopplaytones, "Stop playing a tone list","  StopPlayTones(): Stop playing a tone list");
00427 
00428    return AST_MODULE_LOAD_SUCCESS;
00429 }

static int reload ( void   )  [static]

Reload indications module.

Definition at line 432 of file res_indications.c.

References ind_load_module().

00433 {
00434    return ind_load_module(1);
00435 }

static int unload_module ( void   )  [static]

Unload indicators module.

Definition at line 406 of file res_indications.c.

References ast_cli_unregister_multiple(), ast_unregister_application(), ast_unregister_indication_country(), and cli_indications.

00407 {
00408    /* remove the registed indications... */
00409    ast_unregister_indication_country(NULL);
00410 
00411    /* and the functions */
00412    ast_cli_unregister_multiple(cli_indications, sizeof(cli_indications) / sizeof(struct ast_cli_entry));
00413    ast_unregister_application("PlayTones");
00414    ast_unregister_application("StopPlayTones");
00415    return 0;
00416 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "Region-specific tones" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 441 of file res_indications.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 441 of file res_indications.c.

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 399 of file res_indications.c.

Referenced by load_module(), and unload_module().

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

Definition at line 46 of file res_indications.c.

char* playtones_desc

Definition at line 48 of file res_indications.c.


Generated on Fri Jun 19 12:10:48 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7