Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 = AST_BUILDOPT_SUM, .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 237 of file func_holdintercept.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 237 of file func_holdintercept.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 237 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 193 of file func_holdintercept.c.

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

References ast_log, AST_LOG_WARNING, ast_strlen_zero(), ast_framehook_interface::data, remove_hold_intercept(), and set_hold_intercept().

◆ 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 111 of file func_holdintercept.c.

113{
114 int frame_type;
115
116 if (!f || (event != AST_FRAMEHOOK_EVENT_WRITE)) {
117 return f;
118 }
119
120 if (f->frametype != AST_FRAME_CONTROL) {
121 return f;
122 }
123
126 return f;
127 }
128
129 /* Munch munch */
130 ast_frfree(f);
131 f = &ast_null_frame;
132
135 NULL);
136
137 return f;
138}
frame_type
Definition: codec_builtin.c:44
@ AST_FRAMEHOOK_EVENT_WRITE
Definition: framehook.h:153
struct stasis_message_type * ast_channel_hold_type(void)
Message type for when a channel is placed on 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.
struct stasis_message_type * ast_channel_unhold_type(void)
Message type for when a channel is removed from hold.
#define ast_frfree(fr)
@ AST_FRAME_CONTROL
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_HOLD
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
enum ast_frame_type frametype
Definition: astman.c:222

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

◆ 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 141 of file func_holdintercept.c.

142{
143 return (type == AST_FRAME_CONTROL ? 1 : 0);
144}
static const char type[]
Definition: chan_ooh323.c:109

References AST_FRAME_CONTROL, and type.

Referenced by set_hold_intercept().

◆ load_module()

static int load_module ( void  )
static

Definition at line 232 of file func_holdintercept.c.

233{
235}
static struct ast_custom_function hold_intercept_function
Definition of the HOLD_INTERCEPT function.
@ 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_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1559

References ast_custom_function_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and hold_intercept_function.

◆ remove_hold_intercept()

static int remove_hold_intercept ( struct ast_channel chan)
static

Definition at line 80 of file func_holdintercept.c.

81{
82 struct ast_datastore *datastore = NULL;
83 struct hold_intercept_data *data;
84 SCOPED_CHANNELLOCK(chan_lock, chan);
85
87 if (!datastore) {
88 ast_log(AST_LOG_WARNING, "Cannot remove HOLD_INTERCEPT from %s: HOLD_INTERCEPT not currently enabled\n",
89 ast_channel_name(chan));
90 return -1;
91 }
92 data = datastore->data;
93
94 if (ast_framehook_detach(chan, data->framehook_id)) {
95 ast_log(AST_LOG_WARNING, "Failed to remove HOLD_INTERCEPT framehook from channel %s\n",
96 ast_channel_name(chan));
97 return -1;
98 }
99
100 if (ast_channel_datastore_remove(chan, datastore)) {
101 ast_log(AST_LOG_WARNING, "Failed to remove HOLD_INTERCEPT datastore from channel %s\n",
102 ast_channel_name(chan));
103 return -1;
104 }
105 ast_datastore_free(datastore);
106
107 return 0;
108}
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:2423
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:2428
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
static const struct ast_datastore_info hold_intercept_datastore
The channel datastore the function uses to store state.
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
Definition: lock.h:623
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
Private data structure used with the function's datastore.

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, hold_intercept_datastore, NULL, and SCOPED_CHANNELLOCK.

Referenced by hold_intercept_fn_write().

◆ set_hold_intercept()

static int set_hold_intercept ( struct ast_channel chan)
static

Definition at line 147 of file func_holdintercept.c.

148{
149 struct ast_datastore *datastore;
150 struct hold_intercept_data *data;
151 static struct ast_framehook_interface hold_framehook_interface = {
153 .event_cb = hold_intercept_framehook,
155 .disable_inheritance = 1,
156 };
157 SCOPED_CHANNELLOCK(chan_lock, chan);
158
160 if (datastore) {
161 ast_log(AST_LOG_WARNING, "HOLD_INTERCEPT already set on '%s'\n",
162 ast_channel_name(chan));
163 return 0;
164 }
165
167 if (!datastore) {
168 return -1;
169 }
170
171 data = ast_calloc(1, sizeof(*data));
172 if (!data) {
173 ast_datastore_free(datastore);
174 return -1;
175 }
176
177 data->framehook_id = ast_framehook_attach(chan, &hold_framehook_interface);
178 if (data->framehook_id < 0) {
179 ast_log(AST_LOG_WARNING, "Failed to attach HOLD_INTERCEPT framehook to '%s'\n",
180 ast_channel_name(chan));
181 ast_datastore_free(datastore);
182 ast_free(data);
183 return -1;
184 }
185 datastore->data = data;
186
187 ast_channel_datastore_add(chan, datastore);
188
189 return 0;
190}
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2414
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
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_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227
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.
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.

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_datastore, hold_intercept_framehook(), hold_intercept_framehook_consume(), NULL, SCOPED_CHANNELLOCK, and ast_framehook_interface::version.

Referenced by hold_intercept_fn_write().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 226 of file func_holdintercept.c.

227{
229}
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.

References ast_custom_function_unregister(), and hold_intercept_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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 237 of file func_holdintercept.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 237 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 75 of file func_holdintercept.c.

Referenced by remove_hold_intercept(), and set_hold_intercept().

◆ 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 220 of file func_holdintercept.c.

Referenced by load_module(), and unload_module().