Asterisk - The Open Source Telephony Project GIT-master-66c01d8
Data Structures | Macros | Enumerations | Functions | Variables
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...
 

Macros

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

Enumerations

enum  option_args { OPTION_ARG_NUMGAMES , OPTION_ARG_ARRAY_SIZE }
 
enum  option_flags { OPTION_CHEAT = (1 << 0) , OPTION_NUMGAMES = (1 << 1) , 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. More...
 
static int app_exec (struct ast_channel *chan, const char *data)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 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. More...
 
static int custom_bitfield_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 A custom bitfield handler. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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_DEFAULT , .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, }
 
static char * app = "SkelGuessNumber"
 
static const 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 const struct ast_module_infoast_module_info = &__mod_info
 
static struct ao2_containergames
 The container of active games. More...
 
static struct aco_type global_option
 An aco_type structure to link the "general" category to the skel_global_config type. More...
 
struct aco_typeglobal_options [] = ACO_TYPES(&global_option)
 
static const char * level_categories []
 
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. More...
 
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. More...
 
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.

Macro Definition Documentation

◆ LEVEL_BUCKETS

#define LEVEL_BUCKETS   1
Examples
app_skel.c.

Definition at line 244 of file app_skel.c.

◆ SKEL_FORMAT [1/2]

#define SKEL_FORMAT   "%-15.15s %-15.15s %-15.15s\n"
Examples
app_skel.c.

◆ SKEL_FORMAT [2/2]

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

◆ SKEL_FORMAT1 [1/2]

#define SKEL_FORMAT1   "%-15.15s %-15u %-15u\n"
Examples
app_skel.c.

◆ SKEL_FORMAT1 [2/2]

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

Enumeration Type Documentation

◆ option_args

Enumerator
OPTION_ARG_NUMGAMES 
OPTION_ARG_ARRAY_SIZE 

Definition at line 184 of file app_skel.c.

184 {
186 /* This *must* be the last value in this enum! */
188};
@ OPTION_ARG_NUMGAMES
Definition: app_skel.c:185
@ OPTION_ARG_ARRAY_SIZE
Definition: app_skel.c:187

◆ option_flags

Enumerator
OPTION_CHEAT 
OPTION_NUMGAMES 
OPTION_PATTERNS_DISABLED 

Definition at line 179 of file app_skel.c.

179 {
180 OPTION_CHEAT = (1 << 0),
181 OPTION_NUMGAMES = (1 << 1),
182};
@ OPTION_NUMGAMES
Definition: app_skel.c:181
@ OPTION_CHEAT
Definition: app_skel.c:180

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 817 of file app_skel.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 817 of file app_skel.c.

◆ AO2_GLOBAL_OBJ_STATIC()

static AO2_GLOBAL_OBJ_STATIC ( globals  )
static

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

Examples
app_skel.c.

◆ app_exec()

static int app_exec ( struct ast_channel chan,
const char *  data 
)
static
Examples
app_skel.c.

Definition at line 423 of file app_skel.c.

424{
425 int win = 0;
426 uint32_t guesses;
428 RAII_VAR(struct skel_level *, level, NULL, ao2_cleanup);
429 RAII_VAR(struct skel_current_game *, game, NULL, ao2_cleanup);
430 char *parse, *opts[OPTION_ARG_ARRAY_SIZE];
431 struct ast_flags flags;
433 AST_APP_ARG(level);
435 );
436
437 if (!cfg) {
438 ast_log(LOG_ERROR, "Couldn't access configuratino data!\n");
439 return -1;
440 }
441
442 if (ast_strlen_zero(data)) {
443 ast_log(LOG_WARNING, "%s requires an argument (level[,options])\n", app);
444 return -1;
445 }
446
447 /* We need to make a copy of the input string if we are going to modify it! */
448 parse = ast_strdupa(data);
449
451
452 if (args.argc == 2) {
453 ast_app_parse_options(app_opts, &flags, opts, args.options);
454 }
455
456 if (ast_strlen_zero(args.level)) {
457 ast_log(LOG_ERROR, "%s requires a level argument\n", app);
458 return -1;
459 }
460
461 if (!(level = ao2_find(cfg->levels, args.level, OBJ_KEY))) {
462 ast_log(LOG_ERROR, "Unknown level: %s\n", args.level);
463 return -1;
464 }
465
466 if (!(game = skel_game_alloc(level))) {
467 return -1;
468 }
469
470 ao2_link(games, game);
471
472 /* Use app-specified values, or the options specified in [general] if they aren't passed to the app */
475 ast_parse_arg(opts[OPTION_ARG_NUMGAMES], PARSE_UINT32, &game->total_games)) {
476 game->total_games = cfg->global->num_games;
477 }
478 game->games_left = game->total_games;
479 game->cheat = ast_test_flag(&flags, OPTION_CHEAT) || cfg->global->cheat;
480
481 for (game->games_left = game->total_games; game->games_left; game->games_left--) {
482 uint32_t num = ast_random() % level->max_num; /* random number between 0 and level->max_num */
483
484 ast_debug(1, "They should totally should guess %u\n", num);
485
486 /* Play the prompt */
487 play_files_helper(chan, cfg->global->prompt);
488 ast_say_number(chan, level->max_num, "", ast_channel_language(chan), "");
489
490 for (guesses = 0; guesses < level->max_guesses; guesses++) {
491 size_t buflen = log10(level->max_num) + 1;
492 char buf[buflen];
493 int guess;
494 buf[buflen] = '\0';
495
496 /* Read the number pressed */
497 ast_readstring(chan, buf, buflen - 1, 2000, 10000, "");
498 if (ast_parse_arg(buf, PARSE_INT32 | PARSE_IN_RANGE, &guess, 0, level->max_num)) {
499 if (guesses < level->max_guesses - 1) {
500 play_files_helper(chan, cfg->global->wrong);
501 }
502 continue;
503 }
504
505 /* Inform whether the guess was right, low, or high */
506 if (guess == num && !game->cheat) {
507 /* win */
508 win = 1;
509 play_files_helper(chan, cfg->global->right);
510 guesses++;
511 break;
512 } else if (guess < num) {
513 play_files_helper(chan, cfg->global->low);
514 } else {
515 play_files_helper(chan, cfg->global->high);
516 }
517
518 if (guesses < level->max_guesses - 1) {
519 play_files_helper(chan, cfg->global->wrong);
520 }
521 }
522
523 /* Process game stats */
524 ao2_lock(level->state);
525 if (win) {
526 ++level->state->wins;
527 level->state->avg_guesses = ((level->state->wins - 1) * level->state->avg_guesses + guesses) / level->state->wins;
528 } else {
529 /* lose */
530 level->state->losses++;
531 play_files_helper(chan, cfg->global->lose);
532 }
533 ao2_unlock(level->state);
534 }
535
536 ao2_unlink(games, game);
537
538 return 0;
539}
static void play_files_helper(struct ast_channel *chan, const char *prompts)
Definition: app_skel.c:412
static struct ao2_container * games
The container of active games.
Definition: app_skel.c:333
static const struct ast_app_option app_opts[128]
Definition: app_skel.c:193
static char * app
Definition: app_skel.c:177
static struct skel_current_game * skel_game_alloc(struct skel_level *level)
Definition: app_skel.c:357
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
#define OBJ_KEY
Definition: astobj2.h:1151
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
static struct console_pvt globals
const char * ast_channel_language(const struct ast_channel *chan)
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:6575
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: main/app.c:3066
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
Definition: main/config.c:4047
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
#define LOG_WARNING
#define NULL
Definition: resample.c:96
int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options)
says a number
Definition: channel.c:8261
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Structure used to handle boolean flags.
Definition: utils.h:199
unsigned int flags
Definition: utils.h:200
A container that holds all config-related information.
Definition: app_skel.c:252
Information about a currently running set of games.
Definition: app_skel.c:236
Object to hold level config information.
Definition: app_skel.c:220
const char * args
static struct test_options options
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
long int ast_random(void)
Definition: utils.c:2312

References ao2_cleanup, ao2_find, ao2_global_obj_ref, ao2_link, ao2_lock, ao2_unlink, ao2_unlock, app, 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, ast_flags::flags, games, globals, LOG_ERROR, LOG_WARNING, NULL, OBJ_KEY, OPTION_ARG_ARRAY_SIZE, OPTION_ARG_NUMGAMES, OPTION_CHEAT, OPTION_NUMGAMES, options, PARSE_IN_RANGE, PARSE_INT32, PARSE_UINT32, play_files_helper(), RAII_VAR, and skel_game_alloc().

Referenced by load_module().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 817 of file app_skel.c.

◆ CONFIG_INFO_STANDARD()

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.

Examples
app_skel.c.

◆ custom_bitfield_handler()

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

A custom bitfield handler.

Examples
app_skel.c.

Definition at line 399 of file app_skel.c.

400{
401 struct skel_global_config *global = obj;
402
403 if (!strcasecmp(var->name, "cheat")) {
404 global->cheat = ast_true(var->value);
405 } else {
406 return -1;
407 }
408
409 return 0;
410}
#define var
Definition: ast_expr2f.c:605
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition: utils.c:2199
A structure to hold global configuration-related options.
Definition: app_skel.c:196
static struct aco_type global
Definition: test_config.c:1445

References ast_true(), global, and var.

Referenced by load_module().

◆ handle_skel_show_config()

static char * handle_skel_show_config ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static
Examples
app_skel.c.

Definition at line 639 of file app_skel.c.

640{
641 RAII_VAR(struct skel_config *, cfg, NULL, ao2_cleanup);
642
643 switch(cmd) {
644 case CLI_INIT:
645 e->command = "skel show config";
646 e->usage =
647 "Usage: skel show config\n"
648 " List app_skel global config\n";
649 return NULL;
650 case CLI_GENERATE:
651 return NULL;
652 }
653
654 if (!(cfg = ao2_global_obj_ref(globals)) || !cfg->global) {
655 return NULL;
656 }
657
658 ast_cli(a->fd, "games per call: %u\n", cfg->global->num_games);
659 ast_cli(a->fd, "computer cheats: %s\n", AST_CLI_YESNO(cfg->global->cheat));
660 ast_cli(a->fd, "\n");
661 ast_cli(a->fd, "Sounds\n");
662 ast_cli(a->fd, " prompt: %s\n", cfg->global->prompt);
663 ast_cli(a->fd, " wrong guess: %s\n", cfg->global->wrong);
664 ast_cli(a->fd, " right guess: %s\n", cfg->global->right);
665
666 return CLI_SUCCESS;
667}
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

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

◆ handle_skel_show_games()

static char * handle_skel_show_games ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static
Examples
app_skel.c.

Definition at line 669 of file app_skel.c.

670{
671 struct ao2_iterator iter;
672 struct skel_current_game *game;
673
674 switch(cmd) {
675 case CLI_INIT:
676 e->command = "skel show games";
677 e->usage =
678 "Usage: skel show games\n"
679 " List app_skel active games\n";
680 return NULL;
681 case CLI_GENERATE:
682 return NULL;
683 }
684
685#define SKEL_FORMAT "%-15.15s %-15.15s %-15.15s\n"
686#define SKEL_FORMAT1 "%-15.15s %-15u %-15u\n"
687 ast_cli(a->fd, SKEL_FORMAT, "Level", "Total Games", "Games Left");
688 iter = ao2_iterator_init(games, 0);
689 while ((game = ao2_iterator_next(&iter))) {
690 ast_cli(a->fd, SKEL_FORMAT1, game->level_info->name, game->total_games, game->games_left);
691 ao2_ref(game, -1);
692 }
694#undef SKEL_FORMAT
695#undef SKEL_FORMAT1
696 return CLI_SUCCESS;
697}
#define SKEL_FORMAT
#define SKEL_FORMAT1
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct skel_level * level_info
Definition: app_skel.c:240
uint32_t games_left
Definition: app_skel.c:238
uint32_t total_games
Definition: app_skel.c:237
const ast_string_field name
Definition: app_skel.c:223

References a, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, games, 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.

◆ handle_skel_show_levels()

static char * handle_skel_show_levels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static
Examples
app_skel.c.

Definition at line 699 of file app_skel.c.

700{
701 RAII_VAR(struct skel_config *, cfg, NULL, ao2_cleanup);
702 struct ao2_iterator iter;
703 struct skel_level *level;
704
705 switch(cmd) {
706 case CLI_INIT:
707 e->command = "skel show levels";
708 e->usage =
709 "Usage: skel show levels\n"
710 " List the app_skel levels\n";
711 return NULL;
712 case CLI_GENERATE:
713 return NULL;
714 }
715
716 if (!(cfg = ao2_global_obj_ref(globals)) || !cfg->levels) {
717 return NULL;
718 }
719
720#define SKEL_FORMAT "%-15.15s %-11.11s %-12.12s %-8.8s %-8.8s %-12.12s\n"
721#define SKEL_FORMAT1 "%-15.15s %-11u %-12u %-8u %-8u %-8f\n"
722 ast_cli(a->fd, SKEL_FORMAT, "Name", "Max number", "Max Guesses", "Wins", "Losses", "Avg Guesses");
723 iter = ao2_iterator_init(cfg->levels, 0);
724 while ((level = ao2_iterator_next(&iter))) {
725 ast_cli(a->fd, SKEL_FORMAT1, level->name, level->max_num, level->max_guesses, level->state->wins, level->state->losses, level->state->avg_guesses);
726 ao2_ref(level, -1);
727 }
729#undef SKEL_FORMAT
730#undef SKEL_FORMAT1
731
732 return CLI_SUCCESS;
733}
uint32_t wins
Definition: app_skel.c:211
double avg_guesses
Definition: app_skel.c:213
uint32_t losses
Definition: app_skel.c:212
uint32_t max_guesses
Definition: app_skel.c:225
struct skel_level_state * state
Definition: app_skel.c:226
uint32_t max_num
Definition: app_skel.c:224

References a, 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, 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.

◆ load_module()

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.

Examples
app_skel.c.

Definition at line 769 of file app_skel.c.

770{
771 if (aco_info_init(&cfg_info)) {
772 goto error;
773 }
774
776 if (!games) {
777 goto error;
778 }
779
780 /* Global options */
781 aco_option_register(&cfg_info, "games", ACO_EXACT, global_options, "3", OPT_UINT_T, 0, FLDSET(struct skel_global_config, num_games));
783
784 /* Sound options */
785 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));
786 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));
787 aco_option_register(&cfg_info, "right_guess", ACO_EXACT, sound_options, "auth-thankyou", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, right));
788 aco_option_register(&cfg_info, "too_high", ACO_EXACT, sound_options, "high", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, high));
789 aco_option_register(&cfg_info, "too_low", ACO_EXACT, sound_options, "low", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, low));
790 aco_option_register(&cfg_info, "lose", ACO_EXACT, sound_options, "vm-goodbye", OPT_STRINGFIELD_T, 0, STRFLDSET(struct skel_global_config, lose));
791
792 /* Level options */
793 aco_option_register(&cfg_info, "max_number", ACO_EXACT, level_options, NULL, OPT_UINT_T, 0, FLDSET(struct skel_level, max_num));
794 aco_option_register(&cfg_info, "max_guesses", ACO_EXACT, level_options, NULL, OPT_UINT_T, 0, FLDSET(struct skel_level, max_guesses));
795
796 if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
797 goto error;
798 }
799
802 goto error;
803 }
805
806error:
807 aco_info_destroy(&cfg_info);
810}
struct aco_type * global_options[]
Definition: app_skel.c:292
static int custom_bitfield_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
A custom bitfield handler.
Definition: app_skel.c:399
struct aco_type * level_options[]
Definition: app_skel.c:322
static struct ast_cli_entry skel_cli[]
Definition: app_skel.c:735
static int app_exec(struct ast_channel *chan, const char *data)
Definition: app_skel.c:423
struct aco_type * sound_options[]
Definition: app_skel.c:303
static struct ast_str * prompt
Definition: asterisk.c:2786
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
@ ACO_EXACT
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
@ ACO_PROCESS_ERROR
Their was an error and no changes were applied.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
@ OPT_UINT_T
Type for default option handler for unsigned integers.
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:640
int error(const char *format,...)
Definition: utils/frame.c:999
#define ARRAY_LEN(a)
Definition: utils.h:666

References ACO_EXACT, aco_info_destroy(), aco_info_init(), aco_option_register, aco_option_register_custom, aco_process_config(), ACO_PROCESS_ERROR, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_cleanup, ao2_container_alloc_list, app, 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, games, global_options, level_options, NULL, OPT_STRINGFIELD_T, OPT_UINT_T, prompt, skel_cli, sound_options, and STRFLDSET.

◆ play_files_helper()

static void play_files_helper ( struct ast_channel chan,
const char *  prompts 
)
static
Examples
app_skel.c.

Definition at line 412 of file app_skel.c.

413{
414 char *prompt, *rest = ast_strdupa(prompts);
415
416 ast_stopstream(chan);
417 while ((prompt = ast_strsep(&rest, '&', AST_STRSEP_STRIP | AST_STRSEP_TRIM))
418 && !ast_stream_and_wait(chan, prompt, "")) {
419 ast_stopstream(chan);
420 }
421}
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
Definition: file.c:1886
@ AST_STRSEP_TRIM
Definition: strings.h:256
@ AST_STRSEP_STRIP
Definition: strings.h:255
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835

References ast_stopstream(), ast_strdupa, ast_stream_and_wait(), ast_strsep(), AST_STRSEP_STRIP, AST_STRSEP_TRIM, and prompt.

Referenced by app_exec().

◆ reload_module()

static int reload_module ( void  )
static
Examples
app_skel.c.

Definition at line 741 of file app_skel.c.

742{
743 if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
745 }
746
747 return 0;
748}

References aco_process_config(), ACO_PROCESS_ERROR, and AST_MODULE_LOAD_DECLINE.

◆ skel_config_alloc()

static void * skel_config_alloc ( void  )
static

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

Examples
app_skel.c.

Definition at line 610 of file app_skel.c.

611{
612 struct skel_config *cfg;
613
614 if (!(cfg = ao2_alloc(sizeof(*cfg), skel_config_destructor))) {
615 return NULL;
616 }
617
618 /* Allocate/initialize memory */
619 if (!(cfg->global = ao2_alloc(sizeof(*cfg->global), skel_global_config_destructor))) {
620 goto error;
621 }
622
623 if (ast_string_field_init(cfg->global, 128)) {
624 goto error;
625 }
626
629 if (!cfg->levels) {
630 goto error;
631 }
632
633 return cfg;
634error:
635 ao2_ref(cfg, -1);
636 return NULL;
637}
static int skel_level_hash(const void *obj, const int flags)
Definition: app_skel.c:375
#define LEVEL_BUCKETS
Definition: app_skel.c:244
static void skel_global_config_destructor(void *obj)
Definition: app_skel.c:340
static void skel_config_destructor(void *obj)
Definition: app_skel.c:603
static int skel_level_cmp(void *obj, void *arg, int flags)
Definition: app_skel.c:382
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
struct skel_global_config * global
Definition: app_skel.c:253
struct ao2_container * levels
Definition: app_skel.c:254

References ao2_alloc, AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_hash, 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().

◆ skel_config_destructor()

static void skel_config_destructor ( void *  obj)
static
Examples
app_skel.c.

Definition at line 603 of file app_skel.c.

604{
605 struct skel_config *cfg = obj;
606 ao2_cleanup(cfg->global);
607 ao2_cleanup(cfg->levels);
608}

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

Referenced by skel_config_alloc().

◆ skel_find_or_create_state()

static void * skel_find_or_create_state ( const char *  category)
static

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

Examples
app_skel.c.

Definition at line 565 of file app_skel.c.

566{
568 RAII_VAR(struct skel_level *, level, NULL, ao2_cleanup);
569 if (!cfg || !cfg->levels || !(level = ao2_find(cfg->levels, category, OBJ_KEY))) {
570 return skel_state_alloc(category);
571 }
572 ao2_ref(level->state, +1);
573 return level->state;
574}
static struct skel_level * skel_state_alloc(const char *name)
Definition: app_skel.c:541

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

◆ skel_game_alloc()

static struct skel_current_game * skel_game_alloc ( struct skel_level level)
static
Examples
app_skel.c.

Definition at line 357 of file app_skel.c.

358{
359 struct skel_current_game *game;
360 if (!(game = ao2_alloc(sizeof(struct skel_current_game), skel_game_destructor))) {
361 return NULL;
362 }
363 ao2_ref(level, +1);
364 game->level_info = level;
365 return game;
366}
static void skel_game_destructor(void *obj)
Definition: app_skel.c:346

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

Referenced by app_exec().

◆ skel_game_destructor()

static void skel_game_destructor ( void *  obj)
static
Examples
app_skel.c.

Definition at line 346 of file app_skel.c.

347{
348 struct skel_current_game *game = obj;
349 ao2_cleanup(game->level_info);
350}

References ao2_cleanup, and skel_current_game::level_info.

Referenced by skel_game_alloc().

◆ skel_global_config_destructor()

static void skel_global_config_destructor ( void *  obj)
static
Examples
app_skel.c.

Definition at line 340 of file app_skel.c.

341{
342 struct skel_global_config *global = obj;
344}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ast_string_field_free_memory, and global.

Referenced by skel_config_alloc().

◆ skel_level_alloc()

static void * skel_level_alloc ( const char *  cat)
static

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

Parameters
catThe category to base the level on
Returns
A void pointer to a newly allocated skel_level
Examples
app_skel.c.

Definition at line 576 of file app_skel.c.

577{
578 struct skel_level *level;
579
580 if (!(level = ao2_alloc(sizeof(*level), skel_level_destructor))) {
581 return NULL;
582 }
583
584 if (ast_string_field_init(level, 128)) {
585 ao2_ref(level, -1);
586 return NULL;
587 }
588
589 /* Since the level has state information that needs to persist between reloads,
590 * it is important to handle that here in the level's allocation function.
591 * If not separated out into its own object, the data would be destroyed on
592 * reload. */
593 if (!(level->state = skel_find_or_create_state(cat))) {
594 ao2_ref(level, -1);
595 return NULL;
596 }
597
598 ast_string_field_set(level, name, cat);
599
600 return level;
601}
static void skel_level_destructor(void *obj)
Definition: app_skel.c:368
static void * skel_find_or_create_state(const char *category)
Look up an existing state object, or create a new one.
Definition: app_skel.c:565
static const char name[]
Definition: format_mp3.c:68
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521

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.

◆ skel_level_cmp()

static int skel_level_cmp ( void *  obj,
void *  arg,
int  flags 
)
static
Examples
app_skel.c.

Definition at line 382 of file app_skel.c.

383{
384 struct skel_level *one = obj, *two = arg;
385 const char *match = (flags & OBJ_KEY) ? arg : two->name;
386 return strcasecmp(one->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
387}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition: chan_iax2.c:2384

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

Referenced by skel_config_alloc().

◆ skel_level_destructor()

static void skel_level_destructor ( void *  obj)
static
Examples
app_skel.c.

Definition at line 368 of file app_skel.c.

369{
370 struct skel_level *level = obj;
372 ao2_cleanup(level->state);
373}

References ao2_cleanup, ast_string_field_free_memory, and skel_level::state.

Referenced by skel_level_alloc().

◆ skel_level_find()

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_containerA non-active container to search for a level
categoryThe category associated with the level to check for
Return values
non-NULLThe level from the container
NULLThe level does not exist in the container
Examples
app_skel.c.

Definition at line 552 of file app_skel.c.

553{
554 return ao2_find(tmp_container, category, OBJ_KEY);
555}

References ao2_find, and OBJ_KEY.

◆ skel_level_hash()

static int skel_level_hash ( const void *  obj,
const int  flags 
)
static
Examples
app_skel.c.

Definition at line 375 of file app_skel.c.

376{
377 const struct skel_level *level = obj;
378 const char *name = (flags & OBJ_KEY) ? obj : level->name;
379 return ast_str_case_hash(name);
380}
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
Definition: strings.h:1303

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

Referenced by skel_config_alloc().

◆ skel_state_alloc()

static struct skel_level * skel_state_alloc ( const char *  name)
static
Examples
app_skel.c.

Definition at line 541 of file app_skel.c.

542{
543 struct skel_level *level;
544
545 if (!(level = ao2_alloc(sizeof(*level), skel_state_destructor))) {
546 return NULL;
547 }
548
549 return level;
550}
static void skel_state_destructor(void *obj)
Definition: app_skel.c:352

References ao2_alloc, NULL, and skel_state_destructor().

Referenced by skel_find_or_create_state().

◆ skel_state_destructor()

static void skel_state_destructor ( void *  obj)
static
Examples
app_skel.c.

Definition at line 352 of file app_skel.c.

353{
354 return;
355}

Referenced by skel_state_alloc().

◆ unload_module()

static int unload_module ( void  )
static
Examples
app_skel.c.

Definition at line 750 of file app_skel.c.

751{
753 aco_info_destroy(&cfg_info);
757}
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
Definition: astobj2.h:859
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References aco_info_destroy(), ao2_cleanup, ao2_global_obj_release, app, ARRAY_LEN, ast_cli_unregister_multiple(), ast_unregister_application(), games, globals, and skel_cli.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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, }
static

Definition at line 817 of file app_skel.c.

◆ app

char* app = "SkelGuessNumber"
static
Examples
app_skel.c.

Definition at line 177 of file app_skel.c.

Referenced by app_exec(), load_module(), and unload_module().

◆ app_opts

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

Definition at line 193 of file app_skel.c.

Referenced by app_exec().

◆ app_skel_conf

struct aco_file app_skel_conf
Initial value:
= {
.filename = "app_skel.conf",
}
static struct aco_type sound_option
An aco_type structure to link the "sounds" category to the skel_global_config type.
Definition: app_skel.c:295
static struct aco_type level_option
An aco_type structure to link the everything but the "general" and "sounds" categories to the skel_le...
Definition: app_skel.c:312
static struct aco_type global_option
An aco_type structure to link the "general" category to the skel_global_config type.
Definition: app_skel.c:284
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
Examples
app_skel.c.

Definition at line 324 of file app_skel.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 817 of file app_skel.c.

◆ games

struct ao2_container* games
static

The container of active games.

Examples
app_skel.c.

Definition at line 333 of file app_skel.c.

Referenced by app_exec(), handle_skel_show_games(), load_module(), and unload_module().

◆ global_option

struct aco_type global_option
static

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

Examples
app_skel.c.

Definition at line 284 of file app_skel.c.

◆ global_options

struct aco_type* global_options[] = ACO_TYPES(&global_option)
Examples
app_skel.c.

Definition at line 292 of file app_skel.c.

Referenced by load_module().

◆ level_categories

const char* level_categories[]
static
Initial value:
= {
"general",
"sounds",
}
Examples
app_skel.c.

Definition at line 305 of file app_skel.c.

◆ level_option

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.

Examples
app_skel.c.

Definition at line 312 of file app_skel.c.

◆ level_options

struct aco_type* level_options[] = ACO_TYPES(&level_option)
Examples
app_skel.c.

Definition at line 322 of file app_skel.c.

Referenced by load_module().

◆ skel_cli

struct ast_cli_entry skel_cli[]
static
Initial value:
= {
{ .handler = handle_skel_show_config , .summary = "Show app_skel global config options" ,},
{ .handler = handle_skel_show_levels , .summary = "Show app_skel levels" ,},
{ .handler = handle_skel_show_games , .summary = "Show app_skel active games" ,},
}
static char * handle_skel_show_games(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: app_skel.c:669
static char * handle_skel_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: app_skel.c:639
static char * handle_skel_show_levels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: app_skel.c:699
Examples
app_skel.c.

Definition at line 735 of file app_skel.c.

Referenced by load_module(), and unload_module().

◆ sound_option

struct aco_type sound_option
static

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

Examples
app_skel.c.

Definition at line 295 of file app_skel.c.

◆ sound_options

struct aco_type* sound_options[] = ACO_TYPES(&sound_option)
Examples
app_skel.c.

Definition at line 303 of file app_skel.c.

Referenced by load_module().