summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
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: