From 6ed8f1526056d508e29fa038b6460822be19b09b Mon Sep 17 00:00:00 2001
From: Mark Spencer <markster@digium.com>
Date: Tue, 1 Feb 2005 01:53:25 +0000
Subject: [PATCH] Allow hints to have names (bug #3471)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4938 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 apps/app_dial.c                | 26 ++++++++++++++++++++++++--
 configs/extensions.conf.sample |  2 +-
 doc/README.variables           |  2 ++
 include/asterisk/pbx.h         |  4 +++-
 manager.c                      |  2 +-
 pbx.c                          | 22 +++++++++++++++++-----
 6 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/apps/app_dial.c b/apps/app_dial.c
index 0c155a9078..2e82647536 100755
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -217,6 +217,26 @@ static int ast_onedigit_goto(struct ast_channel *chan, char *context, char exten
 }
 
 
+static char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
+{
+	char *context;
+	char *exten;
+	if (!ast_strlen_zero(chan->macrocontext))
+		context = chan->macrocontext;
+	else
+		context = chan->context;
+
+	if (!ast_strlen_zero(chan->macroexten))
+		exten = chan->macroexten;
+	else
+		exten = chan->exten;
+
+	if (ast_get_hint(NULL, 0, name, namelen, chan, context, exten))
+		return name;
+	else
+		return "";
+}
+
 static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int *result)
 {
 	struct localuser *o;
@@ -235,6 +255,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
 	int single;
 	struct ast_channel *winner;
 	char *context = NULL;
+	char cidname[AST_MAX_EXTENSION];
 
 	single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, DIAL_MUSICONHOLD | DIAL_RINGBACKONLY));
 	
@@ -382,7 +403,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
 							numnochan++;
 						} else {
 							/* After calling, set callerid to extension */
-							ast_set_callerid(o->chan, ast_strlen_zero(in->macroexten) ? in->exten : in->macroexten, NULL, NULL);
+							ast_set_callerid(o->chan, ast_strlen_zero(in->macroexten) ? in->exten : in->macroexten, get_cid_name(cidname, sizeof(cidname), in), NULL);
 						}
 					}
 					/* Hangup the original channel now, in case we needed it */
@@ -558,6 +579,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
 	int cause;
 	char numsubst[AST_MAX_EXTENSION];
 	char restofit[AST_MAX_EXTENSION];
+	char cidname[AST_MAX_EXTENSION];
 	char *transfer = NULL;
 	char *newnum;
 	char *l;
@@ -991,7 +1013,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
 		} else {
 			if (option_verbose > 2)
 				ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
-			ast_set_callerid(tmp->chan, ast_strlen_zero(chan->macroexten) ? chan->exten : chan->macroexten, NULL, NULL);
+			ast_set_callerid(tmp->chan, ast_strlen_zero(chan->macroexten) ? chan->exten : chan->macroexten, get_cid_name(cidname, sizeof(cidname), chan), NULL);
 		}
 		/* Put them in the list of outgoing thingies...  We're ready now. 
 		   XXX If we're forcibly removed, these outgoing calls won't get
diff --git a/configs/extensions.conf.sample b/configs/extensions.conf.sample
index ecbaa5a6f4..dd374d34e4 100755
--- a/configs/extensions.conf.sample
+++ b/configs/extensions.conf.sample
@@ -392,7 +392,7 @@ include => demo
 ; overlap extensions and menu options without conflict.  You can alias them with
 ; names, too and use global variables
 
-;exten => 6245,hint,SIP/Grandstream1&SIP/Xlite1 ; Channel hints for presence
+;exten => 6245,hint,SIP/Grandstream1&SIP/Xlite1,Joe Schmoe ; Channel hints for presence
 ;exten => 6245,1,Dial(SIP/Grandstream1,20,rt)	; permit transfer
 ;exten => 6245,n(dial),Dial(${HINT},20,rtT)		; Use hint as listed
 ;exten => 6245,n,Voicemail(u6245)		; Voicemail (unavailable)
diff --git a/doc/README.variables b/doc/README.variables
index b892556c69..ced8f8e903 100755
--- a/doc/README.variables
+++ b/doc/README.variables
@@ -62,6 +62,8 @@ ${EPOCH}	Current unix style epoch
 ${EXTEN}	Current extension
 ${ENV(VAR)}	Environmental variable VAR
 ${HANGUPCAUSE}	Asterisk hangup cause
+${HINT}		Channel hints for this extension
+${HINTNAME}	Suggested Caller*ID name for this extension
 ${INVALID_EXTEN}The invalid called extension (used in the "i" extension)
 ${LANGUAGE}	Current language
 ${LEN(VAR)}	String length of VAR (integer)
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
index 9607e85209..c45611fea3 100755
--- a/include/asterisk/pbx.h
+++ b/include/asterisk/pbx.h
@@ -285,6 +285,8 @@ int ast_extension_state_del(int id, ast_state_cb_type callback);
 /*!
  * \param hint buffer for hint
  * \param maxlen size of hint buffer
+ * \param hint buffer for name portion of hint
+ * \param maxlen size of name buffer
  * \param c this is not important
  * \param context which context to look in
  * \param exten which extension to search for
@@ -292,7 +294,7 @@ int ast_extension_state_del(int id, ast_state_cb_type callback);
  * is found a non zero value will be returned.
  * Otherwise, 0 is returned.
  */
-int ast_get_hint(char *hint, int maxlen, struct ast_channel *c, const char *context, const char *exten);
+int ast_get_hint(char *hint, int maxlen, char *name, int maxnamelen, struct ast_channel *c, const char *context, const char *exten);
 
 /*! If an extension exists, return non-zero */
 /*  work */
diff --git a/manager.c b/manager.c
index a8eba2594a..856f9294eb 100755
--- a/manager.c
+++ b/manager.c
@@ -1042,7 +1042,7 @@ static int action_extensionstate(struct mansession *s, struct message *m)
 	if (!context || ast_strlen_zero(context))
 		context = "default";
 	status = ast_extension_state(NULL, context, exten);
-	ast_get_hint(hint, sizeof(hint) - 1, NULL, context, exten);
+	ast_get_hint(hint, sizeof(hint) - 1, NULL, 0, NULL, context, exten);
         if (id && !ast_strlen_zero(id)) {
                 snprintf(idText,256,"ActionID: %s\r\n",id);
         }
diff --git a/pbx.c b/pbx.c
index bbc61d7f24..0e4d8eeb10 100755
--- a/pbx.c
+++ b/pbx.c
@@ -900,7 +900,12 @@ void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, c
 		} else
 			*ret = NULL;
 	} else if (c && !strcmp(var, "HINT")) {
-		if (!ast_get_hint(workspace, workspacelen, c, c->context, c->exten))
+		if (!ast_get_hint(workspace, workspacelen, NULL, 0, c, c->context, c->exten))
+			*ret = NULL;
+		else
+			*ret = workspace;
+	} else if (c && !strcmp(var, "HINTNAME")) {
+		if (!ast_get_hint(NULL, 0, workspace, workspacelen, c, c->context, c->exten))
 			*ret = NULL;
 		else
 			*ret = workspace;
@@ -1787,19 +1792,26 @@ static int ast_remove_hint(struct ast_exten *e)
 			prev = list;
 			list = list->next;    
 		}
-    	}
+	}
 
 	ast_mutex_unlock(&hintlock);
 	return -1;
 }
 
 
-int ast_get_hint(char *hint, int hintsize, struct ast_channel *c, const char *context, const char *exten)
+int ast_get_hint(char *hint, int hintsize, char *name, int namesize, struct ast_channel *c, const char *context, const char *exten)
 {
 	struct ast_exten *e;
+	void *tmp;
 	e = ast_hint_extension(c, context, exten);
-	if (e) {	
-	    strncpy(hint, ast_get_extension_app(e), hintsize - 1);
+	if (e) {
+		if (hint) 
+		    strncpy(hint, ast_get_extension_app(e), hintsize - 1);
+		if (name) {
+			tmp = ast_get_extension_app_data(e);
+			if (tmp)
+				strncpy(name, (char *)tmp, namesize - 1);
+		}
 	    return -1;
 	}
 	return 0;	
-- 
GitLab