From 73f48997f90eda77c56fdefbf5f1e3346d2f86a7 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Fri, 20 Apr 2012 00:57:13 +0000 Subject: Add original party id and reason support. ISDN ETSI PTP and Q.SIG (And SS7 in future) have support for reporting who was the original redirecting party of a call. * Added support for the original redirecting party and reason to the REDIRECTING function and the system core as well as to the stubbed locations in sig_pri.c. Review: https://reviewboard.asterisk.org/r/1829/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@362779 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 2 + UPGRADE.txt | 2 + channels/sig_pri.c | 21 +++-- funcs/func_callerid.c | 99 ++++++++++++++++++---- include/asterisk/channel.h | 8 ++ main/channel.c | 203 +++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 307 insertions(+), 28 deletions(-) diff --git a/CHANGES b/CHANGES index aa4fe6a50..067bd6cbf 100644 --- a/CHANGES +++ b/CHANGES @@ -202,6 +202,8 @@ Dialplan functions user information, such as the email address and full name. The MAILBOX_EXISTS dialplan function has been deprecated in favour of VM_INFO. + * The REDIRECTING function now supports the redirecting original party id + and reason. Followme changes ------------- diff --git a/UPGRADE.txt b/UPGRADE.txt index 289043896..adff55169 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -39,6 +39,8 @@ Dialplan Functions: line purposes use the following variables instead of their macro equivalents: REDIRECTING_SEND_SUB, REDIRECTING_SEND_SUB_ARGS, CONNECTED_LINE_SEND_SUB, CONNECTED_LINE_SEND_SUB_ARGS. + - The REDIRECTING function now supports the redirecting original party id + and reason. func_enum: diff --git a/channels/sig_pri.c b/channels/sig_pri.c index e40aa9adb..47724a8e9 100644 --- a/channels/sig_pri.c +++ b/channels/sig_pri.c @@ -902,14 +902,16 @@ static void sig_pri_party_id_from_ast(struct pri_party_id *pri_id, const struct static void sig_pri_redirecting_update(struct sig_pri_chan *pvt, struct ast_channel *ast) { struct pri_party_redirecting pri_redirecting; - -/*! \todo XXX Original called data can be put in a channel data store that is inherited. */ + const struct ast_party_redirecting *ast_redirecting; memset(&pri_redirecting, 0, sizeof(pri_redirecting)); - sig_pri_party_id_from_ast(&pri_redirecting.from, &ast_channel_redirecting(ast)->from); - sig_pri_party_id_from_ast(&pri_redirecting.to, &ast_channel_redirecting(ast)->to); - pri_redirecting.count = ast_channel_redirecting(ast)->count; - pri_redirecting.reason = ast_to_pri_reason(ast_channel_redirecting(ast)->reason); + ast_redirecting = ast_channel_redirecting(ast); + sig_pri_party_id_from_ast(&pri_redirecting.from, &ast_redirecting->from); + sig_pri_party_id_from_ast(&pri_redirecting.to, &ast_redirecting->to); + sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &ast_redirecting->orig); + pri_redirecting.count = ast_redirecting->count; + pri_redirecting.orig_reason = ast_to_pri_reason(ast_redirecting->orig_reason); + pri_redirecting.reason = ast_to_pri_reason(ast_redirecting->reason); pri_redirecting_update(pvt->pri->pri, pvt->call, &pri_redirecting); } @@ -2115,10 +2117,12 @@ static void sig_pri_redirecting_convert(struct ast_party_redirecting *ast_redire { ast_party_redirecting_set_init(ast_redirecting, ast_guide); + sig_pri_party_id_convert(&ast_redirecting->orig, &pri_redirecting->orig_called, pri); sig_pri_party_id_convert(&ast_redirecting->from, &pri_redirecting->from, pri); sig_pri_party_id_convert(&ast_redirecting->to, &pri_redirecting->to, pri); ast_redirecting->count = pri_redirecting->count; ast_redirecting->reason = pri_to_ast_reason(pri_redirecting->reason); + ast_redirecting->orig_reason = pri_to_ast_reason(pri_redirecting->orig_reason); } /*! @@ -4185,11 +4189,9 @@ static void sig_pri_handle_subcmds(struct sig_pri_span *pri, int chanpos, int ev if (owner) { sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting, ast_channel_redirecting(owner), pri); + ast_redirecting.orig.tag = ast_strdup(pri->pvts[chanpos]->user_tag); ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag); ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag); - -/*! \todo XXX Original called data can be put in a channel data store that is inherited. */ - ast_channel_set_redirecting(owner, &ast_redirecting, NULL); if (event_id != PRI_EVENT_RING) { /* This redirection was not from a SETUP message. */ @@ -4257,6 +4259,7 @@ static void sig_pri_handle_subcmds(struct sig_pri_span *pri, int chanpos, int ev } sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection, ast_channel_redirecting(owner), pri); + ast_redirecting.orig.tag = ast_strdup(pri->pvts[chanpos]->user_tag); ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag); ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag); ast_channel_set_redirecting(owner, &ast_redirecting, NULL); diff --git a/funcs/func_callerid.c b/funcs/func_callerid.c index 067628353..f15e3676f 100644 --- a/funcs/func_callerid.c +++ b/funcs/func_callerid.c @@ -69,13 +69,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") * they are active at the same time. The plain pres option will simply * live on as a historical relic. * - * Do not document the REDIRECTING(from-pres) or REDIRECTING(to-pres) datatypes. - * The name and number now have their own presentation value. The from-pres - * and to-pres options will simply live on as a historical relic with as best - * as can be managed backward compatible meaning. + * Do not document the REDIRECTING(orig-pres), REDIRECTING(from-pres), + * or REDIRECTING(to-pres) datatypes. + * The name and number now have their own presentation value. The orig-pres, + * from-pres, and to-pres options will simply live on as a historical relic + * with as best as can be managed backward compatible meaning. * - * Do not document the REDIRECTING(from-ton) or REDIRECTING(to-ton) datatypes. - * They are aliases for from-num-plan and to-num-plan respectively. + * Do not document the REDIRECTING(orig-ton), REDIRECTING(from-ton), + * or REDIRECTING(to-ton) datatypes. + * They are aliases for orig-num-plan, from-num-plan, and to-num-plan + * respectively. */ /*** DOCUMENTATION @@ -239,6 +242,21 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") The allowable datatypes are: + + + + + + + + + + + + + + + @@ -279,7 +297,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") Gets or sets Redirecting data on the channel. The allowable values for the reason - field are the following: + and orig-reason fields are the following: Unknown Call Forwarding Busy @@ -1330,6 +1348,7 @@ static int redirecting_read(struct ast_channel *chan, const char *cmd, char *dat { struct ast_party_members member; char *read_what; + const struct ast_party_redirecting *ast_redirecting; enum ID_FIELD_STATUS status; /* Ensure that the buffer is empty */ @@ -1348,9 +1367,26 @@ static int redirecting_read(struct ast_channel *chan, const char *cmd, char *dat ast_channel_lock(chan); - if (!strcasecmp("from", member.argv[0])) { + ast_redirecting = ast_channel_redirecting(chan); + if (!strcasecmp("orig", member.argv[0])) { + if (member.argc == 2 && !strcasecmp("reason", member.argv[1])) { + ast_copy_string(buf, + ast_redirecting_reason_name(ast_redirecting->orig_reason), len); + } else { + status = party_id_read(buf, len, member.argc - 1, member.argv + 1, + &ast_redirecting->orig); + switch (status) { + case ID_FIELD_VALID: + case ID_FIELD_INVALID: + break; + default: + ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data); + break; + } + } + } else if (!strcasecmp("from", member.argv[0])) { status = party_id_read(buf, len, member.argc - 1, member.argv + 1, - &ast_channel_redirecting(chan)->from); + &ast_redirecting->from); switch (status) { case ID_FIELD_VALID: case ID_FIELD_INVALID: @@ -1361,7 +1397,7 @@ static int redirecting_read(struct ast_channel *chan, const char *cmd, char *dat } } else if (!strcasecmp("to", member.argv[0])) { status = party_id_read(buf, len, member.argc - 1, member.argv + 1, - &ast_channel_redirecting(chan)->to); + &ast_redirecting->to); switch (status) { case ID_FIELD_VALID: case ID_FIELD_INVALID: @@ -1377,11 +1413,11 @@ static int redirecting_read(struct ast_channel *chan, const char *cmd, char *dat */ ast_copy_string(buf, ast_named_caller_presentation( - ast_party_id_presentation(&ast_channel_redirecting(chan)->from)), len); + ast_party_id_presentation(&ast_redirecting->from)), len); } else if (member.argc == 1 && !strcasecmp("reason", member.argv[0])) { - ast_copy_string(buf, ast_redirecting_reason_name(ast_channel_redirecting(chan)->reason), len); + ast_copy_string(buf, ast_redirecting_reason_name(ast_redirecting->reason), len); } else if (member.argc == 1 && !strcasecmp("count", member.argv[0])) { - snprintf(buf, len, "%d", ast_channel_redirecting(chan)->count); + snprintf(buf, len, "%d", ast_redirecting->count); } else { ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data); } @@ -1450,7 +1486,42 @@ static int redirecting_write(struct ast_channel *chan, const char *cmd, char *da value = ast_skip_blanks(value); - if (!strcasecmp("from", member.argv[0])) { + if (!strcasecmp("orig", member.argv[0])) { + if (member.argc == 2 && !strcasecmp("reason", member.argv[1])) { + int reason; + + val = ast_strdupa(value); + ast_trim_blanks(val); + + if (('0' <= val[0]) && (val[0] <= '9')) { + reason = atoi(val); + } else { + reason = ast_redirecting_reason_parse(val); + } + + if (reason < 0) { + ast_log(LOG_ERROR, + "Unknown redirecting orig reason '%s', value unchanged\n", val); + } else { + redirecting.orig_reason = reason; + set_it(chan, &redirecting, NULL); + } + } else { + status = party_id_write(&redirecting.orig, member.argc - 1, member.argv + 1, + value); + switch (status) { + case ID_FIELD_VALID: + set_it(chan, &redirecting, NULL); + break; + case ID_FIELD_INVALID: + break; + default: + ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data); + break; + } + ast_party_redirecting_free(&redirecting); + } + } else if (!strcasecmp("from", member.argv[0])) { status = party_id_write(&redirecting.from, member.argc - 1, member.argv + 1, value); switch (status) { diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 54faa1d51..ab6c736ed 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -449,6 +449,9 @@ struct ast_set_party_connected_line { * \note NULL and "" must be considered equivalent. */ struct ast_party_redirecting { + /*! \brief Who originally redirected the call (Sent to the party the call is redirected toward) */ + struct ast_party_id orig; + /*! \brief Who is redirecting the call (Sent to the party the call is redirected toward) */ struct ast_party_id from; @@ -460,6 +463,9 @@ struct ast_party_redirecting { /*! \brief enum AST_REDIRECTING_REASON value for redirection */ int reason; + + /*! \brief enum AST_REDIRECTING_REASON value for redirection by original party */ + int orig_reason; }; /*! @@ -467,6 +473,8 @@ struct ast_party_redirecting { * \brief Indicate what information in ast_party_redirecting should be set. */ struct ast_set_party_redirecting { + /*! What redirecting-orig id information to set. */ + struct ast_set_party_id orig; /*! What redirecting-from id information to set. */ struct ast_set_party_id from; /*! What redirecting-to id information to set. */ diff --git a/main/channel.c b/main/channel.c index 5f549f379..13ebdad96 100644 --- a/main/channel.c +++ b/main/channel.c @@ -2118,10 +2118,12 @@ void ast_party_connected_line_free(struct ast_party_connected_line *doomed) void ast_party_redirecting_init(struct ast_party_redirecting *init) { + ast_party_id_init(&init->orig); ast_party_id_init(&init->from); ast_party_id_init(&init->to); 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) @@ -2131,30 +2133,37 @@ void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct return; } + ast_party_id_copy(&dest->orig, &src->orig); ast_party_id_copy(&dest->from, &src->from); ast_party_id_copy(&dest->to, &src->to); 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) { + ast_party_id_set_init(&init->orig, &guide->orig); ast_party_id_set_init(&init->from, &guide->from); ast_party_id_set_init(&init->to, &guide->to); 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) { + ast_party_id_set(&dest->orig, &src->orig, update ? &update->orig : NULL); ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL); ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL); - dest->reason = src->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) { + ast_party_id_free(&doomed->orig); ast_party_id_free(&doomed->from); ast_party_id_free(&doomed->to); } @@ -8436,7 +8445,10 @@ struct ast_party_id_ies { struct ast_party_subaddress_ies subaddress; /*! \brief User party id tag ie. */ int tag; - /*! \brief Combined name and number presentation ie. */ + /*! + * \brief Combined name and number presentation ie. + * \note Not sent if value is zero. + */ int combined_presentation; }; @@ -8509,7 +8521,7 @@ static int party_id_build_data(unsigned char *data, size_t datalen, } /* *************** Party id combined presentation *************** */ - if (!update || update->number) { + if (ies->combined_presentation && (!update || update->number)) { int presentation; if (!update || update->name) { @@ -8551,6 +8563,10 @@ enum { AST_CONNECTED_LINE_SUBADDRESS_VALID, AST_CONNECTED_LINE_TAG, AST_CONNECTED_LINE_VERSION, + /* + * No more party id combined number and name presentation values + * need to be created. + */ AST_CONNECTED_LINE_NAME_VALID, AST_CONNECTED_LINE_NAME_CHAR_SET, AST_CONNECTED_LINE_NAME_PRESENTATION, @@ -8864,11 +8880,11 @@ enum { AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NUMBER_PLAN, - AST_REDIRECTING_FROM_ID_PRESENTATION, + AST_REDIRECTING_FROM_ID_PRESENTATION,/* Combined number and name presentation. */ AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NUMBER_PLAN, - AST_REDIRECTING_TO_ID_PRESENTATION, + AST_REDIRECTING_TO_ID_PRESENTATION,/* Combined number and name presentation. */ AST_REDIRECTING_REASON, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_SUBADDRESS, @@ -8882,6 +8898,10 @@ enum { AST_REDIRECTING_FROM_TAG, AST_REDIRECTING_TO_TAG, AST_REDIRECTING_VERSION, + /* + * No more party id combined number and name presentation values + * need to be created. + */ AST_REDIRECTING_FROM_NAME_VALID, AST_REDIRECTING_FROM_NAME_CHAR_SET, AST_REDIRECTING_FROM_NAME_PRESENTATION, @@ -8892,6 +8912,20 @@ enum { AST_REDIRECTING_TO_NAME_PRESENTATION, AST_REDIRECTING_TO_NUMBER_VALID, AST_REDIRECTING_TO_NUMBER_PRESENTATION, + AST_REDIRECTING_ORIG_NUMBER, + AST_REDIRECTING_ORIG_NUMBER_VALID, + AST_REDIRECTING_ORIG_NUMBER_PLAN, + AST_REDIRECTING_ORIG_NUMBER_PRESENTATION, + AST_REDIRECTING_ORIG_NAME, + AST_REDIRECTING_ORIG_NAME_VALID, + AST_REDIRECTING_ORIG_NAME_CHAR_SET, + AST_REDIRECTING_ORIG_NAME_PRESENTATION, + AST_REDIRECTING_ORIG_SUBADDRESS, + AST_REDIRECTING_ORIG_SUBADDRESS_TYPE, + AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN, + AST_REDIRECTING_ORIG_SUBADDRESS_VALID, + AST_REDIRECTING_ORIG_TAG, + AST_REDIRECTING_ORIG_REASON, }; int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update) @@ -8900,6 +8934,25 @@ int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct size_t pos = 0; int res; + static const struct ast_party_id_ies orig_ies = { + .name.str = AST_REDIRECTING_ORIG_NAME, + .name.char_set = AST_REDIRECTING_ORIG_NAME_CHAR_SET, + .name.presentation = AST_REDIRECTING_ORIG_NAME_PRESENTATION, + .name.valid = AST_REDIRECTING_ORIG_NAME_VALID, + + .number.str = AST_REDIRECTING_ORIG_NUMBER, + .number.plan = AST_REDIRECTING_ORIG_NUMBER_PLAN, + .number.presentation = AST_REDIRECTING_ORIG_NUMBER_PRESENTATION, + .number.valid = AST_REDIRECTING_ORIG_NUMBER_VALID, + + .subaddress.str = AST_REDIRECTING_ORIG_SUBADDRESS, + .subaddress.type = AST_REDIRECTING_ORIG_SUBADDRESS_TYPE, + .subaddress.odd_even_indicator = AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN, + .subaddress.valid = AST_REDIRECTING_ORIG_SUBADDRESS_VALID, + + .tag = AST_REDIRECTING_ORIG_TAG, + .combined_presentation = 0,/* Not sent. */ + }; static const struct ast_party_id_ies from_ies = { .name.str = AST_REDIRECTING_FROM_NAME, .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET, @@ -8948,6 +9001,13 @@ int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct data[pos++] = 1; data[pos++] = 2;/* Version 1 did not have a version ie */ + res = party_id_build_data(data + pos, datalen - pos, &redirecting->orig, + "redirecting-orig", &orig_ies, update ? &update->orig : NULL); + if (res < 0) { + return -1; + } + pos += res; + res = party_id_build_data(data + pos, datalen - pos, &redirecting->from, "redirecting-from", &from_ies, update ? &update->from : NULL); if (res < 0) { @@ -8973,6 +9033,17 @@ int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct memcpy(data + pos, &value, sizeof(value)); pos += sizeof(value); + /* Redirecting original reason */ + if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { + ast_log(LOG_WARNING, "No space left for redirecting original reason\n"); + 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); + /* Redirecting count */ if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) { ast_log(LOG_WARNING, "No space left for redirecting count\n"); @@ -9021,6 +9092,115 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct } frame_version = data[pos]; break; +/* Redirecting-orig party id name */ + case AST_REDIRECTING_ORIG_NAME: + ast_free(redirecting->orig.name.str); + redirecting->orig.name.str = ast_malloc(ie_len + 1); + if (redirecting->orig.name.str) { + memcpy(redirecting->orig.name.str, data + pos, ie_len); + redirecting->orig.name.str[ie_len] = 0; + } + break; + case AST_REDIRECTING_ORIG_NAME_CHAR_SET: + if (ie_len != 1) { + ast_log(LOG_WARNING, "Invalid redirecting-orig name char set (%u)\n", + (unsigned) ie_len); + break; + } + redirecting->orig.name.char_set = data[pos]; + break; + case AST_REDIRECTING_ORIG_NAME_PRESENTATION: + if (ie_len != 1) { + ast_log(LOG_WARNING, "Invalid redirecting-orig name presentation (%u)\n", + (unsigned) ie_len); + break; + } + redirecting->orig.name.presentation = data[pos]; + break; + case AST_REDIRECTING_ORIG_NAME_VALID: + if (ie_len != 1) { + ast_log(LOG_WARNING, "Invalid redirecting-orig name valid (%u)\n", + (unsigned) ie_len); + break; + } + redirecting->orig.name.valid = data[pos]; + break; +/* Redirecting-orig party id number */ + case AST_REDIRECTING_ORIG_NUMBER: + ast_free(redirecting->orig.number.str); + redirecting->orig.number.str = ast_malloc(ie_len + 1); + if (redirecting->orig.number.str) { + memcpy(redirecting->orig.number.str, data + pos, ie_len); + redirecting->orig.number.str[ie_len] = 0; + } + break; + case AST_REDIRECTING_ORIG_NUMBER_PLAN: + if (ie_len != 1) { + ast_log(LOG_WARNING, "Invalid redirecting-orig numbering plan (%u)\n", + (unsigned) ie_len); + break; + } + redirecting->orig.number.plan = data[pos]; + break; + case AST_REDIRECTING_ORIG_NUMBER_PRESENTATION: + if (ie_len != 1) { + ast_log(LOG_WARNING, "Invalid redirecting-orig number presentation (%u)\n", + (unsigned) ie_len); + break; + } + redirecting->orig.number.presentation = data[pos]; + break; + case AST_REDIRECTING_ORIG_NUMBER_VALID: + if (ie_len != 1) { + ast_log(LOG_WARNING, "Invalid redirecting-orig number valid (%u)\n", + (unsigned) ie_len); + break; + } + redirecting->orig.number.valid = data[pos]; + break; +/* Redirecting-orig party id subaddress */ + case AST_REDIRECTING_ORIG_SUBADDRESS: + ast_free(redirecting->orig.subaddress.str); + redirecting->orig.subaddress.str = ast_malloc(ie_len + 1); + if (redirecting->orig.subaddress.str) { + memcpy(redirecting->orig.subaddress.str, data + pos, ie_len); + redirecting->orig.subaddress.str[ie_len] = 0; + } + break; + case AST_REDIRECTING_ORIG_SUBADDRESS_TYPE: + if (ie_len != 1) { + ast_log(LOG_WARNING, "Invalid redirecting-orig type of subaddress (%u)\n", + (unsigned) ie_len); + break; + } + redirecting->orig.subaddress.type = data[pos]; + break; + case AST_REDIRECTING_ORIG_SUBADDRESS_ODD_EVEN: + if (ie_len != 1) { + ast_log(LOG_WARNING, + "Invalid redirecting-orig subaddress odd-even indicator (%u)\n", + (unsigned) ie_len); + break; + } + redirecting->orig.subaddress.odd_even_indicator = data[pos]; + break; + case AST_REDIRECTING_ORIG_SUBADDRESS_VALID: + if (ie_len != 1) { + ast_log(LOG_WARNING, "Invalid redirecting-orig subaddress valid (%u)\n", + (unsigned) ie_len); + break; + } + redirecting->orig.subaddress.valid = data[pos]; + break; +/* Redirecting-orig party id tag */ + case AST_REDIRECTING_ORIG_TAG: + ast_free(redirecting->orig.tag); + redirecting->orig.tag = ast_malloc(ie_len + 1); + if (redirecting->orig.tag) { + memcpy(redirecting->orig.tag, data + pos, ie_len); + redirecting->orig.tag[ie_len] = 0; + } + break; /* Redirecting-from party id name */ case AST_REDIRECTING_FROM_NAME: ast_free(redirecting->from.name.str); @@ -9269,6 +9449,16 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct memcpy(&value, data + pos, sizeof(value)); redirecting->reason = ntohl(value); break; +/* Redirecting orig-reason */ + case AST_REDIRECTING_ORIG_REASON: + 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); + break; /* Redirecting count */ case AST_REDIRECTING_COUNT: if (ie_len != sizeof(value)) { @@ -9292,6 +9482,9 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct /* * The other end is an earlier version that we need to adjust * for compatibility. + * + * The earlier version did not have the orig party id or + * orig_reason value. */ redirecting->from.name.valid = 1; redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1; -- cgit v1.2.3