summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2010-07-14 15:48:36 +0000
committerRichard Mudgett <rmudgett@digium.com>2010-07-14 15:48:36 +0000
commitec37ffbdaf4c8e9c134efd4e1fe7fd8bd72632ed (patch)
tree84df3fc1c9db428d5833e3eed3908a71e32cd513 /main
parent608be652ba9e9a8a677f5a6142dbb2f84fde3401 (diff)
ast_callerid restructuring
The purpose of this patch is to eliminate struct ast_callerid since it has turned into a miscellaneous collection of various party information. Eliminate struct ast_callerid and replace it with the following struct organization: struct ast_party_name { char *str; int char_set; int presentation; unsigned char valid; }; struct ast_party_number { char *str; int plan; int presentation; unsigned char valid; }; struct ast_party_subaddress { char *str; int type; unsigned char odd_even_indicator; unsigned char valid; }; struct ast_party_id { struct ast_party_name name; struct ast_party_number number; struct ast_party_subaddress subaddress; char *tag; }; struct ast_party_dialed { struct { char *str; int plan; } number; struct ast_party_subaddress subaddress; int transit_network_select; }; struct ast_party_caller { struct ast_party_id id; char *ani; int ani2; }; The new organization adds some new information as well. * The party name and number now have their own presentation value that can be manipulated independently. ISDN supplies the presentation value for the name and number at different times with the possibility that they could be different. * The party name and number now have a valid flag. Before this change the name or number string could be empty if the presentation were restricted. Most channel drivers assume that the name or number is then simply not available instead of indicating that the name or number was restricted. * The party name now has a character set value. SIP and Q.SIG have the ability to indicate what character set a name string is using so it could be presented properly. * The dialed party now has a numbering plan value that could be useful to have available. The various channel drivers will need to be updated to support the new core features as needed. They have simply been converted to supply current functionality at this time. The following items of note were either corrected or enhanced: * The CONNECTEDLINE() and REDIRECTING() dialplan functions were consolidated into func_callerid.c to share party id handling code. * CALLERPRES() is now deprecated because the name and number have their own presentation values. * Fixed app_alarmreceiver.c write_metadata(). The workstring[] could contain garbage. It also can only contain the caller id number so using ast_callerid_parse() on it is silly. There was also a typo in the CALLERNAME if test. * Fixed app_rpt.c using ast_callerid_parse() on the channel's caller id number string. ast_callerid_parse() alters the given buffer which in this case is the channel's caller id number string. Then using ast_shrink_phone_number() could alter it even more. * Fixed caller ID name and number memory leak in chan_usbradio.c. * Fixed uninitialized char arrays cid_num[] and cid_name[] in sig_analog.c. * Protected access to a caller channel with lock in chan_sip.c. * Clarified intent of code in app_meetme.c sla_ring_station() and dial_trunk(). Also made save all caller ID data instead of just the name and number strings. * Simplified cdr.c set_one_cid(). It hand coded the ast_callerid_merge() function. * Corrected some weirdness with app_privacy.c's use of caller presentation. Review: https://reviewboard.asterisk.org/r/702/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@276347 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/app.c6
-rw-r--r--main/callerid.c55
-rw-r--r--main/ccss.c8
-rw-r--r--main/cdr.c31
-rw-r--r--main/cel.c64
-rw-r--r--main/channel.c1943
-rw-r--r--main/cli.c10
-rw-r--r--main/dial.c4
-rw-r--r--main/features.c105
-rw-r--r--main/file.c3
-rw-r--r--main/manager.c11
-rw-r--r--main/pbx.c105
12 files changed, 1492 insertions, 853 deletions
diff --git a/main/app.c b/main/app.c
index 050c4e238..e6ca51483 100644
--- a/main/app.c
+++ b/main/app.c
@@ -105,13 +105,15 @@ int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect,
break;
}
collect[x++] = res;
- if (!ast_matchmore_extension(chan, context, collect, 1, chan->cid.cid_num)) {
+ if (!ast_matchmore_extension(chan, context, collect, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
break;
}
}
if (res >= 0) {
- res = ast_exists_extension(chan, context, collect, 1, chan->cid.cid_num) ? 1 : 0;
+ res = ast_exists_extension(chan, context, collect, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)) ? 1 : 0;
}
return res;
diff --git a/main/callerid.c b/main/callerid.c
index 17d265ed1..ac8fbde8b 100644
--- a/main/callerid.c
+++ b/main/callerid.c
@@ -1282,3 +1282,58 @@ const char *ast_connected_line_source_name(int data)
return "not-known";
}
+
+/*! \brief Translation table for ast_party_name char-set settings */
+static const struct ast_value_translation party_name_charset_tbl[] = {
+/* *INDENT-OFF* */
+ { AST_PARTY_CHAR_SET_UNKNOWN, "unknown", "Unknown" },
+ { AST_PARTY_CHAR_SET_ISO8859_1, "iso8859-1", "ISO8859-1" },
+ { AST_PARTY_CHAR_SET_WITHDRAWN, "withdrawn", "Withdrawn" },
+ { AST_PARTY_CHAR_SET_ISO8859_2, "iso8859-2", "ISO8859-2" },
+ { AST_PARTY_CHAR_SET_ISO8859_3, "iso8859-3", "ISO8859-3" },
+ { AST_PARTY_CHAR_SET_ISO8859_4, "iso8859-4", "ISO8859-4" },
+ { AST_PARTY_CHAR_SET_ISO8859_5, "iso8859-5", "ISO8859-5" },
+ { AST_PARTY_CHAR_SET_ISO8859_7, "iso8859-7", "ISO8859-7" },
+ { AST_PARTY_CHAR_SET_ISO10646_BMPSTRING, "bmp", "ISO10646 Bmp String" },
+ { AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING, "utf8", "ISO10646 UTF-8 String" },
+/* *INDENT-ON* */
+};
+
+int ast_party_name_charset_parse(const char *data)
+{
+ int index;
+
+ for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
+ if (!strcasecmp(party_name_charset_tbl[index].name, data)) {
+ return party_name_charset_tbl[index].value;
+ }
+ }
+
+ return -1;
+}
+
+const char *ast_party_name_charset_describe(int data)
+{
+ int index;
+
+ for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
+ if (party_name_charset_tbl[index].value == data) {
+ return party_name_charset_tbl[index].description;
+ }
+ }
+
+ return "not-known";
+}
+
+const char *ast_party_name_charset_str(int data)
+{
+ int index;
+
+ for (index = 0; index < ARRAY_LEN(party_name_charset_tbl); ++index) {
+ if (party_name_charset_tbl[index].value == data) {
+ return party_name_charset_tbl[index].name;
+ }
+ }
+
+ return "not-known";
+}
diff --git a/main/ccss.c b/main/ccss.c
index efdcbb17f..2cf828470 100644
--- a/main/ccss.c
+++ b/main/ccss.c
@@ -2339,11 +2339,11 @@ static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel
}
generic_pvt->offer_timer_id = -1;
- if (chan->cid.cid_num) {
- ast_copy_string(generic_pvt->cid_num, chan->cid.cid_num, sizeof(generic_pvt->cid_num));
+ if (chan->caller.id.number.valid && chan->caller.id.number.str) {
+ ast_copy_string(generic_pvt->cid_num, chan->caller.id.number.str, sizeof(generic_pvt->cid_num));
}
- if (chan->cid.cid_name) {
- ast_copy_string(generic_pvt->cid_name, chan->cid.cid_name, sizeof(generic_pvt->cid_name));
+ if (chan->caller.id.name.valid && chan->caller.id.name.str) {
+ ast_copy_string(generic_pvt->cid_name, chan->caller.id.name.str, sizeof(generic_pvt->cid_name));
}
ast_copy_string(generic_pvt->exten, S_OR(chan->macroexten, chan->exten), sizeof(generic_pvt->exten));
ast_copy_string(generic_pvt->context, S_OR(chan->macrocontext, chan->context), sizeof(generic_pvt->context));
diff --git a/main/cdr.c b/main/cdr.c
index f14af2cb9..9dca74ff3 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -846,28 +846,25 @@ void ast_cdr_setdisposition(struct ast_cdr *cdr, long int disposition)
/* set cid info for one record */
static void set_one_cid(struct ast_cdr *cdr, struct ast_channel *c)
{
- /* Grab source from ANI or normal Caller*ID */
- const char *num = S_OR(c->cid.cid_ani, c->cid.cid_num);
- if (!cdr)
+ const char *num;
+
+ if (!cdr) {
return;
- if (!ast_strlen_zero(c->cid.cid_name)) {
- if (!ast_strlen_zero(num)) /* both name and number */
- snprintf(cdr->clid, sizeof(cdr->clid), "\"%s\" <%s>", c->cid.cid_name, num);
- else /* only name */
- ast_copy_string(cdr->clid, c->cid.cid_name, sizeof(cdr->clid));
- } else if (!ast_strlen_zero(num)) { /* only number */
- ast_copy_string(cdr->clid, num, sizeof(cdr->clid));
- } else { /* nothing known */
- cdr->clid[0] = '\0';
}
+
+ /* Grab source from ANI or normal Caller*ID */
+ num = S_OR(c->caller.ani,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL));
+ ast_callerid_merge(cdr->clid, sizeof(cdr->clid),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, NULL), num, "");
ast_copy_string(cdr->src, S_OR(num, ""), sizeof(cdr->src));
- ast_cdr_setvar(cdr, "dnid", S_OR(c->cid.cid_dnid, ""), 0);
+ ast_cdr_setvar(cdr, "dnid", S_OR(c->dialed.number.str, ""), 0);
- if (c->cid.subaddress.valid) {
- ast_cdr_setvar(cdr, "callingsubaddr", S_OR(c->cid.subaddress.str, ""), 0);
+ if (c->caller.id.subaddress.valid) {
+ ast_cdr_setvar(cdr, "callingsubaddr", S_OR(c->caller.id.subaddress.str, ""), 0);
}
- if (c->cid.dialed_subaddress.valid) {
- ast_cdr_setvar(cdr, "calledsubaddr", S_OR(c->cid.dialed_subaddress.str, ""), 0);
+ if (c->dialed.subaddress.valid) {
+ ast_cdr_setvar(cdr, "calledsubaddr", S_OR(c->dialed.subaddress.str, ""), 0);
}
}
diff --git a/main/cel.c b/main/cel.c
index 2c6dd9b27..52c62f6b8 100644
--- a/main/cel.c
+++ b/main/cel.c
@@ -437,11 +437,14 @@ struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event
AST_LIST_INSERT_HEAD(headp, newvariable, entries);
}
- tchan->cid.cid_name = ast_strdup(record.caller_id_name);
- tchan->cid.cid_num = ast_strdup(record.caller_id_num);
- tchan->cid.cid_ani = ast_strdup(record.caller_id_ani);
- tchan->redirecting.from.number = ast_strdup(record.caller_id_rdnis);
- tchan->cid.cid_dnid = ast_strdup(record.caller_id_dnid);
+ tchan->caller.id.name.valid = 1;
+ tchan->caller.id.name.str = ast_strdup(record.caller_id_name);
+ tchan->caller.id.number.valid = 1;
+ tchan->caller.id.number.str = ast_strdup(record.caller_id_num);
+ tchan->caller.ani = ast_strdup(record.caller_id_ani);
+ tchan->redirecting.from.number.valid = 1;
+ tchan->redirecting.from.number.str = ast_strdup(record.caller_id_rdnis);
+ tchan->dialed.number.str = ast_strdup(record.caller_id_dnid);
ast_copy_string(tchan->exten, record.extension, sizeof(tchan->exten));
ast_copy_string(tchan->context, record.context, sizeof(tchan->context));
@@ -526,29 +529,34 @@ int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event
ast_channel_lock(chan);
ev = ast_event_new(AST_EVENT_CEL,
- AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type,
- AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec,
- AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec,
- AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname,
- AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_name, ""),
- AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_num, ""),
- AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_ani, ""),
- AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->redirecting.from.number, ""),
- AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->cid.cid_dnid, ""),
- AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten,
- AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context,
- AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name,
- AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""),
- AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""),
- AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags,
- AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode,
- AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount,
- AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid,
- AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid,
- AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield,
- AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra,
- AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername,
- AST_EVENT_IE_END);
+ AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type,
+ AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec,
+ AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec,
+ AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname,
+ AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR,
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
+ AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
+ AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR,
+ S_OR(chan->caller.ani, ""),
+ AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR,
+ S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, ""),
+ AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR,
+ S_OR(chan->dialed.number.str, ""),
+ AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten,
+ AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context,
+ AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name,
+ AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""),
+ AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""),
+ AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags,
+ AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode,
+ AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount,
+ AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid,
+ AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid,
+ AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield,
+ AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra,
+ AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername,
+ AST_EVENT_IE_END);
ast_channel_unlock(chan);
diff --git a/main/channel.c b/main/channel.c
index ba420fbb9..51cbd553b 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -72,9 +72,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <sys/epoll.h>
#endif
+#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
#if defined(HAVE_PRI)
#include "libpri.h"
#endif /* defined(HAVE_PRI) */
+#endif /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */
struct ast_epoll_data {
struct ast_channel *chan;
@@ -139,6 +141,7 @@ static AST_RWLIST_HEAD_STATIC(backends, chanlist);
#define NUM_CHANNEL_BUCKETS 1567
#endif
+#if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
#define DATA_EXPORT_CALLERID(MEMBER) \
MEMBER(ast_callerid, cid_dnid, AST_DATA_STRING) \
MEMBER(ast_callerid, cid_num, AST_DATA_STRING) \
@@ -149,6 +152,7 @@ static AST_RWLIST_HEAD_STATIC(backends, chanlist);
MEMBER(ast_callerid, cid_tag, AST_DATA_STRING)
AST_DATA_STRUCTURE(ast_callerid, DATA_EXPORT_CALLERID);
+#endif
#define DATA_EXPORT_CHANNEL(MEMBER) \
MEMBER(ast_channel, blockproc, AST_DATA_STRING) \
@@ -283,6 +287,7 @@ static void channel_data_add_flags(struct ast_data *tree,
ast_data_add_bool(tree, "DISABLE_WORKAROUNDS", ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS));
}
+#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
static const char *party_number_ton2str(int ton)
{
#if defined(HAVE_PRI)
@@ -306,7 +311,9 @@ static const char *party_number_ton2str(int ton)
#endif /* defined(HAVE_PRI) */
return "Unknown";
}
+#endif /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */
+#if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED)
static const char *party_number_plan2str(int plan)
{
#if defined(HAVE_PRI)
@@ -330,14 +337,22 @@ static const char *party_number_plan2str(int plan)
#endif /* defined(HAVE_PRI) */
return "Unknown";
}
+#endif /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */
int ast_channel_data_add_structure(struct ast_data *tree,
struct ast_channel *chan, int add_bridged)
{
struct ast_channel *bc;
- struct ast_data *data_bridged, *data_cdr, *data_flags, *data_zones;
- struct ast_data *data_callerid, *enum_node, *data_softhangup;
+ struct ast_data *data_bridged;
+ struct ast_data *data_cdr;
+ struct ast_data *data_flags;
+ struct ast_data *data_zones;
+ struct ast_data *enum_node;
+ struct ast_data *data_softhangup;
+#if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
+ struct ast_data *data_callerid;
char value_str[100];
+#endif
if (!tree) {
return -1;
@@ -417,6 +432,7 @@ int ast_channel_data_add_structure(struct ast_data *tree,
ast_data_add_uint(tree, "timetohangup", chan->whentohangup.tv_sec);
+#if 0 /* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
/* callerid */
data_callerid = ast_data_add_node(tree, "callerid");
if (!data_callerid) {
@@ -433,6 +449,7 @@ int ast_channel_data_add_structure(struct ast_data *tree,
party_number_ton2str(chan->cid.cid_ton),
party_number_plan2str(chan->cid.cid_ton));
ast_data_add_str(enum_node, "text", value_str);
+#endif
/* tone zone */
if (chan->zone) {
@@ -1090,13 +1107,22 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
return ast_channel_unref(tmp);
}
+ ast_party_dialed_init(&tmp->dialed);
+ ast_party_caller_init(&tmp->caller);
+ ast_party_connected_line_init(&tmp->connected);
+ ast_party_redirecting_init(&tmp->redirecting);
+
if (cid_name) {
- if (!(tmp->cid.cid_name = ast_strdup(cid_name))) {
+ tmp->caller.id.name.valid = 1;
+ tmp->caller.id.name.str = ast_strdup(cid_name);
+ if (!tmp->caller.id.name.str) {
return ast_channel_unref(tmp);
}
}
if (cid_num) {
- if (!(tmp->cid.cid_num = ast_strdup(cid_num))) {
+ tmp->caller.id.number.valid = 1;
+ tmp->caller.id.number.str = ast_strdup(cid_num);
+ if (!tmp->caller.id.number.str) {
return ast_channel_unref(tmp);
}
}
@@ -1762,23 +1788,6 @@ int ast_safe_sleep(struct ast_channel *chan, int ms)
return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
}
-static void free_cid(struct ast_callerid *cid)
-{
- if (cid->cid_dnid)
- ast_free(cid->cid_dnid);
- if (cid->cid_num)
- ast_free(cid->cid_num);
- if (cid->cid_name)
- ast_free(cid->cid_name);
- if (cid->cid_ani)
- ast_free(cid->cid_ani);
- if (cid->cid_tag)
- ast_free(cid->cid_tag);
- cid->cid_dnid = cid->cid_num = cid->cid_name = cid->cid_ani = NULL;
- ast_party_subaddress_free(&cid->subaddress);
- ast_party_subaddress_free(&cid->dialed_subaddress);
-}
-
struct ast_channel *ast_channel_release(struct ast_channel *chan)
{
/* Safe, even if already unlinked. */
@@ -1786,6 +1795,112 @@ struct ast_channel *ast_channel_release(struct ast_channel *chan)
return ast_channel_unref(chan);
}
+void ast_party_name_init(struct ast_party_name *init)
+{
+ init->str = NULL;
+ init->char_set = AST_PARTY_CHAR_SET_ISO8859_1;
+ init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ init->valid = 0;
+}
+
+void ast_party_name_copy(struct ast_party_name *dest, const struct ast_party_name *src)
+{
+ if (dest == src) {
+ /* Don't copy to self */
+ return;
+ }
+
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ dest->char_set = src->char_set;
+ dest->presentation = src->presentation;
+ dest->valid = src->valid;
+}
+
+void ast_party_name_set_init(struct ast_party_name *init, const struct ast_party_name *guide)
+{
+ init->str = NULL;
+ init->char_set = guide->char_set;
+ init->presentation = guide->presentation;
+ init->valid = guide->valid;
+}
+
+void ast_party_name_set(struct ast_party_name *dest, const struct ast_party_name *src)
+{
+ if (dest == src) {
+ /* Don't set to self */
+ return;
+ }
+
+ if (src->str && src->str != dest->str) {
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ }
+
+ dest->char_set = src->char_set;
+ dest->presentation = src->presentation;
+ dest->valid = src->valid;
+}
+
+void ast_party_name_free(struct ast_party_name *doomed)
+{
+ ast_free(doomed->str);
+ doomed->str = NULL;
+}
+
+void ast_party_number_init(struct ast_party_number *init)
+{
+ init->str = NULL;
+ init->plan = 0;/* Unknown */
+ init->presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ init->valid = 0;
+}
+
+void ast_party_number_copy(struct ast_party_number *dest, const struct ast_party_number *src)
+{
+ if (dest == src) {
+ /* Don't copy to self */
+ return;
+ }
+
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ dest->plan = src->plan;
+ dest->presentation = src->presentation;
+ dest->valid = src->valid;
+}
+
+void ast_party_number_set_init(struct ast_party_number *init, const struct ast_party_number *guide)
+{
+ init->str = NULL;
+ init->plan = guide->plan;
+ init->presentation = guide->presentation;
+ init->valid = guide->valid;
+}
+
+void ast_party_number_set(struct ast_party_number *dest, const struct ast_party_number *src)
+{
+ if (dest == src) {
+ /* Don't set to self */
+ return;
+ }
+
+ if (src->str && src->str != dest->str) {
+ ast_free(dest->str);
+ dest->str = ast_strdup(src->str);
+ }
+
+ dest->plan = src->plan;
+ dest->presentation = src->presentation;
+ dest->valid = src->valid;
+}
+
+void ast_party_number_free(struct ast_party_number *doomed)
+{
+ ast_free(doomed->str);
+ doomed->str = NULL;
+}
+
void ast_party_subaddress_init(struct ast_party_subaddress *init)
{
init->str = NULL;
@@ -1801,9 +1916,7 @@ void ast_party_subaddress_copy(struct ast_party_subaddress *dest, const struct a
return;
}
- if (dest->str) {
- ast_free(dest->str);
- }
+ ast_free(dest->str);
dest->str = ast_strdup(src->str);
dest->type = src->type;
dest->odd_even_indicator = src->odd_even_indicator;
@@ -1826,9 +1939,7 @@ void ast_party_subaddress_set(struct ast_party_subaddress *dest, const struct as
}
if (src->str && src->str != dest->str) {
- if (dest->str) {
- ast_free(dest->str);
- }
+ ast_free(dest->str);
dest->str = ast_strdup(src->str);
}
@@ -1839,207 +1950,236 @@ void ast_party_subaddress_set(struct ast_party_subaddress *dest, const struct as
void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
{
- if (doomed->str) {
- ast_free(doomed->str);
- doomed->str = NULL;
- }
+ ast_free(doomed->str);
+ doomed->str = NULL;
}
void ast_party_id_init(struct ast_party_id *init)
{
- init->number = NULL;
- init->name = NULL;
- init->tag = NULL;
- init->number_type = 0; /* Unknown */
- init->number_presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ ast_party_name_init(&init->name);
+ ast_party_number_init(&init->number);
ast_party_subaddress_init(&init->subaddress);
+ init->tag = NULL;
}
-/*!
- * \internal
- * \brief Copy the source party id information to the destination party id.
- *
- * \param dest Destination party id
- * \param src Source party id
- *
- * \return Nothing
- */
-static void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
+void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
{
if (dest == src) {
/* Don't copy to self */
return;
}
- if (dest->number) {
- ast_free(dest->number);
- }
- dest->number = ast_strdup(src->number);
-
- if (dest->name) {
- ast_free(dest->name);
- }
- dest->name = ast_strdup(src->name);
+ ast_party_name_copy(&dest->name, &src->name);
+ ast_party_number_copy(&dest->number, &src->number);
+ ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
- if (dest->tag) {
- ast_free(dest->tag);
- }
+ ast_free(dest->tag);
dest->tag = ast_strdup(src->tag);
-
- dest->number_type = src->number_type;
- dest->number_presentation = src->number_presentation;
- ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
}
-/*!
- * \internal
- * \brief Initialize the given party id structure using the given guide
- * for a set update operation.
- *
- * \details
- * The initialization is needed to allow a set operation to know if a
- * value needs to be updated. Simple integers need the guide's original
- * value in case the set operation is not trying to set a new value.
- * String values are simply set to NULL pointers if they are not going
- * to be updated.
- *
- * \param init Party id structure to initialize.
- * \param guide Source party id to use as a guide in initializing.
- *
- * \return Nothing
- */
-static void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
+void ast_party_id_set_init(struct ast_party_id *init, const struct ast_party_id *guide)
{
- init->number = NULL;
- init->name = NULL;
- init->tag = NULL;
- init->number_type = guide->number_type;
- init->number_presentation = guide->number_presentation;
+ ast_party_name_set_init(&init->name, &guide->name);
+ ast_party_number_set_init(&init->number, &guide->number);
ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
+ init->tag = NULL;
}
-/*!
- * \internal
- * \brief Set the source party id information into the destination party id.
- *
- * \param dest Destination party id
- * \param src Source party id
- *
- * \return Nothing
- */
-static void ast_party_id_set(struct ast_party_id *dest, const struct ast_party_id *src)
+void ast_party_id_set(struct ast_party_id *dest, const struct ast_party_id *src, const struct ast_set_party_id *update)
{
if (dest == src) {
/* Don't set to self */
return;
}
- if (src->name && src->name != dest->name) {
- if (dest->name) {
- ast_free(dest->name);
- }
- dest->name = ast_strdup(src->name);
+ if (!update || update->name) {
+ ast_party_name_set(&dest->name, &src->name);
}
-
- if (src->number && src->number != dest->number) {
- if (dest->number) {
- ast_free(dest->number);
- }
- dest->number = ast_strdup(src->number);
+ if (!update || update->number) {
+ ast_party_number_set(&dest->number, &src->number);
+ }
+ if (!update || update->subaddress) {
+ ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
}
if (src->tag && src->tag != dest->tag) {
- if (dest->tag) {
- ast_free(dest->tag);
- }
+ ast_free(dest->tag);
dest->tag = ast_strdup(src->tag);
}
-
- dest->number_type = src->number_type;
- dest->number_presentation = src->number_presentation;
- ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
}
void ast_party_id_free(struct ast_party_id *doomed)
{
- if (doomed->number) {
- ast_free(doomed->number);
- doomed->number = NULL;
+ ast_party_name_free(&doomed->name);
+ ast_party_number_free(&doomed->number);
+ ast_party_subaddress_free(&doomed->subaddress);
+
+ ast_free(doomed->tag);
+ doomed->tag = NULL;
+}
+
+int ast_party_id_presentation(const struct ast_party_id *id)
+{
+ int number_priority;
+ int number_value;
+ int number_screening;
+ int name_priority;
+ int name_value;
+
+ /* Determine name presentation priority. */
+ if (!id->name.valid) {
+ name_value = AST_PRES_UNAVAILABLE;
+ name_priority = 3;
+ } else {
+ name_value = id->name.presentation & AST_PRES_RESTRICTION;
+ switch (name_value) {
+ case AST_PRES_RESTRICTED:
+ name_priority = 0;
+ break;
+ case AST_PRES_ALLOWED:
+ name_priority = 1;
+ break;
+ case AST_PRES_UNAVAILABLE:
+ name_priority = 2;
+ break;
+ default:
+ name_value = AST_PRES_UNAVAILABLE;
+ name_priority = 3;
+ break;
+ }
}
- if (doomed->name) {
- ast_free(doomed->name);
- doomed->name = NULL;
+ /* Determine number presentation priority. */
+ if (!id->number.valid) {
+ number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
+ number_value = AST_PRES_UNAVAILABLE;
+ number_priority = 3;
+ } else {
+ number_screening = id->number.presentation & AST_PRES_NUMBER_TYPE;
+ number_value = id->number.presentation & AST_PRES_RESTRICTION;
+ switch (number_value) {
+ case AST_PRES_RESTRICTED:
+ number_priority = 0;
+ break;
+ case AST_PRES_ALLOWED:
+ number_priority = 1;
+ break;
+ case AST_PRES_UNAVAILABLE:
+ number_priority = 2;
+ break;
+ default:
+ number_screening = AST_PRES_USER_NUMBER_UNSCREENED;
+ number_value = AST_PRES_UNAVAILABLE;
+ number_priority = 3;
+ break;
+ }
}
- if (doomed->tag) {
- ast_free(doomed->tag);
- doomed->tag = NULL;
+ /* Select the wining presentation value. */
+ if (name_priority < number_priority) {
+ number_value = name_value;
}
- ast_party_subaddress_free(&doomed->subaddress);
+
+ return number_value | number_screening;
}
-void ast_party_caller_init(struct ast_party_caller *init)
+void ast_party_dialed_init(struct ast_party_dialed *init)
{
- ast_party_id_init(&init->id);
- init->ani = NULL;
- init->ani2 = 0;
+ init->number.str = NULL;
+ init->number.plan = 0;/* Unknown */
+ ast_party_subaddress_init(&init->subaddress);
+ init->transit_network_select = 0;
}
-void ast_party_caller_copy(struct ast_callerid *dest, const struct ast_callerid *src)
+void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
{
if (dest == src) {
/* Don't copy to self */
return;
}
-#if 1
- /* Copy caller-id specific information ONLY from struct ast_callerid */
- if (dest->cid_num)
- {
- ast_free(dest->cid_num);
- }
- dest->cid_num = ast_strdup(src->cid_num);
+ ast_free(dest->number.str);
+ dest->number.str = ast_strdup(src->number.str);
+ dest->number.plan = src->number.plan;
+ ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
+ dest->transit_network_select = src->transit_network_select;
+}
- if (dest->cid_name)
- {
- ast_free(dest->cid_name);
- }
- dest->cid_name = ast_strdup(src->cid_name);
+void ast_party_dialed_set_init(struct ast_party_dialed *init, const struct ast_party_dialed *guide)
+{
+ init->number.str = NULL;
+ init->number.plan = guide->number.plan;
+ ast_party_subaddress_set_init(&init->subaddress, &guide->subaddress);
+ init->transit_network_select = guide->transit_network_select;
+}
- if (dest->cid_tag) {
- ast_free(dest->cid_tag);
+void ast_party_dialed_set(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
+{
+ if (src->number.str && src->number.str != dest->number.str) {
+ ast_free(dest->number.str);
+ dest->number.str = ast_strdup(src->number.str);
}
- dest->cid_tag = ast_strdup(src->cid_tag);
+ dest->number.plan = src->number.plan;
- dest->cid_ton = src->cid_ton;
- dest->cid_pres = src->cid_pres;
+ ast_party_subaddress_set(&dest->subaddress, &src->subaddress);
+ dest->transit_network_select = src->transit_network_select;
+}
- if (dest->cid_ani)
- {
- ast_free(dest->cid_ani);
+void ast_party_dialed_free(struct ast_party_dialed *doomed)
+{
+ ast_free(doomed->number.str);
+ doomed->number.str = NULL;
+ ast_party_subaddress_free(&doomed->subaddress);
+}
+
+void ast_party_caller_init(struct ast_party_caller *init)
+{
+ ast_party_id_init(&init->id);
+ init->ani = NULL;
+ init->ani2 = 0;
+}
+
+void ast_party_caller_copy(struct ast_party_caller *dest, const struct ast_party_caller *src)
+{
+ if (dest == src) {
+ /* Don't copy to self */
+ return;
}
- dest->cid_ani = ast_strdup(src->cid_ani);
- dest->cid_ani2 = src->cid_ani2;
+ ast_party_id_copy(&dest->id, &src->id);
- ast_party_subaddress_copy(&dest->subaddress, &src->subaddress);
+ ast_free(dest->ani);
+ dest->ani = ast_strdup(src->ani);
-#else
+ dest->ani2 = src->ani2;
+}
- /* The src and dest parameter types will become struct ast_party_caller ptrs. */
- /* This is future code */
+void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
+{
+ ast_party_id_set_init(&init->id, &guide->id);
+ init->ani = NULL;
+ init->ani2 = guide->ani2;
+}
- ast_party_id_copy(&dest->id, &src->id);
+void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_caller *src, const struct ast_set_party_caller *update)
+{
+ ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
- if (dest->ani) {
+ if (src->ani && src->ani != dest->ani) {
ast_free(dest->ani);
+ dest->ani = ast_strdup(src->ani);
}
- dest->ani = ast_strdup(src->ani);
dest->ani2 = src->ani2;
-#endif
+}
+
+void ast_party_caller_free(struct ast_party_caller *doomed)
+{
+ ast_party_id_free(&doomed->id);
+
+ ast_free(doomed->ani);
+ doomed->ani = NULL;
}
void ast_party_connected_line_init(struct ast_party_connected_line *init)
@@ -2059,9 +2199,7 @@ void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const
ast_party_id_copy(&dest->id, &src->id);
- if (dest->ani) {
- ast_free(dest->ani);
- }
+ ast_free(dest->ani);
dest->ani = ast_strdup(src->ani);
dest->ani2 = src->ani2;
@@ -2076,14 +2214,12 @@ void ast_party_connected_line_set_init(struct ast_party_connected_line *init, co
init->source = guide->source;
}
-void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
+void ast_party_connected_line_set(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src, const struct ast_set_party_connected_line *update)
{
- ast_party_id_set(&dest->id, &src->id);
+ ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
if (src->ani && src->ani != dest->ani) {
- if (dest->ani) {
- ast_free(dest->ani);
- }
+ ast_free(dest->ani);
dest->ani = ast_strdup(src->ani);
}
@@ -2091,17 +2227,11 @@ void ast_party_connected_line_set(struct ast_party_connected_line *dest, const s
dest->source = src->source;
}
-void ast_party_connected_line_collect_caller(struct ast_party_connected_line *connected, struct ast_callerid *cid)
+void ast_party_connected_line_collect_caller(struct ast_party_connected_line *connected, struct ast_party_caller *caller)
{
- connected->id.number = cid->cid_num;
- connected->id.name = cid->cid_name;
- connected->id.number_type = cid->cid_ton;
- connected->id.number_presentation = cid->cid_pres;
- connected->id.tag = cid->cid_tag;
- connected->id.subaddress = cid->subaddress;
-
- connected->ani = cid->cid_ani;
- connected->ani2 = cid->cid_ani2;
+ connected->id = caller->id;
+ connected->ani = caller->ani;
+ connected->ani2 = caller->ani2;
connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
}
@@ -2109,10 +2239,16 @@ void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
{
ast_party_id_free(&doomed->id);
- if (doomed->ani) {
- ast_free(doomed->ani);
- doomed->ani = NULL;
- }
+ ast_free(doomed->ani);
+ doomed->ani = NULL;
+}
+
+void ast_party_redirecting_init(struct ast_party_redirecting *init)
+{
+ ast_party_id_init(&init->from);
+ ast_party_id_init(&init->to);
+ init->count = 0;
+ init->reason = AST_REDIRECTING_REASON_UNKNOWN;
}
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
@@ -2136,6 +2272,14 @@ void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const st
init->reason = guide->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->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;
+}
+
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
{
ast_party_id_free(&doomed->from);
@@ -2210,7 +2354,8 @@ static void ast_channel_destructor(void *obj)
if (chan->pbx)
ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
- free_cid(&chan->cid);
+ ast_party_dialed_free(&chan->dialed);
+ ast_party_caller_free(&chan->caller);
ast_party_connected_line_free(&chan->connected);
ast_party_redirecting_free(&chan->redirecting);
@@ -2275,7 +2420,10 @@ static void ast_dummy_channel_destructor(void *obj)
headp = &chan->varshead;
- free_cid(&chan->cid);
+ ast_party_dialed_free(&chan->dialed);
+ ast_party_caller_free(&chan->caller);
+ ast_party_connected_line_free(&chan->connected);
+ ast_party_redirecting_free(&chan->redirecting);
/* loop over the variables list, freeing all data and deleting list items */
/* no need to lock the list, as the channel is already locked */
@@ -2574,19 +2722,19 @@ int ast_hangup(struct ast_channel *chan)
ast_channel_unlock(chan);
ast_cc_offer(chan);
ast_manager_event(chan, EVENT_FLAG_CALL, "Hangup",
- "Channel: %s\r\n"
- "Uniqueid: %s\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Cause: %d\r\n"
- "Cause-txt: %s\r\n",
- chan->name,
- chan->uniqueid,
- S_OR(chan->cid.cid_num, "<unknown>"),
- S_OR(chan->cid.cid_name, "<unknown>"),
- chan->hangupcause,
- ast_cause2str(chan->hangupcause)
- );
+ "Channel: %s\r\n"
+ "Uniqueid: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Cause: %d\r\n"
+ "Cause-txt: %s\r\n",
+ chan->name,
+ chan->uniqueid,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, "<unknown>"),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, "<unknown>"),
+ chan->hangupcause,
+ ast_cause2str(chan->hangupcause)
+ );
if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) &&
!ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) &&
@@ -4012,7 +4160,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
ast_party_connected_line_set_init(&connected, &chan->connected);
res = ast_connected_line_parse_data(data, datalen, &connected);
if (!res) {
- ast_channel_set_connected_line(chan, &connected);
+ ast_channel_set_connected_line(chan, &connected, NULL);
}
ast_party_connected_line_free(&connected);
}
@@ -4025,7 +4173,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
res = ast_redirecting_parse_data(data, datalen, &redirecting);
if (!res) {
- ast_channel_set_redirecting(chan, &redirecting);
+ ast_channel_set_redirecting(chan, &redirecting, NULL);
}
ast_party_redirecting_free(&redirecting);
}
@@ -4810,7 +4958,7 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
return NULL;
}
- ast_channel_set_redirecting(new, apr);
+ ast_channel_set_redirecting(new, apr, NULL);
/* Copy/inherit important information into new channel */
if (oh) {
@@ -4821,7 +4969,7 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num);
}
if (oh->parent_channel) {
- ast_channel_update_redirecting(oh->parent_channel, apr);
+ ast_channel_update_redirecting(oh->parent_channel, apr, NULL);
ast_channel_inherit_variables(oh->parent_channel, new);
ast_channel_datastore_inherit(oh->parent_channel, new);
}
@@ -4829,7 +4977,7 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
ast_cdr_setaccount(new, oh->account);
}
} else if (caller) { /* no outgoing helper so use caller if avaliable */
- ast_channel_update_redirecting(caller, apr);
+ ast_channel_update_redirecting(caller, apr, NULL);
ast_channel_inherit_variables(caller, new);
ast_channel_datastore_inherit(caller, new);
}
@@ -4840,7 +4988,7 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
}
ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
ast_string_field_set(new, accountcode, orig->accountcode);
- ast_party_caller_copy(&new->cid, &orig->cid);
+ ast_party_caller_copy(&new->caller, &orig->caller);
ast_party_connected_line_copy(&new->connected, &orig->connected);
ast_channel_unlock(new);
ast_channel_unlock(orig);
@@ -4895,10 +5043,17 @@ struct ast_channel *__ast_request_and_dial(const char *type, format_t format, co
ast_set_callerid(chan, cid_num, cid_name, cid_num);
ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
ast_party_connected_line_set_init(&connected, &chan->connected);
- connected.id.number = (char *) cid_num;
- connected.id.name = (char *) cid_name;
- connected.id.number_presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
- ast_channel_set_connected_line(chan, &connected);
+ if (cid_num) {
+ connected.id.number.valid = 1;
+ connected.id.number.str = (char *) cid_num;
+ connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ }
+ if (cid_name) {
+ connected.id.name.valid = 1;
+ connected.id.name.str = (char *) cid_name;
+ connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
+ }
+ ast_channel_set_connected_line(chan, &connected, NULL);
if (ast_call(chan, data, 0)) { /* ast_call failed... */
ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
@@ -5658,19 +5813,22 @@ static void ast_set_owners_and_peers(struct ast_channel *chan1,
*/
static void report_new_callerid(struct ast_channel *chan)
{
+ int pres;
+
+ pres = ast_party_id_presentation(&chan->caller.id);
ast_manager_event(chan, EVENT_FLAG_CALL, "NewCallerid",
- "Channel: %s\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Uniqueid: %s\r\n"
- "CID-CallingPres: %d (%s)\r\n",
- chan->name,
- S_OR(chan->cid.cid_num, ""),
- S_OR(chan->cid.cid_name, ""),
- chan->uniqueid,
- chan->cid.cid_pres,
- ast_describe_caller_presentation(chan->cid.cid_pres)
- );
+ "Channel: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Uniqueid: %s\r\n"
+ "CID-CallingPres: %d (%s)\r\n",
+ chan->name,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
+ chan->uniqueid,
+ pres,
+ ast_describe_caller_presentation(pres)
+ );
}
/*!
@@ -5690,7 +5848,8 @@ int ast_do_masquerade(struct ast_channel *original)
const struct ast_channel_tech *t;
void *t_pvt;
union {
- struct ast_callerid cid;
+ struct ast_party_dialed dialed;
+ struct ast_party_caller caller;
struct ast_party_connected_line connected;
struct ast_party_redirecting redirecting;
} exchange;
@@ -5917,18 +6076,24 @@ int ast_do_masquerade(struct ast_channel *original)
* Just swap the whole structures, nevermind the allocations,
* they'll work themselves out.
*/
- exchange.cid = original->cid;
- original->cid = clonechan->cid;
- clonechan->cid = exchange.cid;
- report_new_callerid(original);
+ exchange.dialed = original->dialed;
+ original->dialed = clonechan->dialed;
+ clonechan->dialed = exchange.dialed;
+
+ exchange.caller = original->caller;
+ original->caller = clonechan->caller;
+ clonechan->caller = exchange.caller;
exchange.connected = original->connected;
original->connected = clonechan->connected;
clonechan->connected = exchange.connected;
+
exchange.redirecting = original->redirecting;
original->redirecting = clonechan->redirecting;
clonechan->redirecting = exchange.redirecting;
+ report_new_callerid(original);
+
/* Restore original timing file descriptor */
ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
@@ -6030,19 +6195,18 @@ void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char
ast_channel_lock(chan);
if (cid_num) {
- if (chan->cid.cid_num)
- ast_free(chan->cid.cid_num);
- chan->cid.cid_num = ast_strdup(cid_num);
+ chan->caller.id.number.valid = 1;
+ ast_free(chan->caller.id.number.str);
+ chan->caller.id.number.str = ast_strdup(cid_num);
}
if (cid_name) {
- if (chan->cid.cid_name)
- ast_free(chan->cid.cid_name);
- chan->cid.cid_name = ast_strdup(cid_name);
+ chan->caller.id.name.valid = 1;
+ ast_free(chan->caller.id.name.str);
+ chan->caller.id.name.str = ast_strdup(cid_name);
}
if (cid_ani) {
- if (chan->cid.cid_ani)
- ast_free(chan->cid.cid_ani);
- chan->cid.cid_ani = ast_strdup(cid_ani);
+ ast_free(chan->caller.ani);
+ chan->caller.ani = ast_strdup(cid_ani);
}
report_new_callerid(chan);
@@ -6050,6 +6214,40 @@ void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char
ast_channel_unlock(chan);
}
+void ast_channel_set_caller(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
+{
+ if (&chan->caller == caller) {
+ /* Don't set to self */
+ return;
+ }
+
+ ast_channel_lock(chan);
+ ast_party_caller_set(&chan->caller, caller, update);
+ ast_channel_unlock(chan);
+}
+
+void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
+{
+ struct ast_party_caller pre_set;
+
+ if (&chan->caller == caller) {
+ /* Don't set to self */
+ return;
+ }
+
+ ast_channel_lock(chan);
+ pre_set = chan->caller;
+ ast_party_caller_set(&chan->caller, caller, update);
+ if (S_COR(pre_set.id.number.valid, pre_set.id.number.str, NULL)
+ != S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)
+ || S_COR(pre_set.id.name.valid, pre_set.id.name.str, NULL)
+ != S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)) {
+ /* The caller id name or number changed. */
+ report_new_callerid(chan);
+ }
+ ast_channel_unlock(chan);
+}
+
int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
{
int oldstate = chan->_state;
@@ -6072,16 +6270,16 @@ int ast_setstate(struct ast_channel *chan, enum ast_channel_state state)
/* setstate used to conditionally report Newchannel; this is no more */
ast_manager_event(chan, EVENT_FLAG_CALL, "Newstate",
- "Channel: %s\r\n"
- "ChannelState: %d\r\n"
- "ChannelStateDesc: %s\r\n"
- "CallerIDNum: %s\r\n"
- "CallerIDName: %s\r\n"
- "Uniqueid: %s\r\n",
- chan->name, chan->_state, ast_state2str(chan->_state),
- S_OR(chan->cid.cid_num, ""),
- S_OR(chan->cid.cid_name, ""),
- chan->uniqueid);
+ "Channel: %s\r\n"
+ "ChannelState: %d\r\n"
+ "ChannelStateDesc: %s\r\n"
+ "CallerIDNum: %s\r\n"
+ "CallerIDName: %s\r\n"
+ "Uniqueid: %s\r\n",
+ chan->name, chan->_state, ast_state2str(chan->_state),
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""),
+ S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""),
+ chan->uniqueid);
return 0;
}
@@ -6346,19 +6544,20 @@ static void manager_bridge_event(int onoff, int type, struct ast_channel *c0, st
{
struct ast_channel *chans[2] = { c0, c1 };
ast_manager_event_multichan(EVENT_FLAG_CALL, "Bridge", 2, chans,
- "Bridgestate: %s\r\n"
- "Bridgetype: %s\r\n"
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- onoff ? "Link" : "Unlink",
- type == 1 ? "core" : "native",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid,
- S_OR(c0->cid.cid_num, ""),
- S_OR(c1->cid.cid_num, ""));
+ "Bridgestate: %s\r\n"
+ "Bridgetype: %s\r\n"
+ "Channel1: %s\r\n"
+ "Channel2: %s\r\n"
+ "Uniqueid1: %s\r\n"
+ "Uniqueid2: %s\r\n"
+ "CallerID1: %s\r\n"
+ "CallerID2: %s\r\n",
+ onoff ? "Link" : "Unlink",
+ type == 1 ? "core" : "native",
+ c0->name, c1->name,
+ c0->uniqueid, c1->uniqueid,
+ S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, ""),
+ S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, ""));
}
static void update_bridge_vars(struct ast_channel *c0, struct ast_channel *c1)
@@ -6606,13 +6805,16 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
ast_set_flag(c1, AST_FLAG_NBRIDGE);
if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, timeoutms)) == AST_BRIDGE_COMPLETE) {
ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid, S_OR(c0->cid.cid_num, "<unknown>"), S_OR(c1->cid.cid_num, "<unknown>"));
+ "Channel1: %s\r\n"
+ "Channel2: %s\r\n"
+ "Uniqueid1: %s\r\n"
+ "Uniqueid2: %s\r\n"
+ "CallerID1: %s\r\n"
+ "CallerID2: %s\r\n",
+ c0->name, c1->name,
+ c0->uniqueid, c1->uniqueid,
+ S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
+ S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
@@ -6677,13 +6879,16 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
c1->_bridge = NULL;
ast_manager_event_multichan(EVENT_FLAG_CALL, "Unlink", 2, chans,
- "Channel1: %s\r\n"
- "Channel2: %s\r\n"
- "Uniqueid1: %s\r\n"
- "Uniqueid2: %s\r\n"
- "CallerID1: %s\r\n"
- "CallerID2: %s\r\n",
- c0->name, c1->name, c0->uniqueid, c1->uniqueid, S_OR(c0->cid.cid_num, "<unknown>"), S_OR(c1->cid.cid_num, "<unknown>"));
+ "Channel1: %s\r\n"
+ "Channel2: %s\r\n"
+ "Uniqueid1: %s\r\n"
+ "Uniqueid2: %s\r\n"
+ "CallerID1: %s\r\n"
+ "CallerID2: %s\r\n",
+ c0->name, c1->name,
+ c0->uniqueid, c1->uniqueid,
+ S_COR(c0->caller.id.number.valid, c0->caller.id.number.str, "<unknown>"),
+ S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
return res;
@@ -7289,101 +7494,27 @@ int ast_say_digits_full(struct ast_channel *chan, int num,
return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
}
-void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_callerid *src)
+void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
{
-#if 1
- /* Must manually fill in struct ast_party_id until struct ast_callerid goes away */
- if (dest->id.number) {
- ast_free(dest->id.number);
- }
- dest->id.number = ast_strdup(src->cid_num);
-
- if (dest->id.name) {
- ast_free(dest->id.name);
- }
- dest->id.name = ast_strdup(src->cid_name);
-
- if (dest->id.tag) {
- ast_free(dest->id.tag);
- }
- dest->id.tag = ast_strdup(src->cid_tag);
-
- dest->id.number_type = src->cid_ton;
- dest->id.number_presentation = src->cid_pres;
-
-
- if (dest->ani) {
- ast_free(dest->ani);
- }
- dest->ani = ast_strdup(src->cid_ani);
-
- dest->ani2 = src->cid_ani2;
- ast_party_subaddress_copy(&dest->id.subaddress, &src->subaddress);
-
-#else
-
- /* The src parameter type will become a struct ast_party_caller ptr. */
- /* This is future code */
-
ast_party_id_copy(&dest->id, &src->id);
- if (dest->ani) {
- ast_free(dest->ani);
- }
+ ast_free(dest->ani);
dest->ani = ast_strdup(src->ani);
dest->ani2 = src->ani2;
-#endif
}
-void ast_connected_line_copy_to_caller(struct ast_callerid *dest, const struct ast_party_connected_line *src)
+void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
{
-#if 1
- /* Must manually extract from struct ast_party_id until struct ast_callerid goes away */
- if (dest->cid_num) {
- ast_free(dest->cid_num);
- }
- dest->cid_num = ast_strdup(src->id.number);
-
- if (dest->cid_name) {
- ast_free(dest->cid_name);
- }
- dest->cid_name = ast_strdup(src->id.name);
-
- if (dest->cid_tag) {
- ast_free(dest->cid_tag);
- }
- dest->cid_tag = ast_strdup(src->id.tag);
-
- dest->cid_ton = src->id.number_type;
- dest->cid_pres = src->id.number_presentation;
-
-
- if (dest->cid_ani) {
- ast_free(dest->cid_ani);
- }
- dest->cid_ani = ast_strdup(src->ani);
-
- dest->cid_ani2 = src->ani2;
- ast_party_subaddress_copy(&dest->subaddress, &src->id.subaddress);
-
-#else
-
- /* The dest parameter type will become a struct ast_party_caller ptr. */
- /* This is future code */
-
ast_party_id_copy(&dest->id, &src->id);
- if (dest->ani) {
- ast_free(dest->ani);
- }
+ ast_free(dest->ani);
dest->ani = ast_strdup(src->ani);
dest->ani2 = src->ani2;
-#endif
}
-void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected)
+void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
{
if (&chan->connected == connected) {
/* Don't set to self */
@@ -7391,30 +7522,38 @@ void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_p
}
ast_channel_lock(chan);
- ast_party_connected_line_set(&chan->connected, connected);
+ ast_party_connected_line_set(&chan->connected, connected, update);
ast_channel_unlock(chan);
}
-/*!
- * \brief Element identifiers for connected line indication frame data
- * \note Only add to the end of this enum.
- */
-enum {
- AST_CONNECTED_LINE_NUMBER,
- AST_CONNECTED_LINE_NAME,
- AST_CONNECTED_LINE_NUMBER_TYPE,
- AST_CONNECTED_LINE_NUMBER_PRESENTATION,
- AST_CONNECTED_LINE_SOURCE,
- AST_CONNECTED_LINE_SUBADDRESS,
- AST_CONNECTED_LINE_SUBADDRESS_TYPE,
- AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
- AST_CONNECTED_LINE_SUBADDRESS_VALID,
- AST_CONNECTED_LINE_TAG,
+/*! \note Should follow struct ast_party_name */
+struct ast_party_name_ies {
+ /*! \brief Subscriber name ie */
+ int str;
+ /*! \brief Character set ie. */
+ int char_set;
+ /*! \brief presentation-indicator ie */
+ int presentation;
+ /*! \brief valid/present ie */
+ int valid;
};
-int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected)
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party name information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param name Party name information
+ * \param label Name of particular party name
+ * \param ies Data frame ie values for the party name components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int party_name_build_data(unsigned char *data, size_t datalen, const struct ast_party_name *name, const char *label, const struct ast_party_name_ies *ies)
{
- int32_t value;
size_t length;
size_t pos = 0;
@@ -7422,110 +7561,383 @@ int ast_connected_line_build_data(unsigned char *data, size_t datalen, const str
* The size of integer values must be fixed in case the frame is
* shipped to another machine.
*/
-
- /* *************** Connected line party id *************** */
- if (connected->id.number) {
- length = strlen(connected->id.number);
+ if (name->str) {
+ length = strlen(name->str);
if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for connected line number\n");
+ ast_log(LOG_WARNING, "No space left for %s name\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_NUMBER;
+ data[pos++] = ies->str;
data[pos++] = length;
- memcpy(data + pos, connected->id.number, length);
+ memcpy(data + pos, name->str, length);
pos += length;
}
- if (connected->id.name) {
- length = strlen(connected->id.name);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for connected line name\n");
- return -1;
- }
- data[pos++] = AST_CONNECTED_LINE_NAME;
- data[pos++] = length;
- memcpy(data + pos, connected->id.name, length);
- pos += length;
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s name char set\n", label);
+ return -1;
}
+ data[pos++] = ies->char_set;
+ data[pos++] = 1;
+ data[pos++] = name->char_set;
+
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s name presentation\n", label);
+ return -1;
+ }
+ data[pos++] = ies->presentation;
+ data[pos++] = 1;
+ data[pos++] = name->presentation;
+
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s name valid\n", label);
+ return -1;
+ }
+ data[pos++] = ies->valid;
+ data[pos++] = 1;
+ data[pos++] = name->valid;
+
+ return pos;
+}
- if (connected->id.tag) {
- length = strlen(connected->id.tag);
+/*! \note Should follow struct ast_party_number */
+struct ast_party_number_ies {
+ /*! \brief Subscriber phone number ie */
+ int str;
+ /*! \brief Type-Of-Number and Numbering-Plan ie */
+ int plan;
+ /*! \brief presentation-indicator ie */
+ int presentation;
+ /*! \brief valid/present ie */
+ int valid;
+};
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party number information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param number Party number information
+ * \param label Name of particular party number
+ * \param ies Data frame ie values for the party number components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int party_number_build_data(unsigned char *data, size_t datalen, const struct ast_party_number *number, const char *label, const struct ast_party_number_ies *ies)
+{
+ size_t length;
+ size_t pos = 0;
+
+ /*
+ * The size of integer values must be fixed in case the frame is
+ * shipped to another machine.
+ */
+ if (number->str) {
+ length = strlen(number->str);
if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for connected line tag\n");
+ ast_log(LOG_WARNING, "No space left for %s number\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_TAG;
+ data[pos++] = ies->str;
data[pos++] = length;
- memcpy(data + pos, connected->id.tag, length);
+ memcpy(data + pos, number->str, length);
pos += length;
}
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for connected line type of number\n");
+ ast_log(LOG_WARNING, "No space left for %s numbering plan\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_NUMBER_TYPE;
+ data[pos++] = ies->plan;
data[pos++] = 1;
- data[pos++] = connected->id.number_type;
+ data[pos++] = number->plan;
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for connected line presentation\n");
+ ast_log(LOG_WARNING, "No space left for %s number presentation\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_NUMBER_PRESENTATION;
+ data[pos++] = ies->presentation;
data[pos++] = 1;
- data[pos++] = connected->id.number_presentation;
+ data[pos++] = number->presentation;
- /* Connected line source */
- if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
- ast_log(LOG_WARNING, "No space left for connected line source\n");
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s number valid\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SOURCE;
- data[pos++] = sizeof(value);
- value = htonl(connected->source);
- memcpy(data + pos, &value, sizeof(value));
- pos += sizeof(value);
+ data[pos++] = ies->valid;
+ data[pos++] = 1;
+ data[pos++] = number->valid;
+
+ return pos;
+}
+
+/*! \note Should follow struct ast_party_subaddress */
+struct ast_party_subaddress_ies {
+ /*! \brief subaddress ie. */
+ int str;
+ /*! \brief subaddress type ie */
+ int type;
+ /*! \brief odd/even indicator ie */
+ int odd_even_indicator;
+ /*! \brief valid/present ie */
+ int valid;
+};
- /* Connected line Subaddress */
- if (connected->id.subaddress.str) {
- length = strlen(connected->id.subaddress.str);
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party subaddress information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param subaddress Party subaddress information
+ * \param label Name of particular party subaddress
+ * \param ies Data frame ie values for the party subaddress components
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int party_subaddress_build_data(unsigned char *data, size_t datalen, const struct ast_party_subaddress *subaddress, const char *label, const struct ast_party_subaddress_ies *ies)
+{
+ size_t length;
+ size_t pos = 0;
+
+ /*
+ * The size of integer values must be fixed in case the frame is
+ * shipped to another machine.
+ */
+ if (subaddress->str) {
+ length = strlen(subaddress->str);
if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for connected line subaddress\n");
+ ast_log(LOG_WARNING, "No space left for %s subaddress\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SUBADDRESS;
+ data[pos++] = ies->str;
data[pos++] = length;
- memcpy(data + pos, connected->id.subaddress.str, length);
+ memcpy(data + pos, subaddress->str, length);
pos += length;
}
- /* Connected line Subaddress Type */
+
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for connected line type of subaddress\n");
+ ast_log(LOG_WARNING, "No space left for %s type of subaddress\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_TYPE;
+ data[pos++] = ies->type;
data[pos++] = 1;
- data[pos++] = connected->id.subaddress.type;
+ data[pos++] = subaddress->type;
- /* Connected line Subaddress Odd/Even indicator */
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
ast_log(LOG_WARNING,
- "No space left for connected line subaddress odd-even indicator\n");
+ "No space left for %s subaddress odd-even indicator\n", label);
+ return -1;
+ }
+ data[pos++] = ies->odd_even_indicator;
+ data[pos++] = 1;
+ data[pos++] = subaddress->odd_even_indicator;
+
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s subaddress valid\n", label);
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN;
+ data[pos++] = ies->valid;
data[pos++] = 1;
- data[pos++] = connected->id.subaddress.odd_even_indicator;
+ data[pos++] = subaddress->valid;
+
+ return pos;
+}
+
+/*! \note Should follow struct ast_party_id */
+struct ast_party_id_ies {
+ /*! \brief Subscriber name ies */
+ struct ast_party_name_ies name;
+ /*! \brief Subscriber phone number ies */
+ struct ast_party_number_ies number;
+ /*! \brief Subscriber subaddress ies. */
+ struct ast_party_subaddress_ies subaddress;
+ /*! \brief User party id tag ie. */
+ int tag;
+ /*! \brief Combined name and number presentation ie. */
+ int combined_presentation;
+};
+
+/*!
+ * \internal
+ * \since 1.8
+ * \brief Build a party id information data frame component.
+ *
+ * \param data Buffer to fill with the frame data
+ * \param datalen Size of the buffer to fill
+ * \param id Party id information
+ * \param label Name of particular party id
+ * \param ies Data frame ie values for the party id components
+ * \param update What id information to build. NULL if all.
+ *
+ * \retval -1 if error
+ * \retval Amount of data buffer used
+ */
+static int party_id_build_data(unsigned char *data, size_t datalen,
+ const struct ast_party_id *id, const char *label, const struct ast_party_id_ies *ies,
+ const struct ast_set_party_id *update)
+{
+ size_t length;
+ size_t pos = 0;
+ int res;
+
+ /*
+ * The size of integer values must be fixed in case the frame is
+ * shipped to another machine.
+ */
+
+ if (!update || update->name) {
+ res = party_name_build_data(data + pos, datalen - pos, &id->name, label,
+ &ies->name);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+ }
+
+ if (!update || update->number) {
+ res = party_number_build_data(data + pos, datalen - pos, &id->number, label,
+ &ies->number);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+ }
+
+ if (!update || update->subaddress) {
+ res = party_subaddress_build_data(data + pos, datalen - pos, &id->subaddress,
+ label, &ies->subaddress);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+ }
+
+ /* *************** Party id user tag **************************** */
+ if (id->tag) {
+ length = strlen(id->tag);
+ if (datalen < pos + (sizeof(data[0]) * 2) + length) {
+ ast_log(LOG_WARNING, "No space left for %s tag\n", label);
+ return -1;
+ }
+ data[pos++] = ies->tag;
+ data[pos++] = length;
+ memcpy(data + pos, id->tag, length);
+ pos += length;
+ }
+
+ /* *************** Party id combined presentation *************** */
+ if (!update || update->number) {
+ int presentation;
+
+ if (!update || update->name) {
+ presentation = ast_party_id_presentation(id);
+ } else {
+ /*
+ * We must compromise because not all the information is available
+ * to determine a combined presentation value.
+ * We will only send the number presentation instead.
+ */
+ presentation = id->number.presentation;
+ }
+
+ if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
+ ast_log(LOG_WARNING, "No space left for %s combined presentation\n", label);
+ return -1;
+ }
+ data[pos++] = ies->combined_presentation;
+ data[pos++] = 1;
+ data[pos++] = presentation;
+ }
+
+ return pos;
+}
+
+/*!
+ * \brief Element identifiers for connected line indication frame data
+ * \note Only add to the end of this enum.
+ */
+enum {
+ AST_CONNECTED_LINE_NUMBER,
+ AST_CONNECTED_LINE_NAME,
+ AST_CONNECTED_LINE_NUMBER_PLAN,
+ AST_CONNECTED_LINE_ID_PRESENTATION,/* Combined number and name presentation. */
+ AST_CONNECTED_LINE_SOURCE,
+ AST_CONNECTED_LINE_SUBADDRESS,
+ AST_CONNECTED_LINE_SUBADDRESS_TYPE,
+ AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
+ AST_CONNECTED_LINE_SUBADDRESS_VALID,
+ AST_CONNECTED_LINE_TAG,
+ AST_CONNECTED_LINE_VERSION,
+ AST_CONNECTED_LINE_NAME_VALID,
+ AST_CONNECTED_LINE_NAME_CHAR_SET,
+ AST_CONNECTED_LINE_NAME_PRESENTATION,
+ AST_CONNECTED_LINE_NUMBER_VALID,
+ AST_CONNECTED_LINE_NUMBER_PRESENTATION,
+};
- /* Connected line Subaddress Valid */
+int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
+{
+ int32_t value;
+ size_t pos = 0;
+ int res;
+
+ static const struct ast_party_id_ies ies = {
+ .name.str = AST_CONNECTED_LINE_NAME,
+ .name.char_set = AST_CONNECTED_LINE_NAME_CHAR_SET,
+ .name.presentation = AST_CONNECTED_LINE_NAME_PRESENTATION,
+ .name.valid = AST_CONNECTED_LINE_NAME_VALID,
+
+ .number.str = AST_CONNECTED_LINE_NUMBER,
+ .number.plan = AST_CONNECTED_LINE_NUMBER_PLAN,
+ .number.presentation = AST_CONNECTED_LINE_NUMBER_PRESENTATION,
+ .number.valid = AST_CONNECTED_LINE_NUMBER_VALID,
+
+ .subaddress.str = AST_CONNECTED_LINE_SUBADDRESS,
+ .subaddress.type = AST_CONNECTED_LINE_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_CONNECTED_LINE_SUBADDRESS_VALID,
+
+ .tag = AST_CONNECTED_LINE_TAG,
+ .combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
+ };
+
+ /*
+ * The size of integer values must be fixed in case the frame is
+ * shipped to another machine.
+ */
+
+ /* Connected line frame version */
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for connected line subaddress valid\n");
+ ast_log(LOG_WARNING, "No space left for connected line frame version\n");
return -1;
}
- data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_VALID;
+ data[pos++] = AST_CONNECTED_LINE_VERSION;
data[pos++] = 1;
- data[pos++] = connected->id.subaddress.valid;
+ data[pos++] = 2;/* Version 1 did not have a version ie */
+
+ res = party_id_build_data(data + pos, datalen - pos, &connected->id,
+ "connected line", &ies, update ? &update->id : NULL);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+
+ /* Connected line source */
+ if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
+ ast_log(LOG_WARNING, "No space left for connected line source\n");
+ return -1;
+ }
+ data[pos++] = AST_CONNECTED_LINE_SOURCE;
+ data[pos++] = sizeof(value);
+ value = htonl(connected->source);
+ memcpy(data + pos, &value, sizeof(value));
+ pos += sizeof(value);
return pos;
}
@@ -7536,6 +7948,9 @@ int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, str
unsigned char ie_len;
unsigned char ie_id;
int32_t value;
+ int frame_version = 1;
+ int combined_presentation = 0;
+ int got_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
for (pos = 0; pos < datalen; pos += ie_len) {
if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
@@ -7550,62 +7965,94 @@ int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, str
}
switch (ie_id) {
- case AST_CONNECTED_LINE_NUMBER:
- if (connected->id.number) {
- ast_free(connected->id.number);
- }
- connected->id.number = ast_malloc(ie_len + 1);
- if (connected->id.number) {
- memcpy(connected->id.number, data + pos, ie_len);
- connected->id.number[ie_len] = 0;
+/* Connected line party frame version */
+ case AST_CONNECTED_LINE_VERSION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line frame version (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ frame_version = data[pos];
break;
+/* Connected line party id name */
case AST_CONNECTED_LINE_NAME:
- if (connected->id.name) {
- ast_free(connected->id.name);
+ ast_free(connected->id.name.str);
+ connected->id.name.str = ast_malloc(ie_len + 1);
+ if (connected->id.name.str) {
+ memcpy(connected->id.name.str, data + pos, ie_len);
+ connected->id.name.str[ie_len] = 0;
}
- connected->id.name = ast_malloc(ie_len + 1);
- if (connected->id.name) {
- memcpy(connected->id.name, data + pos, ie_len);
- connected->id.name[ie_len] = 0;
+ break;
+ case AST_CONNECTED_LINE_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ connected->id.name.char_set = data[pos];
break;
- case AST_CONNECTED_LINE_TAG:
- if (connected->id.tag) {
- ast_free(connected->id.tag);
+ case AST_CONNECTED_LINE_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
}
- connected->id.tag = ast_malloc(ie_len + 1);
- if (connected->id.tag) {
- memcpy(connected->id.tag, data + pos, ie_len);
- connected->id.tag[ie_len] = 0;
+ connected->id.name.presentation = data[pos];
+ break;
+ case AST_CONNECTED_LINE_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->id.name.valid = data[pos];
+ break;
+/* Connected line party id number */
+ case AST_CONNECTED_LINE_NUMBER:
+ ast_free(connected->id.number.str);
+ connected->id.number.str = ast_malloc(ie_len + 1);
+ if (connected->id.number.str) {
+ memcpy(connected->id.number.str, data + pos, ie_len);
+ connected->id.number.str[ie_len] = 0;
}
break;
- case AST_CONNECTED_LINE_NUMBER_TYPE:
+ case AST_CONNECTED_LINE_NUMBER_PLAN:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid connected line type of number (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid connected line numbering plan (%u)\n",
+ (unsigned) ie_len);
break;
}
- connected->id.number_type = data[pos];
+ connected->id.number.plan = data[pos];
break;
case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid connected line presentation (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid connected line number presentation (%u)\n",
+ (unsigned) ie_len);
break;
}
- connected->id.number_presentation = data[pos];
+ connected->id.number.presentation = data[pos];
break;
- case AST_CONNECTED_LINE_SOURCE:
- if (ie_len != sizeof(value)) {
- ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", (unsigned) ie_len);
+ case AST_CONNECTED_LINE_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line number valid (%u)\n",
+ (unsigned) ie_len);
break;
}
- memcpy(&value, data + pos, sizeof(value));
- connected->source = ntohl(value);
+ connected->id.number.valid = data[pos];
break;
- case AST_CONNECTED_LINE_SUBADDRESS:
- if (connected->id.subaddress.str) {
- ast_free(connected->id.subaddress.str);
+/* Connected line party id combined presentation */
+ case AST_CONNECTED_LINE_ID_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line combined presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ combined_presentation = data[pos];
+ got_combined_presentation = 1;
+ break;
+/* Connected line party id subaddress */
+ case AST_CONNECTED_LINE_SUBADDRESS:
+ ast_free(connected->id.subaddress.str);
connected->id.subaddress.str = ast_malloc(ie_len + 1);
if (connected->id.subaddress.str) {
memcpy(connected->id.subaddress.str, data + pos, ie_len);
@@ -7637,21 +8084,69 @@ int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, str
}
connected->id.subaddress.valid = data[pos];
break;
+/* Connected line party tag */
+ case AST_CONNECTED_LINE_TAG:
+ ast_free(connected->id.tag);
+ connected->id.tag = ast_malloc(ie_len + 1);
+ if (connected->id.tag) {
+ memcpy(connected->id.tag, data + pos, ie_len);
+ connected->id.tag[ie_len] = 0;
+ }
+ break;
+/* Connected line party source */
+ case AST_CONNECTED_LINE_SOURCE:
+ if (ie_len != sizeof(value)) {
+ ast_log(LOG_WARNING, "Invalid connected line source (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ memcpy(&value, data + pos, sizeof(value));
+ connected->source = ntohl(value);
+ break;
+/* Connected line party unknown element */
default:
- ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", (unsigned) ie_id, (unsigned) ie_len);
+ ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n",
+ (unsigned) ie_id, (unsigned) ie_len);
break;
}
}
+ switch (frame_version) {
+ case 1:
+ /*
+ * The other end is an earlier version that we need to adjust
+ * for compatibility.
+ */
+ connected->id.name.valid = 1;
+ connected->id.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
+ connected->id.number.valid = 1;
+ if (got_combined_presentation) {
+ connected->id.name.presentation = combined_presentation;
+ connected->id.number.presentation = combined_presentation;
+ }
+ break;
+ case 2:
+ /* The other end is at the same level as we are. */
+ break;
+ default:
+ /*
+ * The other end is newer than we are.
+ * We need to assume that they are compatible with us.
+ */
+ ast_log(LOG_DEBUG, "Connected line frame has newer version: %u\n",
+ (unsigned) frame_version);
+ break;
+ }
+
return 0;
}
-void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected)
+void ast_channel_update_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
{
unsigned char data[1024]; /* This should be large enough */
size_t datalen;
- datalen = ast_connected_line_build_data(data, sizeof(data), connected);
+ datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
if (datalen == (size_t) -1) {
return;
}
@@ -7659,12 +8154,12 @@ void ast_channel_update_connected_line(struct ast_channel *chan, const struct as
ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
}
-void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected)
+void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
{
unsigned char data[1024]; /* This should be large enough */
size_t datalen;
- datalen = ast_connected_line_build_data(data, sizeof(data), connected);
+ datalen = ast_connected_line_build_data(data, sizeof(data), connected, update);
if (datalen == (size_t) -1) {
return;
}
@@ -7672,7 +8167,7 @@ void ast_channel_queue_connected_line_update(struct ast_channel *chan, const str
ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
}
-void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting)
+void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
{
if (&chan->redirecting == redirecting) {
/* Don't set to self */
@@ -7680,12 +8175,7 @@ void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_part
}
ast_channel_lock(chan);
-
- ast_party_id_set(&chan->redirecting.from, &redirecting->from);
- ast_party_id_set(&chan->redirecting.to, &redirecting->to);
- chan->redirecting.reason = redirecting->reason;
- chan->redirecting.count = redirecting->count;
-
+ ast_party_redirecting_set(&chan->redirecting, redirecting, update);
ast_channel_unlock(chan);
}
@@ -7696,12 +8186,12 @@ void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_part
enum {
AST_REDIRECTING_FROM_NUMBER,
AST_REDIRECTING_FROM_NAME,
- AST_REDIRECTING_FROM_NUMBER_TYPE,
- AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
+ AST_REDIRECTING_FROM_NUMBER_PLAN,
+ AST_REDIRECTING_FROM_ID_PRESENTATION,
AST_REDIRECTING_TO_NUMBER,
AST_REDIRECTING_TO_NAME,
- AST_REDIRECTING_TO_NUMBER_TYPE,
- AST_REDIRECTING_TO_NUMBER_PRESENTATION,
+ AST_REDIRECTING_TO_NUMBER_PLAN,
+ AST_REDIRECTING_TO_ID_PRESENTATION,
AST_REDIRECTING_REASON,
AST_REDIRECTING_COUNT,
AST_REDIRECTING_FROM_SUBADDRESS,
@@ -7714,200 +8204,86 @@ enum {
AST_REDIRECTING_TO_SUBADDRESS_VALID,
AST_REDIRECTING_FROM_TAG,
AST_REDIRECTING_TO_TAG,
+ AST_REDIRECTING_VERSION,
+ AST_REDIRECTING_FROM_NAME_VALID,
+ AST_REDIRECTING_FROM_NAME_CHAR_SET,
+ AST_REDIRECTING_FROM_NAME_PRESENTATION,
+ AST_REDIRECTING_FROM_NUMBER_VALID,
+ AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
+ AST_REDIRECTING_TO_NAME_VALID,
+ AST_REDIRECTING_TO_NAME_CHAR_SET,
+ AST_REDIRECTING_TO_NAME_PRESENTATION,
+ AST_REDIRECTING_TO_NUMBER_VALID,
+ AST_REDIRECTING_TO_NUMBER_PRESENTATION,
};
-int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting)
+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;
- size_t length;
size_t pos = 0;
+ int res;
- /*
- * The size of integer values must be fixed in case the frame is
- * shipped to another machine.
- */
-
- /* *************** Redirecting from party id *************** */
- if (redirecting->from.number) {
- length = strlen(redirecting->from.number);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting from number\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_NUMBER;
- data[pos++] = length;
- memcpy(data + pos, redirecting->from.number, length);
- pos += length;
- }
-
- if (redirecting->from.name) {
- length = strlen(redirecting->from.name);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting from name\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_NAME;
- data[pos++] = length;
- memcpy(data + pos, redirecting->from.name, length);
- pos += length;
- }
-
- if (redirecting->from.tag) {
- length = strlen(redirecting->from.tag);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting from name\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_TAG;
- data[pos++] = length;
- memcpy(data + pos, redirecting->from.tag, length);
- pos += length;
- }
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting from type of number\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_NUMBER_TYPE;
- data[pos++] = 1;
- data[pos++] = redirecting->from.number_type;
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting from presentation\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_NUMBER_PRESENTATION;
- data[pos++] = 1;
- data[pos++] = redirecting->from.number_presentation;
-
- /* subaddress */
- if (redirecting->from.subaddress.str) {
- length = strlen(redirecting->from.subaddress.str);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting-from subaddress\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_SUBADDRESS;
- data[pos++] = length;
- memcpy(data + pos, redirecting->from.subaddress.str, length);
- pos += length;
- }
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting-from type of subaddress\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_SUBADDRESS_TYPE;
- data[pos++] = 1;
- data[pos++] = redirecting->from.subaddress.type;
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING,
- "No space left for redirecting-from subaddress odd-even indicator\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN;
- data[pos++] = 1;
- data[pos++] = redirecting->from.subaddress.odd_even_indicator;
-
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting-from subaddress valid\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_FROM_SUBADDRESS_VALID;
- data[pos++] = 1;
- data[pos++] = redirecting->from.subaddress.valid;
-
- /* *************** Redirecting to party id *************** */
- if (redirecting->to.number) {
- length = strlen(redirecting->to.number);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting to number\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_NUMBER;
- data[pos++] = length;
- memcpy(data + pos, redirecting->to.number, length);
- pos += length;
- }
-
- if (redirecting->to.name) {
- length = strlen(redirecting->to.name);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting to name\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_NAME;
- data[pos++] = length;
- memcpy(data + pos, redirecting->to.name, length);
- pos += length;
- }
-
- if (redirecting->to.tag) {
- length = strlen(redirecting->to.tag);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting to name\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_TAG;
- data[pos++] = length;
- memcpy(data + pos, redirecting->to.tag, length);
- pos += length;
- }
+ static const struct ast_party_id_ies from_ies = {
+ .name.str = AST_REDIRECTING_FROM_NAME,
+ .name.char_set = AST_REDIRECTING_FROM_NAME_CHAR_SET,
+ .name.presentation = AST_REDIRECTING_FROM_NAME_PRESENTATION,
+ .name.valid = AST_REDIRECTING_FROM_NAME_VALID,
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting to type of number\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_NUMBER_TYPE;
- data[pos++] = 1;
- data[pos++] = redirecting->to.number_type;
+ .number.str = AST_REDIRECTING_FROM_NUMBER,
+ .number.plan = AST_REDIRECTING_FROM_NUMBER_PLAN,
+ .number.presentation = AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
+ .number.valid = AST_REDIRECTING_FROM_NUMBER_VALID,
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting to presentation\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_NUMBER_PRESENTATION;
- data[pos++] = 1;
- data[pos++] = redirecting->to.number_presentation;
+ .subaddress.str = AST_REDIRECTING_FROM_SUBADDRESS,
+ .subaddress.type = AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_REDIRECTING_FROM_SUBADDRESS_VALID,
- /* subaddress */
- if (redirecting->to.subaddress.str) {
- length = strlen(redirecting->to.subaddress.str);
- if (datalen < pos + (sizeof(data[0]) * 2) + length) {
- ast_log(LOG_WARNING, "No space left for redirecting-to subaddress\n");
- return -1;
- }
- data[pos++] = AST_REDIRECTING_TO_SUBADDRESS;
- data[pos++] = length;
- memcpy(data + pos, redirecting->to.subaddress.str, length);
- pos += length;
- }
+ .tag = AST_REDIRECTING_FROM_TAG,
+ .combined_presentation = AST_REDIRECTING_FROM_ID_PRESENTATION,
+ };
+ static const struct ast_party_id_ies to_ies = {
+ .name.str = AST_REDIRECTING_TO_NAME,
+ .name.char_set = AST_REDIRECTING_TO_NAME_CHAR_SET,
+ .name.presentation = AST_REDIRECTING_TO_NAME_PRESENTATION,
+ .name.valid = AST_REDIRECTING_TO_NAME_VALID,
+
+ .number.str = AST_REDIRECTING_TO_NUMBER,
+ .number.plan = AST_REDIRECTING_TO_NUMBER_PLAN,
+ .number.presentation = AST_REDIRECTING_TO_NUMBER_PRESENTATION,
+ .number.valid = AST_REDIRECTING_TO_NUMBER_VALID,
+
+ .subaddress.str = AST_REDIRECTING_TO_SUBADDRESS,
+ .subaddress.type = AST_REDIRECTING_TO_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_REDIRECTING_TO_SUBADDRESS_VALID,
+
+ .tag = AST_REDIRECTING_TO_TAG,
+ .combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
+ };
+ /* Redirecting frame version */
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting-to type of subaddress\n");
+ ast_log(LOG_WARNING, "No space left for redirecting frame version\n");
return -1;
}
- data[pos++] = AST_REDIRECTING_TO_SUBADDRESS_TYPE;
+ data[pos++] = AST_REDIRECTING_VERSION;
data[pos++] = 1;
- data[pos++] = redirecting->to.subaddress.type;
+ data[pos++] = 2;/* Version 1 did not have a version ie */
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING,
- "No space left for redirecting-to subaddress odd-even indicator\n");
+ res = party_id_build_data(data + pos, datalen - pos, &redirecting->from,
+ "redirecting-from", &from_ies, update ? &update->from : NULL);
+ if (res < 0) {
return -1;
}
- data[pos++] = AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN;
- data[pos++] = 1;
- data[pos++] = redirecting->to.subaddress.odd_even_indicator;
+ pos += res;
- if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
- ast_log(LOG_WARNING, "No space left for redirecting-to subaddress valid\n");
+ res = party_id_build_data(data + pos, datalen - pos, &redirecting->to,
+ "redirecting-to", &to_ies, update ? &update->to : NULL);
+ if (res < 0) {
return -1;
}
- data[pos++] = AST_REDIRECTING_TO_SUBADDRESS_VALID;
- data[pos++] = 1;
- data[pos++] = redirecting->to.subaddress.valid;
+ pos += res;
/* Redirecting reason */
if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
@@ -7940,6 +8316,11 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
unsigned char ie_len;
unsigned char ie_id;
int32_t value;
+ int frame_version = 1;
+ int from_combined_presentation = 0;
+ int got_from_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
+ int to_combined_presentation = 0;
+ int got_to_combined_presentation = 0;/* TRUE if got a combined name and number presentation value. */
for (pos = 0; pos < datalen; pos += ie_len) {
if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
@@ -7954,54 +8335,94 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
}
switch (ie_id) {
- case AST_REDIRECTING_FROM_NUMBER:
- if (redirecting->from.number) {
- ast_free(redirecting->from.number);
- }
- redirecting->from.number = ast_malloc(ie_len + 1);
- if (redirecting->from.number) {
- memcpy(redirecting->from.number, data + pos, ie_len);
- redirecting->from.number[ie_len] = 0;
+/* Redirecting frame version */
+ case AST_REDIRECTING_VERSION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting frame version (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ frame_version = data[pos];
break;
+/* Redirecting-from party id name */
case AST_REDIRECTING_FROM_NAME:
- if (redirecting->from.name) {
- ast_free(redirecting->from.name);
+ ast_free(redirecting->from.name.str);
+ redirecting->from.name.str = ast_malloc(ie_len + 1);
+ if (redirecting->from.name.str) {
+ memcpy(redirecting->from.name.str, data + pos, ie_len);
+ redirecting->from.name.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_FROM_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
}
- redirecting->from.name = ast_malloc(ie_len + 1);
- if (redirecting->from.name) {
- memcpy(redirecting->from.name, data + pos, ie_len);
- redirecting->from.name[ie_len] = 0;
+ redirecting->from.name.char_set = data[pos];
+ break;
+ case AST_REDIRECTING_FROM_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ redirecting->from.name.presentation = data[pos];
break;
- case AST_REDIRECTING_FROM_TAG:
- if (redirecting->from.tag) {
- ast_free(redirecting->from.tag);
+ case AST_REDIRECTING_FROM_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
}
- redirecting->from.tag = ast_malloc(ie_len + 1);
- if (redirecting->from.tag) {
- memcpy(redirecting->from.tag, data + pos, ie_len);
- redirecting->from.tag[ie_len] = 0;
+ redirecting->from.name.valid = data[pos];
+ break;
+/* Redirecting-from party id number */
+ case AST_REDIRECTING_FROM_NUMBER:
+ ast_free(redirecting->from.number.str);
+ redirecting->from.number.str = ast_malloc(ie_len + 1);
+ if (redirecting->from.number.str) {
+ memcpy(redirecting->from.number.str, data + pos, ie_len);
+ redirecting->from.number.str[ie_len] = 0;
}
break;
- case AST_REDIRECTING_FROM_NUMBER_TYPE:
+ case AST_REDIRECTING_FROM_NUMBER_PLAN:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting from type of number (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting-from numbering plan (%u)\n",
+ (unsigned) ie_len);
break;
}
- redirecting->from.number_type = data[pos];
+ redirecting->from.number.plan = data[pos];
break;
case AST_REDIRECTING_FROM_NUMBER_PRESENTATION:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting from presentation (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting-from number presentation (%u)\n",
+ (unsigned) ie_len);
break;
}
- redirecting->from.number_presentation = data[pos];
+ redirecting->from.number.presentation = data[pos];
break;
- case AST_REDIRECTING_FROM_SUBADDRESS:
- if (redirecting->from.subaddress.str) {
- ast_free(redirecting->from.subaddress.str);
+ case AST_REDIRECTING_FROM_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from number valid (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ redirecting->from.number.valid = data[pos];
+ break;
+/* Redirecting-from party id combined presentation */
+ case AST_REDIRECTING_FROM_ID_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-from combined presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ from_combined_presentation = data[pos];
+ got_from_combined_presentation = 1;
+ break;
+/* Redirecting-from party id subaddress */
+ case AST_REDIRECTING_FROM_SUBADDRESS:
+ ast_free(redirecting->from.subaddress.str);
redirecting->from.subaddress.str = ast_malloc(ie_len + 1);
if (redirecting->from.subaddress.str) {
memcpy(redirecting->from.subaddress.str, data + pos, ie_len);
@@ -8010,7 +8431,7 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
break;
case AST_REDIRECTING_FROM_SUBADDRESS_TYPE:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting from type of subaddress (%u)\n",
+ ast_log(LOG_WARNING, "Invalid redirecting-from type of subaddress (%u)\n",
(unsigned) ie_len);
break;
}
@@ -8019,7 +8440,7 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
case AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN:
if (ie_len != 1) {
ast_log(LOG_WARNING,
- "Invalid redirecting from subaddress odd-even indicator (%u)\n",
+ "Invalid redirecting-from subaddress odd-even indicator (%u)\n",
(unsigned) ie_len);
break;
}
@@ -8027,60 +8448,100 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
break;
case AST_REDIRECTING_FROM_SUBADDRESS_VALID:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting from subaddress valid (%u)\n",
+ ast_log(LOG_WARNING, "Invalid redirecting-from subaddress valid (%u)\n",
(unsigned) ie_len);
break;
}
redirecting->from.subaddress.valid = data[pos];
break;
- case AST_REDIRECTING_TO_NUMBER:
- if (redirecting->to.number) {
- ast_free(redirecting->to.number);
- }
- redirecting->to.number = ast_malloc(ie_len + 1);
- if (redirecting->to.number) {
- memcpy(redirecting->to.number, data + pos, ie_len);
- redirecting->to.number[ie_len] = 0;
+/* Redirecting-from party id tag */
+ case AST_REDIRECTING_FROM_TAG:
+ ast_free(redirecting->from.tag);
+ redirecting->from.tag = ast_malloc(ie_len + 1);
+ if (redirecting->from.tag) {
+ memcpy(redirecting->from.tag, data + pos, ie_len);
+ redirecting->from.tag[ie_len] = 0;
}
break;
+/* Redirecting-to party id name */
case AST_REDIRECTING_TO_NAME:
- if (redirecting->to.name) {
- ast_free(redirecting->to.name);
+ ast_free(redirecting->to.name.str);
+ redirecting->to.name.str = ast_malloc(ie_len + 1);
+ if (redirecting->to.name.str) {
+ memcpy(redirecting->to.name.str, data + pos, ie_len);
+ redirecting->to.name.str[ie_len] = 0;
}
- redirecting->to.name = ast_malloc(ie_len + 1);
- if (redirecting->to.name) {
- memcpy(redirecting->to.name, data + pos, ie_len);
- redirecting->to.name[ie_len] = 0;
+ break;
+ case AST_REDIRECTING_TO_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ redirecting->to.name.char_set = data[pos];
break;
- case AST_REDIRECTING_TO_TAG:
- if (redirecting->to.tag) {
- ast_free(redirecting->to.tag);
+ case AST_REDIRECTING_TO_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
}
- redirecting->to.tag = ast_malloc(ie_len + 1);
- if (redirecting->to.tag) {
- memcpy(redirecting->to.tag, data + pos, ie_len);
- redirecting->to.tag[ie_len] = 0;
+ redirecting->to.name.presentation = data[pos];
+ break;
+ case AST_REDIRECTING_TO_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->to.name.valid = data[pos];
+ break;
+/* Redirecting-to party id number */
+ case AST_REDIRECTING_TO_NUMBER:
+ ast_free(redirecting->to.number.str);
+ redirecting->to.number.str = ast_malloc(ie_len + 1);
+ if (redirecting->to.number.str) {
+ memcpy(redirecting->to.number.str, data + pos, ie_len);
+ redirecting->to.number.str[ie_len] = 0;
}
break;
- case AST_REDIRECTING_TO_NUMBER_TYPE:
+ case AST_REDIRECTING_TO_NUMBER_PLAN:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting to type of number (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting-to numbering plan (%u)\n",
+ (unsigned) ie_len);
break;
}
- redirecting->to.number_type = data[pos];
+ redirecting->to.number.plan = data[pos];
break;
case AST_REDIRECTING_TO_NUMBER_PRESENTATION:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting to presentation (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting-to number presentation (%u)\n",
+ (unsigned) ie_len);
break;
}
- redirecting->to.number_presentation = data[pos];
+ redirecting->to.number.presentation = data[pos];
break;
- case AST_REDIRECTING_TO_SUBADDRESS:
- if (redirecting->to.subaddress.str) {
- ast_free(redirecting->to.subaddress.str);
+ case AST_REDIRECTING_TO_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to number valid (%u)\n",
+ (unsigned) ie_len);
+ break;
}
+ redirecting->to.number.valid = data[pos];
+ break;
+/* Redirecting-to party id combined presentation */
+ case AST_REDIRECTING_TO_ID_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid redirecting-to combined presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ to_combined_presentation = data[pos];
+ got_to_combined_presentation = 1;
+ break;
+/* Redirecting-to party id subaddress */
+ case AST_REDIRECTING_TO_SUBADDRESS:
+ ast_free(redirecting->to.subaddress.str);
redirecting->to.subaddress.str = ast_malloc(ie_len + 1);
if (redirecting->to.subaddress.str) {
memcpy(redirecting->to.subaddress.str, data + pos, ie_len);
@@ -8089,7 +8550,7 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
break;
case AST_REDIRECTING_TO_SUBADDRESS_TYPE:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting to type of subaddress (%u)\n",
+ ast_log(LOG_WARNING, "Invalid redirecting-to type of subaddress (%u)\n",
(unsigned) ie_len);
break;
}
@@ -8098,7 +8559,7 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
case AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN:
if (ie_len != 1) {
ast_log(LOG_WARNING,
- "Invalid redirecting to subaddress odd-even indicator (%u)\n",
+ "Invalid redirecting-to subaddress odd-even indicator (%u)\n",
(unsigned) ie_len);
break;
}
@@ -8106,43 +8567,93 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
break;
case AST_REDIRECTING_TO_SUBADDRESS_VALID:
if (ie_len != 1) {
- ast_log(LOG_WARNING, "Invalid redirecting to subaddress valid (%u)\n",
+ ast_log(LOG_WARNING, "Invalid redirecting-to subaddress valid (%u)\n",
(unsigned) ie_len);
break;
}
redirecting->to.subaddress.valid = data[pos];
break;
+/* Redirecting-to party id tag */
+ case AST_REDIRECTING_TO_TAG:
+ ast_free(redirecting->to.tag);
+ redirecting->to.tag = ast_malloc(ie_len + 1);
+ if (redirecting->to.tag) {
+ memcpy(redirecting->to.tag, data + pos, ie_len);
+ redirecting->to.tag[ie_len] = 0;
+ }
+ break;
+/* Redirecting reason */
case AST_REDIRECTING_REASON:
if (ie_len != sizeof(value)) {
- ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting reason (%u)\n",
+ (unsigned) ie_len);
break;
}
memcpy(&value, data + pos, sizeof(value));
redirecting->reason = ntohl(value);
break;
+/* Redirecting count */
case AST_REDIRECTING_COUNT:
if (ie_len != sizeof(value)) {
- ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n", (unsigned) ie_len);
+ ast_log(LOG_WARNING, "Invalid redirecting count (%u)\n",
+ (unsigned) ie_len);
break;
}
memcpy(&value, data + pos, sizeof(value));
redirecting->count = ntohl(value);
break;
+/* Redirecting unknown element */
default:
- ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n", (unsigned) ie_id, (unsigned) ie_len);
+ ast_log(LOG_DEBUG, "Unknown redirecting element: %u (%u)\n",
+ (unsigned) ie_id, (unsigned) ie_len);
break;
}
}
+ switch (frame_version) {
+ case 1:
+ /*
+ * The other end is an earlier version that we need to adjust
+ * for compatibility.
+ */
+ redirecting->from.name.valid = 1;
+ redirecting->from.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
+ redirecting->from.number.valid = 1;
+ if (got_from_combined_presentation) {
+ redirecting->from.name.presentation = from_combined_presentation;
+ redirecting->from.number.presentation = from_combined_presentation;
+ }
+
+ redirecting->to.name.valid = 1;
+ redirecting->to.name.char_set = AST_PARTY_CHAR_SET_ISO8859_1;
+ redirecting->to.number.valid = 1;
+ if (got_to_combined_presentation) {
+ redirecting->to.name.presentation = to_combined_presentation;
+ redirecting->to.number.presentation = to_combined_presentation;
+ }
+ break;
+ case 2:
+ /* The other end is at the same level as we are. */
+ break;
+ default:
+ /*
+ * The other end is newer than we are.
+ * We need to assume that they are compatible with us.
+ */
+ ast_log(LOG_DEBUG, "Redirecting frame has newer version: %u\n",
+ (unsigned) frame_version);
+ break;
+ }
+
return 0;
}
-void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting)
+void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
{
unsigned char data[1024]; /* This should be large enough */
size_t datalen;
- datalen = ast_redirecting_build_data(data, sizeof(data), redirecting);
+ datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
if (datalen == (size_t) -1) {
return;
}
@@ -8150,12 +8661,12 @@ void ast_channel_update_redirecting(struct ast_channel *chan, const struct ast_p
ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
}
-void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting)
+void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
{
unsigned char data[1024]; /* This should be large enough */
size_t datalen;
- datalen = ast_redirecting_build_data(data, sizeof(data), redirecting);
+ datalen = ast_redirecting_build_data(data, sizeof(data), redirecting, update);
if (datalen == (size_t) -1) {
return;
}
@@ -8193,7 +8704,7 @@ int ast_channel_connected_line_macro(struct ast_channel *autoservice_chan, struc
}
if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) {
- ast_channel_update_connected_line(macro_chan, &macro_chan->connected);
+ ast_channel_update_connected_line(macro_chan, &macro_chan->connected, NULL);
}
return retval;
@@ -8230,7 +8741,7 @@ int ast_channel_redirecting_macro(struct ast_channel *autoservice_chan, struct a
retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args);
if (!retval) {
- ast_channel_update_redirecting(macro_chan, &macro_chan->redirecting);
+ ast_channel_update_redirecting(macro_chan, &macro_chan->redirecting, NULL);
}
return retval;
diff --git a/main/cli.c b/main/cli.c
index 0b58c3461..c9dbc6d02 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -872,7 +872,7 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
ast_cli(a->fd, CONCISE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
c->appl ? c->appl : "(None)",
S_OR(c->data, ""), /* XXX different from verbose ? */
- S_OR(c->cid.cid_num, ""),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
S_OR(c->accountcode, ""),
S_OR(c->peeraccount, ""),
c->amaflags,
@@ -883,7 +883,7 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
ast_cli(a->fd, VERBOSE_FORMAT_STRING, c->name, c->context, c->exten, c->priority, ast_state2str(c->_state),
c->appl ? c->appl : "(None)",
c->data ? S_OR(c->data, "(Empty)" ): "(None)",
- S_OR(c->cid.cid_num, ""),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
durbuf,
S_OR(c->accountcode, ""),
S_OR(c->peeraccount, ""),
@@ -1417,9 +1417,9 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
" Data: %s\n"
" Blocking in: %s\n",
c->name, c->tech->type, c->uniqueid, c->linkedid,
- S_OR(c->cid.cid_num, "(N/A)"),
- S_OR(c->cid.cid_name, "(N/A)"),
- S_OR(c->cid.cid_dnid, "(N/A)"),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, "(N/A)"),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, "(N/A)"),
+ S_OR(c->dialed.number.str, "(N/A)"),
c->language,
ast_state2str(c->_state), c->_state, c->rings,
ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats),
diff --git a/main/dial.c b/main/dial.c
index bfd0c44a4..ba1a2bb53 100644
--- a/main/dial.c
+++ b/main/dial.c
@@ -268,9 +268,9 @@ static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_chann
/* Copy over callerid information */
ast_party_redirecting_copy(&channel->owner->redirecting, &chan->redirecting);
- channel->owner->cid.cid_tns = chan->cid.cid_tns;
+ channel->owner->dialed.transit_network_select = chan->dialed.transit_network_select;
- ast_connected_line_copy_from_caller(&channel->owner->connected, &chan->cid);
+ ast_connected_line_copy_from_caller(&channel->owner->connected, &chan->caller);
ast_string_field_set(channel->owner, language, chan->language);
ast_string_field_set(channel->owner, accountcode, chan->accountcode);
diff --git a/main/features.c b/main/features.c
index a107b4b7a..d5fc289f2 100644
--- a/main/features.c
+++ b/main/features.c
@@ -961,8 +961,8 @@ static int park_call_full(struct ast_channel *chan, struct ast_channel *peer, st
"Uniqueid: %s\r\n",
pu->parkingexten, pu->chan->name, pu->parkinglot->name, event_from ? event_from : "",
(long)pu->start.tv_sec + (long)(pu->parkingtime/1000) - (long)time(NULL),
- S_OR(pu->chan->cid.cid_num, "<unknown>"),
- S_OR(pu->chan->cid.cid_name, "<unknown>"),
+ S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
+ S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
pu->chan->uniqueid
);
@@ -1417,8 +1417,10 @@ static int builtin_automonitor(struct ast_channel *chan, struct ast_channel *pee
snprintf(touch_filename, len, "%s-%ld-%s", S_OR(touch_monitor_prefix, "auto"), (long)time(NULL), touch_monitor);
snprintf(args, len, "%s,%s,m", S_OR(touch_format, "wav"), touch_filename);
} else {
- caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
- callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
+ caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
+ caller_chan->caller.id.number.str, caller_chan->name));
+ callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
+ callee_chan->caller.id.number.str, callee_chan->name));
len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
args = alloca(len);
touch_filename = alloca(len);
@@ -1530,8 +1532,10 @@ static int builtin_automixmonitor(struct ast_channel *chan, struct ast_channel *
snprintf(touch_filename, len, "auto-%ld-%s", (long)time(NULL), touch_monitor);
snprintf(args, len, "%s.%s,b", touch_filename, (touch_format) ? touch_format : "wav");
} else {
- caller_chan_id = ast_strdupa(S_OR(caller_chan->cid.cid_num, caller_chan->name));
- callee_chan_id = ast_strdupa(S_OR(callee_chan->cid.cid_num, callee_chan->name));
+ caller_chan_id = ast_strdupa(S_COR(caller_chan->caller.id.number.valid,
+ caller_chan->caller.id.number.str, caller_chan->name));
+ callee_chan_id = ast_strdupa(S_COR(callee_chan->caller.id.number.valid,
+ callee_chan->caller.id.number.str, callee_chan->name));
len = strlen(caller_chan_id) + strlen(callee_chan_id) + 50;
args = alloca(len);
touch_filename = alloca(len);
@@ -1653,7 +1657,8 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p
ast_log(LOG_WARNING, "Unable to park call %s, parkstatus = %d\n", transferee->name, parkstatus);
}
/*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */
- } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
+ } else if (ast_exists_extension(transferee, transferer_real_context, xferto, 1,
+ S_COR(transferer->caller.id.number.valid, transferer->caller.id.number.str, NULL))) {
ast_cel_report_event(transferer, AST_CEL_BLINDTRANSFER, NULL, xferto, transferee);
pbx_builtin_setvar_helper(transferer, "BLINDTRANSFER", transferee->name);
pbx_builtin_setvar_helper(transferee, "BLINDTRANSFER", transferer->name);
@@ -1688,7 +1693,7 @@ static int builtin_blindtransfer(struct ast_channel *chan, struct ast_channel *p
ast_set_flag(transferee, AST_FLAG_BRIDGE_HANGUP_DONT); /* don't let the after-bridge code run the h-exten */
ast_log(LOG_DEBUG,"ABOUT TO AST_ASYNC_GOTO, have a pbx... set HANGUP_DONT on chan=%s\n", transferee->name);
if (ast_channel_connected_line_macro(transferee, transferer, &transferer->connected, 1, 0)) {
- ast_channel_update_connected_line(transferee, &transferer->connected);
+ ast_channel_update_connected_line(transferee, &transferer->connected, NULL);
}
set_c_e_p(transferee, transferer_real_context, xferto, 0);
}
@@ -1792,7 +1797,8 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
}
/* valid extension, res == 1 */
- if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1, transferer->cid.cid_num)) {
+ if (!ast_exists_extension(transferer, transferer_real_context, xferto, 1,
+ S_COR(transferer->caller.id.number.valid, transferer->caller.id.number.str, NULL))) {
ast_log(LOG_WARNING, "Extension %s does not exist in context %s\n",xferto,transferer_real_context);
finishup(transferee);
if (ast_stream_and_wait(transferer, "beeperr", ""))
@@ -1824,8 +1830,12 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
}
}
- newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
- xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
+ newchan = feature_request_and_dial(transferer, transferee, "Local",
+ ast_best_codec(transferer->nativeformats),
+ xferto, atxfernoanswertimeout, &outstate,
+ transferer->caller.id.number.valid ? transferer->caller.id.number.str : NULL,
+ transferer->caller.id.name.valid ? transferer->caller.id.name.str : NULL,
+ 1, transferer->language);
ast_party_connected_line_init(&connected_line);
if (!ast_check_hangup(transferer)) {
@@ -1979,14 +1989,14 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
*/
connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
- ast_channel_update_connected_line(xferchan, &connected_line);
+ ast_channel_update_connected_line(xferchan, &connected_line, NULL);
}
ast_channel_lock(xferchan);
- ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
+ ast_connected_line_copy_from_caller(&connected_line, &xferchan->caller);
ast_channel_unlock(xferchan);
connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
- ast_channel_update_connected_line(newchan, &connected_line);
+ ast_channel_update_connected_line(newchan, &connected_line, NULL);
}
ast_party_connected_line_free(&connected_line);
@@ -2016,15 +2026,23 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
}
ast_log(LOG_NOTICE, "We're trying to call %s/%s\n", transferer_tech, transferer_name);
- newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
- transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
+ newchan = feature_request_and_dial(transferee, NULL, transferer_tech,
+ ast_best_codec(transferee->nativeformats),
+ transferer_name, atxfernoanswertimeout, &outstate,
+ transferee->caller.id.number.valid ? transferee->caller.id.number.str : NULL,
+ transferee->caller.id.name.valid ? transferee->caller.id.name.str : NULL,
+ 0, transferer->language);
while (!newchan && !atxferdropcall && tries < atxfercallbackretries) {
/* Trying to transfer again */
ast_autoservice_start(transferee);
ast_indicate(transferee, AST_CONTROL_HOLD);
- newchan = feature_request_and_dial(transferer, transferee, "Local", ast_best_codec(transferer->nativeformats),
- xferto, atxfernoanswertimeout, &outstate, transferer->cid.cid_num, transferer->cid.cid_name, 1, transferer->language);
+ newchan = feature_request_and_dial(transferer, transferee, "Local",
+ ast_best_codec(transferer->nativeformats),
+ xferto, atxfernoanswertimeout, &outstate,
+ transferer->caller.id.number.valid ? transferer->caller.id.number.str : NULL,
+ transferer->caller.id.name.valid ? transferer->caller.id.name.str : NULL,
+ 1, transferer->language);
if (ast_autoservice_stop(transferee) < 0) {
if (newchan)
ast_hangup(newchan);
@@ -2035,8 +2053,12 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
ast_debug(1, "Sleeping for %d ms before callback.\n", atxferloopdelay);
ast_safe_sleep(transferee, atxferloopdelay);
ast_debug(1, "Trying to callback...\n");
- newchan = feature_request_and_dial(transferee, NULL, transferer_tech, ast_best_codec(transferee->nativeformats),
- transferer_name, atxfernoanswertimeout, &outstate, transferee->cid.cid_num, transferee->cid.cid_name, 0, transferer->language);
+ newchan = feature_request_and_dial(transferee, NULL, transferer_tech,
+ ast_best_codec(transferee->nativeformats),
+ transferer_name, atxfernoanswertimeout, &outstate,
+ transferee->caller.id.number.valid ? transferee->caller.id.number.str : NULL,
+ transferee->caller.id.name.valid ? transferee->caller.id.name.str : NULL,
+ 0, transferer->language);
}
tries++;
}
@@ -2094,18 +2116,18 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
}
ast_channel_lock(newchan);
- ast_connected_line_copy_from_caller(&connected_line, &newchan->cid);
+ ast_connected_line_copy_from_caller(&connected_line, &newchan->caller);
ast_channel_unlock(newchan);
connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
if (ast_channel_connected_line_macro(newchan, xferchan, &connected_line, 1, 0)) {
- ast_channel_update_connected_line(xferchan, &connected_line);
+ ast_channel_update_connected_line(xferchan, &connected_line, NULL);
}
ast_channel_lock(xferchan);
- ast_connected_line_copy_from_caller(&connected_line, &xferchan->cid);
+ ast_connected_line_copy_from_caller(&connected_line, &xferchan->caller);
ast_channel_unlock(xferchan);
connected_line.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
if (ast_channel_connected_line_macro(xferchan, newchan, &connected_line, 0, 0)) {
- ast_channel_update_connected_line(newchan, &connected_line);
+ ast_channel_update_connected_line(newchan, &connected_line, NULL);
}
ast_party_connected_line_free(&connected_line);
@@ -2676,7 +2698,7 @@ static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", caller->name);
ast_channel_lock(chan);
- ast_connected_line_copy_from_caller(&chan->connected, &caller->cid);
+ ast_connected_line_copy_from_caller(&chan->connected, &caller->caller);
ast_channel_unlock(chan);
if (ast_call(chan, data, timeout)) {
@@ -3328,8 +3350,9 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
* if it were, then chan belongs to a different thread now, and might have been hung up long
* ago.
*/
- if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN) &&
- ast_exists_extension(chan, chan->context, "h", 1, chan->cid.cid_num)) {
+ if (!ast_test_flag(&(config->features_caller),AST_FEATURE_NO_H_EXTEN)
+ && ast_exists_extension(chan, chan->context, "h", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
struct ast_cdr *swapper = NULL;
char savelastapp[AST_MAX_EXTENSION];
char savelastdata[AST_MAX_EXTENSION];
@@ -3357,10 +3380,16 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast
ast_copy_string(chan->exten, "h", sizeof(chan->exten));
chan->priority = 1;
ast_channel_unlock(chan);
- while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &found, 1)) == 0) {
+ while ((spawn_error = ast_spawn_extension(chan, chan->context, chan->exten,
+ chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
+ &found, 1)) == 0) {
chan->priority++;
}
- if (spawn_error && (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num) || ast_check_hangup(chan))) {
+ if (spawn_error
+ && (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
+ || ast_check_hangup(chan))) {
/* if the extension doesn't exist or a hangup occurred, this isn't really a spawn error */
spawn_error = 0;
}
@@ -3503,8 +3532,8 @@ static void post_manager_event(const char *s, struct parkeduser *pu)
pu->parkingexten,
pu->chan->name,
pu->parkinglot->name,
- S_OR(pu->chan->cid.cid_num, "<unknown>"),
- S_OR(pu->chan->cid.cid_name, "<unknown>"),
+ S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
+ S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>"),
pu->chan->uniqueid
);
}
@@ -3952,8 +3981,8 @@ static int park_exec_full(struct ast_channel *chan, const char *data, struct ast
"CallerIDNum: %s\r\n"
"CallerIDName: %s\r\n",
pu->parkingexten, pu->chan->name, chan->name,
- S_OR(pu->chan->cid.cid_num, "<unknown>"),
- S_OR(pu->chan->cid.cid_name, "<unknown>")
+ S_COR(pu->chan->caller.id.number.valid, pu->chan->caller.id.number.str, "<unknown>"),
+ S_COR(pu->chan->caller.id.name.valid, pu->chan->caller.id.name.str, "<unknown>")
);
ast_free(pu);
@@ -4998,8 +5027,8 @@ static int manager_parking_status(struct mansession *s, const struct message *m)
"\r\n",
cur->parkingnum, cur->chan->name, cur->peername,
(long) cur->start.tv_sec + (long) (cur->parkingtime / 1000) - (long) time(NULL),
- S_OR(cur->chan->cid.cid_num, ""), /* XXX in other places it is <unknown> */
- S_OR(cur->chan->cid.cid_name, ""),
+ S_COR(cur->chan->caller.id.number.valid, cur->chan->caller.id.number.str, ""), /* XXX in other places it is <unknown> */
+ S_COR(cur->chan->caller.id.name.valid, cur->chan->caller.id.name.str, ""),
idText);
}
AST_LIST_UNLOCK(&curlot->parkings);
@@ -5135,12 +5164,12 @@ int ast_pickup_call(struct ast_channel *chan)
connected_caller = cur->connected;
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
if (ast_channel_connected_line_macro(NULL, chan, &connected_caller, 0, 0)) {
- ast_channel_update_connected_line(chan, &connected_caller);
+ ast_channel_update_connected_line(chan, &connected_caller, NULL);
}
- ast_party_connected_line_collect_caller(&connected_caller, &chan->cid);
+ ast_party_connected_line_collect_caller(&connected_caller, &chan->caller);
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
- ast_channel_queue_connected_line_update(chan, &connected_caller);
+ ast_channel_queue_connected_line_update(chan, &connected_caller, NULL);
ast_channel_unlock(cur);
ast_channel_unlock(chan);
diff --git a/main/file.c b/main/file.c
index 6f3794338..726a72b64 100644
--- a/main/file.c
+++ b/main/file.c
@@ -1236,7 +1236,8 @@ static int waitstream_core(struct ast_channel *c, const char *breakon,
case AST_FRAME_DTMF_END:
if (context) {
const char exten[2] = { fr->subclass.integer, '\0' };
- if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
+ if (ast_exists_extension(c, context, exten, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
res = fr->subclass.integer;
ast_frfree(fr);
ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
diff --git a/main/manager.c b/main/manager.c
index 5c8f893af..620361452 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -3165,8 +3165,8 @@ static int action_status(struct mansession *s, const struct message *m)
"%s"
"\r\n",
c->name,
- S_OR(c->cid.cid_num, ""),
- S_OR(c->cid.cid_name, ""),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, ""),
c->accountcode,
c->_state,
ast_state2str(c->_state), c->context,
@@ -3186,8 +3186,8 @@ static int action_status(struct mansession *s, const struct message *m)
"%s"
"\r\n",
c->name,
- S_OR(c->cid.cid_num, "<unknown>"),
- S_OR(c->cid.cid_name, "<unknown>"),
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, "<unknown>"),
+ S_COR(c->caller.id.name.valid, c->caller.id.name.str, "<unknown>"),
c->accountcode,
ast_state2str(c->_state), bridge, c->uniqueid,
ast_str_buffer(str), idText);
@@ -4276,7 +4276,8 @@ static int action_coreshowchannels(struct mansession *s, const struct message *m
"BridgedUniqueID: %s\r\n"
"\r\n", idText, c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state,
ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, "") : "",
- S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, ""),
+ durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "");
ast_channel_unlock(c);
diff --git a/main/pbx.c b/main/pbx.c
index dbc4db497..3de941740 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -3011,16 +3011,17 @@ const char *ast_str_retrieve_variable(struct ast_str **str, ssize_t maxlen, stru
if (!strncmp(var, "CALL", 4)) {
if (!strncmp(var + 4, "ING", 3)) {
if (!strcmp(var + 7, "PRES")) { /* CALLINGPRES */
- ast_str_set(str, maxlen, "%d", c->cid.cid_pres);
+ ast_str_set(str, maxlen, "%d",
+ ast_party_id_presentation(&c->caller.id));
s = ast_str_buffer(*str);
} else if (!strcmp(var + 7, "ANI2")) { /* CALLINGANI2 */
- ast_str_set(str, maxlen, "%d", c->cid.cid_ani2);
+ ast_str_set(str, maxlen, "%d", c->caller.ani2);
s = ast_str_buffer(*str);
} else if (!strcmp(var + 7, "TON")) { /* CALLINGTON */
- ast_str_set(str, maxlen, "%d", c->cid.cid_ton);
+ ast_str_set(str, maxlen, "%d", c->caller.id.number.plan);
s = ast_str_buffer(*str);
} else if (!strcmp(var + 7, "TNS")) { /* CALLINGTNS */
- ast_str_set(str, maxlen, "%d", c->cid.cid_tns);
+ ast_str_set(str, maxlen, "%d", c->dialed.transit_network_select);
s = ast_str_buffer(*str);
}
}
@@ -4581,7 +4582,8 @@ static int collect_digits(struct ast_channel *c, int waittime, char *buf, int bu
int digit;
buf[pos] = '\0'; /* make sure it is properly terminated */
- while (ast_matchmore_extension(c, c->context, buf, 1, c->cid.cid_num)) {
+ while (ast_matchmore_extension(c, c->context, buf, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/* As long as we're willing to wait, and as long as it's not defined,
keep reading digits until we can't possibly get a right answer anymore. */
digit = ast_waitfordigit(c, waittime);
@@ -4626,7 +4628,8 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
ast_set_flag(c, AST_FLAG_IN_AUTOLOOP);
/* Start by trying whatever the channel is set to */
- if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
+ if (!ast_exists_extension(c, c->context, c->exten, c->priority,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/* If not successful fall back to 's' */
ast_verb(2, "Starting %s at %s,%s,%d failed so falling back to exten 's'\n", c->name, c->context, c->exten, c->priority);
/* XXX the original code used the existing priority in the call to
@@ -4634,7 +4637,8 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
* I believe the correct thing is to set it to 1 immediately.
*/
set_ext_pri(c, "s", 1);
- if (!ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
+ if (!ast_exists_extension(c, c->context, c->exten, c->priority,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/* JK02: And finally back to default if everything else failed */
ast_verb(2, "Starting %s at %s,%s,%d still failed so falling back to context 'default'\n", c->name, c->context, c->exten, c->priority);
ast_copy_string(c->context, "default", sizeof(c->context));
@@ -4652,13 +4656,19 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
int timeout = 0;
/* loop on priorities in this context/exten */
- while ( !(res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found,1))) {
- if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "T", 1, c->cid.cid_num)) {
+ while (!(res = ast_spawn_extension(c, c->context, c->exten, c->priority,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL),
+ &found, 1))) {
+ if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT
+ && ast_exists_extension(c, c->context, "T", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */
/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
memset(&c->whentohangup, 0, sizeof(c->whentohangup));
c->_softhangup &= ~AST_SOFTHANGUP_TIMEOUT;
- } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT
+ && ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
pbx_builtin_raise_exception(c, "ABSOLUTETIMEOUT");
/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
memset(&c->whentohangup, 0, sizeof(c->whentohangup));
@@ -4686,7 +4696,8 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
ast_verb(2, "Spawn extension (%s, %s, %d) exited INCOMPLETE on '%s'\n", c->context, c->exten, c->priority, c->name);
/* Don't cycle on incomplete - this will happen if the only extension that matches is our "incomplete" extension */
- if (!ast_matchmore_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
+ if (!ast_matchmore_extension(c, c->context, c->exten, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
invalid = 1;
} else {
ast_copy_string(dst_exten, c->exten, sizeof(dst_exten));
@@ -4697,7 +4708,9 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
- if ((res == AST_PBX_ERROR) && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ if ((res == AST_PBX_ERROR)
+ && ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/* if we are already on the 'e' exten, don't jump to it again */
if (!strcmp(c->exten, "e")) {
ast_verb(2, "Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s'\n", c->context, c->exten, c->priority, c->name);
@@ -4711,7 +4724,9 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
c->_softhangup = 0;
continue;
- } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "T", 1, c->cid.cid_num)) {
+ } else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT
+ && ast_exists_extension(c, c->context, "T", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
set_ext_pri(c, "T", 1);
/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
memset(&c->whentohangup, 0, sizeof(c->whentohangup));
@@ -4733,17 +4748,21 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
* hangup. We have options, here. We can either catch the failure
* and continue, or we can drop out entirely. */
- if (invalid || !ast_exists_extension(c, c->context, c->exten, 1, c->cid.cid_num)) {
+ if (invalid
+ || !ast_exists_extension(c, c->context, c->exten, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
/*!\note
* If there is no match at priority 1, it is not a valid extension anymore.
* Try to continue at "i" (for invalid) or "e" (for exception) or exit if
* neither exist.
*/
- if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
+ if (ast_exists_extension(c, c->context, "i", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
ast_verb(3, "Sent into invalid extension '%s' in context '%s' on %s\n", c->exten, c->context, c->name);
pbx_builtin_setvar_helper(c, "INVALID_EXTEN", c->exten);
set_ext_pri(c, "i", 1);
- } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ } else if (ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
pbx_builtin_raise_exception(c, "INVALID");
} else {
ast_log(LOG_WARNING, "Channel '%s' sent into invalid extension '%s' in context '%s', but no invalid handler\n",
@@ -4779,17 +4798,21 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
break;
if (res == AST_PBX_INCOMPLETE && ast_strlen_zero(&dst_exten[pos]))
timeout = 1;
- if (!timeout && ast_exists_extension(c, c->context, dst_exten, 1, c->cid.cid_num)) /* Prepare the next cycle */
+ if (!timeout
+ && ast_exists_extension(c, c->context, dst_exten, 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) { /* Prepare the next cycle */
set_ext_pri(c, dst_exten, 1);
- else {
+ } else {
/* No such extension */
if (!timeout && !ast_strlen_zero(dst_exten)) {
/* An invalid extension */
- if (ast_exists_extension(c, c->context, "i", 1, c->cid.cid_num)) {
+ if (ast_exists_extension(c, c->context, "i", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
ast_verb(3, "Invalid extension '%s' in context '%s' on %s\n", dst_exten, c->context, c->name);
pbx_builtin_setvar_helper(c, "INVALID_EXTEN", dst_exten);
set_ext_pri(c, "i", 1);
- } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ } else if (ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
pbx_builtin_raise_exception(c, "INVALID");
} else {
ast_log(LOG_WARNING, "Invalid extension '%s', but no rule 'i' in context '%s'\n", dst_exten, c->context);
@@ -4798,10 +4821,12 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
}
} else {
/* A simple timeout */
- if (ast_exists_extension(c, c->context, "t", 1, c->cid.cid_num)) {
+ if (ast_exists_extension(c, c->context, "t", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
ast_verb(3, "Timeout on %s\n", c->name);
set_ext_pri(c, "t", 1);
- } else if (ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+ } else if (ast_exists_extension(c, c->context, "e", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
pbx_builtin_raise_exception(c, "RESPONSETIMEOUT");
} else {
ast_log(LOG_WARNING, "Timeout, but no rule 't' in context '%s'\n", c->context);
@@ -4825,14 +4850,17 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c,
ast_softhangup(c, AST_SOFTHANGUP_APPUNLOAD);
}
- if ((!args || !args->no_hangup_chan) &&
- !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) &&
- ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) {
+ if ((!args || !args->no_hangup_chan)
+ && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN)
+ && ast_exists_extension(c, c->context, "h", 1,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
set_ext_pri(c, "h", 1);
if (c->cdr && ast_opt_end_cdr_before_h_exten) {
ast_cdr_end(c->cdr);
}
- while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found, 1)) == 0) {
+ while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority,
+ S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL),
+ &found, 1)) == 0) {
c->priority++;
}
if (found && res) {
@@ -9188,12 +9216,14 @@ static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
res = ast_waitfordigit(chan, ms);
if (!res) {
- if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 1, chan->cid.cid_num)) {
+ if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_verb(3, "Timeout on %s, continuing...\n", chan->name);
} else if (chan->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
ast_verb(3, "Call timeout on %s, checking for 'T'\n", chan->name);
res = -1;
- } else if (ast_exists_extension(chan, chan->context, "t", 1, chan->cid.cid_num)) {
+ } else if (ast_exists_extension(chan, chan->context, "t", 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
ast_verb(3, "Timeout on %s, going to 't'\n", chan->name);
set_ext_pri(chan, "t", 0); /* 0 will become 1, next time through the loop */
} else {
@@ -9309,10 +9339,12 @@ static int pbx_builtin_background(struct ast_channel *chan, const char *data)
* users can EXEC Background and reasonably expect that the DTMF code will
* be returned (see #16434).
*/
- if (!ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS) &&
- (exten[0] = res) &&
- ast_canmatch_extension(chan, args.context, exten, 1, chan->cid.cid_num) &&
- !ast_matchmore_extension(chan, args.context, exten, 1, chan->cid.cid_num)) {
+ if (!ast_test_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS)
+ && (exten[0] = res)
+ && ast_canmatch_extension(chan, args.context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))
+ && !ast_matchmore_extension(chan, args.context, exten, 1,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
snprintf(chan->exten, sizeof(chan->exten), "%c", res);
ast_copy_string(chan->context, args.context, sizeof(chan->context));
chan->priority = 0;
@@ -10032,7 +10064,8 @@ static int __ast_goto_if_exists(struct ast_channel *chan, const char *context, c
exten = chan->exten;
goto_func = (async) ? ast_async_goto : ast_explicit_goto;
- if (ast_exists_extension(chan, context, exten, priority, chan->cid.cid_num))
+ if (ast_exists_extension(chan, context, exten, priority,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL)))
return goto_func(chan, context, exten, priority);
else {
return AST_PBX_GOTO_FAILED;
@@ -10081,8 +10114,10 @@ static int pbx_parseable_goto(struct ast_channel *chan, const char *goto_string,
pri++;
}
if (sscanf(pri, "%30d", &ipri) != 1) {
- if ((ipri = ast_findlabel_extension(chan, context ? context : chan->context, exten ? exten : chan->exten,
- pri, chan->cid.cid_num)) < 1) {
+ ipri = ast_findlabel_extension(chan, context ? context : chan->context,
+ exten ? exten : chan->exten, pri,
+ S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL));
+ if (ipri < 1) {
ast_log(LOG_WARNING, "Priority '%s' must be a number > 0, or valid label\n", pri);
return -1;
} else