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