From c96810b9d35bec45981515148a63d6c0482f2482 Mon Sep 17 00:00:00 2001
From: Mark Spencer <markster@digium.com>
Date: Sat, 26 Feb 2005 07:34:09 +0000
Subject: [PATCH] Add new callerpres parsing API (bug #3648)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5086 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 apps/app_setcallerid.c      | 46 +++++++-------------------------
 callerid.c                  | 40 ++++++++++++++++++++++++++++
 channels/chan_sip.c         | 16 +++++++----
 include/asterisk/callerid.h | 53 ++++++++++++++++++++++++++++++-------
 4 files changed, 103 insertions(+), 52 deletions(-)

diff --git a/apps/app_setcallerid.c b/apps/app_setcallerid.c
index 100fb813c0..78bd17c432 100755
--- a/apps/app_setcallerid.c
+++ b/apps/app_setcallerid.c
@@ -31,25 +31,9 @@ STANDARD_LOCAL_USER;
 
 LOCAL_USER_DECL;
 
-static struct {
-	int val;
-	char *name;
-} preses[] = {
-	{  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened" },
-	{  AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen" },
-	{  AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen" },
-	{  AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed" },
-	{  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED	, "prohib_not_screened" },
-	{  AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen" },
-	{  AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen" },
-	{  AST_PRES_PROHIB_NETWORK_NUMBER, "prohib" },
-	{  AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable" },
-};
-
 static char *descrip2 = 
-"  SetCallerPres(presentation): Set Caller*ID presentation on\n"
-"a call to a new value.  Sets ANI as well if a flag is used.\n"
-"Always returns 0.  Valid presentations are:\n"
+"  SetCallerPres(presentation): Set Caller*ID presentation on a call.\n"
+"  Always returns 0.  Valid presentations are:\n"
 "\n"
 "      allowed_not_screened    : Presentation Allowed, Not Screened\n"
 "      allowed_passed_screen   : Presentation Allowed, Passed Screen\n" 
@@ -65,33 +49,21 @@ static char *descrip2 =
 
 static int setcallerid_pres_exec(struct ast_channel *chan, void *data)
 {
-	int res = 0;
-	char tmp[256] = "";
 	struct localuser *u;
-	int x;
-	char *opts;
 	int pres = -1;
-	if (data)
-		strncpy(tmp, (char *)data, sizeof(tmp) - 1);
-	opts = strchr(tmp, '|');
-	if (opts) {
-		*opts = '\0';
-		opts++;
-	}
-	for (x=0;x<sizeof(preses) / sizeof(preses[0]);x++) {
-		if (!strcasecmp(preses[x].name, tmp)) {
-			pres = preses[x].val;
-			break;
-		}
-	}
+
+	pres = ast_parse_caller_presentation(data);
+
 	if (pres < 0) {
-		ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show application SetCallerPres')\n", tmp);
+		ast_log(LOG_WARNING, "'%s' is not a valid presentation (see 'show application SetCallerPres')\n",
+			(char *) data);
 		return 0;
 	}
+
 	LOCAL_USER_ADD(u);
 	chan->cid.cid_pres = pres;
 	LOCAL_USER_REMOVE(u);
-	return res;
+	return 0;
 }
 
 
diff --git a/callerid.c b/callerid.c
index 19d0d4b6ea..3a55a73111 100755
--- a/callerid.c
+++ b/callerid.c
@@ -715,3 +715,43 @@ int ast_callerid_split(const char *buf, char *name, int namelen, char *num, int
 		num[0] = '\0';
 	return 0;
 }
+
+static struct {
+	int val;
+	char *name;
+	char *description;
+} pres_types[] = {
+	{  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, "allowed_not_screened", "Presentation Allowed, Not Screened"},
+	{  AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, "allowed_passed_screen", "Presentation Allowed, Passed Screen"},
+	{  AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, "allowed_failed_screen", "Presentation Allowed, Failed Screen"},
+	{  AST_PRES_ALLOWED_NETWORK_NUMBER, "allowed", "Presentation Allowed, Network Number"},
+	{  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, "prohib_not_screened", "Presentation Prohibited, Not Screened"},
+	{  AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, "prohib_passed_screen", "Presentation Prohibited, Passed Screen"},
+	{  AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, "prohib_failed_screen", "Presentation Prohibited, Failed Screen"},
+	{  AST_PRES_PROHIB_NETWORK_NUMBER, "prohib", "Presentation Prohibited, Network Number"},
+	{  AST_PRES_NUMBER_NOT_AVAILABLE, "unavailable", "Number Unavailable"},
+};
+
+int ast_parse_caller_presentation(const char *data)
+{
+	int i;
+
+	for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
+		if (!strcasecmp(pres_types[i].name, data))
+			return pres_types[i].val;
+	}
+
+	return -1;
+}
+
+const char *ast_describe_caller_presentation(int data)
+{
+	int i;
+
+	for (i = 0; i < ((sizeof(pres_types) / sizeof(pres_types[0]))); i++) {
+		if (pres_types[i].val == data)
+			return pres_types[i].description;
+	}
+
+	return "unknown";
+}
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 5a569616b4..97c9e35226 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -3864,7 +3864,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, char *cmd, c
 	if (!l || (!ast_isphonenumber(l) && default_callerid[0]))
 			l = default_callerid;
 	/* if user want's his callerid restricted */
-	if (p->callingpres & AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED) {
+	if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) {
 		l = CALLERID_UNKNOWN;
 		n = l;
 	}
@@ -6256,7 +6256,8 @@ static int sip_show_peer(int fd, int argc, char *argv[])
 		ast_cli(fd, "  Language     : %s\n", peer->language);
 		if (!ast_strlen_zero(peer->accountcode))
 			ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
-		ast_cli(fd, "  AMA flag     : %s\n", ast_cdr_flags2str(peer->amaflags));
+		ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
+		ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
 		if (!ast_strlen_zero(peer->fromuser))
 			ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
 		if (!ast_strlen_zero(peer->fromdomain))
@@ -6357,7 +6358,8 @@ static int sip_show_user(int fd, int argc, char *argv[])
 		ast_cli(fd, "  Language     : %s\n", user->language);
 		if (!ast_strlen_zero(user->accountcode))
 			ast_cli(fd, "  Accountcode  : %s\n", user->accountcode);
-		ast_cli(fd, "  AMA flag     : %s\n", ast_cdr_flags2str(user->amaflags));
+		ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
+		ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
 		ast_cli(fd, "  Inc. limit   : %d\n", user->incominglimit);
 		ast_cli(fd, "  Outg. limit  : %d\n", user->outgoinglimit);
 		ast_cli(fd, "  Callgroup    : ");
@@ -9113,7 +9115,9 @@ static struct sip_user *build_user(const char *name, struct ast_variable *v, int
 			} else if (!strcasecmp(v->name, "disallow")) {
 				ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 0);
 			} else if (!strcasecmp(v->name, "callingpres")) {
-				user->callingpres = atoi(v->value);
+				user->callingpres = ast_parse_caller_presentation(v->value);
+				if (user->callingpres == -1)
+					user->callingpres = atoi(v->value);
 			}
 			/*else if (strcasecmp(v->name,"type"))
 			 *	ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
@@ -9316,7 +9320,9 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
 				else
 					peer->addr.sin_port = htons(atoi(v->value));
 			} else if (!strcasecmp(v->name, "callingpres")) {
-				peer->callingpres = atoi(v->value);
+				peer->callingpres = ast_parse_caller_presentation(v->value);
+				if (peer->callingpres == -1)
+					peer->callingpres = atoi(v->value);
 			} else if (!strcasecmp(v->name, "username")) {
 				strncpy(peer->username, v->value, sizeof(peer->username)-1);
 			} else if (!strcasecmp(v->name, "language")) {
diff --git a/include/asterisk/callerid.h b/include/asterisk/callerid.h
index 15497be8b8..ce33879157 100755
--- a/include/asterisk/callerid.h
+++ b/include/asterisk/callerid.h
@@ -190,16 +190,6 @@ static inline float callerid_getcarrier(float *cr, float *ci, int bit)
 	return *cr;
 }	
 
-#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED	0x00
-#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN	0x01
-#define AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN	0x02
-#define AST_PRES_ALLOWED_NETWORK_NUMBER				0x03
-#define AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED	0x20
-#define AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN	0x21
-#define AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN	0x22
-#define AST_PRES_PROHIB_NETWORK_NUMBER				0x23
-#define AST_PRES_NUMBER_NOT_AVAILABLE				0x43
-
 #define PUT_BYTE(a) do { \
 	*(buf++) = (a); \
 	bytes++; \
@@ -237,5 +227,48 @@ static inline float callerid_getcarrier(float *cr, float *ci, int bit)
 	PUT_CLID_BAUD(1);	/* Stop bit */ \
 } while(0);	
 
+/* Various defines and bits for handling PRI- and SS7-type restriction */
+
+#define AST_PRES_NUMBER_TYPE				0x03
+#define AST_PRES_USER_NUMBER_UNSCREENED			0x00
+#define AST_PRES_USER_NUMBER_PASSED_SCREEN		0x01
+#define AST_PRES_USER_NUMBER_FAILED_SCREEN		0x02
+#define AST_PRES_NETWORK_NUMBER				0x03
+
+#define AST_PRES_RESTRICTION				0x60
+#define AST_PRES_ALLOWED				0x00
+#define AST_PRES_RESTRICTED				0x20
+#define AST_PRES_UNAVAILABLE				0x40
+#define AST_PRES_RESERVED				0x60
+
+#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED \
+	AST_PRES_USER_NUMBER_UNSCREENED + AST_PRES_ALLOWED
+
+#define AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN \
+	AST_PRES_USER_NUMBER_PASSED_SCREEN + AST_PRES_ALLOWED
+
+#define AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN \
+	AST_PRES_USER_NUMBER_FAILED_SCREEN + AST_PRES_ALLOWED
+
+#define AST_PRES_ALLOWED_NETWORK_NUMBER	\
+	AST_PRES_NETWORK_NUMBER + AST_PRES_ALLOWED
+
+#define AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED \
+	AST_PRES_USER_NUMBER_UNSCREENED + AST_PRES_RESTRICTED
+
+#define AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN \
+	AST_PRES_USER_NUMBER_PASSED_SCREEN + AST_PRES_RESTRICTED
+
+#define AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN \
+	AST_PRES_USER_NUMBER_FAILED_SCREEN + AST_PRES_RESTRICTED
+
+#define AST_PRES_PROHIB_NETWORK_NUMBER \
+	AST_PRES_NETWORK_NUMBER + AST_PRES_RESTRICTED
+
+#define AST_PRES_NUMBER_NOT_AVAILABLE \
+	AST_PRES_NETWORK_NUMBER + AST_PRES_UNAVAILABLE
+
+int ast_parse_caller_presentation(const char *data);
+const char *ast_describe_caller_presentation(int data);
 
 #endif
-- 
GitLab