summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2012-09-25 19:29:14 +0000
committerMark Michelson <mmichelson@digium.com>2012-09-25 19:29:14 +0000
commitfdfb3ae5faac680bf939eea1312919bee14db76f (patch)
tree75907425ac9b850412fae5bc7b7e6d89e1aa19e1 /main
parentb7233b18ebd9ce2f8f4bad1309fbe33edaf44e44 (diff)
Allow for redirecting reasons to be set to arbitrary strings.
This allows for the REDIRECTING dialplan function to be used to set the reason to any string. The SIP channel driver has been modified to set the redirecting reason string to the value received in a Diversion header. In addition, SIP 480 response reason text will set the redirecting reason as well. (closes issue AST-942) reported by Malcolm Davenport (closes issue AST-943) reported by Malcolm Davenport Review: https://reviewboard.asterisk.org/r/2101 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@373701 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/callerid.c9
-rw-r--r--main/channel.c166
2 files changed, 143 insertions, 32 deletions
diff --git a/main/callerid.c b/main/callerid.c
index d9f74180a..db5e795ff 100644
--- a/main/callerid.c
+++ b/main/callerid.c
@@ -1237,12 +1237,17 @@ const char *ast_redirecting_reason_describe(int data)
return "not-known";
}
-const char *ast_redirecting_reason_name(int data)
+const char *ast_redirecting_reason_name(const struct ast_party_redirecting_reason *data)
{
int index;
+ if (!ast_strlen_zero(data->str)) {
+ /* Use this string if it has been set. Otherwise, use the table. */
+ return data->str;
+ }
+
for (index = 0; index < ARRAY_LEN(redirecting_reason_types); ++index) {
- if (redirecting_reason_types[index].value == data) {
+ if (redirecting_reason_types[index].value == data->code) {
return redirecting_reason_types[index].name;
}
}
diff --git a/main/channel.c b/main/channel.c
index dbc4703b5..751cbdd52 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -2235,6 +2235,49 @@ void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
ast_party_id_free(&doomed->priv);
}
+void ast_party_redirecting_reason_init(struct ast_party_redirecting_reason *init)
+{
+ init->str = NULL;
+ init->code = AST_REDIRECTING_REASON_UNKNOWN;
+}
+
+void ast_party_redirecting_reason_copy(struct ast_party_redirecting_reason *dest, const struct ast_party_redirecting_reason *src)
+{
+ if (dest == src) {
+ return;
+ }
+
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ dest->code = src->code;
+}
+
+void ast_party_redirecting_reason_set_init(struct ast_party_redirecting_reason *init, const struct ast_party_redirecting_reason *guide)
+{
+ init->str = NULL;
+ init->code = guide->code;
+}
+
+void ast_party_redirecting_reason_set(struct ast_party_redirecting_reason *dest, const struct ast_party_redirecting_reason *src)
+{
+ if (dest == src) {
+ return;
+ }
+
+ if (src->str && src->str != dest->str) {
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ }
+
+ dest->code = src->code;
+}
+
+void ast_party_redirecting_reason_free(struct ast_party_redirecting_reason *doomed)
+{
+ ast_free(doomed->str);
+}
+
+
void ast_party_redirecting_init(struct ast_party_redirecting *init)
{
ast_party_id_init(&init->orig);
@@ -2243,9 +2286,9 @@ void ast_party_redirecting_init(struct ast_party_redirecting *init)
ast_party_id_init(&init->priv_orig);
ast_party_id_init(&init->priv_from);
ast_party_id_init(&init->priv_to);
+ ast_party_redirecting_reason_init(&init->reason);
+ ast_party_redirecting_reason_init(&init->orig_reason);
init->count = 0;
- init->reason = AST_REDIRECTING_REASON_UNKNOWN;
- init->orig_reason = AST_REDIRECTING_REASON_UNKNOWN;
}
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
@@ -2261,9 +2304,9 @@ void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct
ast_party_id_copy(&dest->priv_orig, &src->priv_orig);
ast_party_id_copy(&dest->priv_from, &src->priv_from);
ast_party_id_copy(&dest->priv_to, &src->priv_to);
+ ast_party_redirecting_reason_copy(&dest->reason, &src->reason);
+ ast_party_redirecting_reason_copy(&dest->orig_reason, &src->orig_reason);
dest->count = src->count;
- dest->reason = src->reason;
- dest->orig_reason = src->orig_reason;
}
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
@@ -2274,9 +2317,9 @@ void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const st
ast_party_id_set_init(&init->priv_orig, &guide->priv_orig);
ast_party_id_set_init(&init->priv_from, &guide->priv_from);
ast_party_id_set_init(&init->priv_to, &guide->priv_to);
+ ast_party_redirecting_reason_set_init(&init->reason, &guide->reason);
+ ast_party_redirecting_reason_set_init(&init->orig_reason, &guide->orig_reason);
init->count = guide->count;
- init->reason = guide->reason;
- init->orig_reason = guide->orig_reason;
}
void ast_party_redirecting_set(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src, const struct ast_set_party_redirecting *update)
@@ -2287,9 +2330,9 @@ void ast_party_redirecting_set(struct ast_party_redirecting *dest, const struct
ast_party_id_set(&dest->priv_orig, &src->priv_orig, update ? &update->priv_orig : NULL);
ast_party_id_set(&dest->priv_from, &src->priv_from, update ? &update->priv_from : NULL);
ast_party_id_set(&dest->priv_to, &src->priv_to, update ? &update->priv_to : NULL);
+ ast_party_redirecting_reason_set(&dest->reason, &src->reason);
+ ast_party_redirecting_reason_set(&dest->orig_reason, &src->orig_reason);
dest->count = src->count;
- dest->reason = src->reason;
- dest->orig_reason = src->orig_reason;
}
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
@@ -2300,6 +2343,8 @@ void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
ast_party_id_free(&doomed->priv_orig);
ast_party_id_free(&doomed->priv_from);
ast_party_id_free(&doomed->priv_to);
+ ast_party_redirecting_reason_free(&doomed->reason);
+ ast_party_redirecting_reason_free(&doomed->orig_reason);
}
/*! \brief Free a channel structure */
@@ -9616,7 +9661,7 @@ enum {
AST_REDIRECTING_TO_NAME,
AST_REDIRECTING_TO_NUMBER_PLAN,
AST_REDIRECTING_TO_ID_PRESENTATION,/* Combined number and name presentation. */
- AST_REDIRECTING_REASON,
+ AST_REDIRECTING_REASON_CODE,
AST_REDIRECTING_COUNT,
AST_REDIRECTING_FROM_SUBADDRESS,
AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
@@ -9656,7 +9701,7 @@ enum {
AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN,
AST_REDIRECTING_ORIG_SUBADDRESS_VALID,
AST_REDIRECTING_ORIG_TAG,
- AST_REDIRECTING_ORIG_REASON,
+ AST_REDIRECTING_ORIG_REASON_CODE,
AST_REDIRECTING_PRIV_TO_NUMBER,
AST_REDIRECTING_PRIV_TO_NUMBER_PLAN,
AST_REDIRECTING_PRIV_TO_NUMBER_VALID,
@@ -9696,8 +9741,48 @@ enum {
AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN,
AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID,
AST_REDIRECTING_PRIV_ORIG_TAG,
+ AST_REDIRECTING_REASON_STR,
+ AST_REDIRECTING_ORIG_REASON_STR,
};
+struct ast_party_redirecting_reason_ies {
+ int code;
+ int str;
+};
+
+static int redirecting_reason_build_data(unsigned char *data, size_t datalen,
+ const struct ast_party_redirecting_reason *reason, const char *label,
+ const struct ast_party_redirecting_reason_ies *ies)
+{
+ size_t length;
+ size_t pos = 0;
+ int32_t value;
+
+ if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
+ ast_log(LOG_WARNING, "No space left for %s code\n", label);
+ return -1;
+ }
+ data[pos++] = ies->code;
+ data[pos++] = sizeof(value);
+ value = htonl(reason->code);
+ memcpy(data + pos, &value, sizeof(value));
+ pos += sizeof(value);
+
+ if (reason->str) {
+ length = strlen(reason->str);
+ if (datalen < pos + sizeof(data[0] * 2) + length) {
+ ast_log(LOG_WARNING, "No space left for %s string\n", label);
+ return -1;
+ }
+ data[pos++] = ies->str;
+ data[pos++] = length;
+ memcpy(data + pos, reason->str, length);
+ pos += length;
+ }
+
+ return pos;
+}
+
int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
{
int32_t value;
@@ -9818,6 +9903,15 @@ int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct
.tag = AST_REDIRECTING_PRIV_TO_TAG,
.combined_presentation = 0,/* Not sent. */
};
+ static const struct ast_party_redirecting_reason_ies reason_ies = {
+ .code = AST_REDIRECTING_REASON_CODE,
+ .str = AST_REDIRECTING_REASON_STR,
+ };
+
+ static const struct ast_party_redirecting_reason_ies orig_reason_ies = {
+ .code = AST_REDIRECTING_ORIG_REASON_CODE,
+ .str = AST_REDIRECTING_ORIG_REASON_STR,
+ };
/* Redirecting frame version */
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
@@ -9871,26 +9965,20 @@ int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct
pos += res;
/* Redirecting reason */
- if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
- ast_log(LOG_WARNING, "No space left for redirecting reason\n");
+ res = redirecting_reason_build_data(data + pos, datalen - pos, &redirecting->reason,
+ "redirecting-reason", &reason_ies);
+ if (res < 0) {
return -1;
}
- data[pos++] = AST_REDIRECTING_REASON;
- data[pos++] = sizeof(value);
- value = htonl(redirecting->reason);
- memcpy(data + pos, &value, sizeof(value));
- pos += sizeof(value);
+ pos += res;
/* Redirecting original reason */
- if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
- ast_log(LOG_WARNING, "No space left for redirecting original reason\n");
+ res = redirecting_reason_build_data(data + pos, datalen - pos, &redirecting->orig_reason,
+ "redirecting-orig-reason", &orig_reason_ies);
+ if (res < 0) {
return -1;
}
- data[pos++] = AST_REDIRECTING_ORIG_REASON;
- data[pos++] = sizeof(value);
- value = htonl(redirecting->orig_reason);
- memcpy(data + pos, &value, sizeof(value));
- pos += sizeof(value);
+ pos += res;
/* Redirecting count */
if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
@@ -10614,25 +10702,43 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
redirecting->priv_to.tag[ie_len] = 0;
}
break;
-/* Redirecting reason */
- case AST_REDIRECTING_REASON:
+/* Redirecting reason code */
+ case AST_REDIRECTING_REASON_CODE:
if (ie_len != sizeof(value)) {
ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
(unsigned) ie_len);
break;
}
memcpy(&value, data + pos, sizeof(value));
- redirecting->reason = ntohl(value);
+ redirecting->reason.code = ntohl(value);
break;
-/* Redirecting orig-reason */
- case AST_REDIRECTING_ORIG_REASON:
+/* Redirecting reason string */
+ case AST_REDIRECTING_REASON_STR:
+ ast_free(redirecting->reason.str);
+ redirecting->reason.str = ast_malloc(ie_len + 1);
+ if (redirecting->reason.str) {
+ memcpy(redirecting->reason.str, data + pos, ie_len);
+ redirecting->reason.str[ie_len] = 0;
+ }
+ break;
+/* Redirecting orig-reason code */
+ case AST_REDIRECTING_ORIG_REASON_CODE:
if (ie_len != sizeof(value)) {
ast_log(LOG_WARNING, "Invalid redirecting original reason (%u)\n",
(unsigned) ie_len);
break;
}
memcpy(&value, data + pos, sizeof(value));
- redirecting->orig_reason = ntohl(value);
+ redirecting->orig_reason.code = ntohl(value);
+ break;
+/* Redirecting orig-reason string */
+ case AST_REDIRECTING_ORIG_REASON_STR:
+ ast_free(redirecting->orig_reason.str);
+ redirecting->orig_reason.str = ast_malloc(ie_len + 1);
+ if (redirecting->orig_reason.str) {
+ memcpy(redirecting->orig_reason.str, data + pos, ie_len);
+ redirecting->orig_reason.str[ie_len] = 0;
+ }
break;
/* Redirecting count */
case AST_REDIRECTING_COUNT: