diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/callerid.c | 9 | ||||
-rw-r--r-- | main/channel.c | 166 |
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: |