Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Functions | Variables
pbx_app.c File Reference

Custom function management routines. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/strings.h"
#include "asterisk/term.h"
#include "asterisk/utils.h"
#include "asterisk/xmldoc.h"
#include "pbx_private.h"

Go to the source code of this file.

Data Structures

struct  apps
 Registered applications container. More...
 
struct  ast_app
 ast_app: A registered application More...
 

Functions

const char * app_name (struct ast_app *app)
 
char * ast_complete_applications (const char *line, const char *word, int state)
 Command completion for the list of installed applications. More...
 
int ast_pbx_exec_application (struct ast_channel *chan, const char *app_name, const char *app_args)
 Execute an application. More...
 
int ast_register_application2 (const char *app, int(*execute)(struct ast_channel *, const char *), const char *synopsis, const char *description, void *mod)
 Dynamically register a new dial plan application. More...
 
int ast_unregister_application (const char *app)
 Unregister an application. More...
 
static char * handle_show_application (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 'show application' CLI command implementation function...
 
static char * handle_show_applications (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
int load_pbx_app (void)
 
int pbx_exec (struct ast_channel *c, struct ast_app *app, const char *data)
 Execute an application. More...
 
struct ast_apppbx_findapp (const char *app)
 Look up an application. More...
 
static struct ast_apppbx_findapp_nolock (const char *name)
 
static void print_app_docs (struct ast_app *aa, int fd)
 
static void unload_pbx_app (void)
 

Variables

static struct ast_cli_entry app_cli []
 
static struct apps apps = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 

Detailed Description

Custom function management routines.

Author
Corey Farrell git@c.nosp@m.fwar.nosp@m.e.com

Definition in file pbx_app.c.

Function Documentation

const char* app_name ( struct ast_app app)

pbx_app.c functions needed by pbx.c

Definition at line 463 of file pbx_app.c.

Referenced by app_exec(), handle_exec(), lua_pbx_exec(), lua_pbx_findapp(), pbx_extension_helper(), and stasis_app_set_global_debug().

464 {
465  return app->name;
466 }
char* ast_complete_applications ( const char *  line,
const char *  word,
int  state 
)

Command completion for the list of installed applications.

This can be called from a CLI command completion function that wants to complete from the list of available applications.

Definition at line 429 of file pbx_app.c.

References ast_cli_completion_add(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, and ast_strdup.

Referenced by handle_orig(), and handle_show_application().

430 {
431  struct ast_app *app;
432  int which = 0;
433  int cmp;
434  char *ret = NULL;
435  size_t wordlen = strlen(word);
436 
438  AST_RWLIST_TRAVERSE(&apps, app, list) {
439  cmp = strncasecmp(word, app->name, wordlen);
440  if (cmp < 0) {
441  /* No more matches. */
442  break;
443  } else if (!cmp) {
444  /* Found match. */
445  if (state != -1) {
446  if (++which <= state) {
447  /* Not enough matches. */
448  continue;
449  }
450  ret = ast_strdup(app->name);
451  break;
452  }
453  if (ast_cli_completion_add(ast_strdup(app->name))) {
454  break;
455  }
456  }
457  }
459 
460  return ret;
461 }
Registered applications container.
Definition: pbx_app.c:67
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
ast_app: A registered application
Definition: pbx_app.c:45
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2761
int ast_pbx_exec_application ( struct ast_channel chan,
const char *  app_name,
const char *  app_args 
)

Execute an application.

Parameters
chanchannel to execute on
app_namename of app to execute
app_argsthe data passed into the app

This application executes an application by name on a given channel. It is a wrapper around pbx_exec that will perform variable substitution and then execute the application if it exists. If the application is not found, a warning is logged.

Return values
0success
-1failure (including application not found)

Definition at line 501 of file pbx_app.c.

References ast_channel_publish_snapshot(), ast_str_buffer(), ast_str_create, ast_str_substitute_variables(), pbx_exec(), and pbx_findapp().

Referenced by answer_exec_run(), and snoop_stasis_thread().

502 {
503  int res = -1;
504  struct ast_app *app;
505 
506  app = pbx_findapp(app_name);
507  if (!app) {
508  ast_log(LOG_WARNING, "Could not find application (%s)\n", app_name);
509  } else {
510  struct ast_str *substituted_args = NULL;
511 
512  if (!ast_strlen_zero(app_args) && (substituted_args = ast_str_create(16))) {
513  ast_str_substitute_variables(&substituted_args, 0, chan, app_args);
514  res = pbx_exec(chan, app, ast_str_buffer(substituted_args));
515  ast_free(substituted_args);
516  } else {
517  if (!ast_strlen_zero(app_args)) {
518  ast_log(LOG_WARNING, "Could not substitute application argument variables for %s\n", app_name);
519  }
520  res = pbx_exec(chan, app, app_args);
521  }
522  /* Manually make a snapshot now, since pbx_exec won't necessarily get called again immediately. */
524  }
525  return res;
526 }
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
Support for dynamic strings.
Definition: strings.h:623
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
ast_app: A registered application
Definition: pbx_app.c:45
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: pbx_app.c:91
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_register_application2 ( const char *  app,
int(*)(struct ast_channel *, const char *)  execute,
const char *  synopsis,
const char *  description,
void *  mod 
)

Dynamically register a new dial plan application.

Register an application.

Definition at line 103 of file pbx_app.c.

References ast_app::arguments, ast_calloc, ast_module_name(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, AST_STATIC_DOC, ast_string_field_init, ast_string_field_set, AST_XML_DOC, ast_xmldoc_build_arguments(), ast_xmldoc_build_description(), ast_xmldoc_build_seealso(), ast_xmldoc_build_synopsis(), ast_xmldoc_build_syntax(), COLORIZE_FMT, ast_app::docsrc, ast_app::seealso, and ast_app::syntax.

Referenced by ast_msg_init(), load_pbx_builtins(), and load_pbx_variables().

104 {
105  struct ast_app *tmp;
106  struct ast_app *cur;
107  int length;
108 #ifdef AST_XML_DOCS
109  char *tmpxml;
110 #endif
111 
113  cur = pbx_findapp_nolock(app);
114  if (cur) {
115  ast_log(LOG_WARNING, "Already have an application '%s'\n", app);
117  return -1;
118  }
119 
120  length = sizeof(*tmp) + strlen(app) + 1;
121 
122  if (!(tmp = ast_calloc(1, length))) {
124  return -1;
125  }
126 
127  if (ast_string_field_init(tmp, 128)) {
129  ast_free(tmp);
130  return -1;
131  }
132 
133  strcpy(tmp->name, app);
134  tmp->execute = execute;
135  tmp->module = mod;
136 
137 #ifdef AST_XML_DOCS
138  /* Try to lookup the docs in our XML documentation database */
139  if (ast_strlen_zero(synopsis) && ast_strlen_zero(description)) {
140  /* load synopsis */
141  tmpxml = ast_xmldoc_build_synopsis("application", app, ast_module_name(tmp->module));
142  ast_string_field_set(tmp, synopsis, tmpxml);
143  ast_free(tmpxml);
144 
145  /* load description */
146  tmpxml = ast_xmldoc_build_description("application", app, ast_module_name(tmp->module));
147  ast_string_field_set(tmp, description, tmpxml);
148  ast_free(tmpxml);
149 
150  /* load syntax */
151  tmpxml = ast_xmldoc_build_syntax("application", app, ast_module_name(tmp->module));
152  ast_string_field_set(tmp, syntax, tmpxml);
153  ast_free(tmpxml);
154 
155  /* load arguments */
156  tmpxml = ast_xmldoc_build_arguments("application", app, ast_module_name(tmp->module));
157  ast_string_field_set(tmp, arguments, tmpxml);
158  ast_free(tmpxml);
159 
160  /* load seealso */
161  tmpxml = ast_xmldoc_build_seealso("application", app, ast_module_name(tmp->module));
162  ast_string_field_set(tmp, seealso, tmpxml);
163  ast_free(tmpxml);
164  tmp->docsrc = AST_XML_DOC;
165  } else {
166 #endif
169 #ifdef AST_XML_DOCS
170  tmp->docsrc = AST_STATIC_DOC;
171  }
172 #endif
173 
174  /* Store in alphabetical order */
175  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
176  if (strcasecmp(tmp->name, cur->name) < 0) {
177  AST_RWLIST_INSERT_BEFORE_CURRENT(tmp, list);
178  break;
179  }
180  }
181  AST_RWLIST_TRAVERSE_SAFE_END;
182  if (!cur)
183  AST_RWLIST_INSERT_TAIL(&apps, tmp, list);
184 
185  ast_verb(5, "Registered application '" COLORIZE_FMT "'\n", COLORIZE(COLOR_BRCYAN, 0, tmp->name));
186 
188 
189  return 0;
190 }
const ast_string_field description
Definition: pbx_app.c:53
static SQLHSTMT execute(struct odbc_obj *obj, void *data, int silent)
Common execution function for SQL queries.
Definition: func_odbc.c:471
const ast_string_field synopsis
Definition: pbx_app.c:53
Registered applications container.
Definition: pbx_app.c:67
char * ast_xmldoc_build_description(const char *type, const char *name, const char *module)
Generate description documentation from XML.
Definition: xmldoc.c:2271
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
char * ast_xmldoc_build_synopsis(const char *type, const char *name, const char *module)
Generate synopsis documentation from XML.
Definition: xmldoc.c:2248
char * ast_xmldoc_build_arguments(const char *type, const char *name, const char *module)
Generate the [arguments] tag based on type of node ('application', 'function' or 'agi') and name...
Definition: xmldoc.c:2084
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define COLORIZE_FMT
Shortcut macros for coloring a set of text.
Definition: term.h:71
const ast_string_field syntax
Definition: pbx_app.c:53
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
enum ast_doc_src docsrc
Definition: pbx_app.c:55
char * ast_xmldoc_build_syntax(const char *type, const char *name, const char *module)
Get the syntax for a specified application or function.
Definition: xmldoc.c:1252
char * ast_xmldoc_build_seealso(const char *type, const char *name, const char *module)
Parse the node content.
Definition: xmldoc.c:1702
const char * ast_module_name(const struct ast_module *mod)
Get the name of a module.
Definition: loader.c:615
ast_app: A registered application
Definition: pbx_app.c:45
const ast_string_field seealso
Definition: pbx_app.c:53
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
const ast_string_field arguments
Definition: pbx_app.c:53
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
int ast_unregister_application ( const char *  app)

Unregister an application.

Parameters
appname of the application (does not have to be the same string as the one that was registered)

This unregisters an application from Asterisk's internal application list.

Return values
0success
-1failure

Definition at line 392 of file pbx_app.c.

References ast_rdlock_contexts(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_string_field_free_memory, ast_unlock_contexts(), and unreference_cached_app().

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

393 {
394  struct ast_app *cur;
395  int cmp;
396 
397  /* Anticipate need for conlock in unreference_cached_app(), in order to avoid
398  * possible deadlock with pbx_extension_helper()/pbx_findapp()
399  */
401 
403  AST_RWLIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) {
404  cmp = strcasecmp(app, cur->name);
405  if (cmp > 0) {
406  continue;
407  }
408  if (!cmp) {
409  /* Found it. */
411  AST_RWLIST_REMOVE_CURRENT(list);
412  ast_verb(5, "Unregistered application '%s'\n", cur->name);
414  ast_free(cur);
415  break;
416  }
417  /* Not in container. */
418  cur = NULL;
419  break;
420  }
421  AST_RWLIST_TRAVERSE_SAFE_END;
423 
425 
426  return cur ? 0 : -1;
427 }
Registered applications container.
Definition: pbx_app.c:67
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
int ast_rdlock_contexts(void)
Read locks the context list.
Definition: pbx.c:8468
int ast_unlock_contexts(void)
Unlocks contexts.
Definition: pbx.c:8473
void unreference_cached_app(struct ast_app *app)
Definition: pbx.c:6130
ast_app: A registered application
Definition: pbx_app.c:45
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
int load_pbx_app ( void  )

Provided by pbx_app.c

Definition at line 538 of file pbx_app.c.

References ast_cli_register_multiple, and ast_register_cleanup().

539 {
540  ast_cli_register_multiple(app_cli, ARRAY_LEN(app_cli));
541  ast_register_cleanup(unload_pbx_app);
542 
543  return 0;
544 }
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
int pbx_exec ( struct ast_channel c,
struct ast_app app,
const char *  data 
)

Execute an application.

Note
This function is special. It saves the stack so that no matter how many times it is called, it returns to the same place
Parameters
cChannel
appApplication
dataData for execution

Definition at line 471 of file pbx_app.c.

References ast_channel_publish_snapshot(), and S_OR.

Referenced by ari_channel_thread(), ari_originate_dial(), ast_pbx_exec_application(), forward_message(), handle_exec(), iax2_exec(), lua_pbx_exec(), pbx_extension_helper(), and pbx_outgoing_exec().

474 {
475  int res;
476  struct ast_module_user *u = NULL;
477  const char *saved_c_appl;
478  const char *saved_c_data;
479 
480  /* save channel values */
481  saved_c_appl= ast_channel_appl(c);
482  saved_c_data= ast_channel_data(c);
483 
484  ast_channel_lock(c);
485  ast_channel_appl_set(c, app->name);
486  ast_channel_data_set(c, data);
488  ast_channel_unlock(c);
489 
490  if (app->module)
491  u = __ast_module_user_add(app->module, c);
492  res = app->execute(c, S_OR(data, ""));
493  if (app->module && u)
494  __ast_module_user_remove(app->module, u);
495  /* restore channel values */
496  ast_channel_appl_set(c, saved_c_appl);
497  ast_channel_data_set(c, saved_c_data);
498  return res;
499 }
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
void ast_channel_publish_snapshot(struct ast_channel *chan)
Publish a ast_channel_snapshot for a channel.
struct ast_app* pbx_findapp ( const char *  app)

Look up an application.

Parameters
appname of the app

This function searches for the ast_app structure within the apps that are registered for the one with the name you passed in.

Returns
the ast_app structure that matches on success, or NULL on failure

Definition at line 91 of file pbx_app.c.

References AST_RWLIST_RDLOCK, and AST_RWLIST_UNLOCK.

Referenced by ast_pbx_exec_application().

92 {
93  struct ast_app *ret;
94 
96  ret = pbx_findapp_nolock(app);
98 
99  return ret;
100 }
Registered applications container.
Definition: pbx_app.c:67
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
ast_app: A registered application
Definition: pbx_app.c:45
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151

Variable Documentation

struct ast_cli_entry app_cli[]
static
Initial value:
= {
{ .handler = handle_show_applications , .summary = "Shows registered dialplan applications" ,},
{ .handler = handle_show_application , .summary = "Describe a specific dialplan application" ,},
}
static char * handle_show_application(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
'show application' CLI command implementation function...
Definition: pbx_app.c:260

Definition at line 528 of file pbx_app.c.