Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:49:15 2009

## Asterisk developer's documentation

# res_indications.c File Reference

Load the indications. More...

`#include <unistd.h>`
`#include <string.h>`
`#include <ctype.h>`
`#include <stdlib.h>`
`#include <stdio.h>`
`#include <errno.h>`
`#include <sys/types.h>`
`#include <sys/stat.h>`
`#include "asterisk.h"`
`#include "asterisk/lock.h"`
`#include "asterisk/file.h"`
`#include "asterisk/cli.h"`
`#include "asterisk/logger.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 dependency graph for res_indications.c:

Go to the source code of this file.

## Functions

char * | description (void)
| Provides a description of the module.
static int | handle_add_indication (int fd, int argc, char *argv[])
static int | handle_playtones (struct ast_channel *chan, void *data)
static int | handle_remove_indication (int fd, int argc, char *argv[])
static int | handle_show_indications (int fd, int argc, char *argv[])
static int | handle_stopplaytones (struct ast_channel *chan, void *data)
static int | ind_load_module (void)
char * | key ()
| Returns the ASTERISK_GPL_KEY.
int | load_module (void)
| Initialize the module.
int | reload (void)
| Reload stuff.
int | unload_module (void)
| Cleanup all module structures, sockets, etc.
int | usecount (void)
| Provides a usecount.

## Variables

static struct ast_cli_entry | add_indication_cli
static const char | config [] = "indications.conf"
static const char | dtext [] = "Indications Configuration"
static char | help_add_indication []
static char | help_remove_indication []
static char | help_show_indications []
char * | playtones_desc
static struct ast_cli_entry | remove_indication_cli
static struct ast_cli_entry | show_indications_cli

## 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

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 421 of file res_indications.c.

    00422 {
    00423    /* that the following cast is needed, is yuk! */
    00424    return (char*)dtext;
    00425 }

static int handle_add_indication | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 87 of file res_indications.c.

References ast_get_indication_zone(), ast_log(), ast_register_indication(), ast_register_indication_country(), ast_unregister_indication_country(), tone_zone::country, free, LOG_NOTICE, LOG_WARNING, malloc, and RESULT_SHOWUSAGE.

    00088 {
    00089    struct tone_zone *tz;
    00090    int created_country = 0;
    00091    if (argc != 5) return RESULT_SHOWUSAGE;
    00092
    00093    tz = ast_get_indication_zone(argv[2]);
    00094    if (!tz) {
    00095       /* country does not exist, create it */
    00096       ast_log(LOG_NOTICE, "Country '%s' does not exist, creating it.\n",argv[2]);
    00097
    00098       tz = malloc(sizeof(struct tone_zone));
    00099       if (!tz) {
    00100          ast_log(LOG_WARNING, "Out of memory\n");
    00101          return -1;
    00102       }
    00103       memset(tz,0,sizeof(struct tone_zone));
    00104       ast_copy_string(tz->country,argv[2],sizeof(tz->country));
    00105       if (ast_register_indication_country(tz)) {
    00106          ast_log(LOG_WARNING, "Unable to register new country\n");
    00107          free(tz);
    00108          return -1;
    00109       }
    00110       created_country = 1;
    00111    }
    00112    if (ast_register_indication(tz,argv[3],argv[4])) {
    00113       ast_log(LOG_WARNING, "Unable to register indication %s/%s\n",argv[2],argv[3]);
    00114       if (created_country)
    00115          ast_unregister_indication_country(argv[2]);
    00116       return -1;
    00117    }
    00118    return 0;
    00119 }

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

Definition at line 207 of file res_indications.c.

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

Referenced by load_module().

    00208 {
    00209    struct tone_zone_sound *ts;
    00210    int res;
    00211
    00212    if (!data || !((char*)data)[0]) {
    00213       ast_log(LOG_NOTICE,"Nothing to play\n");
    00214       return -1;
    00215    }
    00216    ts = ast_get_indication_tone(chan->zone, (const char*)data);
    00217    if (ts && ts->data[0])
    00218       res = ast_playtones_start(chan, 0, ts->data, 0);
    00219    else
    00220       res = ast_playtones_start(chan, 0, (const char*)data, 0);
    00221    if (res)
    00222       ast_log(LOG_NOTICE,"Unable to start playtones\n");
    00223    return res;
    00224 }

static int handle_remove_indication | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 124 of file res_indications.c.

References ast_get_indication_zone(), ast_log(), ast_unregister_indication(), ast_unregister_indication_country(), LOG_WARNING, and RESULT_SHOWUSAGE.

    00125 {
    00126    struct tone_zone *tz;
    00127    if (argc != 3 && argc != 4) return RESULT_SHOWUSAGE;
    00128
    00129    if (argc == 3) {
    00130       /* remove entiry country */
    00131       if (ast_unregister_indication_country(argv[2])) {
    00132          ast_log(LOG_WARNING, "Unable to unregister indication country %s\n",argv[2]);
    00133          return -1;
    00134       }
    00135       return 0;
    00136    }
    00137
    00138    tz = ast_get_indication_zone(argv[2]);
    00139    if (!tz) {
    00140       ast_log(LOG_WARNING, "Unable to unregister indication %s/%s, country does not exists\n",argv[2],argv[3]);
    00141       return -1;
    00142    }
    00143    if (ast_unregister_indication(tz,argv[3])) {
    00144       ast_log(LOG_WARNING, "Unable to unregister indication %s/%s\n",argv[2],argv[3]);
    00145       return -1;
    00146    }
    00147    return 0;
    00148 }

static int handle_show_indications | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 153 of file res_indications.c.

References tone_zone::alias, ast_cli(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), tone_zone::country, tone_zone_sound::data, tone_zone::description, LOG_WARNING, tone_zone_sound::name, tone_zone_sound::next, tone_zone::next, tone_zone::nrringcadence, tone_zone::ringcadence, tone_zones, tone_zone::tones, and tzlock.

    00154 {
    00155    struct tone_zone *tz;
    00156    char buf[256];
    00157    int found_country = 0;
    00158
    00159    if (ast_mutex_lock(&tzlock)) {
    00160       ast_log(LOG_WARNING, "Unable to lock tone_zones list\n");
    00161       return 0;
    00162    }
    00163    if (argc == 2) {
    00164       /* no arguments, show a list of countries */
    00165       ast_cli(fd,"Country Alias   Description\n"
    00166             "===========================\n");
    00167       for (tz=tone_zones; tz; tz=tz->next) {
    00168          ast_cli(fd,"%-7.7s %-7.7s %s\n", tz->country, tz->alias, tz->description);
    00169       }
    00170       ast_mutex_unlock(&tzlock);
    00171       return 0;
    00172    }
    00173    /* there was a request for specific country(ies), lets humor them */
    00174    for (tz=tone_zones; tz; tz=tz->next) {
    00175       int i,j;
    00176       for (i=2; i<argc; i++) {
    00177          if (strcasecmp(tz->country,argv[i])==0 &&
    00178              !tz->alias[0]) {
    00179             struct tone_zone_sound* ts;
    00180             if (!found_country) {
    00181                found_country = 1;
    00182                ast_cli(fd,"Country Indication      PlayList\n"
    00183                      "=====================================\n");
    00184             }
    00185             j = snprintf(buf,sizeof(buf),"%-7.7s %-15.15s ",tz->country,"<ringcadence>");
    00186             for (i=0; i<tz->nrringcadence; i++) {
    00187                j += snprintf(buf+j,sizeof(buf)-j,"%d,",tz->ringcadence[i]);
    00188             }
    00189             if (tz->nrringcadence) j--;
    00190             ast_copy_string(buf+j,"\n",sizeof(buf)-j);
    00191             ast_cli(fd,buf);
    00192             for (ts=tz->tones; ts; ts=ts->next)
    00193                ast_cli(fd,"%-7.7s %-15.15s %s\n",tz->country,ts->name,ts->data);
    00194             break;
    00195          }
    00196       }
    00197    }
    00198    if (!found_country)
    00199       ast_cli(fd,"No countries matched your criteria.\n");
    00200    ast_mutex_unlock(&tzlock);
    00201    return -1;
    00202 }

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

Definition at line 229 of file res_indications.c.

References ast_playtones_stop().

Referenced by load_module().

    00230 {
    00231    ast_playtones_stop(chan);
    00232    return 0;
    00233 }

static int ind_load_module | ( | void |  | ) | `[static]`

Definition at line 238 of file res_indications.c.

References tone_zone::alias, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_register_indication_country(), ast_set_indication_country(), ast_strdupa, ast_variable_browse(), ast_variable_retrieve(), cfg, tone_zone::country, country, tone_zone_sound::data, tone_zone::description, free, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, malloc, tone_zone_sound::name, ast_variable::name, ast_variable::next, tone_zone_sound::next, tone_zone::nrringcadence, realloc, ring(), tone_zone::ringcadence, strdup, strsep(), tone_zone::tones, and ast_variable::value.

Referenced by load_module(), and reload().

    00239 {
    00240    struct ast_config *cfg;
    00241    struct ast_variable *v;
    00242    char *cxt;
    00243    char *c;
    00244    struct tone_zone *tones;
    00245    const char *country = NULL;
    00246
    00247    /* that the following cast is needed, is yuk! */
    00248    /* yup, checked it out. It is NOT written to. */
    00249    cfg = ast_config_load((char *)config);
    00250    if (!cfg)
    00251       return 0;
    00252
    00253    /* Use existing config to populate the Indication table */
    00254    cxt = ast_category_browse(cfg, NULL);
    00255    while(cxt) {
    00256       /* All categories but "general" are considered countries */
    00257       if (!strcasecmp(cxt, "general")) {
    00258          cxt = ast_category_browse(cfg, cxt);
    00259          continue;
    00260       }
    00261       tones = malloc(sizeof(struct tone_zone));
    00262       if (!tones) {
    00263          ast_log(LOG_WARNING,"Out of memory\n");
    00264          ast_config_destroy(cfg);
    00265          return -1;
    00266       }
    00267       memset(tones,0,sizeof(struct tone_zone));
    00268       ast_copy_string(tones->country,cxt,sizeof(tones->country));
    00269
    00270       v = ast_variable_browse(cfg, cxt);
    00271       while(v) {
    00272          if (!strcasecmp(v->name, "description")) {
    00273             ast_copy_string(tones->description, v->value, sizeof(tones->description));
    00274          } else if ((!strcasecmp(v->name,"ringcadence"))||(!strcasecmp(v->name,"ringcadance"))) {
    00275             char *ring,*rings = ast_strdupa(v->value);
    00276             c = rings;
    00277             ring = strsep(&c,",");
    00278             while (ring) {
    00279                int *tmp, val;
    00280                if (!isdigit(ring[0]) || (val=atoi(ring))==-1) {
    00281                   ast_log(LOG_WARNING,"Invalid ringcadence given '%s' at line %d.\n",ring,v->lineno);
    00282                   ring = strsep(&c,",");
    00283                   continue;
    00284                }
    00285                tmp = realloc(tones->ringcadence,(tones->nrringcadence+1)*sizeof(int));
    00286                if (!tmp) {
    00287                   ast_log(LOG_WARNING, "Out of memory\n");
    00288                   ast_config_destroy(cfg);
    00289                   return -1;
    00290                }
    00291                tones->ringcadence = tmp;
    00292                tmp[tones->nrringcadence] = val;
    00293                tones->nrringcadence++;
    00294                /* next item */
    00295                ring = strsep(&c,",");
    00296             }
    00297          } else if (!strcasecmp(v->name,"alias")) {
    00298             char *countries = ast_strdupa(v->value);
    00299             c = countries;
    00300             country = strsep(&c,",");
    00301             while (country) {
    00302                struct tone_zone* azone = malloc(sizeof(struct tone_zone));
    00303                if (!azone) {
    00304                   ast_log(LOG_WARNING,"Out of memory\n");
    00305                   ast_config_destroy(cfg);
    00306                   return -1;
    00307                }
    00308                memset(azone,0,sizeof(struct tone_zone));
    00309                ast_copy_string(azone->country, country, sizeof(azone->country));
    00310                ast_copy_string(azone->alias, cxt, sizeof(azone->alias));
    00311                if (ast_register_indication_country(azone)) {
    00312                   ast_log(LOG_WARNING, "Unable to register indication alias at line %d.\n",v->lineno);
    00313                   free(tones);
    00314                }
    00315                /* next item */
    00316                country = strsep(&c,",");
    00317             }
    00318          } else {
    00319             /* add tone to country */
    00320             struct tone_zone_sound *ps,*ts;
    00321             for (ps=NULL,ts=tones->tones; ts; ps=ts, ts=ts->next) {
    00322                if (strcasecmp(v->name,ts->name)==0) {
    00323                   /* already there */
    00324                   ast_log(LOG_NOTICE,"Duplicate entry '%s', skipped.\n",v->name);
    00325                   goto out;
    00326                }
    00327             }
    00328             /* not there, add it to the back */
    00329             ts = malloc(sizeof(struct tone_zone_sound));
    00330             if (!ts) {
    00331                ast_log(LOG_WARNING, "Out of memory\n");
    00332                ast_config_destroy(cfg);
    00333                return -1;
    00334             }
    00335             ts->next = NULL;
    00336             ts->name = strdup(v->name);
    00337             ts->data = strdup(v->value);
    00338             if (ps)
    00339                ps->next = ts;
    00340             else
    00341                tones->tones = ts;
    00342          }
    00343 out:        v = v->next;
    00344       }
    00345       if (tones->description[0] || tones->alias[0] || tones->tones) {
    00346          if (ast_register_indication_country(tones)) {
    00347             ast_log(LOG_WARNING, "Unable to register indication at line %d.\n",v->lineno);
    00348             free(tones);
    00349          }
    00350       } else free(tones);
    00351
    00352       cxt = ast_category_browse(cfg, cxt);
    00353    }
    00354
    00355    /* determine which country is the default */
    00356    country = ast_variable_retrieve(cfg,"general","country");
    00357    if (!country || !*country || ast_set_indication_country(country))
    00358       ast_log(LOG_WARNING,"Unable to set the default country (for indication tones)\n");
    00359
    00360    ast_config_destroy(cfg);
    00361    return 0;
    00362 }

char* key | ( | void |  | ) |

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

     char *key(void) {
             return ASTERISK_GPL_KEY;
     }

Returns:
  ASTERISK_GPL_KEY

Definition at line 432 of file res_indications.c.

References ASTERISK_GPL_KEY.

    00433 {
    00434    return ASTERISK_GPL_KEY;
    00435 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
  int Always 0.

TE STUFF END

Definition at line 400 of file res_indications.c.

References ast_cli_register(), ast_register_application(), handle_playtones(), handle_stopplaytones(), and ind_load_module().

    00401 {
    00402    if (ind_load_module()) return -1;
    00403
    00404    ast_cli_register(&add_indication_cli);
    00405    ast_cli_register(&remove_indication_cli);
    00406    ast_cli_register(&show_indications_cli);
    00407    ast_register_application("PlayTones", handle_playtones, "Play a tone list", playtones_desc);
    00408    ast_register_application("StopPlayTones", handle_stopplaytones, "Stop playing a tone list","Stop playing a tone list");
    00409
    00410    return 0;
    00411 }

int reload | ( | void |  | ) |

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
  The return value is not used.

Definition at line 413 of file res_indications.c.

References ast_unregister_indication_country(), and ind_load_module().

    00414 {
    00415    /* remove the registed indications... */
    00416    ast_unregister_indication_country(NULL);
    00417
    00418    return ind_load_module();
    00419 }

int unload_module | ( | void |  | ) |

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
  Zero on success, or non-zero on error.

Standard module functions ...

Definition at line 385 of file res_indications.c.

References ast_cli_unregister(), ast_unregister_application(), and ast_unregister_indication_country().

    00386 {
    00387    /* remove the registed indications... */
    00388    ast_unregister_indication_country(NULL);
    00389
    00390    /* and the functions */
    00391    ast_cli_unregister(&add_indication_cli);
    00392    ast_cli_unregister(&remove_indication_cli);
    00393    ast_cli_unregister(&show_indications_cli);
    00394    ast_unregister_application("PlayTones");
    00395    ast_unregister_application("StopPlayTones");
    00396    return 0;
    00397 }

int usecount | ( | void |  | ) |

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
  The module's usecount.

Definition at line 427 of file res_indications.c.

    00428 {
    00429    return 0;
    00430 }

## Variable Documentation

struct ast_cli_entry add_indication_cli`[static]`

Initial value:

       { { "indication", "add", NULL }, handle_add_indication,
          "Add the given indication to the country", help_add_indication,
          NULL }

Definition at line 367 of file res_indications.c.

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

Definition at line 54 of file res_indications.c.

const char dtext[] = "Indications Configuration"`[static]`

Definition at line 53 of file res_indications.c.

char help_add_indication[]`[static]`

Initial value:

    "Usage: indication add <country> <indication> \"<tonelist>\"\n"
    "       Add the given indication to the country.\n"

Definition at line 59 of file res_indications.c.

char help_remove_indication[]`[static]`

Initial value:

    "Usage: indication remove <country> <indication>\n"
    "       Remove the given indication from the country.\n"

Definition at line 63 of file res_indications.c.

char help_show_indications[]`[static]`

Initial value:

    "Usage: show indications [<country> ...]\n"
    "       Show either a condensed for of all country/indications, or the\n"
    "       indications for the specified countries.\n"

Definition at line 67 of file res_indications.c.

char* playtones_desc

Definition at line 72 of file res_indications.c.

struct ast_cli_entry remove_indication_cli`[static]`

Initial value:

       { { "indication", "remove", NULL }, handle_remove_indication,
          "Remove the given indication from the country", help_remove_indication,
          NULL }

Definition at line 372 of file res_indications.c.

struct ast_cli_entry show_indications_cli`[static]`

Initial value:

       { { "show", "indications", NULL }, handle_show_indications,
          "Show a list of all country/indications", help_show_indications,
          NULL }

Definition at line 377 of file res_indications.c.