summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-04-20 00:57:13 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-04-20 00:57:13 +0000
commit73f48997f90eda77c56fdefbf5f1e3346d2f86a7 (patch)
tree9a919c0fb4d0188db743e9b4e6c31f414305c993
parent92ca507d72d96313fb834269db0e19ea28eff37a (diff)
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
-rw-r--r--CHANGES2
-rw-r--r--UPGRADE.txt2
-rw-r--r--channels/sig_pri.c21
-rw-r--r--funcs/func_callerid.c99
-rw-r--r--include/asterisk/channel.h8
-rw-r--r--main/channel.c203
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
<function name="CALLERID" language="en_US">
@@ -239,6 +242,21 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<parameter name="datatype" required="true">
<para>The allowable datatypes are:</para>
<enumlist>
+ <enum name = "orig-all" />
+ <enum name = "orig-name" />
+ <enum name = "orig-name-valid" />
+ <enum name = "orig-name-charset" />
+ <enum name = "orig-name-pres" />
+ <enum name = "orig-num" />
+ <enum name = "orig-num-valid" />
+ <enum name = "orig-num-plan" />
+ <enum name = "orig-num-pres" />
+ <enum name = "orig-subaddr" />
+ <enum name = "orig-subaddr-valid" />
+ <enum name = "orig-subaddr-type" />
+ <enum name = "orig-subaddr-odd" />
+ <enum name = "orig-tag" />
+ <enum name = "orig-reason" />
<enum name = "from-all" />
<enum name = "from-name" />
<enum name = "from-name-valid" />
@@ -279,7 +297,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<description>
<para>Gets or sets Redirecting data on the channel.</para>
<para>The allowable values for the <replaceable>reason</replaceable>
- field are the following:</para>
+ and <replaceable>orig-reason</replaceable> fields are the following:</para>
<enumlist>
<enum name = "unknown"><para>Unknown</para></enum>
<enum name = "cfb"><para>Call Forwarding Busy</para></enum>
@@ -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;