app_skel.c File Reference

Skeleton application. More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/config.h"
#include "asterisk/config_options.h"
#include "asterisk/say.h"
#include "asterisk/astobj2.h"
#include "asterisk/acl.h"
#include "asterisk/netsock2.h"
#include "asterisk/strings.h"
#include "asterisk/cli.h"

Include dependency graph for app_skel.c:

Go to the source code of this file.

Data Structures

struct  skel_config
 A container that holds all config-related information. More...
struct  skel_current_game
 Information about a currently running set of games. More...
struct  skel_global_config
 A structure to hold global configuration-related options. More...
struct  skel_level
 Object to hold level config information. More...
struct  skel_level_state
 A structure to maintain level state across reloads. More...

Defines

#define LEVEL_BUCKETS   1
#define SKEL_FORMAT   "%-15.15s %-11.11s %-12.12s %-8.8s %-8.8s %-12.12s\n"
#define SKEL_FORMAT   "%-15.15s %-15.15s %-15.15s\n"
#define SKEL_FORMAT1   "%-15.15s %-11u %-12u %-8u %-8u %-8f\n"
#define SKEL_FORMAT1   "%-15.15s %-15u %-15u\n"

Enumerations

enum  option_args { OPTION_ARG_NUMGAMES, OPTION_ARG_ARRAY_SIZE }
enum  option_flags { OPTION_CHEAT = (1 << 0), OPTION_NUMGAMES = (1 << 1), OPTION_WAIT = (1 << 0), OPTION_PATTERNS_DISABLED = (1 << 0) }

Functions

static void __reg_module (void)
static void __unreg_module (void)
static AO2_GLOBAL_OBJ_STATIC (globals)
 A global object container that will contain the skel_config that gets swapped out on reloads.
static int app_exec (struct ast_channel *chan, const char *data)
 CONFIG_INFO_STANDARD (cfg_info, globals, skel_config_alloc,.files=ACO_FILES(&app_skel_conf),)
 Register information about the configs being processed by this module.
static int custom_bitfield_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 A custom bitfield handler.
static char * handle_skel_show_config (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_skel_show_games (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_skel_show_levels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int load_module (void)
 Load the module.
static void play_files_helper (struct ast_channel *chan, const char *prompts)
static int reload_module (void)
static void * skel_config_alloc (void)
 Allocate a skel_config to hold a snapshot of the complete results of parsing a config.
static void skel_config_destructor (void *obj)
static void * skel_find_or_create_state (const char *category)
 Look up an existing state object, or create a new one.
static struct skel_current_gameskel_game_alloc (struct skel_level *level)
static void skel_game_destructor (void *obj)
static void skel_global_config_destructor (void *obj)
static void * skel_level_alloc (const char *cat)
 Allocate a skel_level based on a category in a configuration file.
static int skel_level_cmp (void *obj, void *arg, int flags)
static void skel_level_destructor (void *obj)
static void * skel_level_find (struct ao2_container *tmp_container, const char *category)
 Find a skel level in the specified container.
static int skel_level_hash (const void *obj, const int flags)
static struct skel_levelskel_state_alloc (const char *name)
static void skel_state_destructor (void *obj)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Skeleton (sample) Application" , .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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_DEFAULT, }
static char * app = "SkelGuessNumber"
static struct ast_app_option app_opts [128] = { [ 'c' ] = { .flag = OPTION_CHEAT }, [ 'n' ] = { .flag = OPTION_NUMGAMES , .arg_index = OPTION_ARG_NUMGAMES + 1 },}
struct aco_file app_skel_conf
static struct ast_module_infoast_module_info = &__mod_info
static struct ao2_containergames
 The container of active games.
static struct aco_type global_option
 An aco_type structure to link the "general" category to the skel_global_config type.
struct aco_typeglobal_options [] = ACO_TYPES(&global_option)
static struct aco_type level_option
 An aco_type structure to link the everything but the "general" and "sounds" categories to the skel_level type.
struct aco_typelevel_options [] = ACO_TYPES(&level_option)
static struct ast_cli_entry skel_cli []
static struct aco_type sound_option
 An aco_type structure to link the "sounds" category to the skel_global_config type.
struct aco_typesound_options [] = ACO_TYPES(&sound_option)


Detailed Description

Skeleton application.

Author:
<Your Name Here> <<Your Email Here>> 
This is a skeleton for development of an Asterisk application

Definition in file app_skel.c.


Define Documentation

#define LEVEL_BUCKETS   1

Definition at line 203 of file app_skel.c.

Referenced by skel_config_alloc().

#define SKEL_FORMAT   "%-15.15s %-11.11s %-12.12s %-8.8s %-8.8s %-12.12s\n"

#define SKEL_FORMAT   "%-15.15s %-15.15s %-15.15s\n"

#define SKEL_FORMAT1   "%-15.15s %-11u %-12u %-8u %-8u %-8f\n"

#define SKEL_FORMAT1   "%-15.15s %-15u %-15u\n"


Enumeration Type Documentation

Enumerator:
OPTION_ARG_NUMGAMES 
OPTION_ARG_ARRAY_SIZE 

Definition at line 143 of file app_skel.c.

00143                  {
00144    OPTION_ARG_NUMGAMES,
00145    /* This *must* be the last value in this enum! */
00146    OPTION_ARG_ARRAY_SIZE,
00147 };

Enumerator:
OPTION_CHEAT 
OPTION_NUMGAMES 
OPTION_WAIT 
OPTION_PATTERNS_DISABLED 

Definition at line 138 of file app_skel.c.

00138                   {
00139    OPTION_CHEAT    = (1 << 0),
00140    OPTION_NUMGAMES = (1 << 1),
00141 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 766 of file app_skel.c.

static void __unreg_module ( void   )  [static]

Definition at line 766 of file app_skel.c.

static AO2_GLOBAL_OBJ_STATIC ( globals   )  [static]

A global object container that will contain the skel_config that gets swapped out on reloads.

static int app_exec ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 375 of file app_skel.c.

References ao2_cleanup, ao2_find, ao2_global_obj_ref, ao2_link, ao2_lock, ao2_unlink, ao2_unlock, app_opts, args, AST_APP_ARG, ast_app_parse_options(), ast_channel_language(), ast_debug, AST_DECLARE_APP_ARGS, ast_log, ast_parse_arg(), ast_random(), ast_readstring(), ast_say_number(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero, ast_test_flag, buf, globals, LOG_ERROR, LOG_WARNING, NULL, OBJ_KEY, OPTION_ARG_ARRAY_SIZE, OPTION_ARG_NUMGAMES, OPTION_CHEAT, OPTION_NUMGAMES, parse(), PARSE_IN_RANGE, PARSE_INT32, PARSE_UINT32, play_files_helper(), RAII_VAR, and skel_game_alloc().

00376 {
00377    int win = 0;
00378    uint32_t guesses;
00379    RAII_VAR(struct skel_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
00380    RAII_VAR(struct skel_level *, level, NULL, ao2_cleanup);
00381    RAII_VAR(struct skel_current_game *, game, NULL, ao2_cleanup);
00382    char *parse, *opts[OPTION_ARG_ARRAY_SIZE];
00383    struct ast_flags flags;
00384    AST_DECLARE_APP_ARGS(args,
00385       AST_APP_ARG(level);
00386       AST_APP_ARG(options);
00387    );
00388 
00389    if (!cfg) {
00390       ast_log(LOG_ERROR, "Couldn't access configuratino data!\n");
00391       return -1;
00392    }
00393 
00394    if (ast_strlen_zero(data)) {
00395       ast_log(LOG_WARNING, "%s requires an argument (level[,options])\n", app);
00396       return -1;
00397    }
00398 
00399    /* We need to make a copy of the input string if we are going to modify it! */
00400    parse = ast_strdupa(data);
00401 
00402    AST_STANDARD_APP_ARGS(args, parse);
00403 
00404    if (args.argc == 2) {
00405       ast_app_parse_options(app_opts, &flags, opts, args.options);
00406    }
00407 
00408    if (ast_strlen_zero(args.level)) {
00409       ast_log(LOG_ERROR, "%s requires a level argument\n", app);
00410       return -1;
00411    }
00412 
00413    if (!(level = ao2_find(cfg->levels, args.level, OBJ_KEY))) {
00414       ast_log(LOG_ERROR, "Unknown level: %s\n", args.level);
00415       return -1;
00416    }
00417 
00418    if (!(game = skel_game_alloc(level))) {
00419       return -1;
00420    }
00421 
00422    ao2_link(games, game);
00423 
00424    /* Use app-specified values, or the options specified in [general] if they aren't passed to the app */
00425    if (!ast_test_flag(&flags, OPTION_NUMGAMES) ||
00426          ast_strlen_zero(opts[OPTION_ARG_NUMGAMES]) ||
00427          ast_parse_arg(opts[OPTION_ARG_NUMGAMES], PARSE_UINT32, &game->total_games)) {
00428       game->total_games = cfg->global->num_games;
00429    }
00430    game->games_left = game->total_games;
00431    game->cheat = ast_test_flag(&flags, OPTION_CHEAT) || cfg->global->cheat;
00432 
00433    for (game->games_left = game->total_games; game->games_left; game->games_left--) {
00434       uint32_t num = ast_random() % level->max_num; /* random number between 0 and level->max_num */
00435 
00436       ast_debug(1, "They should totally should guess %u\n", num);
00437 
00438       /* Play the prompt */
00439       play_files_helper(chan, cfg->global->prompt);
00440       ast_say_number(chan, level->max_num, "", ast_channel_language(chan), "");
00441 
00442       for (guesses = 0; guesses < level->max_guesses; guesses++) {
00443          size_t buflen = log10(level->max_num) + 1;
00444          char buf[buflen];
00445          int guess;
00446          buf[buflen] = '\0';
00447 
00448          /* Read the number pressed */
00449          ast_readstring(chan, buf, buflen - 1, 2000, 10000, "");
00450          if (ast_parse_arg(buf, PARSE_INT32 | PARSE_IN_RANGE, &guess, 0, level->max_num)) {
00451             if (guesses < level->max_guesses - 1) {
00452                play_files_helper(chan, cfg->global->wrong);
00453             }
00454             continue;
00455          }
00456 
00457          /* Inform whether the guess was right, low, or high */
00458          if (guess == num && !game->cheat) {
00459             /* win */
00460             win = 1;
00461             play_files_helper(chan, cfg->global->right);
00462             guesses++;
00463             break;
00464          } else if (guess < num) {
00465             play_files_helper(chan, cfg->global->low);
00466          } else {
00467             play_files_helper(chan, cfg->global->high);
00468          }
00469 
00470          if (guesses < level->max_guesses - 1) {
00471             play_files_helper(chan, cfg->global->wrong);
00472          }
00473       }
00474 
00475       /* Process game stats */
00476       ao2_lock(level->state);
00477       if (win) {
00478          ++level->state->wins;
00479          level->state->avg_guesses = ((level->state->wins - 1) * level->state->avg_guesses + guesses) / level->state->wins;
00480       } else {
00481          /* lose */
00482          level->state->losses++;
00483          play_files_helper(chan, cfg->global->lose);
00484       }
00485       ao2_unlock(level->state);
00486    }
00487 
00488    ao2_unlink(games, game);
00489 
00490    return 0;
00491 }

CONFIG_INFO_STANDARD ( cfg_info  ,
globals  ,
skel_config_alloc  ,
files = ACO_FILES(&app_skel_conf) 
)

Register information about the configs being processed by this module.

static int custom_bitfield_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

A custom bitfield handler.

Definition at line 352 of file app_skel.c.

References ast_true(), skel_global_config::cheat, global, ast_variable::name, and ast_variable::value.

Referenced by load_module().

00353 {
00354    struct skel_global_config *global = obj;
00355 
00356    if (!strcasecmp(var->name, "cheat")) {
00357       global->cheat = ast_true(var->value);
00358    } else {
00359       return -1;
00360    }
00361 
00362    return 0;
00363 }

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

Definition at line 589 of file app_skel.c.

References ao2_cleanup, ao2_global_obj_ref, ast_cli(), AST_CLI_YESNO, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, globals, NULL, RAII_VAR, and ast_cli_entry::usage.

00590 {
00591    RAII_VAR(struct skel_config *, cfg, NULL, ao2_cleanup);
00592 
00593    switch(cmd) {
00594    case CLI_INIT:
00595       e->command = "skel show config";
00596       e->usage =
00597          "Usage: skel show config\n"
00598          "       List app_skel global config\n";
00599       return NULL;
00600    case CLI_GENERATE:
00601       return NULL;
00602    }
00603 
00604    if (!(cfg = ao2_global_obj_ref(globals)) || !cfg->global) {
00605       return NULL;
00606    }
00607 
00608    ast_cli(a->fd, "games per call:  %u\n", cfg->global->num_games);
00609    ast_cli(a->fd, "computer cheats: %s\n", AST_CLI_YESNO(cfg->global->cheat));
00610    ast_cli(a->fd, "\n");
00611    ast_cli(a->fd, "Sounds\n");
00612    ast_cli(a->fd, "  prompt:      %s\n", cfg->global->prompt);
00613    ast_cli(a->fd, "  wrong guess: %s\n", cfg->global->wrong);
00614    ast_cli(a->fd, "  right guess: %s\n", cfg->global->right);
00615 
00616    return CLI_SUCCESS;
00617 }

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

Definition at line 619 of file app_skel.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, skel_current_game::games_left, skel_current_game::level_info, skel_level::name, NULL, SKEL_FORMAT, SKEL_FORMAT1, skel_current_game::total_games, and ast_cli_entry::usage.

00620 {
00621    struct ao2_iterator iter;
00622    struct skel_current_game *game;
00623 
00624    switch(cmd) {
00625    case CLI_INIT:
00626       e->command = "skel show games";
00627       e->usage =
00628          "Usage: skel show games\n"
00629          "       List app_skel active games\n";
00630       return NULL;
00631    case CLI_GENERATE:
00632       return NULL;
00633    }
00634 
00635 #define SKEL_FORMAT "%-15.15s %-15.15s %-15.15s\n"
00636 #define SKEL_FORMAT1 "%-15.15s %-15u %-15u\n"
00637    ast_cli(a->fd, SKEL_FORMAT, "Level", "Total Games", "Games Left");
00638    iter = ao2_iterator_init(games, 0);
00639    while ((game = ao2_iterator_next(&iter))) {
00640       ast_cli(a->fd, SKEL_FORMAT1, game->level_info->name, game->total_games, game->games_left);
00641       ao2_ref(game, -1);
00642    }
00643    ao2_iterator_destroy(&iter);
00644 #undef SKEL_FORMAT
00645 #undef SKEL_FORMAT1
00646    return CLI_SUCCESS;
00647 }

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

Definition at line 649 of file app_skel.c.

References ao2_cleanup, ao2_global_obj_ref, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), skel_level_state::avg_guesses, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, globals, skel_level_state::losses, skel_level::max_guesses, skel_level::max_num, skel_level::name, NULL, RAII_VAR, SKEL_FORMAT, SKEL_FORMAT1, skel_level::state, ast_cli_entry::usage, and skel_level_state::wins.

00650 {
00651    RAII_VAR(struct skel_config *, cfg, NULL, ao2_cleanup);
00652    struct ao2_iterator iter;
00653    struct skel_level *level;
00654 
00655    switch(cmd) {
00656    case CLI_INIT:
00657       e->command = "skel show levels";
00658       e->usage =
00659          "Usage: skel show levels\n"
00660          "       List the app_skel levels\n";
00661       return NULL;
00662    case CLI_GENERATE:
00663       return NULL;
00664    }
00665 
00666    if (!(cfg = ao2_global_obj_ref(globals)) || !cfg->levels) {
00667       return NULL;
00668    }
00669 
00670 #define SKEL_FORMAT "%-15.15s %-11.11s %-12.12s %-8.8s %-8.8s %-12.12s\n"
00671 #define SKEL_FORMAT1 "%-15.15s %-11u %-12u %-8u %-8u %-8f\n"
00672    ast_cli(a->fd, SKEL_FORMAT, "Name", "Max number", "Max Guesses", "Wins", "Losses", "Avg Guesses");
00673    iter = ao2_iterator_init(cfg->levels, 0);
00674    while ((level = ao2_iterator_next(&iter))) {
00675       ast_cli(a->fd, SKEL_FORMAT1, level->name, level->max_num, level->max_guesses, level->state->wins, level->state->losses, level->state->avg_guesses);
00676       ao2_ref(level, -1);
00677    }
00678    ao2_iterator_destroy(&iter);
00679 #undef SKEL_FORMAT
00680 #undef SKEL_FORMAT1
00681 
00682    return CLI_SUCCESS;
00683 }

static int load_module ( void   )  [static]

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 719 of file app_skel.c.

References ACO_EXACT, aco_info_destroy(), aco_info_init(), aco_option_register, aco_option_register_custom, aco_process_config(), ACO_PROCESS_ERROR, ao2_cleanup, ao2_container_alloc, app_exec, ARRAY_LEN, ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, custom_bitfield_handler(), error(), FLDSET, NULL, OPT_STRINGFIELD_T, OPT_UINT_T, prompt, and STRFLDSET.

00720 {
00721    if (aco_info_init(&cfg_info)) {
00722       goto error;
00723    }
00724    if (!(games = ao2_container_alloc(1, NULL, NULL))) {
00725       goto error;
00726    }
00727 
00728    /* Global options */
00729    aco_option_register(&cfg_info, "games", ACO_EXACT, global_options, "3", OPT_UINT_T, 0, FLDSET(struct skel_global_config, num_games));
00730    aco_option_register_custom(&cfg_info, "cheat", ACO_EXACT, global_options, "no", custom_bitfield_handler, 0);
00731 
00732    /* Sound options */
00733    aco_option_register(&cfg_info, "prompt", ACO_EXACT, sound_options, "please-enter-your&number&queue-less-than", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, prompt));
00734    aco_option_register(&cfg_info, "wrong_guess", ACO_EXACT, sound_options, "vm-pls-try-again", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, wrong));
00735    aco_option_register(&cfg_info, "right_guess", ACO_EXACT, sound_options, "auth-thankyou", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, right));
00736    aco_option_register(&cfg_info, "too_high", ACO_EXACT, sound_options, "high", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, high));
00737    aco_option_register(&cfg_info, "too_low", ACO_EXACT, sound_options, "low", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, low));
00738    aco_option_register(&cfg_info, "lose", ACO_EXACT, sound_options, "vm-goodbye", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, lose));
00739 
00740    /* Level options */
00741    aco_option_register(&cfg_info, "max_number", ACO_EXACT, level_options, NULL, OPT_UINT_T, 0, FLDSET(struct skel_level, max_num));
00742    aco_option_register(&cfg_info, "max_guesses", ACO_EXACT, level_options, NULL, OPT_UINT_T, 1, FLDSET(struct skel_level, max_guesses));
00743 
00744    if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
00745       goto error;
00746    }
00747 
00748    ast_cli_register_multiple(skel_cli, ARRAY_LEN(skel_cli));
00749    if (ast_register_application_xml(app, app_exec)) {
00750       goto error;
00751    }
00752    return AST_MODULE_LOAD_SUCCESS;
00753 
00754 error:
00755    aco_info_destroy(&cfg_info);
00756    ao2_cleanup(games);
00757    return AST_MODULE_LOAD_DECLINE;
00758 }

static void play_files_helper ( struct ast_channel chan,
const char *  prompts 
) [static]

Definition at line 365 of file app_skel.c.

References ast_stopstream(), ast_strdupa, ast_stream_and_wait(), prompt, and strsep().

Referenced by app_exec().

00366 {
00367    char *prompt, *rest = ast_strdupa(prompts);
00368 
00369    ast_stopstream(chan);
00370    while ((prompt = strsep(&rest, "&")) && !ast_stream_and_wait(chan, prompt, "")) {
00371       ast_stopstream(chan);
00372    }
00373 }

static int reload_module ( void   )  [static]

Definition at line 691 of file app_skel.c.

References aco_process_config(), ACO_PROCESS_ERROR, and AST_MODULE_LOAD_DECLINE.

00692 {
00693    if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
00694       return AST_MODULE_LOAD_DECLINE;
00695    }
00696 
00697    return 0;
00698 }

static void * skel_config_alloc ( void   )  [static]

Allocate a skel_config to hold a snapshot of the complete results of parsing a config.

Definition at line 562 of file app_skel.c.

References ao2_alloc, ao2_container_alloc, ao2_ref, ast_string_field_init, error(), skel_config::global, LEVEL_BUCKETS, skel_config::levels, NULL, skel_config_destructor(), skel_global_config_destructor(), skel_level_cmp(), and skel_level_hash().

00563 {
00564    struct skel_config *cfg;
00565 
00566    if (!(cfg = ao2_alloc(sizeof(*cfg), skel_config_destructor))) {
00567       return NULL;
00568    }
00569 
00570    /* Allocate/initialize memory */
00571    if (!(cfg->global = ao2_alloc(sizeof(*cfg->global), skel_global_config_destructor))) {
00572       goto error;
00573    }
00574 
00575    if (ast_string_field_init(cfg->global, 128)) {
00576       goto error;
00577    }
00578 
00579    if (!(cfg->levels = ao2_container_alloc(LEVEL_BUCKETS, skel_level_hash, skel_level_cmp))) {
00580       goto error;
00581    }
00582 
00583    return cfg;
00584 error:
00585    ao2_ref(cfg, -1);
00586    return NULL;
00587 }

static void skel_config_destructor ( void *  obj  )  [static]

Definition at line 555 of file app_skel.c.

References ao2_cleanup, skel_config::global, and skel_config::levels.

Referenced by skel_config_alloc().

00556 {
00557    struct skel_config *cfg = obj;
00558    ao2_cleanup(cfg->global);
00559    ao2_cleanup(cfg->levels);
00560 }

static void* skel_find_or_create_state ( const char *  category  )  [static]

Look up an existing state object, or create a new one.

Definition at line 517 of file app_skel.c.

References ao2_cleanup, ao2_find, ao2_global_obj_ref, ao2_ref, globals, NULL, OBJ_KEY, RAII_VAR, and skel_state_alloc().

Referenced by skel_level_alloc().

00518 {
00519    RAII_VAR(struct skel_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
00520    RAII_VAR(struct skel_level *, level, NULL, ao2_cleanup);
00521    if (!cfg || !cfg->levels || !(level = ao2_find(cfg->levels, category, OBJ_KEY))) {
00522       return skel_state_alloc(category);
00523    }
00524    ao2_ref(level->state, +1);
00525    return level->state;
00526 }

static struct skel_current_game* skel_game_alloc ( struct skel_level level  )  [static, read]

Definition at line 310 of file app_skel.c.

References ao2_alloc, ao2_ref, skel_current_game::level_info, NULL, and skel_game_destructor().

Referenced by app_exec().

00311 {
00312    struct skel_current_game *game;
00313    if (!(game = ao2_alloc(sizeof(struct skel_current_game), skel_game_destructor))) {
00314       return NULL;
00315    }
00316    ao2_ref(level, +1);
00317    game->level_info = level;
00318    return game;
00319 }

static void skel_game_destructor ( void *  obj  )  [static]

Definition at line 299 of file app_skel.c.

References ao2_cleanup, and skel_current_game::level_info.

Referenced by skel_game_alloc().

00300 {
00301    struct skel_current_game *game = obj;
00302    ao2_cleanup(game->level_info);
00303 }

static void skel_global_config_destructor ( void *  obj  )  [static]

Definition at line 293 of file app_skel.c.

References ast_string_field_free_memory, and global.

Referenced by skel_config_alloc().

00294 {
00295    struct skel_global_config *global = obj;
00296    ast_string_field_free_memory(global);
00297 }

static void * skel_level_alloc ( const char *  cat  )  [static]

Allocate a skel_level based on a category in a configuration file.

Parameters:
cat The category to base the level on
Returns:
A void pointer to a newly allocated skel_level

Definition at line 528 of file app_skel.c.

References ao2_alloc, ao2_ref, ast_string_field_init, ast_string_field_set, name, NULL, skel_find_or_create_state(), skel_level_destructor(), and skel_level::state.

00529 {
00530    struct skel_level *level;
00531 
00532    if (!(level = ao2_alloc(sizeof(*level), skel_level_destructor))) {
00533       return NULL;
00534    }
00535 
00536    if (ast_string_field_init(level, 128)) {
00537       ao2_ref(level, -1);
00538       return NULL;
00539    }
00540 
00541    /* Since the level has state information that needs to persist between reloads,
00542     * it is important to handle that here in the level's allocation function.
00543     * If not separated out into its own object, the data would be destroyed on
00544     * reload. */
00545    if (!(level->state = skel_find_or_create_state(cat))) {
00546       ao2_ref(level, -1);
00547       return NULL;
00548    }
00549 
00550    ast_string_field_set(level, name, cat);
00551 
00552    return level;
00553 }

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

Definition at line 335 of file app_skel.c.

References CMP_MATCH, CMP_STOP, match(), skel_level::name, and OBJ_KEY.

Referenced by skel_config_alloc().

00336 {
00337    struct skel_level *one = obj, *two = arg;
00338    const char *match = (flags & OBJ_KEY) ? arg : two->name;
00339    return strcasecmp(one->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
00340 }

static void skel_level_destructor ( void *  obj  )  [static]

Definition at line 321 of file app_skel.c.

References ao2_cleanup, ast_string_field_free_memory, and skel_level::state.

Referenced by skel_level_alloc().

00322 {
00323    struct skel_level *level = obj;
00324    ast_string_field_free_memory(level);
00325    ao2_cleanup(level->state);
00326 }

static void * skel_level_find ( struct ao2_container tmp_container,
const char *  category 
) [static]

Find a skel level in the specified container.

Note:
This function *does not* look for a skel_level in the active container. It is used internally by the Config Options code to check if an level has already been added to the container that will be swapped for the live container on a successul reload.
Parameters:
tmp_container A non-active container to search for a level
category The category associated with the level to check for
Return values:
non-NULL The level from the container
NULL The level does not exist in the container

Definition at line 504 of file app_skel.c.

References ao2_find, and OBJ_KEY.

00505 {
00506    return ao2_find(tmp_container, category, OBJ_KEY);
00507 }

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

Definition at line 328 of file app_skel.c.

References ast_str_case_hash(), skel_level::name, name, and OBJ_KEY.

Referenced by skel_config_alloc().

00329 {
00330    const struct skel_level *level = obj;
00331    const char *name = (flags & OBJ_KEY) ? obj : level->name;
00332    return ast_str_case_hash(name);
00333 }

static struct skel_level* skel_state_alloc ( const char *  name  )  [static, read]

Definition at line 493 of file app_skel.c.

References ao2_alloc, NULL, and skel_state_destructor().

Referenced by skel_find_or_create_state().

00494 {
00495    struct skel_level *level;
00496 
00497    if (!(level = ao2_alloc(sizeof(*level), skel_state_destructor))) {
00498       return NULL;
00499    }
00500 
00501    return level;
00502 }

static void skel_state_destructor ( void *  obj  )  [static]

Definition at line 305 of file app_skel.c.

Referenced by skel_state_alloc().

00306 {
00307    return;
00308 }

static int unload_module ( void   )  [static]


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Skeleton (sample) Application" , .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 = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 766 of file app_skel.c.

char* app = "SkelGuessNumber" [static]

Definition at line 136 of file app_skel.c.

struct ast_app_option app_opts[128] = { [ 'c' ] = { .flag = OPTION_CHEAT }, [ 'n' ] = { .flag = OPTION_NUMGAMES , .arg_index = OPTION_ARG_NUMGAMES + 1 },} [static]

Definition at line 152 of file app_skel.c.

Initial value:

 {
   .filename = "app_skel.conf",
   .types = ACO_TYPES(&global_option, &sound_option, &level_option),
}

Definition at line 277 of file app_skel.c.

Definition at line 766 of file app_skel.c.

struct ao2_container* games [static]

The container of active games.

Definition at line 286 of file app_skel.c.

struct aco_type global_option [static]

An aco_type structure to link the "general" category to the skel_global_config type.

Definition at line 243 of file app_skel.c.

struct aco_type* global_options[] = ACO_TYPES(&global_option)

Definition at line 251 of file app_skel.c.

struct aco_type level_option [static]

An aco_type structure to link the everything but the "general" and "sounds" categories to the skel_level type.

Definition at line 265 of file app_skel.c.

struct aco_type* level_options[] = ACO_TYPES(&level_option)

Definition at line 275 of file app_skel.c.

struct ast_cli_entry skel_cli[] [static]

Initial value:

 {
   AST_CLI_DEFINE(handle_skel_show_config, "Show app_skel global config options"),
   AST_CLI_DEFINE(handle_skel_show_levels, "Show app_skel levels"),
   AST_CLI_DEFINE(handle_skel_show_games, "Show app_skel active games"),
}

Definition at line 685 of file app_skel.c.

struct aco_type sound_option [static]

An aco_type structure to link the "sounds" category to the skel_global_config type.

Definition at line 254 of file app_skel.c.

struct aco_type* sound_options[] = ACO_TYPES(&sound_option)

Definition at line 262 of file app_skel.c.


Generated on Thu Apr 16 06:28:43 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6