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

Function that intercepts HOLD frames from channels and raises events. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/app.h"
#include "asterisk/frame.h"
#include "asterisk/stasis.h"
#include "asterisk/stasis_channels.h"
Include dependency graph for func_holdintercept.c:

Go to the source code of this file.

Data Structures

struct  hold_intercept_data
 Private data structure used with the function's datastore. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int hold_intercept_fn_write (struct ast_channel *chan, const char *function, char *data, const char *value)
 
static struct ast_framehold_intercept_framehook (struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
 Frame hook that is called to intercept hold/unhold. More...
 
static int hold_intercept_framehook_consume (void *data, enum ast_frame_type type)
 Callback function which informs upstream if we are consuming a frame of a specific type. More...
 
static int load_module (void)
 
static int remove_hold_intercept (struct ast_channel *chan)
 
static int set_hold_intercept (struct ast_channel *chan)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Hold interception dialplan function" , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const struct ast_datastore_info hold_intercept_datastore
 The channel datastore the function uses to store state. More...
 
static struct ast_custom_function hold_intercept_function
 Definition of the HOLD_INTERCEPT function. More...
 

Detailed Description

Function that intercepts HOLD frames from channels and raises events.

Author
Matt Jordan mjord.nosp@m.an@d.nosp@m.igium.nosp@m..com

Definition in file func_holdintercept.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 234 of file func_holdintercept.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 234 of file func_holdintercept.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 234 of file func_holdintercept.c.

◆ hold_intercept_fn_write()

static int hold_intercept_fn_write ( struct ast_channel chan,
const char *  function,
char *  data,
const char *  value 
)
static

Definition at line 190 of file func_holdintercept.c.

References ast_log, AST_LOG_WARNING, ast_strlen_zero, remove_hold_intercept(), and set_hold_intercept().

192 {
193  int res;
194 
195  if (!chan) {
196  return -1;
197  }
198 
199  if (ast_strlen_zero(data)) {
200  ast_log(AST_LOG_WARNING, "HOLD_INTERCEPT requires an argument\n");
201  return -1;
202  }
203 
204  if (!strcasecmp(data, "set")) {
205  res = set_hold_intercept(chan);
206  } else if (!strcasecmp(data, "remove")) {
207  res = remove_hold_intercept(chan);
208  } else {
209  ast_log(AST_LOG_WARNING, "HOLD_INTERCEPT: unknown option %s\n", data);
210  res = -1;
211  }
212 
213  return res;
214 }
#define AST_LOG_WARNING
Definition: logger.h:279
static int remove_hold_intercept(struct ast_channel *chan)
static int set_hold_intercept(struct ast_channel *chan)
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42

◆ hold_intercept_framehook()

static struct ast_frame* hold_intercept_framehook ( struct ast_channel chan,
struct ast_frame f,
enum ast_framehook_event  event,
void *  data 
)
static

Frame hook that is called to intercept hold/unhold.

Definition at line 108 of file func_holdintercept.c.

References ast_channel_hold_type(), ast_channel_publish_cached_blob(), ast_channel_unhold_type(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, AST_FRAMEHOOK_EVENT_WRITE, ast_frfree, ast_null_frame, ast_frame::frametype, ast_frame_subclass::integer, NULL, and ast_frame::subclass.

Referenced by set_hold_intercept().

110 {
111  int frame_type;
112 
113  if (!f || (event != AST_FRAMEHOOK_EVENT_WRITE)) {
114  return f;
115  }
116 
117  if (f->frametype != AST_FRAME_CONTROL) {
118  return f;
119  }
120 
121  frame_type = f->subclass.integer;
122  if (frame_type != AST_CONTROL_HOLD && frame_type != AST_CONTROL_UNHOLD) {
123  return f;
124  }
125 
126  /* Munch munch */
127  ast_frfree(f);
128  f = &ast_null_frame;
129 
132  NULL);
133 
134  return f;
135 }
struct stasis_message_type * ast_channel_hold_type(void)
Message type for when a channel is placed on hold.
struct stasis_message_type * ast_channel_unhold_type(void)
Message type for when a channel is removed from hold.
void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message using the latest snapshot from the cache.
Definition: astman.c:222
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
frame_type
Definition: codec_builtin.c:44
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define ast_frfree(fr)
enum ast_frame_type frametype

◆ hold_intercept_framehook_consume()

static int hold_intercept_framehook_consume ( void *  data,
enum ast_frame_type  type 
)
static

Callback function which informs upstream if we are consuming a frame of a specific type.

Definition at line 138 of file func_holdintercept.c.

References AST_FRAME_CONTROL.

Referenced by set_hold_intercept().

139 {
140  return (type == AST_FRAME_CONTROL ? 1 : 0);
141 }
static const char type[]
Definition: chan_ooh323.c:109

◆ load_module()

static int load_module ( void  )
static

Definition at line 229 of file func_holdintercept.c.

References ast_custom_function_register, AST_MODULE_LOAD_DECLINE, and AST_MODULE_LOAD_SUCCESS.

230 {
232 }
static struct ast_custom_function hold_intercept_function
Definition of the HOLD_INTERCEPT function.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508

◆ remove_hold_intercept()

static int remove_hold_intercept ( struct ast_channel chan)
static

Definition at line 77 of file func_holdintercept.c.

References ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_name(), ast_datastore_free(), ast_framehook_detach(), ast_log, AST_LOG_WARNING, ast_datastore::data, hold_intercept_data::framehook_id, NULL, and SCOPED_CHANNELLOCK.

Referenced by hold_intercept_fn_write().

78 {
79  struct ast_datastore *datastore = NULL;
80  struct hold_intercept_data *data;
81  SCOPED_CHANNELLOCK(chan_lock, chan);
82 
84  if (!datastore) {
85  ast_log(AST_LOG_WARNING, "Cannot remove HOLD_INTERCEPT from %s: HOLD_INTERCEPT not currently enabled\n",
86  ast_channel_name(chan));
87  return -1;
88  }
89  data = datastore->data;
90 
91  if (ast_framehook_detach(chan, data->framehook_id)) {
92  ast_log(AST_LOG_WARNING, "Failed to remove HOLD_INTERCEPT framehook from channel %s\n",
93  ast_channel_name(chan));
94  return -1;
95  }
96 
97  if (ast_channel_datastore_remove(chan, datastore)) {
98  ast_log(AST_LOG_WARNING, "Failed to remove HOLD_INTERCEPT datastore from channel %s\n",
99  ast_channel_name(chan));
100  return -1;
101  }
102  ast_datastore_free(datastore);
103 
104  return 0;
105 }
#define AST_LOG_WARNING
Definition: logger.h:279
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
Structure for a data store object.
Definition: datastore.h:68
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2404
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define ast_log
Definition: astobj2.c:42
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:617
Private data structure used with the function's datastore.
static const struct ast_datastore_info hold_intercept_datastore
The channel datastore the function uses to store state.
void * data
Definition: datastore.h:70
const char * ast_channel_name(const struct ast_channel *chan)
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2399

◆ set_hold_intercept()

static int set_hold_intercept ( struct ast_channel chan)
static

Definition at line 144 of file func_holdintercept.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_name(), ast_datastore_alloc, ast_datastore_free(), ast_framehook_attach(), AST_FRAMEHOOK_INTERFACE_VERSION, ast_free, ast_log, AST_LOG_WARNING, ast_datastore::data, ast_framehook_interface::data, hold_intercept_data::framehook_id, hold_intercept_framehook(), hold_intercept_framehook_consume(), NULL, SCOPED_CHANNELLOCK, and ast_framehook_interface::version.

Referenced by hold_intercept_fn_write().

145 {
146  struct ast_datastore *datastore;
147  struct hold_intercept_data *data;
148  static struct ast_framehook_interface hold_framehook_interface = {
150  .event_cb = hold_intercept_framehook,
151  .consume_cb = hold_intercept_framehook_consume,
152  .disable_inheritance = 1,
153  };
154  SCOPED_CHANNELLOCK(chan_lock, chan);
155 
157  if (datastore) {
158  ast_log(AST_LOG_WARNING, "HOLD_INTERCEPT already set on '%s'\n",
159  ast_channel_name(chan));
160  return 0;
161  }
162 
164  if (!datastore) {
165  return -1;
166  }
167 
168  data = ast_calloc(1, sizeof(*data));
169  if (!data) {
170  ast_datastore_free(datastore);
171  return -1;
172  }
173 
174  data->framehook_id = ast_framehook_attach(chan, &hold_framehook_interface);
175  if (data->framehook_id < 0) {
176  ast_log(AST_LOG_WARNING, "Failed to attach HOLD_INTERCEPT framehook to '%s'\n",
177  ast_channel_name(chan));
178  ast_datastore_free(datastore);
179  ast_free(data);
180  return -1;
181  }
182  datastore->data = data;
183 
184  ast_channel_datastore_add(chan, datastore);
185 
186  return 0;
187 }
static int hold_intercept_framehook_consume(void *data, enum ast_frame_type type)
Callback function which informs upstream if we are consuming a frame of a specific type...
#define AST_LOG_WARNING
Definition: logger.h:279
Structure for a data store object.
Definition: datastore.h:68
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2404
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
Definition: framehook.c:132
#define ast_log
Definition: astobj2.c:42
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:617
#define AST_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227
static struct ast_frame * hold_intercept_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
Frame hook that is called to intercept hold/unhold.
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
Private data structure used with the function&#39;s datastore.
static const struct ast_datastore_info hold_intercept_datastore
The channel datastore the function uses to store state.
void * data
Definition: datastore.h:70
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 223 of file func_holdintercept.c.

References ast_custom_function_unregister().

224 {
226 }
static struct ast_custom_function hold_intercept_function
Definition of the HOLD_INTERCEPT function.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Hold interception dialplan function" , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 234 of file func_holdintercept.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 234 of file func_holdintercept.c.

◆ hold_intercept_datastore

const struct ast_datastore_info hold_intercept_datastore
static
Initial value:
= {
.type = "hold_intercept",
}

The channel datastore the function uses to store state.

Definition at line 72 of file func_holdintercept.c.

◆ hold_intercept_function

struct ast_custom_function hold_intercept_function
static
Initial value:
= {
.name = "HOLD_INTERCEPT",
}
static int hold_intercept_fn_write(struct ast_channel *chan, const char *function, char *data, const char *value)

Definition of the HOLD_INTERCEPT function.

Definition at line 217 of file func_holdintercept.c.