Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
pbx_hangup_handler.c File Reference

PBX Hangup Handler management routines. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include "asterisk/app.h"
#include "asterisk/cli.h"
#include "asterisk/linkedlists.h"
#include "asterisk/pbx.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/utils.h"
Include dependency graph for pbx_hangup_handler.c:

Go to the source code of this file.

Macros

#define HANDLER_FORMAT   "%-30s %s\n"
 

Functions

void ast_pbx_hangup_handler_destroy (struct ast_channel *chan)
 Destroy the hangup handler container on a channel. More...
 
static void ast_pbx_hangup_handler_headers (int fd)
 
void ast_pbx_hangup_handler_init (struct ast_channel *chan)
 Init the hangup handler container on a channel. More...
 
int ast_pbx_hangup_handler_pop (struct ast_channel *chan)
 Pop the top of the channel hangup handler stack. More...
 
void ast_pbx_hangup_handler_push (struct ast_channel *chan, const char *handler)
 Push the given hangup handler onto the channel hangup handler stack. More...
 
int ast_pbx_hangup_handler_run (struct ast_channel *chan)
 Run all hangup handlers on the channel. More...
 
static void ast_pbx_hangup_handler_show (int fd, struct ast_channel *chan)
 
static char * handle_show_hangup_all (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_show_hangup_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
int load_pbx_hangup_handler (void)
 
static void publish_hangup_handler_message (const char *action, struct ast_channel *chan, const char *handler)
 
static void unload_pbx_hangup_handler (void)
 

Variables

static struct ast_cli_entry cli []
 

Detailed Description

PBX Hangup Handler management routines.

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

Definition in file pbx_hangup_handler.c.

Macro Definition Documentation

◆ HANDLER_FORMAT

#define HANDLER_FORMAT   "%-30s %s\n"

Function Documentation

◆ ast_pbx_hangup_handler_destroy()

void ast_pbx_hangup_handler_destroy ( struct ast_channel chan)

Destroy the hangup handler container on a channel.

Since
11.0
Parameters
chanChannel to destroy the hangup handler container on.
Returns
Nothing

Definition at line 103 of file pbx_hangup_handler.c.

References ast_channel_hangup_handlers(), ast_channel_lock, ast_channel_unlock, ast_free, and AST_LIST_REMOVE_HEAD.

Referenced by ast_channel_destructor(), and ast_dummy_channel_destructor().

104 {
105  struct ast_hangup_handler_list *handlers;
106  struct ast_hangup_handler *h_handler;
107 
108  ast_channel_lock(chan);
109 
110  /* Get rid of each of the hangup handlers on the channel */
111  handlers = ast_channel_hangup_handlers(chan);
112  while ((h_handler = AST_LIST_REMOVE_HEAD(handlers, node))) {
113  ast_free(h_handler);
114  }
115 
116  ast_channel_unlock(chan);
117 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Definition: test_heap.c:38
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_hangup_handler_list * ast_channel_hangup_handlers(struct ast_channel *chan)
#define ast_free(a)
Definition: astmm.h:182

◆ ast_pbx_hangup_handler_headers()

static void ast_pbx_hangup_handler_headers ( int  fd)
static

Definition at line 179 of file pbx_hangup_handler.c.

References ast_cli(), and HANDLER_FORMAT.

Referenced by handle_show_hangup_all(), and handle_show_hangup_channel().

180 {
181  ast_cli(fd, HANDLER_FORMAT, "Channel", "Handler");
182 }
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define HANDLER_FORMAT

◆ ast_pbx_hangup_handler_init()

void ast_pbx_hangup_handler_init ( struct ast_channel chan)

Init the hangup handler container on a channel.

Since
11.0
Parameters
chanChannel to init the hangup handler container on.
Returns
Nothing

Definition at line 95 of file pbx_hangup_handler.c.

References ast_channel_hangup_handlers(), and AST_LIST_HEAD_INIT_NOLOCK.

Referenced by __ast_channel_alloc_ap(), and __ast_dummy_channel_alloc().

96 {
97  struct ast_hangup_handler_list *handlers;
98 
99  handlers = ast_channel_hangup_handlers(chan);
100  AST_LIST_HEAD_INIT_NOLOCK(handlers);
101 }
struct ast_hangup_handler_list * ast_channel_hangup_handlers(struct ast_channel *chan)
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680

◆ ast_pbx_hangup_handler_pop()

int ast_pbx_hangup_handler_pop ( struct ast_channel chan)

Pop the top of the channel hangup handler stack.

Since
11.0
Parameters
chanChannel to push the hangup handler onto.
Return values
TRUEif a handler was popped off of the stack.

Definition at line 119 of file pbx_hangup_handler.c.

References ast_hangup_handler::args, ast_channel_hangup_handlers(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_REMOVE_HEAD, and publish_hangup_handler_message().

Referenced by func_channel_write_real().

120 {
121  struct ast_hangup_handler_list *handlers;
122  struct ast_hangup_handler *h_handler;
123 
124  ast_channel_lock(chan);
125  handlers = ast_channel_hangup_handlers(chan);
126  h_handler = AST_LIST_REMOVE_HEAD(handlers, node);
127  if (h_handler) {
128  publish_hangup_handler_message("pop", chan, h_handler->args);
129  }
130  ast_channel_unlock(chan);
131  if (h_handler) {
132  ast_free(h_handler);
133  return 1;
134  }
135  return 0;
136 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Definition: test_heap.c:38
static void publish_hangup_handler_message(const char *action, struct ast_channel *chan, const char *handler)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_hangup_handler_list * ast_channel_hangup_handlers(struct ast_channel *chan)
#define ast_free(a)
Definition: astmm.h:182

◆ ast_pbx_hangup_handler_push()

void ast_pbx_hangup_handler_push ( struct ast_channel chan,
const char *  handler 
)

Push the given hangup handler onto the channel hangup handler stack.

Since
11.0
Parameters
chanChannel to push the hangup handler onto.
handlerGosub application parameter string.
Returns
Nothing

Definition at line 138 of file pbx_hangup_handler.c.

References ast_hangup_handler::args, ast_app_expand_sub_args(), ast_channel_hangup_handlers(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_INSERT_HEAD, ast_malloc, ast_strlen_zero, and publish_hangup_handler_message().

Referenced by func_channel_write_real().

139 {
140  struct ast_hangup_handler_list *handlers;
141  struct ast_hangup_handler *h_handler;
142  const char *expanded_handler;
143 
144  if (ast_strlen_zero(handler)) {
145  return;
146  }
147 
148  expanded_handler = ast_app_expand_sub_args(chan, handler);
149  if (!expanded_handler) {
150  return;
151  }
152  h_handler = ast_malloc(sizeof(*h_handler) + 1 + strlen(expanded_handler));
153  if (!h_handler) {
154  ast_free((char *) expanded_handler);
155  return;
156  }
157  strcpy(h_handler->args, expanded_handler);/* Safe */
158  ast_free((char *) expanded_handler);
159 
160  ast_channel_lock(chan);
161 
162  handlers = ast_channel_hangup_handlers(chan);
163  AST_LIST_INSERT_HEAD(handlers, h_handler, node);
164  publish_hangup_handler_message("push", chan, h_handler->args);
165  ast_channel_unlock(chan);
166 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Definition: test_heap.c:38
const char * ast_app_expand_sub_args(struct ast_channel *chan, const char *args)
Add missing context/exten to subroutine argument string.
Definition: main/app.c:351
static void publish_hangup_handler_message(const char *action, struct ast_channel *chan, const char *handler)
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_hangup_handler_list * ast_channel_hangup_handlers(struct ast_channel *chan)
#define ast_free(a)
Definition: astmm.h:182
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59

◆ ast_pbx_hangup_handler_run()

int ast_pbx_hangup_handler_run ( struct ast_channel chan)

Run all hangup handlers on the channel.

Since
11.0
Parameters
chanChannel to run the hangup handlers on.
Note
Absolutely NO channel locks should be held before calling this function.
Return values
Zeroif no hangup handlers run.
non-zeroif hangup handlers were run.

Definition at line 58 of file pbx_hangup_handler.c.

References ast_hangup_handler::args, ast_app_exec_sub(), ast_channel_hangup_handlers(), ast_channel_lock, ast_channel_unlock, ast_free, AST_LIST_EMPTY, AST_LIST_REMOVE_HEAD, AST_SOFTHANGUP_HANGUP_EXEC, ast_softhangup_nolock(), NULL, and publish_hangup_handler_message().

Referenced by __ast_pbx_run(), and ast_hangup().

59 {
60  struct ast_hangup_handler_list *handlers;
61  struct ast_hangup_handler *h_handler;
62 
63  ast_channel_lock(chan);
64  handlers = ast_channel_hangup_handlers(chan);
65  if (AST_LIST_EMPTY(handlers)) {
66  ast_channel_unlock(chan);
67  return 0;
68  }
69 
70  /*
71  * Make sure that the channel is marked as hungup since we are
72  * going to run the hangup handlers on it.
73  */
75 
76  for (;;) {
77  handlers = ast_channel_hangup_handlers(chan);
78  h_handler = AST_LIST_REMOVE_HEAD(handlers, node);
79  if (!h_handler) {
80  break;
81  }
82 
83  publish_hangup_handler_message("run", chan, h_handler->args);
84  ast_channel_unlock(chan);
85 
86  ast_app_exec_sub(NULL, chan, h_handler->args, 1);
87  ast_free(h_handler);
88 
89  ast_channel_lock(chan);
90  }
91  ast_channel_unlock(chan);
92  return 1;
93 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Definition: test_heap.c:38
static void publish_hangup_handler_message(const char *action, struct ast_channel *chan, const char *handler)
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_hangup_handler_list * ast_channel_hangup_handlers(struct ast_channel *chan)
#define ast_free(a)
Definition: astmm.h:182
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Definition: main/app.c:370

◆ ast_pbx_hangup_handler_show()

static void ast_pbx_hangup_handler_show ( int  fd,
struct ast_channel chan 
)
static

Definition at line 194 of file pbx_hangup_handler.c.

References ast_hangup_handler::args, ast_channel_hangup_handlers(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_cli(), AST_LIST_TRAVERSE, first, and HANDLER_FORMAT.

Referenced by handle_show_hangup_all(), and handle_show_hangup_channel().

195 {
196  struct ast_hangup_handler_list *handlers;
197  struct ast_hangup_handler *h_handler;
198  int first = 1;
199 
200  ast_channel_lock(chan);
201  handlers = ast_channel_hangup_handlers(chan);
202  AST_LIST_TRAVERSE(handlers, h_handler, node) {
203  ast_cli(fd, HANDLER_FORMAT, first ? ast_channel_name(chan) : "", h_handler->args);
204  first = 0;
205  }
206  ast_channel_unlock(chan);
207 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Definition: test_heap.c:38
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define HANDLER_FORMAT
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_hangup_handler_list * ast_channel_hangup_handlers(struct ast_channel *chan)
const char * ast_channel_name(const struct ast_channel *chan)

◆ handle_show_hangup_all()

static char* handle_show_hangup_all ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 248 of file pbx_hangup_handler.c.

References ast_cli_args::argc, ast_channel_iterator_all_new(), ast_channel_iterator_destroy(), ast_channel_iterator_next(), ast_channel_unref, ast_pbx_hangup_handler_headers(), ast_pbx_hangup_handler_show(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

249 {
250  struct ast_channel_iterator *iter;
251  struct ast_channel *chan;
252 
253  switch (cmd) {
254  case CLI_INIT:
255  e->command = "core show hanguphandlers all";
256  e->usage =
257  "Usage: core show hanguphandlers all\n"
258  " Show hangup handlers for all channels.\n";
259  return NULL;
260  case CLI_GENERATE:
261  return NULL;
262  }
263 
264  if (a->argc < 4) {
265  return CLI_SHOWUSAGE;
266  }
267 
269  if (!iter) {
270  return CLI_FAILURE;
271  }
272 
274  for (; (chan = ast_channel_iterator_next(iter)); ast_channel_unref(chan)) {
276  }
278 
279  return CLI_SUCCESS;
280 }
Main Channel structure associated with a channel.
struct ast_channel * ast_channel_iterator_next(struct ast_channel_iterator *i)
Get the next channel for a channel iterator.
Definition: channel.c:1422
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
const int argc
Definition: cli.h:160
Definition: cli.h:152
static void ast_pbx_hangup_handler_headers(int fd)
#define NULL
Definition: resample.c:96
static void ast_pbx_hangup_handler_show(int fd, struct ast_channel *chan)
const int fd
Definition: cli.h:159
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
struct ast_channel_iterator * ast_channel_iterator_destroy(struct ast_channel_iterator *i)
Destroy a channel iterator.
Definition: channel.c:1360
struct ast_channel_iterator * ast_channel_iterator_all_new(void)
Create a new channel iterator.
Definition: channel.c:1408

◆ handle_show_hangup_channel()

static char* handle_show_hangup_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 212 of file pbx_hangup_handler.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_channel_get_by_name(), ast_channel_unref, ast_cli(), ast_complete_channels(), ast_pbx_hangup_handler_headers(), ast_pbx_hangup_handler_show(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

213 {
214  struct ast_channel *chan;
215 
216  switch (cmd) {
217  case CLI_INIT:
218  e->command = "core show hanguphandlers";
219  e->usage =
220  "Usage: core show hanguphandlers <channel>\n"
221  " Show hangup handlers of a specified channel.\n";
222  return NULL;
223  case CLI_GENERATE:
224  return ast_complete_channels(a->line, a->word, a->pos, a->n, e->args);
225  }
226 
227  if (a->argc < 4) {
228  return CLI_SHOWUSAGE;
229  }
230 
231  chan = ast_channel_get_by_name(a->argv[3]);
232  if (!chan) {
233  ast_cli(a->fd, "Channel does not exist.\n");
234  return CLI_FAILURE;
235  }
236 
239 
240  ast_channel_unref(chan);
241 
242  return CLI_SUCCESS;
243 }
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
const int argc
Definition: cli.h:160
Definition: cli.h:152
static void ast_pbx_hangup_handler_headers(int fd)
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const char * line
Definition: cli.h:162
int args
This gets set in ast_cli_register()
Definition: cli.h:185
static void ast_pbx_hangup_handler_show(int fd, struct ast_channel *chan)
const int fd
Definition: cli.h:159
const int n
Definition: cli.h:165
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: main/cli.c:1830
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454

◆ load_pbx_hangup_handler()

int load_pbx_hangup_handler ( void  )

Provided by pbx_hangup_handler.c

Definition at line 292 of file pbx_hangup_handler.c.

References ARRAY_LEN, ast_cli_register_multiple, ast_register_cleanup(), and unload_pbx_hangup_handler().

Referenced by asterisk_daemon().

293 {
296 
297  return 0;
298 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static void unload_pbx_hangup_handler(void)
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static struct ast_cli_entry cli[]

◆ publish_hangup_handler_message()

static void publish_hangup_handler_message ( const char *  action,
struct ast_channel chan,
const char *  handler 
)
static

Definition at line 44 of file pbx_hangup_handler.c.

References ast_channel_hangup_handler_type(), ast_channel_publish_blob(), ast_json_pack(), ast_json_unref(), NULL, RAII_VAR, and S_OR.

Referenced by ast_pbx_hangup_handler_pop(), ast_pbx_hangup_handler_push(), and ast_pbx_hangup_handler_run().

45 {
46  RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
47 
48  blob = ast_json_pack("{s: s, s: s}",
49  "type", action,
50  "handler", S_OR(handler, ""));
51  if (!blob) {
52  return;
53  }
54 
56 }
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:591
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
#define NULL
Definition: resample.c:96
#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:911
struct stasis_message_type * ast_channel_hangup_handler_type(void)
Message type for hangup handler related actions.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
Abstract JSON element (object, array, string, int, ...).
void ast_channel_publish_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message.

◆ unload_pbx_hangup_handler()

static void unload_pbx_hangup_handler ( void  )
static

Definition at line 287 of file pbx_hangup_handler.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by load_pbx_hangup_handler().

288 {
290 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static struct ast_cli_entry cli[]

Variable Documentation

◆ cli

struct ast_cli_entry cli[]
static
Initial value:
= {
{ .handler = handle_show_hangup_all , .summary = "Show hangup handlers of all channels" ,},
{ .handler = handle_show_hangup_channel , .summary = "Show hangup handlers of a specified channel" ,},
}
static char * handle_show_hangup_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_show_hangup_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 282 of file pbx_hangup_handler.c.