67 #define REC_FORMAT "sln" 148 static char *
app =
"FollowMe";
151 #define MAX_YN_STRING 20 351 if (!strcasecmp(param,
"musicclass") || !strcasecmp(param,
"musiconhold") || !strcasecmp(param,
"music"))
353 else if (!strcasecmp(param,
"context"))
355 else if (!strcasecmp(param,
"enable_callee_prompt"))
357 else if (!strcasecmp(param,
"takecall"))
359 else if (!strcasecmp(param,
"declinecall"))
361 else if (!strcasecmp(param,
"call-from-prompt") || !strcasecmp(param,
"call_from_prompt"))
363 else if (!strcasecmp(param,
"followme-norecording-prompt") || !strcasecmp(param,
"norecording_prompt"))
365 else if (!strcasecmp(param,
"followme-options-prompt") || !strcasecmp(param,
"options_prompt"))
367 else if (!strcasecmp(param,
"followme-pls-hold-prompt") || !strcasecmp(param,
"pls_hold_prompt"))
369 else if (!strcasecmp(param,
"followme-status-prompt") || !strcasecmp(param,
"status_prompt"))
371 else if (!strcasecmp(param,
"followme-sorry-prompt") || !strcasecmp(param,
"sorry_prompt"))
373 else if (!strcasecmp(param,
"followme-connecting-prompt") || !strcasecmp(param,
"connecting_prompt")) {
375 }
else if (failunknown) {
377 ast_log(
LOG_WARNING,
"Unknown keyword in profile '%s': %s at line %d of followme.conf\n", f->
name, param, linenum);
394 if ((tmp = strchr(buf,
',')))
397 cur->
order = numorder;
413 const char* enable_callee_prompt_str;
414 const char *takecallstr;
415 const char *declinecallstr;
425 ast_log(
LOG_ERROR,
"Config file followme.conf is in an invalid format. Aborting.\n");
432 featuredigittimeout = 5000;
442 if (!sscanf(featuredigittostr,
"%30d", &featuredigittimeout))
443 featuredigittimeout = 5000;
447 "enable_callee_prompt")) &&
449 enable_callee_prompt =
ast_true(enable_callee_prompt_str);
508 if (!strcasecmp(cat,
"general"))
513 if (!strcasecmp(f->
name, cat))
536 if (!strcasecmp(var->
name,
"number")) {
542 strcpy(copy, var->
value);
544 if ((tmp = strchr(numberstr,
','))) {
550 if ((tmp = strchr(tmp,
','))) {
552 numorder = atoi(tmp);
597 if (tmpuser->
ochan && tmpuser->
ochan != exception) {
607 if (!tmpuser->
ochan) {
612 outbound = tmpuser->
ochan;
655 long totalwait = 0, wtd = 0, towas = 0;
657 char *pressbuttonname;
664 totalwait = nm->
timeout * 1000;
670 watchers[0] = caller;
674 if (!tmpuser->
ochan) {
677 if (tmpuser->
state == 3) {
678 tmpuser->
digts += (towas - wtd);
680 if (tmpuser->
digts && (tmpuser->
digts > featuredigittimeout)) {
681 ast_verb(3,
"<%s> We've been waiting for digits longer than we should have.\n",
712 if (tmpto > 0 && tmpto < to)
716 switch (tmpuser->
state) {
718 ast_verb(3,
"<%s> Playback of the call-from file appears to be done.\n",
723 ast_log(
LOG_NOTICE,
"<%s> Unable to playback %s. Maybe the caller didn't record their name?\n",
725 memset(tmpuser->
yn, 0,
sizeof(tmpuser->
yn));
737 ast_verb(3,
"<%s> Playback of name file appears to be done.\n",
739 memset(tmpuser->
yn, 0,
sizeof(tmpuser->
yn));
749 ast_verb(3,
"<%s> Playback of the next step file appears to be done.\n",
758 watchers[pos++] = tmpuser->
ochan;
762 ast_verb(3,
"No live channels left for this step.\n");
772 if (totalwait <= 0) {
773 ast_verb(3,
"We've hit our timeout for this step. Dropping unanswered calls and starting the next step.\n");
779 if (winner != caller) {
782 if (tmpuser->
ochan == winner) {
800 ast_verb(3,
"The calling channel hungup. Need to drop everyone.\n");
820 ast_verb(3,
"Starting playback of %s\n", callfromname);
839 ast_verb(3,
"Skip playback of caller name / norecording\n");
917 ast_verb(3,
"Connected line update from %s prevented.\n",
927 "%s connected line has changed. Saving it until we have a winner.\n",
938 "%s connected line has changed. Saving it until answer.\n",
962 ast_debug(1,
"Dunno what to do with control type %d from %s\n",
968 ast_debug(1,
"Taking call with no prompt\n");
970 return tmpuser->
ochan;
983 memmove(tmpuser->
yn, tmpuser->
yn + 1,
984 sizeof(tmpuser->
yn) - 2 *
sizeof(tmpuser->
yn[0]));
989 if (cmp_len <= tmpuser->
ynidx 990 && !strcmp(tmpuser->
yn + (tmpuser->
ynidx - cmp_len), tpargs->
takecall)) {
991 ast_debug(1,
"Match to take the call!\n");
993 return tmpuser->
ochan;
996 if (cmp_len <= tmpuser->
ynidx 997 && !strcmp(tmpuser->
yn + (tmpuser->
ynidx - cmp_len), tpargs->
nextindp)) {
998 ast_debug(1,
"Declined to take the call.\n");
1005 ast_debug(1,
"we didn't get a frame. hanging up.\n");
1008 ast_verb(3,
"The calling channel hungup. Need to drop everyone.\n");
1016 ast_debug(1,
"timed out waiting for action\n");
1048 if (nm->
order == idx) {
1053 ast_verb(3,
"No more steps left.\n");
1066 if (tmpuser->
ochan) {
1073 for (number = num;
number; number = rest) {
1076 rest = strchr(number,
'&');
1124 tmpuser->
ochan = outbound;
1158 if (tmpuser->
ochan) {
1170 ast_verb(3,
"couldn't reach at this number.\n");
1204 if (!tmpuser->
ochan) {
1215 if (fmuser->
ochan == winner) {
1263 for (v = var; v; v = v->
next) {
1264 if (!strcasecmp(v->
name,
"active")) {
1292 const char *timeoutstr;
1301 || sscanf(timeoutstr,
"%30d", &timeout) != 1
1315 return new_follower;
1344 struct number *nm, *newnm;
1365 if (max_forwards <= 0) {
1366 ast_log(
LOG_WARNING,
"Unable to execute FollowMe on channel %s. Max forwards exceeded\n",
1520 memset(&config, 0,
sizeof(config));
1583 snprintf(fn,
sizeof(fn),
"%s.%s", targs->
namerecloc,
1590 ast_debug(2,
"deleted recorded prompt %s.\n", fn);
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void free_numbers(struct call_followme *f)
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
struct ast_variable * next
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
char norecordingprompt[PATH_MAX]
int ast_max_forwards_get(struct ast_channel *chan)
Get the current max forwards for a particular channel.
int ast_streamfile(struct ast_channel *c, const char *filename, const char *preflang)
Streams a file.
Asterisk locking-related definitions:
static char connprompt[PATH_MAX]
Asterisk main include file. File version handling, generic pbx functions.
int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int is_caller, int frame)
Run a connected line interception macro and update a channel's connected line information.
struct ast_party_caller caller
Channel Caller ID information.
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
unsigned int pending_out_connected_update
static void publish_dial_end_event(struct ast_channel *in, struct findme_user_listptr *findme_user_list, struct ast_channel *exception, const char *status)
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
char connprompt[PATH_MAX]
struct ast_flags features_callee
static void destroy_calling_node(struct findme_user *node)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
const char * ast_app_expand_sub_args(struct ast_channel *chan, const char *args)
Add missing context/exten to subroutine argument string.
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation...
#define ast_test_flag(p, flag)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Support for translation of data formats. translate.c.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
char norecordingprompt[PATH_MAX]
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
Convenient Signal Processing routines.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
#define ast_set_flag(p, flag)
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Indicate that the connected line information has changed.
#define CONFIG_STATUS_FILEINVALID
static struct number * create_followme_number(const char *number, int timeout, int numorder)
Add a new number.
struct fm_args::cnumbers cnumbers
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Structure for variables, used for configurations and for channel variables.
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
char callfromprompt[PATH_MAX]
struct ast_party_connected_line connected_out
ast_channel_state
ast_channel states
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer, struct ast_bridge_config *config)
Bridge a call, optionally allowing redirection.
char connprompt[PATH_MAX]
static int copy(char *infile, char *outfile)
Utility function to copy a file.
int ast_channel_get_up_time(struct ast_channel *chan)
Obtain how long it has been since the channel was answered.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define ast_mutex_lock(a)
struct call_followme::numbers numbers
char context[AST_MAX_CONTEXT]
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
char namerecloc[PATH_MAX]
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
static void clear_unanswered_calls(struct findme_user_listptr *findme_user_list)
char plsholdprompt[PATH_MAX]
unsigned int enable_callee_prompt
int ast_unregister_application(const char *app)
Unregister an application.
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define ast_verb(level,...)
static void profile_set_param(struct call_followme *f, const char *param, const char *val, int linenum, int failunknown)
Set parameter in profile from configuration file.
struct ast_frame_subclass subclass
char nextindp[MAX_YN_STRING]
#define ast_strlen_zero(foo)
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
char callfromprompt[PATH_MAX]
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static void destroy_calling_tree(struct findme_user_listptr *findme_user_list)
static void clear_caller(struct findme_user *tmpuser)
Configuration File Parser.
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
static int reload_followme(int reload)
Reload followme application module.
#define AST_RWLIST_INSERT_HEAD
#define ast_debug(level,...)
Log a DEBUG message.
void ast_replace_subargument_delimiter(char *s)
Replace '^' in a string with ','.
unsigned int pending_hold
static char callfromprompt[PATH_MAX]
#define ast_config_load(filename, flags)
Load a config file.
struct call_followme::wlnumbers wlnumbers
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Data structure for followme scripts.
static int featuredigittimeout
General Asterisk PBX channel definitions.
Asterisk file paths, configured in asterisk.conf.
static char optionsprompt[PATH_MAX]
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
unsigned int pending_in_connected_update
#define AST_MAX_EXTENSION
#define AST_RWLIST_TRAVERSE
struct ast_party_connected_line connected
#define AST_CAUSE_NORMAL_CLEARING
void * end_bridge_callback_data
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
char sorryprompt[PATH_MAX]
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
void ast_config_destroy(struct ast_config *config)
Destroys a config.
void(* end_bridge_callback_data_fixup)(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator)
#define ast_strdupa(s)
duplicate a string in memory from the stack
static void end_bridge_callback(void *data)
char context[AST_MAX_CONTEXT]
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
int ast_pre_call(struct ast_channel *chan, const char *sub_args)
Execute a Gosub call on the channel before a call is placed.
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
static char statusprompt[PATH_MAX]
Core PBX routines and definitions.
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
static char nextindp[MAX_YN_STRING]
struct ast_flags features_caller
#define CONFIG_STATUS_FILEUNCHANGED
const char * ast_channel_uniqueid(const struct ast_channel *chan)
static int load_module(void)
Load the module.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
Parse connected line indication frame data.
struct ast_config * ast_load_realtime_multientry(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
struct ast_sched_context * ast_channel_sched(const struct ast_channel *chan)
static struct ast_channel * wait_for_winner(struct findme_user_listptr *findme_user_list, struct number *nm, struct ast_channel *caller, struct fm_args *tpargs)
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
char nextindp[MAX_YN_STRING]
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
char optionsprompt[PATH_MAX]
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel's connected line information...
Channel datastore data for max forwards.
void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update)
Set the connected line information based on another connected line source.
Connected Line/Party information.
int ast_play_and_record(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime_sec, const char *fmt, int *duration, int *sound_duration, int silencethreshold, int maxsilence_ms, const char *path)
Record a file based on input from a channel. Use default accept and cancel DTMF. This function will p...
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
struct call_followme::blnumbers blnumbers
static char norecordingprompt[PATH_MAX]
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
char name[AST_MAX_EXTENSION]
#define ast_channel_unlock(chan)
struct ast_flags followmeflags
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
int ast_channel_get_duration(struct ast_channel *chan)
Obtain how long the channel since the channel was created.
#define ast_calloc(num, len)
A wrapper for calloc()
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
#define AST_RWLIST_REMOVE_HEAD
char statusprompt[PATH_MAX]
Module has failed to load, may be in an inconsistent state.
const char * ast_config_AST_SPOOL_DIR
char suggested_moh[MAX_MUSICCLASS]
void ast_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
Structure used to handle boolean flags.
#define AST_LIST_HEAD_NOLOCK_INIT_VALUE
Defines initial values for a declaration of AST_LIST_HEAD_NOLOCK.
static struct call_followme * alloc_profile(const char *fmname)
Allocate and initialize followme profile.
#define ast_clear_flag(p, flag)
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
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(* end_bridge_callback)(void *)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
void ast_deactivate_generator(struct ast_channel *chan)
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
static const char * featuredigittostr
int ast_max_forwards_decrement(struct ast_channel *chan)
Decrement the max forwards count for a particular channel.
static int app_exec(struct ast_channel *chan, const char *data)
Standard Command Line Interface.
struct ast_channel * ochan
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
char plsholdprompt[PATH_MAX]
const char * ast_channel_name(const struct ast_channel *chan)
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
const char * predial_callee
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
int ast_answer(struct ast_channel *chan)
Answer a channel.
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Data structure associated with a single frame of data.
char takecall[MAX_YN_STRING]
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.
Internal Asterisk hangup causes.
const char * ast_channel_language(const struct ast_channel *chan)
union ast_frame::@263 data
static int unload_module(void)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
#define ast_mutex_init(pmutex)
static const struct ast_app_option followme_opts[128]
static const char * defaultmoh
static char context[AST_MAX_CONTEXT]
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define ast_mutex_destroy(a)
char sorryprompt[PATH_MAX]
char takecall[MAX_YN_STRING]
static struct ast_channel * findmeexec(struct fm_args *tpargs, struct ast_channel *caller)
Say numbers and dates (maybe words one day too)
#define ASTERISK_GPL_KEY
The text the key() function should return.
static char plsholdprompt[PATH_MAX]
char optionsprompt[PATH_MAX]
static struct call_followme * find_realtime(const char *name)
int ast_dsp_get_threshold_from_settings(enum threshold which)
Get silence threshold from dsp.conf.
Asterisk module definitions.
static void init_profile(struct call_followme *f, int activate)
ast_timing_func_t ast_channel_timingfunc(const struct ast_channel *chan)
static char takecall[MAX_YN_STRING]
static char sorryprompt[PATH_MAX]
Persistant data storage (akin to *doze registry)
#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...
struct ast_party_connected_line connected_in
static int enable_callee_prompt
int ast_stopstream(struct ast_channel *c)
Stops a stream.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Structure for mutex and tracking information.
const char * ast_channel_musicclass(const struct ast_channel *chan)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define ast_mutex_unlock(a)
#define AST_APP_ARG(name)
Define an application argument.
#define AST_LIST_APPEND_LIST(head, list, field)
Appends a whole list to the tail of a list.
unsigned int pending_connected_update
char statusprompt[PATH_MAX]
unsigned int enable_callee_prompt