Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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 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.

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

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
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}
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 138 of file func_holdintercept.c.

139{
140 return (type == AST_FRAME_CONTROL ? 1 : 0);
141}
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 229 of file func_holdintercept.c.

230{
232}
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:1558

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

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}
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:2394
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:2399
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:619
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 144 of file func_holdintercept.c.

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,
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}
#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:2385
#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 223 of file func_holdintercept.c.

224{
226}
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 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.

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

Referenced by load_module(), and unload_module().