80 static char *app =
"StoreDTMF";
90 static void datastore_destroy_cb(
void *data) {
106 .
type =
"dtmf_store",
107 .destroy = datastore_destroy_cb
111 static int remove_dtmf_store(
struct ast_channel *chan)
119 ast_log(AST_LOG_WARNING,
"Cannot remove StoreDTMF from %s: StoreDTMF not currently enabled\n",
120 ast_channel_name(chan));
123 data = datastore->
data;
126 ast_log(AST_LOG_WARNING,
"Failed to remove StoreDTMF framehook from channel %s\n",
127 ast_channel_name(chan));
132 ast_log(AST_LOG_WARNING,
"Failed to remove StoreDTMF datastore from channel %s\n",
133 ast_channel_name(chan));
145 char currentdata[512];
147 char *varname = NULL;
151 if (!f || !framedata) {
165 varname = framedata->rx_var;
167 varname = framedata->tx_var;
174 sprintf(varnamesub,
"${%s}", varname);
175 pbx_substitute_variables_helper(chan, varnamesub, currentdata, 511);
177 if (ast_strlen_zero(currentdata)) {
178 ast_debug(3,
"Creating new digit store: %s\n", varname);
180 len = strlen(currentdata);
181 if (framedata->maxdigits > 0 && len >= framedata->maxdigits) {
182 ast_debug(3,
"Reached digit limit: %d\n", framedata->maxdigits);
183 remove_dtmf_store(chan);
186 char newdata[len + 2];
191 newdata[len + 1] =
'\0';
192 ast_debug(3,
"Appending to digit store: now %s\n", newdata);
199 static int dtmfstore_exec(
struct ast_channel *chan,
const char *appdata)
204 .
version = AST_FRAMEHOOK_INTERFACE_VERSION,
206 .disable_inheritance = 1,
217 if (ast_strlen_zero(appdata)) {
218 ast_log(AST_LOG_WARNING,
"StoreDTMF requires an argument\n");
222 if (!strcasecmp(args.direction,
"remove")) {
223 return remove_dtmf_store(chan);
228 ast_log(AST_LOG_WARNING,
"StoreDTMF already set on '%s'\n",
229 ast_channel_name(chan));
233 datastore = ast_datastore_alloc(&dtmf_store_datastore, NULL);
244 digit_framehook_interface.
data =
data;
250 if (!strcasecmp(args.direction,
"tx")) {
252 }
else if (!strcasecmp(args.direction,
"rx")) {
255 ast_log(LOG_ERROR,
"Direction must be either RX or TX\n");
259 if (!ast_strlen_zero(args.maxdigits)) {
261 ast_log(LOG_ERROR,
"Invalid integer: %s\n", args.maxdigits);
264 if (data->maxdigits < 0) {
265 ast_log(LOG_ERROR,
"Invalid natural number: %d\n", data->maxdigits);
267 }
else if (data->maxdigits == 0) {
268 ast_log(LOG_WARNING,
"No maximum digit count set\n");
273 if (data->framehook_id < 0) {
274 ast_log(AST_LOG_WARNING,
"Failed to attach StoreDTMF framehook to '%s'\n",
275 ast_channel_name(chan));
287 static int unload_module(
void)
292 static int load_module(
void)
297 AST_MODULE_INFO_STANDARD_EXTENDED(
ASTERISK_GPL_KEY,
"Technology independent async DTMF storage");
Main Channel structure associated with a channel.
static struct ast_frame * dtmf_store_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
Frame hook that is called to intercept digit/undigit.
Asterisk main include file. File version handling, generic pbx functions.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
ast_framehook_event
These are the types of events that the framehook's event callback can receive.
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Structure for a data store type.
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
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.
int ast_unregister_application(const char *app)
Unregister an application.
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
struct ast_frame_subclass subclass
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
static const struct ast_datastore_info dtmf_store_datastore
The channel datastore the function uses to store state.
#define SCOPED_CHANNELLOCK(varname, chan)
scoped lock specialization for channels.
General Asterisk PBX channel definitions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Conversion utility functions.
#define ast_debug(level,...)
Log a DEBUG message.
Core PBX routines and definitions.
int ast_str_to_int(const char *str, int *res)
Convert the given string to a signed integer.
Private data structure used with the function's datastore.
#define ast_calloc(num, len)
A wrapper for calloc()
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Data structure associated with a single frame of data.
enum ast_frame_type frametype
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
#define AST_APP_ARG(name)
Define an application argument.