From 938c2edf40ff7a834f12ef2986335f2495576a59 Mon Sep 17 00:00:00 2001 From: tilghman Date: Mon, 25 Aug 2008 16:02:56 +0000 Subject: Realtime capabilities for the Find-Me-Follow-Me application. (closes issue #13295) Reported by: Corydon76 Patches: 20080813__followme_realtime_enabled.diff.txt uploaded by Corydon76 (license 14) Tested by: dferrer git-svn-id: http://svn.digium.com/svn/asterisk/trunk@139775 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_followme.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++---- doc/followme.txt | 32 ++++++++++++++++++++ 2 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 doc/followme.txt diff --git a/apps/app_followme.c b/apps/app_followme.c index e582cc5df..84fe26c08 100644 --- a/apps/app_followme.c +++ b/apps/app_followme.c @@ -89,6 +89,7 @@ struct call_followme { char moh[AST_MAX_CONTEXT]; /*!< Music On Hold Class to be used */ char context[AST_MAX_CONTEXT]; /*!< Context to dial from */ unsigned int active; /*!< Profile is active (1), or disabled (0). */ + int realtime; /*!< Cached from realtime */ char takecall[20]; /*!< Digit mapping to take a call */ char nextindp[20]; /*!< Digit mapping to decline a call */ char callfromprompt[PATH_MAX]; /*!< Sound prompt name and path */ @@ -233,17 +234,17 @@ static void profile_set_param(struct call_followme *f, const char *param, const ast_copy_string(f->takecall, val, sizeof(f->takecall)); else if (!strcasecmp(param, "declinecall")) ast_copy_string(f->nextindp, val, sizeof(f->nextindp)); - else if (!strcasecmp(param, "call-from-prompt")) + else if (!strcasecmp(param, "call-from-prompt") || !strcasecmp(param, "call_from_prompt")) ast_copy_string(f->callfromprompt, val, sizeof(f->callfromprompt)); - else if (!strcasecmp(param, "followme-norecording-prompt")) + else if (!strcasecmp(param, "followme-norecording-prompt") || !strcasecmp(param, "norecording_prompt")) ast_copy_string(f->norecordingprompt, val, sizeof(f->norecordingprompt)); - else if (!strcasecmp(param, "followme-options-prompt")) + else if (!strcasecmp(param, "followme-options-prompt") || !strcasecmp(param, "options_prompt")) ast_copy_string(f->optionsprompt, val, sizeof(f->optionsprompt)); - else if (!strcasecmp(param, "followme-pls-hold-prompt")) + else if (!strcasecmp(param, "followme-pls-hold-prompt") || !strcasecmp(param, "hold_prompt")) ast_copy_string(f->plsholdprompt, val, sizeof(f->plsholdprompt)); - else if (!strcasecmp(param, "followme-status-prompt")) + else if (!strcasecmp(param, "followme-status-prompt") || !strcasecmp(param, "status_prompt")) ast_copy_string(f->statusprompt, val, sizeof(f->statusprompt)); - else if (!strcasecmp(param, "followme-sorry-prompt")) + else if (!strcasecmp(param, "followme-sorry-prompt") || !strcasecmp(param, "sorry_prompt")) ast_copy_string(f->sorryprompt, val, sizeof(f->sorryprompt)); else if (failunknown) { if (linenum >= 0) @@ -873,6 +874,67 @@ static void findmeexec(struct fm_args *tpargs) return; } +static struct call_followme *find_realtime(const char *name) +{ + struct ast_variable *var = ast_load_realtime("followme", "name", name, NULL), *v; + struct ast_config *cfg; + const char *catg; + struct call_followme *new; + struct ast_str *str = ast_str_create(16); + + if (!var) { + return NULL; + } + + if (!(new = alloc_profile(name))) { + return NULL; + } + + for (v = var; v; v = v->next) { + if (!strcasecmp(v->name, "active")) { + if (ast_false(v->value)) { + ast_mutex_destroy(&new->lock); + ast_free(new); + return NULL; + } + } else { + profile_set_param(new, v->name, v->value, 0, 0); + } + } + + ast_variables_destroy(var); + new->realtime = 1; + + /* Load numbers */ + if (!(cfg = ast_load_realtime_multientry("followme_numbers", "ordinal LIKE", "%", "name", name, NULL))) { + ast_mutex_destroy(&new->lock); + ast_free(new); + return NULL; + } + + for (catg = ast_category_browse(cfg, NULL); catg; catg = ast_category_browse(cfg, catg)) { + const char *numstr, *timeoutstr, *ordstr; + int timeout; + struct number *cur; + if (!(numstr = ast_variable_retrieve(cfg, catg, "phonenumber"))) { + continue; + } + if (!(timeoutstr = ast_variable_retrieve(cfg, catg, "timeout")) || sscanf(timeoutstr, "%d", &timeout) != 1 || timeout < 1) { + timeout = 25; + } + /* This one has to exist; it was part of the query */ + ordstr = ast_variable_retrieve(cfg, catg, "ordinal"); + ast_str_make_space(&str, strlen(numstr) + 1); + ast_copy_string(str->str, numstr, str->len); + if ((cur = create_followme_number(str->str, timeout, atoi(ordstr)))) { + AST_LIST_INSERT_TAIL(&new->numbers, cur, entry); + } + } + ast_config_destroy(cfg); + + return new; +} + static int app_exec(struct ast_channel *chan, void *data) { struct fm_args targs; @@ -917,6 +979,10 @@ static int app_exec(struct ast_channel *chan, void *data) ast_debug(1, "New profile %s.\n", args.followmeid); + if (!f) { + f = find_realtime(args.followmeid); + } + if (!f) { ast_log(LOG_WARNING, "Profile requested, %s, not found in the configuration.\n", args.followmeid); return 0; @@ -1016,6 +1082,12 @@ static int app_exec(struct ast_channel *chan, void *data) outrun: + if (f->realtime) { + /* Not in list */ + free_numbers(f); + ast_free(f); + } + return res; } diff --git a/doc/followme.txt b/doc/followme.txt new file mode 100644 index 000000000..971814aac --- /dev/null +++ b/doc/followme.txt @@ -0,0 +1,32 @@ +Followme is now realtime-enabled: + +To use, you must define two backend data structures, with the following fields: + +followme: + name Name of this followme entry. Specified when invoking the FollowMe + application in the dialplan. This field is the only one which is + mandatory. All of the other fields will inherit the default from + followme.conf, if not specified in this data resource. + musicclass OR The musiconhold class used for the caller while waiting to be + musiconhold OR connected. + music + context Dialplan context from which to dial numbers + takecall DTMF used to accept the call and be connected. For obvious reasons, + this needs to be a single digit, '*', or '#'. + declinecall DTMF used to refuse the call, sending it onto the next step, if any. + call_from_prompt Prompt to play to the callee, announcing the call. + norecording_prompt The alternate prompt to play to the callee, when the caller + refuses to leave a name (or the option isn't set to allow them). + options_prompt Normally, "press 1 to accept, 2 to decline". + hold_prompt Message played to the caller while dialing the followme steps. + status_prompt Normally, "Party is not at their desk". + sorry_prompt Normally, "Unable to locate party". + +followme_numbers: + name Name of this followme entry. Must match the name above. + ordinal An integer, specifying the order in which these numbers will be + followed. + phonenumber The telephone number(s) you would like to call, separated by '&'. + timeout Timeout associated with this step. See the followme documentation + for more information on how this value is handled. + -- cgit v1.2.3