summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--channels/chan_misdn.c145
-rw-r--r--channels/chan_sip.c88
-rw-r--r--channels/sig_pri.c39
-rw-r--r--funcs/func_callerid.c208
-rw-r--r--include/asterisk/channel.h99
-rw-r--r--main/channel.c706
-rw-r--r--main/channel_internal_api.c16
-rw-r--r--main/cli.c7
-rw-r--r--main/features.c3
9 files changed, 1219 insertions, 92 deletions
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index ce654ee41..da45db9c3 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -6109,6 +6109,13 @@ static void misdn_queue_connected_line_update(struct ast_channel *ast, const str
| misdn_to_ast_plan(id->number_plan);
connected.id.number.presentation = misdn_to_ast_pres(id->presentation)
| misdn_to_ast_screen(id->screening);
+
+ /*
+ * Make sure that any earlier private connected id
+ * representation at the remote end is invalidated
+ */
+ ast_set_party_id_all(&update_connected.priv);
+
connected.id.tag = cid_tag;
connected.source = source;
ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
@@ -6182,20 +6189,21 @@ static void misdn_update_remote_party(struct ast_channel *ast, const struct misd
static void misdn_get_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
{
int number_type;
+ struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
if (originator == ORG_MISDN) {
/* ORIGINATOR MISDN (incoming call) */
ast_copy_string(bc->connected.name,
- S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
+ S_COR(connected_id.name.valid, connected_id.name.str, ""),
sizeof(bc->connected.name));
- if (ast_channel_connected(ast)->id.number.valid) {
- ast_copy_string(bc->connected.number, S_OR(ast_channel_connected(ast)->id.number.str, ""),
+ if (connected_id.number.valid) {
+ ast_copy_string(bc->connected.number, S_OR(connected_id.number.str, ""),
sizeof(bc->connected.number));
- bc->connected.presentation = ast_to_misdn_pres(ast_channel_connected(ast)->id.number.presentation);
- bc->connected.screening = ast_to_misdn_screen(ast_channel_connected(ast)->id.number.presentation);
- bc->connected.number_type = ast_to_misdn_ton(ast_channel_connected(ast)->id.number.plan);
- bc->connected.number_plan = ast_to_misdn_plan(ast_channel_connected(ast)->id.number.plan);
+ bc->connected.presentation = ast_to_misdn_pres(connected_id.number.presentation);
+ bc->connected.screening = ast_to_misdn_screen(connected_id.number.presentation);
+ bc->connected.number_type = ast_to_misdn_ton(connected_id.number.plan);
+ bc->connected.number_plan = ast_to_misdn_plan(connected_id.number.plan);
} else {
bc->connected.number[0] = '\0';
bc->connected.presentation = 0;/* Allowed */
@@ -6215,15 +6223,15 @@ static void misdn_get_connected_line(struct ast_channel *ast, struct misdn_bchan
/* ORIGINATOR Asterisk (outgoing call) */
ast_copy_string(bc->caller.name,
- S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
+ S_COR(connected_id.name.valid, connected_id.name.str, ""),
sizeof(bc->caller.name));
- if (ast_channel_connected(ast)->id.number.valid) {
- ast_copy_string(bc->caller.number, S_OR(ast_channel_connected(ast)->id.number.str, ""),
+ if (connected_id.number.valid) {
+ ast_copy_string(bc->caller.number, S_OR(connected_id.number.str, ""),
sizeof(bc->caller.number));
- bc->caller.presentation = ast_to_misdn_pres(ast_channel_connected(ast)->id.number.presentation);
- bc->caller.screening = ast_to_misdn_screen(ast_channel_connected(ast)->id.number.presentation);
- bc->caller.number_type = ast_to_misdn_ton(ast_channel_connected(ast)->id.number.plan);
- bc->caller.number_plan = ast_to_misdn_plan(ast_channel_connected(ast)->id.number.plan);
+ bc->caller.presentation = ast_to_misdn_pres(connected_id.number.presentation);
+ bc->caller.screening = ast_to_misdn_screen(connected_id.number.presentation);
+ bc->caller.number_type = ast_to_misdn_ton(connected_id.number.plan);
+ bc->caller.number_plan = ast_to_misdn_plan(connected_id.number.plan);
} else {
bc->caller.number[0] = '\0';
bc->caller.presentation = 0;/* Allowed */
@@ -6336,16 +6344,19 @@ static void misdn_update_connected_line(struct ast_channel *ast, struct misdn_bc
*/
static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
{
+ struct ast_party_id from_id = ast_channel_redirecting_effective_from(ast);
+ struct ast_party_id to_id = ast_channel_redirecting_effective_to(ast);
+
ast_copy_string(bc->redirecting.from.name,
- S_COR(ast_channel_redirecting(ast)->from.name.valid, ast_channel_redirecting(ast)->from.name.str, ""),
+ S_COR(from_id.name.valid, from_id.name.str, ""),
sizeof(bc->redirecting.from.name));
- if (ast_channel_redirecting(ast)->from.number.valid) {
- ast_copy_string(bc->redirecting.from.number, S_OR(ast_channel_redirecting(ast)->from.number.str, ""),
+ if (from_id.number.valid) {
+ ast_copy_string(bc->redirecting.from.number, S_OR(from_id.number.str, ""),
sizeof(bc->redirecting.from.number));
- bc->redirecting.from.presentation = ast_to_misdn_pres(ast_channel_redirecting(ast)->from.number.presentation);
- bc->redirecting.from.screening = ast_to_misdn_screen(ast_channel_redirecting(ast)->from.number.presentation);
- bc->redirecting.from.number_type = ast_to_misdn_ton(ast_channel_redirecting(ast)->from.number.plan);
- bc->redirecting.from.number_plan = ast_to_misdn_plan(ast_channel_redirecting(ast)->from.number.plan);
+ bc->redirecting.from.presentation = ast_to_misdn_pres(from_id.number.presentation);
+ bc->redirecting.from.screening = ast_to_misdn_screen(from_id.number.presentation);
+ bc->redirecting.from.number_type = ast_to_misdn_ton(from_id.number.plan);
+ bc->redirecting.from.number_plan = ast_to_misdn_plan(from_id.number.plan);
} else {
bc->redirecting.from.number[0] = '\0';
bc->redirecting.from.presentation = 0;/* Allowed */
@@ -6355,15 +6366,15 @@ static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct as
}
ast_copy_string(bc->redirecting.to.name,
- S_COR(ast_channel_redirecting(ast)->to.name.valid, ast_channel_redirecting(ast)->to.name.str, ""),
+ S_COR(to_id.name.valid, to_id.name.str, ""),
sizeof(bc->redirecting.to.name));
- if (ast_channel_redirecting(ast)->to.number.valid) {
- ast_copy_string(bc->redirecting.to.number, S_OR(ast_channel_redirecting(ast)->to.number.str, ""),
+ if (to_id.number.valid) {
+ ast_copy_string(bc->redirecting.to.number, S_OR(to_id.number.str, ""),
sizeof(bc->redirecting.to.number));
- bc->redirecting.to.presentation = ast_to_misdn_pres(ast_channel_redirecting(ast)->to.number.presentation);
- bc->redirecting.to.screening = ast_to_misdn_screen(ast_channel_redirecting(ast)->to.number.presentation);
- bc->redirecting.to.number_type = ast_to_misdn_ton(ast_channel_redirecting(ast)->to.number.plan);
- bc->redirecting.to.number_plan = ast_to_misdn_plan(ast_channel_redirecting(ast)->to.number.plan);
+ bc->redirecting.to.presentation = ast_to_misdn_pres(to_id.number.presentation);
+ bc->redirecting.to.screening = ast_to_misdn_screen(to_id.number.presentation);
+ bc->redirecting.to.number_type = ast_to_misdn_ton(to_id.number.plan);
+ bc->redirecting.to.number_plan = ast_to_misdn_plan(to_id.number.plan);
} else {
bc->redirecting.to.number[0] = '\0';
bc->redirecting.to.presentation = 0;/* Allowed */
@@ -6595,6 +6606,8 @@ static int misdn_call(struct ast_channel *ast, const char *dest, int timeout)
} else
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
{
+ struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
+
/*
* dest is ---v
* Dial(mISDN/g:group_name[/extension[/options]])
@@ -6616,15 +6629,15 @@ static int misdn_call(struct ast_channel *ast, const char *dest, int timeout)
ast_copy_string(newbc->dialed.number, args.ext, sizeof(newbc->dialed.number));
if (ast_strlen_zero(newbc->caller.name)
- && ast_channel_connected(ast)->id.name.valid
- && !ast_strlen_zero(ast_channel_connected(ast)->id.name.str)) {
- ast_copy_string(newbc->caller.name, ast_channel_connected(ast)->id.name.str, sizeof(newbc->caller.name));
+ && connected_id.name.valid
+ && !ast_strlen_zero(connected_id.name.str)) {
+ ast_copy_string(newbc->caller.name, connected_id.name.str, sizeof(newbc->caller.name));
chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
}
if (ast_strlen_zero(newbc->caller.number)
- && ast_channel_connected(ast)->id.number.valid
- && !ast_strlen_zero(ast_channel_connected(ast)->id.number.str)) {
- ast_copy_string(newbc->caller.number, ast_channel_connected(ast)->id.number.str, sizeof(newbc->caller.number));
+ && connected_id.number.valid
+ && !ast_strlen_zero(connected_id.number.str)) {
+ ast_copy_string(newbc->caller.number, connected_id.number.str, sizeof(newbc->caller.number));
chan_misdn_log(3, port, " --> * set caller:\"%s\" <%s>\n", newbc->caller.name, newbc->caller.number);
}
@@ -6638,9 +6651,9 @@ static int misdn_call(struct ast_channel *ast, const char *dest, int timeout)
misdn_cfg_get(port, MISDN_CFG_LOCALDIALPLAN, &number_type, sizeof(number_type));
if (number_type < 0) {
- if (ast_channel_connected(ast)->id.number.valid) {
- newbc->caller.number_type = ast_to_misdn_ton(ast_channel_connected(ast)->id.number.plan);
- newbc->caller.number_plan = ast_to_misdn_plan(ast_channel_connected(ast)->id.number.plan);
+ if (connected_id.number.valid) {
+ newbc->caller.number_type = ast_to_misdn_ton(connected_id.number.plan);
+ newbc->caller.number_plan = ast_to_misdn_plan(connected_id.number.plan);
} else {
newbc->caller.number_type = NUMTYPE_UNKNOWN;
newbc->caller.number_plan = NUMPLAN_ISDN;
@@ -8605,8 +8618,16 @@ static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list
ast_party_connected_line_init(&target_colp);
ast_party_connected_line_copy(&target_colp, ast_channel_connected(target));
+
+ /* Reset any earlier private connected id representation */
+ ast_party_id_reset(&target_colp.priv);
+
ast_party_connected_line_init(&transferee_colp);
ast_party_connected_line_copy(&transferee_colp, ast_channel_connected(held_ch->ast));
+
+ /* Reset any earlier private connected id representation*/
+ ast_party_id_reset(&transferee_colp.priv);
+
held_ch->hold.state = MISDN_HOLD_TRANSFER;
/*
@@ -9283,11 +9304,25 @@ static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel
bc->div_leg_3_rx_wanted = 0;
if (ch && ch->ast) {
+ struct ast_party_redirecting redirecting;
+
ast_channel_redirecting(ch->ast)->to.number.presentation =
bc->fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator
? AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED
: AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
- ast_channel_queue_redirecting_update(ch->ast, ast_channel_redirecting(ch->ast), NULL);
+ ast_party_redirecting_init(&redirecting);
+ ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(ch->ast));
+
+ /*
+ * Reset any earlier private redirecting id representations and
+ * make sure that it is invalidated at the remote end.
+ */
+ ast_party_id_reset(&redirecting.priv_orig);
+ ast_party_id_reset(&redirecting.priv_from);
+ ast_party_id_reset(&redirecting.priv_to);
+
+ ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
+ ast_party_redirecting_free(&redirecting);
}
}
break;
@@ -10518,9 +10553,23 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
bc->div_leg_3_rx_wanted = 0;
if (ch->ast) {
+ struct ast_party_redirecting redirecting;
+
ast_channel_redirecting(ch->ast)->to.number.presentation =
AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
- ast_channel_queue_redirecting_update(ch->ast, ast_channel_redirecting(ch->ast), NULL);
+ ast_party_redirecting_init(&redirecting);
+ ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(ch->ast));
+
+ /*
+ * Reset any earlier private redirecting id representations and
+ * make sure that it is invalidated at the remote end.
+ */
+ ast_party_id_reset(&redirecting.priv_orig);
+ ast_party_id_reset(&redirecting.priv_from);
+ ast_party_id_reset(&redirecting.priv_to);
+
+ ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
+ ast_party_redirecting_free(&redirecting);
}
}
#endif /* defined(AST_MISDN_ENHANCEMENTS) */
@@ -10939,6 +10988,9 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
bc->redirecting.to_changed = 0;
break;
case mISDN_NOTIFY_CODE_CALL_IS_DIVERTING:
+ {
+ struct ast_party_redirecting redirecting;
+
if (!bc->redirecting.to_changed) {
break;
}
@@ -10957,8 +11009,21 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
break;
}
misdn_copy_redirecting_to_ast(ch->ast, &bc->redirecting, bc->incoming_cid_tag);
- ast_channel_queue_redirecting_update(ch->ast, ast_channel_redirecting(ch->ast), NULL);
+ ast_party_redirecting_init(&redirecting);
+ ast_party_redirecting_copy(&redirecting, ast_channel_redirecting(ch->ast));
+
+ /*
+ * Reset any earlier private redirecting id representations and
+ * make sure that it is invalidated at the remote end.
+ */
+ ast_party_id_reset(&redirecting.priv_orig);
+ ast_party_id_reset(&redirecting.priv_from);
+ ast_party_id_reset(&redirecting.priv_to);
+
+ ast_channel_queue_redirecting_update(ch->ast, &redirecting, NULL);
+ ast_party_redirecting_free(&redirecting);
break;
+ }
case mISDN_NOTIFY_CODE_CALL_TRANSFER_ALERTING:
/*
* It would be preferable to update the connected line information
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index eaaffebae..7569bba11 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -6009,6 +6009,9 @@ static int sip_call(struct ast_channel *ast, const char *dest, int timeout)
connected.id.name.presentation = p->callingpres;
}
if (update_connected.id.number || update_connected.id.name) {
+ /* Invalidate any earlier private connected id representation */
+ ast_set_party_id_all(&update_connected.priv);
+
connected.id.tag = (char *) p->cid_tag;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
ast_channel_queue_connected_line_update(ast, &connected, &update_connected);
@@ -11872,25 +11875,28 @@ static int add_rpid(struct sip_request *req, struct sip_pvt *p)
char tmp2[256];
char *lid_num = NULL;
char *lid_name = NULL;
- int lid_pres;
+ int lid_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
const char *fromdomain;
const char *privacy = NULL;
const char *screen = NULL;
const char *anonymous_string = "\"Anonymous\" <sip:anonymous@anonymous.invalid>";
+ struct ast_party_id connected_id;
if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
return 0;
}
- if (p->owner && ast_channel_connected(p->owner)->id.number.valid
- && ast_channel_connected(p->owner)->id.number.str) {
- lid_num = ast_channel_connected(p->owner)->id.number.str;
- }
- if (p->owner && ast_channel_connected(p->owner)->id.name.valid
- && ast_channel_connected(p->owner)->id.name.str) {
- lid_name = ast_channel_connected(p->owner)->id.name.str;
+ if (p->owner) {
+ connected_id = ast_channel_connected_effective_id(p->owner);
+
+ if (connected_id.number.valid) {
+ lid_num = connected_id.number.str;
+ }
+ if (connected_id.name.valid) {
+ lid_name = connected_id.name.str;
+ }
+ lid_pres = ast_party_id_presentation(&connected_id);
}
- lid_pres = (p->owner) ? ast_party_id_presentation(&ast_channel_connected(p->owner)->id) : AST_PRES_NUMBER_NOT_AVAILABLE;
if (ast_strlen_zero(lid_num))
return 0;
@@ -13079,6 +13085,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
int ourport;
int cid_has_name = 1;
int cid_has_num = 1;
+ struct ast_party_id connected_id;
if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
const char *s = p->username; /* being a string field, cannot be NULL */
@@ -13104,9 +13111,15 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
d = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip));
if (p->owner) {
- if ((ast_party_id_presentation(&ast_channel_connected(p->owner)->id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
- l = ast_channel_connected(p->owner)->id.number.valid ? ast_channel_connected(p->owner)->id.number.str : NULL;
- n = ast_channel_connected(p->owner)->id.name.valid ? ast_channel_connected(p->owner)->id.name.str : NULL;
+ connected_id = ast_channel_connected_effective_id(p->owner);
+
+ if ((ast_party_id_presentation(&connected_id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
+ if (connected_id.number.valid) {
+ l = connected_id.number.str;
+ }
+ if (connected_id.name.valid) {
+ n = connected_id.name.str;
+ }
} else {
/* Even if we are using RPID, we shouldn't leak information in the From if the user wants
* their callerid restricted */
@@ -13260,8 +13273,7 @@ static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmetho
*/
static void add_diversion(struct sip_request *req, struct sip_pvt *pvt)
{
- const char *diverting_number;
- const char *diverting_name;
+ struct ast_party_id diverting_from;
const char *reason;
char header_text[256];
@@ -13274,23 +13286,22 @@ static void add_diversion(struct sip_request *req, struct sip_pvt *pvt)
return;
}
- diverting_number = ast_channel_redirecting(pvt->owner)->from.number.str;
- if (!ast_channel_redirecting(pvt->owner)->from.number.valid
- || ast_strlen_zero(diverting_number)) {
+ diverting_from = ast_channel_redirecting_effective_from(pvt->owner);
+ if (!diverting_from.number.valid
+ || ast_strlen_zero(diverting_from.number.str)) {
return;
}
reason = sip_reason_code_to_str(ast_channel_redirecting(pvt->owner)->reason);
/* We at least have a number to place in the Diversion header, which is enough */
- diverting_name = ast_channel_redirecting(pvt->owner)->from.name.str;
- if (!ast_channel_redirecting(pvt->owner)->from.name.valid
- || ast_strlen_zero(diverting_name)) {
- snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_number,
+ if (!diverting_from.name.valid
+ || ast_strlen_zero(diverting_from.name.str)) {
+ snprintf(header_text, sizeof(header_text), "<sip:%s@%s>;reason=%s", diverting_from.number.str,
ast_sockaddr_stringify_host_remote(&pvt->ourip), reason);
} else {
snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;reason=%s",
- diverting_name, diverting_number,
+ diverting_from.name.str, diverting_from.number.str,
ast_sockaddr_stringify_host_remote(&pvt->ourip), reason);
}
@@ -14195,19 +14206,20 @@ static void update_redirecting(struct sip_pvt *p, const void *data, size_t datal
/*! \brief Notify peer that the connected line has changed */
static void update_connectedline(struct sip_pvt *p, const void *data, size_t datalen)
{
+ struct ast_party_id connected_id = ast_channel_connected_effective_id(p->owner);
if (!ast_test_flag(&p->flags[0], SIP_SENDRPID)) {
return;
}
- if (!ast_channel_connected(p->owner)->id.number.valid
- || ast_strlen_zero(ast_channel_connected(p->owner)->id.number.str)) {
+ if (!connected_id.number.valid
+ || ast_strlen_zero(connected_id.number.str)) {
return;
}
append_history(p, "ConnectedLine", "%s party is now %s <%s>",
ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "Calling" : "Called",
- S_COR(ast_channel_connected(p->owner)->id.name.valid, ast_channel_connected(p->owner)->id.name.str, ""),
- S_COR(ast_channel_connected(p->owner)->id.number.valid, ast_channel_connected(p->owner)->id.number.str, ""));
+ S_COR(connected_id.name.valid, connected_id.name.str, ""),
+ S_COR(connected_id.number.valid, connected_id.number.str, ""));
if (ast_channel_state(p->owner) == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
struct sip_request req;
@@ -21789,6 +21801,9 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
connected.id.name.str = (char *) p->cid_name;
connected.id.name.presentation = p->callingpres;
+ /* Invalidate any earlier private connected id representation */
+ ast_set_party_id_all(&update_connected.priv);
+
connected.id.tag = (char *) p->cid_tag;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
ast_channel_queue_connected_line_update(p->owner, &connected,
@@ -21832,6 +21847,12 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
memset(&update_redirecting, 0, sizeof(update_redirecting));
change_redirecting_information(p, req, &redirecting, &update_redirecting,
FALSE);
+
+ /* Invalidate any earlier private redirecting id representations */
+ ast_set_party_id_all(&update_redirecting.priv_orig);
+ ast_set_party_id_all(&update_redirecting.priv_from);
+ ast_set_party_id_all(&update_redirecting.priv_to);
+
ast_channel_queue_redirecting_update(p->owner, &redirecting,
&update_redirecting);
ast_party_redirecting_free(&redirecting);
@@ -21867,6 +21888,9 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
connected.id.name.str = (char *) p->cid_name;
connected.id.name.presentation = p->callingpres;
+ /* Invalidate any earlier private connected id representation */
+ ast_set_party_id_all(&update_connected.priv);
+
connected.id.tag = (char *) p->cid_tag;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
ast_channel_queue_connected_line_update(p->owner, &connected,
@@ -21936,6 +21960,9 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
connected.id.name.presentation = p->callingpres;
}
if (update_connected.id.number || update_connected.id.name) {
+ /* Invalidate any earlier private connected id representation */
+ ast_set_party_id_all(&update_connected.priv);
+
connected.id.tag = (char *) p->cid_tag;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
ast_channel_queue_connected_line_update(p->owner, &connected,
@@ -24010,6 +24037,9 @@ static int handle_request_update(struct sip_pvt *p, struct sip_request *req)
connected.id.name.str = (char *) p->cid_name;
connected.id.name.presentation = p->callingpres;
+ /* Invalidate any earlier private connected id representation */
+ ast_set_party_id_all(&update_connected.priv);
+
connected.id.tag = (char *) p->cid_tag;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
ast_channel_queue_connected_line_update(p->owner, &connected, &update_connected);
@@ -24360,6 +24390,9 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
connected.id.name.str = (char *) p->cid_name;
connected.id.name.presentation = p->callingpres;
+ /* Invalidate any earlier private connected id representation */
+ ast_set_party_id_all(&update_connected.priv);
+
connected.id.tag = (char *) p->cid_tag;
connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
ast_channel_queue_connected_line_update(p->owner, &connected,
@@ -25054,6 +25087,9 @@ static int local_attended_transfer(struct sip_pvt *transferer, struct sip_dual *
ast_party_connected_line_copy(&connected_to_transferee, ast_channel_connected(current->chan1));
/* No need to lock target.chan1 here since it was locked in get_sip_pvt_byid_locked */
ast_party_connected_line_copy(&connected_to_target, ast_channel_connected(target.chan1));
+ /* Reset any earlier private connected id representation */
+ ast_party_id_reset(&connected_to_transferee.priv);
+ ast_party_id_reset(&connected_to_target.priv);
connected_to_target.source = connected_to_transferee.source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER;
res = attempt_transfer(current, &target);
if (res) {
diff --git a/channels/sig_pri.c b/channels/sig_pri.c
index 902c5098d..2840c3b28 100644
--- a/channels/sig_pri.c
+++ b/channels/sig_pri.c
@@ -906,12 +906,15 @@ static void sig_pri_redirecting_update(struct sig_pri_chan *pvt, struct ast_chan
{
struct pri_party_redirecting pri_redirecting;
const struct ast_party_redirecting *ast_redirecting;
+ struct ast_party_id redirecting_from = ast_channel_redirecting_effective_from(ast);
+ struct ast_party_id redirecting_to = ast_channel_redirecting_effective_to(ast);
+ struct ast_party_id redirecting_orig = ast_channel_redirecting_effective_orig(ast);
memset(&pri_redirecting, 0, sizeof(pri_redirecting));
ast_redirecting = ast_channel_redirecting(ast);
- sig_pri_party_id_from_ast(&pri_redirecting.from, &ast_redirecting->from);
- sig_pri_party_id_from_ast(&pri_redirecting.to, &ast_redirecting->to);
- sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &ast_redirecting->orig);
+ sig_pri_party_id_from_ast(&pri_redirecting.from, &redirecting_from);
+ sig_pri_party_id_from_ast(&pri_redirecting.to, &redirecting_to);
+ sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &redirecting_orig);
pri_redirecting.count = ast_redirecting->count;
pri_redirecting.orig_reason = ast_to_pri_reason(ast_redirecting->orig_reason);
pri_redirecting.reason = ast_to_pri_reason(ast_redirecting->reason);
@@ -4247,6 +4250,12 @@ static void sig_pri_handle_subcmds(struct sig_pri_span *pri, int chanpos, int ev
ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
if (event_id != PRI_EVENT_RING) {
/* This redirection was not from a SETUP message. */
+
+ /* Invalidate any earlier private redirecting id representations */
+ ast_party_id_invalidate(&ast_redirecting.priv_orig);
+ ast_party_id_invalidate(&ast_redirecting.priv_from);
+ ast_party_id_invalidate(&ast_redirecting.priv_to);
+
ast_channel_queue_redirecting_update(owner, &ast_redirecting, NULL);
}
ast_party_redirecting_free(&ast_redirecting);
@@ -7726,10 +7735,11 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rd
);
struct ast_flags opts;
char *opt_args[OPT_ARG_ARRAY_SIZE];
+ struct ast_party_id connected_id = ast_channel_connected_effective_id(ast);
ast_debug(1, "CALLER NAME: %s NUM: %s\n",
- S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
- S_COR(ast_channel_connected(ast)->id.number.valid, ast_channel_connected(ast)->id.number.str, ""));
+ S_COR(connected_id.name.valid, connected_id.name.str, ""),
+ S_COR(connected_id.number.valid, connected_id.number.str, ""));
if (!p->pri) {
ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel);
@@ -7785,14 +7795,14 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rd
l = NULL;
n = NULL;
if (!p->hidecallerid) {
- if (ast_channel_connected(ast)->id.number.valid) {
+ if (connected_id.number.valid) {
/* If we get to the end of this loop without breaking, there's no
* calleridnum. This is done instead of testing for "unknown" or
* the thousands of other ways that the calleridnum could be
* invalid. */
- for (l = ast_channel_connected(ast)->id.number.str; l && *l; l++) {
+ for (l = connected_id.number.str; l && *l; l++) {
if (strchr("0123456789", *l)) {
- l = ast_channel_connected(ast)->id.number.str;
+ l = connected_id.number.str;
break;
}
}
@@ -7800,7 +7810,7 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rd
l = NULL;
}
if (!p->hidecalleridname) {
- n = ast_channel_connected(ast)->id.name.valid ? ast_channel_connected(ast)->id.name.str : NULL;
+ n = connected_id.name.valid ? connected_id.name.str : NULL;
}
}
@@ -8016,7 +8026,7 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rd
}
} else if (prilocaldialplan == -1) {
/* Use the numbering plan passed in. */
- prilocaldialplan = ast_channel_connected(ast)->id.number.plan;
+ prilocaldialplan = connected_id.number.plan;
}
if (l != NULL) {
while (*l > '9' && *l != '*' && *l != '#') {
@@ -8075,14 +8085,14 @@ int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rd
}
}
pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
- p->use_callingpres ? ast_channel_connected(ast)->id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
+ p->use_callingpres ? connected_id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
#if defined(HAVE_PRI_SUBADDR)
- if (ast_channel_connected(ast)->id.subaddress.valid) {
+ if (connected_id.subaddress.valid) {
struct pri_party_subaddress subaddress;
memset(&subaddress, 0, sizeof(subaddress));
- sig_pri_party_subaddress_from_ast(&subaddress, &ast_channel_connected(ast)->id.subaddress);
+ sig_pri_party_subaddress_from_ast(&subaddress, &connected_id.subaddress);
pri_sr_set_caller_subaddress(sr, &subaddress);
}
#endif /* defined(HAVE_PRI_SUBADDR) */
@@ -8313,6 +8323,7 @@ int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condi
int dialplan;
int prefix_strip;
int colp_allowed = 0;
+ struct ast_party_id connected_id = ast_channel_connected_effective_id(chan);
pri_grab(p, p->pri);
@@ -8341,7 +8352,7 @@ int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condi
}
memset(&connected, 0, sizeof(connected));
- sig_pri_party_id_from_ast(&connected.id, &ast_channel_connected(chan)->id);
+ sig_pri_party_id_from_ast(&connected.id, &connected_id);
/* Determine the connected line numbering plan to actually use. */
switch (p->pri->cpndialplan) {
diff --git a/funcs/func_callerid.c b/funcs/func_callerid.c
index f15e3676f..789575399 100644
--- a/funcs/func_callerid.c
+++ b/funcs/func_callerid.c
@@ -103,6 +103,20 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<enum name = "subaddr-type" />
<enum name = "subaddr-odd" />
<enum name = "tag" />
+ <enum name = "priv-all" />
+ <enum name = "priv-name" />
+ <enum name = "priv-name-valid" />
+ <enum name = "priv-name-charset" />
+ <enum name = "priv-name-pres" />
+ <enum name = "priv-num" />
+ <enum name = "priv-num-valid" />
+ <enum name = "priv-num-plan" />
+ <enum name = "priv-num-pres" />
+ <enum name = "priv-subaddr" />
+ <enum name = "priv-subaddr-valid" />
+ <enum name = "priv-subaddr-type" />
+ <enum name = "priv-subaddr-odd" />
+ <enum name = "priv-tag" />
<enum name = "ANI-all" />
<enum name = "ANI-name" />
<enum name = "ANI-name-valid" />
@@ -209,6 +223,20 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<enum name = "subaddr-type" />
<enum name = "subaddr-odd" />
<enum name = "tag" />
+ <enum name = "priv-all" />
+ <enum name = "priv-name" />
+ <enum name = "priv-name-valid" />
+ <enum name = "priv-name-charset" />
+ <enum name = "priv-name-pres" />
+ <enum name = "priv-num" />
+ <enum name = "priv-num-valid" />
+ <enum name = "priv-num-plan" />
+ <enum name = "priv-num-pres" />
+ <enum name = "priv-subaddr" />
+ <enum name = "priv-subaddr-valid" />
+ <enum name = "priv-subaddr-type" />
+ <enum name = "priv-subaddr-odd" />
+ <enum name = "priv-tag" />
</enumlist>
</parameter>
<parameter name="i">
@@ -285,6 +313,48 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<enum name = "to-subaddr-type" />
<enum name = "to-subaddr-odd" />
<enum name = "to-tag" />
+ <enum name = "priv-orig-all" />
+ <enum name = "priv-orig-name" />
+ <enum name = "priv-orig-name-valid" />
+ <enum name = "priv-orig-name-charset" />
+ <enum name = "priv-orig-name-pres" />
+ <enum name = "priv-orig-num" />
+ <enum name = "priv-orig-num-valid" />
+ <enum name = "priv-orig-num-plan" />
+ <enum name = "priv-orig-num-pres" />
+ <enum name = "priv-orig-subaddr" />
+ <enum name = "priv-orig-subaddr-valid" />
+ <enum name = "priv-orig-subaddr-type" />
+ <enum name = "priv-orig-subaddr-odd" />
+ <enum name = "priv-orig-tag" />
+ <enum name = "priv-from-all" />
+ <enum name = "priv-from-name" />
+ <enum name = "priv-from-name-valid" />
+ <enum name = "priv-from-name-charset" />
+ <enum name = "priv-from-name-pres" />
+ <enum name = "priv-from-num" />
+ <enum name = "priv-from-num-valid" />
+ <enum name = "priv-from-num-plan" />
+ <enum name = "priv-from-num-pres" />
+ <enum name = "priv-from-subaddr" />
+ <enum name = "priv-from-subaddr-valid" />
+ <enum name = "priv-from-subaddr-type" />
+ <enum name = "priv-from-subaddr-odd" />
+ <enum name = "priv-from-tag" />
+ <enum name = "priv-to-all" />
+ <enum name = "priv-to-name" />
+ <enum name = "priv-to-name-valid" />
+ <enum name = "priv-to-name-charset" />
+ <enum name = "priv-to-name-pres" />
+ <enum name = "priv-to-num" />
+ <enum name = "priv-to-num-valid" />
+ <enum name = "priv-to-num-plan" />
+ <enum name = "priv-to-num-pres" />
+ <enum name = "priv-to-subaddr" />
+ <enum name = "priv-to-subaddr-valid" />
+ <enum name = "priv-to-subaddr-type" />
+ <enum name = "priv-to-subaddr-odd" />
+ <enum name = "priv-to-tag" />
<enum name = "reason" />
<enum name = "count" />
</enumlist>
@@ -997,6 +1067,17 @@ static int callerid_read(struct ast_channel *chan, const char *cmd, char *data,
ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
break;
}
+ } else if (!strcasecmp("priv", member.argv[0])) {
+ status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
+ &ast_channel_caller(chan)->priv);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+ break;
+ }
} else {
status = party_id_read(buf, len, member.argc, member.argv, &ast_channel_caller(chan)->id);
switch (status) {
@@ -1159,6 +1240,23 @@ static int callerid_write(struct ast_channel *chan, const char *cmd, char *data,
break;
}
ast_party_caller_free(&caller);
+ } else if (!strcasecmp("priv", member.argv[0])) {
+ ast_party_caller_set_init(&caller, ast_channel_caller(chan));
+ status = party_id_write(&caller.priv, member.argc - 1, member.argv + 1, value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ ast_party_caller_set(ast_channel_caller(chan), &caller, NULL);
+ if (ast_channel_cdr(chan)) {
+ ast_cdr_setcid(ast_channel_cdr(chan), chan);
+ }
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown callerid data type '%s'.\n", data);
+ break;
+ }
+ ast_party_caller_free(&caller);
} else {
ast_party_caller_set_init(&caller, ast_channel_caller(chan));
status = party_id_write(&caller.id, member.argc, member.argv, value);
@@ -1199,6 +1297,7 @@ static int connectedline_read(struct ast_channel *chan, const char *cmd, char *d
{
struct ast_party_members member;
char *read_what;
+ enum ID_FIELD_STATUS status;
/* Ensure that the buffer is empty */
*buf = 0;
@@ -1218,8 +1317,18 @@ static int connectedline_read(struct ast_channel *chan, const char *cmd, char *d
if (member.argc == 1 && !strcasecmp("source", member.argv[0])) {
ast_copy_string(buf, ast_connected_line_source_name(ast_channel_connected(chan)->source), len);
+ } else if (!strcasecmp("priv", member.argv[0])) {
+ status = party_id_read(buf, len, member.argc - 1, member.argv + 1,
+ &ast_channel_connected(chan)->priv);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
+ break;
+ }
} else {
- enum ID_FIELD_STATUS status;
status = party_id_read(buf, len, member.argc, member.argv, &ast_channel_connected(chan)->id);
switch (status) {
case ID_FIELD_VALID:
@@ -1258,6 +1367,7 @@ static int connectedline_write(struct ast_channel *chan, const char *cmd, char *
struct ast_party_members member;
struct ast_flags opts;
char *opt_args[CONNECTED_LINE_OPT_ARG_ARRAY_SIZE];
+ enum ID_FIELD_STATUS status;
if (!value || !chan) {
return -1;
@@ -1312,8 +1422,20 @@ static int connectedline_write(struct ast_channel *chan, const char *cmd, char *
connected.source = source;
set_it(chan, &connected, NULL);
}
+ } else if (!strcasecmp("priv", member.argv[0])) {
+ status = party_id_write(&connected.priv, member.argc - 1, member.argv + 1, value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ set_it(chan, &connected, NULL);
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown connectedline data type '%s'.\n", data);
+ break;
+ }
+ ast_party_connected_line_free(&connected);
} else {
- enum ID_FIELD_STATUS status;
status = party_id_write(&connected.id, member.argc, member.argv, value);
switch (status) {
case ID_FIELD_VALID:
@@ -1418,6 +1540,43 @@ static int redirecting_read(struct ast_channel *chan, const char *cmd, char *dat
ast_copy_string(buf, ast_redirecting_reason_name(ast_redirecting->reason), len);
} else if (member.argc == 1 && !strcasecmp("count", member.argv[0])) {
snprintf(buf, len, "%d", ast_redirecting->count);
+ } else if (1 < member.argc && !strcasecmp("priv", member.argv[0])) {
+ if (!strcasecmp("orig", member.argv[1])) {
+ status = party_id_read(buf, len, member.argc - 2, member.argv + 2,
+ &ast_redirecting->priv_orig);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ } else if (!strcasecmp("from", member.argv[1])) {
+ status = party_id_read(buf, len, member.argc - 2, member.argv + 2,
+ &ast_redirecting->priv_from);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ } else if (!strcasecmp("to", member.argv[1])) {
+ status = party_id_read(buf, len, member.argc - 2, member.argv + 2,
+ &ast_redirecting->priv_to);
+ switch (status) {
+ case ID_FIELD_VALID:
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ } else {
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ }
} else {
ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
}
@@ -1598,6 +1757,51 @@ static int redirecting_write(struct ast_channel *chan, const char *cmd, char *da
} else {
ast_log(LOG_ERROR, "Unknown redirecting count '%s', value unchanged\n", val);
}
+ } else if (1 < member.argc && !strcasecmp("priv", member.argv[0])) {
+ if (!strcasecmp("orig", member.argv[1])) {
+ status = party_id_write(&redirecting.priv_orig, member.argc - 2, member.argv + 2,
+ value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ set_it(chan, &redirecting, NULL);
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ ast_party_redirecting_free(&redirecting);
+ } else if (!strcasecmp("from", member.argv[1])) {
+ status = party_id_write(&redirecting.priv_from, member.argc - 2, member.argv + 2,
+ value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ set_it(chan, &redirecting, NULL);
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ ast_party_redirecting_free(&redirecting);
+ } else if (!strcasecmp("to", member.argv[1])) {
+ status = party_id_write(&redirecting.priv_to, member.argc - 2, member.argv + 2, value);
+ switch (status) {
+ case ID_FIELD_VALID:
+ set_it(chan, &redirecting, NULL);
+ break;
+ case ID_FIELD_INVALID:
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ break;
+ }
+ ast_party_redirecting_free(&redirecting);
+ } else {
+ ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
+ }
} else {
ast_log(LOG_ERROR, "Unknown redirecting data type '%s'.\n", data);
}
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index c9d13187c..abfe18139 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -380,6 +380,9 @@ struct ast_party_caller {
*/
struct ast_party_id ani;
+ /*! \brief Private caller party ID */
+ struct ast_party_id priv;
+
/*! \brief Automatic Number Identification 2 (Info Digits) */
int ani2;
};
@@ -393,6 +396,8 @@ struct ast_set_party_caller {
struct ast_set_party_id id;
/*! What ANI id information to set. */
struct ast_set_party_id ani;
+ /*! What private caller id information to set. */
+ struct ast_set_party_id priv;
};
/*!
@@ -413,6 +418,9 @@ struct ast_party_connected_line {
*/
struct ast_party_id ani;
+ /*! \brief Private connected party ID */
+ struct ast_party_id priv;
+
/*!
* \brief Automatic Number Identification 2 (Info Digits)
* \note Not really part of connected line data but needed to
@@ -437,6 +445,8 @@ struct ast_set_party_connected_line {
struct ast_set_party_id id;
/*! What ANI id information to set. */
struct ast_set_party_id ani;
+ /*! What private connected line id information to set. */
+ struct ast_set_party_id priv;
};
/*!
@@ -458,6 +468,15 @@ struct ast_party_redirecting {
/*! \brief Call is redirecting to a new party (Sent to the caller) */
struct ast_party_id to;
+ /*! \brief Who originally redirected the call (Sent to the party the call is redirected toward) - private representation */
+ struct ast_party_id priv_orig;
+
+ /*! \brief Who is redirecting the call (Sent to the party the call is redirected toward) - private representation */
+ struct ast_party_id priv_from;
+
+ /*! \brief Call is redirecting to a new party (Sent to the caller) - private representation */
+ struct ast_party_id priv_to;
+
/*! \brief Number of times the call was redirected */
int count;
@@ -479,6 +498,12 @@ struct ast_set_party_redirecting {
struct ast_set_party_id from;
/*! What redirecting-to id information to set. */
struct ast_set_party_id to;
+ /*! What private redirecting-orig id information to set. */
+ struct ast_set_party_id priv_orig;
+ /*! What private redirecting-from id information to set. */
+ struct ast_set_party_id priv_from;
+ /*! What private redirecting-to id information to set. */
+ struct ast_set_party_id priv_to;
};
/*!
@@ -2864,6 +2889,16 @@ void ast_party_subaddress_set(struct ast_party_subaddress *dest, const struct as
void ast_party_subaddress_free(struct ast_party_subaddress *doomed);
/*!
+ * \brief Set the update marker to update all information of a corresponding party id.
+ * \since 11.0
+ *
+ * \param update_id The update marker for a corresponding party id.
+ *
+ * \return Nothing
+ */
+void ast_set_party_id_all(struct ast_set_party_id *update_id);
+
+/*!
* \brief Initialize the given party id structure.
* \since 1.8
*
@@ -2936,6 +2971,66 @@ void ast_party_id_free(struct ast_party_id *doomed);
int ast_party_id_presentation(const struct ast_party_id *id);
/*!
+ * \brief Invalidate all components of the given party id.
+ * \since 11.0
+ *
+ * \param id The party id to invalidate.
+ *
+ * \return Nothing
+ */
+void ast_party_id_invalidate(struct ast_party_id *id);
+
+/*!
+ * \brief Destroy and initialize the given party id structure.
+ * \since 11.0
+ *
+ * \param id The party id to reset.
+ *
+ * \return Nothing
+ */
+void ast_party_id_reset(struct ast_party_id *id);
+
+/*!
+ * \brief Merge a given party id into another given party id.
+ * \since 11.0
+ *
+ * \details
+ * This function will generate an effective party id.
+ *
+ * Each party id component of the party id 'base' is overwritten
+ * by components of the party id 'overlay' if the overlay
+ * component is marked as valid. However the component 'tag' of
+ * the base party id remains untouched.
+ *
+ * \param base The party id which is merged.
+ * \param overlay The party id which is used to merge into.
+ *
+ * \return The merged party id as a struct, not as a pointer.
+ * \note The merged party id returned is a shallow copy and must not be freed.
+ */
+struct ast_party_id ast_party_id_merge(struct ast_party_id *base, struct ast_party_id *overlay);
+
+/*!
+ * \brief Copy a merge of a given party id into another given party id to a given destination party id.
+ * \since 11.0
+ *
+ * \details
+ * Each party id component of the party id 'base' is overwritten by components
+ * of the party id 'overlay' if the 'overlay' component is marked as valid.
+ * However the component 'tag' of the 'base' party id remains untouched.
+ * The result is copied into the given party id 'dest'.
+ *
+ * \note The resulting merged party id is a real copy and has to be freed.
+ *
+ * \param dest The resulting merged party id.
+ * \param base The party id which is merged.
+ * \param overlay The party id which is used to merge into.
+ *
+ * \return Nothing
+ */
+void ast_party_id_merge_copy(struct ast_party_id *dest, struct ast_party_id *base, struct ast_party_id *overlay);
+
+/*!
* \brief Initialize the given dialed structure.
* \since 1.8
*
@@ -3778,8 +3873,12 @@ struct ast_frame *ast_channel_dtmff(struct ast_channel *chan);
struct ast_jb *ast_channel_jb(struct ast_channel *chan);
struct ast_party_caller *ast_channel_caller(struct ast_channel *chan);
struct ast_party_connected_line *ast_channel_connected(struct ast_channel *chan);
+struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan);
struct ast_party_dialed *ast_channel_dialed(struct ast_channel *chan);
struct ast_party_redirecting *ast_channel_redirecting(struct ast_channel *chan);
+struct ast_party_id ast_channel_redirecting_effective_orig(struct ast_channel *chan);
+struct ast_party_id ast_channel_redirecting_effective_from(struct ast_channel *chan);
+struct ast_party_id ast_channel_redirecting_effective_to(struct ast_channel *chan);
struct timeval *ast_channel_dtmf_tv(struct ast_channel *chan);
struct timeval *ast_channel_whentohangup(struct ast_channel *chan);
struct varshead *ast_channel_varshead(struct ast_channel *chan);
diff --git a/main/channel.c b/main/channel.c
index d5f1d31c1..bccba2e14 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1891,6 +1891,13 @@ void ast_party_subaddress_free(struct ast_party_subaddress *doomed)
doomed->str = NULL;
}
+void ast_set_party_id_all(struct ast_set_party_id *update_id)
+{
+ update_id->name = 1;
+ update_id->number = 1;
+ update_id->subaddress = 1;
+}
+
void ast_party_id_init(struct ast_party_id *init)
{
ast_party_name_init(&init->name);
@@ -2023,6 +2030,45 @@ int ast_party_id_presentation(const struct ast_party_id *id)
return number_value | number_screening;
}
+void ast_party_id_invalidate(struct ast_party_id *id)
+{
+ id->name.valid = 0;
+ id->number.valid = 0;
+ id->subaddress.valid = 0;
+}
+
+void ast_party_id_reset(struct ast_party_id *id)
+{
+ ast_party_id_free(id);
+ ast_party_id_init(id);
+}
+
+struct ast_party_id ast_party_id_merge(struct ast_party_id *base, struct ast_party_id *overlay)
+{
+ struct ast_party_id merged;
+
+ merged = *base;
+ if (overlay->name.valid) {
+ merged.name = overlay->name;
+ }
+ if (overlay->number.valid) {
+ merged.number = overlay->number;
+ }
+ if (overlay->subaddress.valid) {
+ merged.subaddress = overlay->subaddress;
+ }
+ /* Note the actual structure is returned and not a pointer to it! */
+ return merged;
+}
+
+void ast_party_id_merge_copy(struct ast_party_id *dest, struct ast_party_id *base, struct ast_party_id *overlay)
+{
+ struct ast_party_id merged;
+
+ merged = ast_party_id_merge(base, overlay);
+ ast_party_id_copy(dest, &merged);
+}
+
void ast_party_dialed_init(struct ast_party_dialed *init)
{
init->number.str = NULL;
@@ -2077,6 +2123,7 @@ void ast_party_caller_init(struct ast_party_caller *init)
{
ast_party_id_init(&init->id);
ast_party_id_init(&init->ani);
+ ast_party_id_init(&init->priv);
init->ani2 = 0;
}
@@ -2089,6 +2136,7 @@ void ast_party_caller_copy(struct ast_party_caller *dest, const struct ast_party
ast_party_id_copy(&dest->id, &src->id);
ast_party_id_copy(&dest->ani, &src->ani);
+ ast_party_id_copy(&dest->priv, &src->priv);
dest->ani2 = src->ani2;
}
@@ -2096,6 +2144,7 @@ void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_p
{
ast_party_id_set_init(&init->id, &guide->id);
ast_party_id_set_init(&init->ani, &guide->ani);
+ ast_party_id_set_init(&init->priv, &guide->priv);
init->ani2 = guide->ani2;
}
@@ -2103,6 +2152,7 @@ void ast_party_caller_set(struct ast_party_caller *dest, const struct ast_party_
{
ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
+ ast_party_id_set(&dest->priv, &src->priv, update ? &update->priv : NULL);
dest->ani2 = src->ani2;
}
@@ -2110,12 +2160,14 @@ void ast_party_caller_free(struct ast_party_caller *doomed)
{
ast_party_id_free(&doomed->id);
ast_party_id_free(&doomed->ani);
+ ast_party_id_free(&doomed->priv);
}
void ast_party_connected_line_init(struct ast_party_connected_line *init)
{
ast_party_id_init(&init->id);
ast_party_id_init(&init->ani);
+ ast_party_id_init(&init->priv);
init->ani2 = 0;
init->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
}
@@ -2129,6 +2181,7 @@ void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const
ast_party_id_copy(&dest->id, &src->id);
ast_party_id_copy(&dest->ani, &src->ani);
+ ast_party_id_copy(&dest->priv, &src->priv);
dest->ani2 = src->ani2;
dest->source = src->source;
}
@@ -2137,6 +2190,7 @@ void ast_party_connected_line_set_init(struct ast_party_connected_line *init, co
{
ast_party_id_set_init(&init->id, &guide->id);
ast_party_id_set_init(&init->ani, &guide->ani);
+ ast_party_id_set_init(&init->priv, &guide->priv);
init->ani2 = guide->ani2;
init->source = guide->source;
}
@@ -2145,6 +2199,7 @@ void ast_party_connected_line_set(struct ast_party_connected_line *dest, const s
{
ast_party_id_set(&dest->id, &src->id, update ? &update->id : NULL);
ast_party_id_set(&dest->ani, &src->ani, update ? &update->ani : NULL);
+ ast_party_id_set(&dest->priv, &src->priv, update ? &update->priv : NULL);
dest->ani2 = src->ani2;
dest->source = src->source;
}
@@ -2153,6 +2208,7 @@ void ast_party_connected_line_collect_caller(struct ast_party_connected_line *co
{
connected->id = caller->id;
connected->ani = caller->ani;
+ connected->priv = caller->priv;
connected->ani2 = caller->ani2;
connected->source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN;
}
@@ -2161,6 +2217,7 @@ void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
{
ast_party_id_free(&doomed->id);
ast_party_id_free(&doomed->ani);
+ ast_party_id_free(&doomed->priv);
}
void ast_party_redirecting_init(struct ast_party_redirecting *init)
@@ -2168,6 +2225,9 @@ void ast_party_redirecting_init(struct ast_party_redirecting *init)
ast_party_id_init(&init->orig);
ast_party_id_init(&init->from);
ast_party_id_init(&init->to);
+ ast_party_id_init(&init->priv_orig);
+ ast_party_id_init(&init->priv_from);
+ ast_party_id_init(&init->priv_to);
init->count = 0;
init->reason = AST_REDIRECTING_REASON_UNKNOWN;
init->orig_reason = AST_REDIRECTING_REASON_UNKNOWN;
@@ -2183,6 +2243,9 @@ void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct
ast_party_id_copy(&dest->orig, &src->orig);
ast_party_id_copy(&dest->from, &src->from);
ast_party_id_copy(&dest->to, &src->to);
+ ast_party_id_copy(&dest->priv_orig, &src->priv_orig);
+ ast_party_id_copy(&dest->priv_from, &src->priv_from);
+ ast_party_id_copy(&dest->priv_to, &src->priv_to);
dest->count = src->count;
dest->reason = src->reason;
dest->orig_reason = src->orig_reason;
@@ -2193,6 +2256,9 @@ void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const st
ast_party_id_set_init(&init->orig, &guide->orig);
ast_party_id_set_init(&init->from, &guide->from);
ast_party_id_set_init(&init->to, &guide->to);
+ ast_party_id_set_init(&init->priv_orig, &guide->priv_orig);
+ ast_party_id_set_init(&init->priv_from, &guide->priv_from);
+ ast_party_id_set_init(&init->priv_to, &guide->priv_to);
init->count = guide->count;
init->reason = guide->reason;
init->orig_reason = guide->orig_reason;
@@ -2203,6 +2269,9 @@ void ast_party_redirecting_set(struct ast_party_redirecting *dest, const struct
ast_party_id_set(&dest->orig, &src->orig, update ? &update->orig : NULL);
ast_party_id_set(&dest->from, &src->from, update ? &update->from : NULL);
ast_party_id_set(&dest->to, &src->to, update ? &update->to : NULL);
+ ast_party_id_set(&dest->priv_orig, &src->priv_orig, update ? &update->priv_orig : NULL);
+ ast_party_id_set(&dest->priv_from, &src->priv_from, update ? &update->priv_from : NULL);
+ ast_party_id_set(&dest->priv_to, &src->priv_to, update ? &update->priv_to : NULL);
dest->count = src->count;
dest->reason = src->reason;
dest->orig_reason = src->orig_reason;
@@ -2213,6 +2282,9 @@ void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
ast_party_id_free(&doomed->orig);
ast_party_id_free(&doomed->from);
ast_party_id_free(&doomed->to);
+ ast_party_id_free(&doomed->priv_orig);
+ ast_party_id_free(&doomed->priv_from);
+ ast_party_id_free(&doomed->priv_to);
}
/*! \brief Free a channel structure */
@@ -6624,6 +6696,11 @@ static void masquerade_colp_transfer(struct ast_channel *transferee, struct xfer
* case, the frame we queue tells ast_read() to call the
* connected line interception macro configured for transferee.
*/
+
+ /* Reset any earlier private connected id representation */
+ ast_party_id_reset(&colp->target_id.priv);
+ ast_party_id_reset(&colp->transferee_id.priv);
+
payload_size = ast_connected_line_build_data(connected_line_data,
sizeof(connected_line_data), &colp->target_id, NULL);
if (payload_size != -1) {
@@ -6947,14 +7024,30 @@ int ast_do_masquerade(struct ast_channel *original)
ast_channel_dialed_set(original, ast_channel_dialed(clonechan));
ast_channel_dialed_set(clonechan, &exchange.dialed);
+ /* Reset any earlier private caller id representations */
+ ast_party_id_reset(&ast_channel_caller(original)->priv);
+ ast_party_id_reset(&ast_channel_caller(clonechan)->priv);
+
exchange.caller = *ast_channel_caller(original);
ast_channel_caller_set(original, ast_channel_caller(clonechan));
ast_channel_caller_set(clonechan, &exchange.caller);
+ /* Reset any earlier private connected id representations */
+ ast_party_id_reset(&ast_channel_connected(original)->priv);
+ ast_party_id_reset(&ast_channel_connected(clonechan)->priv);
+
exchange.connected = *ast_channel_connected(original);
ast_channel_connected_set(original, ast_channel_connected(clonechan));
ast_channel_connected_set(clonechan, &exchange.connected);
+ /* Reset any earlier private redirecting orig, from or to representations */
+ ast_party_id_reset(&ast_channel_redirecting(original)->priv_orig);
+ ast_party_id_reset(&ast_channel_redirecting(clonechan)->priv_orig);
+ ast_party_id_reset(&ast_channel_redirecting(original)->priv_from);
+ ast_party_id_reset(&ast_channel_redirecting(clonechan)->priv_from);
+ ast_party_id_reset(&ast_channel_redirecting(original)->priv_to);
+ ast_party_id_reset(&ast_channel_redirecting(clonechan)->priv_to);
+
exchange.redirecting = *ast_channel_redirecting(original);
ast_channel_redirecting_set(original, ast_channel_redirecting(clonechan));
ast_channel_redirecting_set(clonechan, &exchange.redirecting);
@@ -9029,6 +9122,19 @@ enum {
AST_CONNECTED_LINE_NAME_PRESENTATION,
AST_CONNECTED_LINE_NUMBER_VALID,
AST_CONNECTED_LINE_NUMBER_PRESENTATION,
+ AST_CONNECTED_LINE_PRIV_NUMBER,
+ AST_CONNECTED_LINE_PRIV_NUMBER_PLAN,
+ AST_CONNECTED_LINE_PRIV_NUMBER_VALID,
+ AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION,
+ AST_CONNECTED_LINE_PRIV_NAME,
+ AST_CONNECTED_LINE_PRIV_NAME_VALID,
+ AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET,
+ AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION,
+ AST_CONNECTED_LINE_PRIV_SUBADDRESS,
+ AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE,
+ AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN,
+ AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID,
+ AST_CONNECTED_LINE_PRIV_TAG,
};
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)
@@ -9057,6 +9163,26 @@ int ast_connected_line_build_data(unsigned char *data, size_t datalen, const str
.combined_presentation = AST_CONNECTED_LINE_ID_PRESENTATION,
};
+ static const struct ast_party_id_ies priv_ies = {
+ .name.str = AST_CONNECTED_LINE_PRIV_NAME,
+ .name.char_set = AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET,
+ .name.presentation = AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION,
+ .name.valid = AST_CONNECTED_LINE_PRIV_NAME_VALID,
+
+ .number.str = AST_CONNECTED_LINE_PRIV_NUMBER,
+ .number.plan = AST_CONNECTED_LINE_PRIV_NUMBER_PLAN,
+ .number.presentation = AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION,
+ .number.valid = AST_CONNECTED_LINE_PRIV_NUMBER_VALID,
+
+ .subaddress.str = AST_CONNECTED_LINE_PRIV_SUBADDRESS,
+ .subaddress.type = AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID,
+
+ .tag = AST_CONNECTED_LINE_PRIV_TAG,
+ .combined_presentation = 0,/* Not sent. */
+ };
+
/*
* The size of integer values must be fixed in case the frame is
* shipped to another machine.
@@ -9078,6 +9204,13 @@ int ast_connected_line_build_data(unsigned char *data, size_t datalen, const str
}
pos += res;
+ res = party_id_build_data(data + pos, datalen - pos, &connected->priv,
+ "connected line priv", &priv_ies, update ? &update->priv : 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");
@@ -9190,16 +9323,6 @@ int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, str
}
connected->id.number.valid = data[pos];
break;
-/* 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);
@@ -9243,6 +9366,125 @@ int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, str
connected->id.tag[ie_len] = 0;
}
break;
+/* 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;
+/* Private connected line party id name */
+ case AST_CONNECTED_LINE_PRIV_NAME:
+ ast_free(connected->priv.name.str);
+ connected->priv.name.str = ast_malloc(ie_len + 1);
+ if (connected->priv.name.str) {
+ memcpy(connected->priv.name.str, data + pos, ie_len);
+ connected->priv.name.str[ie_len] = 0;
+ }
+ break;
+ case AST_CONNECTED_LINE_PRIV_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line private name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->priv.name.char_set = data[pos];
+ break;
+ case AST_CONNECTED_LINE_PRIV_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line private name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->priv.name.presentation = data[pos];
+ break;
+ case AST_CONNECTED_LINE_PRIV_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line private name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->priv.name.valid = data[pos];
+ break;
+/* Private connected line party id number */
+ case AST_CONNECTED_LINE_PRIV_NUMBER:
+ ast_free(connected->priv.number.str);
+ connected->priv.number.str = ast_malloc(ie_len + 1);
+ if (connected->priv.number.str) {
+ memcpy(connected->priv.number.str, data + pos, ie_len);
+ connected->priv.number.str[ie_len] = 0;
+ }
+ break;
+ case AST_CONNECTED_LINE_PRIV_NUMBER_PLAN:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line private numbering plan (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->priv.number.plan = data[pos];
+ break;
+ case AST_CONNECTED_LINE_PRIV_NUMBER_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line private number presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->priv.number.presentation = data[pos];
+ break;
+ case AST_CONNECTED_LINE_PRIV_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line private number valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->priv.number.valid = data[pos];
+ break;
+/* Private connected line party id subaddress */
+ case AST_CONNECTED_LINE_PRIV_SUBADDRESS:
+ ast_free(connected->priv.subaddress.str);
+ connected->priv.subaddress.str = ast_malloc(ie_len + 1);
+ if (connected->priv.subaddress.str) {
+ memcpy(connected->priv.subaddress.str, data + pos, ie_len);
+ connected->priv.subaddress.str[ie_len] = 0;
+ }
+ break;
+ case AST_CONNECTED_LINE_PRIV_SUBADDRESS_TYPE:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line private type of subaddress (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->priv.subaddress.type = data[pos];
+ break;
+ case AST_CONNECTED_LINE_PRIV_SUBADDRESS_ODD_EVEN:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING,
+ "Invalid connected line private subaddress odd-even indicator (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->priv.subaddress.odd_even_indicator = data[pos];
+ break;
+ case AST_CONNECTED_LINE_PRIV_SUBADDRESS_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid connected line private subaddress valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ connected->priv.subaddress.valid = data[pos];
+ break;
+/* Private connected line party tag */
+ case AST_CONNECTED_LINE_PRIV_TAG:
+ ast_free(connected->priv.tag);
+ connected->priv.tag = ast_malloc(ie_len + 1);
+ if (connected->priv.tag) {
+ memcpy(connected->priv.tag, data + pos, ie_len);
+ connected->priv.tag[ie_len] = 0;
+ }
+ break;
/* Connected line party source */
case AST_CONNECTED_LINE_SOURCE:
if (ie_len != sizeof(value)) {
@@ -9383,6 +9625,45 @@ enum {
AST_REDIRECTING_ORIG_SUBADDRESS_VALID,
AST_REDIRECTING_ORIG_TAG,
AST_REDIRECTING_ORIG_REASON,
+ AST_REDIRECTING_PRIV_TO_NUMBER,
+ AST_REDIRECTING_PRIV_TO_NUMBER_PLAN,
+ AST_REDIRECTING_PRIV_TO_NUMBER_VALID,
+ AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION,
+ AST_REDIRECTING_PRIV_TO_NAME,
+ AST_REDIRECTING_PRIV_TO_NAME_VALID,
+ AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET,
+ AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION,
+ AST_REDIRECTING_PRIV_TO_SUBADDRESS,
+ AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE,
+ AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN,
+ AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID,
+ AST_REDIRECTING_PRIV_TO_TAG,
+ AST_REDIRECTING_PRIV_FROM_NUMBER,
+ AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN,
+ AST_REDIRECTING_PRIV_FROM_NUMBER_VALID,
+ AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION,
+ AST_REDIRECTING_PRIV_FROM_NAME,
+ AST_REDIRECTING_PRIV_FROM_NAME_VALID,
+ AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET,
+ AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION,
+ AST_REDIRECTING_PRIV_FROM_SUBADDRESS,
+ AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE,
+ AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN,
+ AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID,
+ AST_REDIRECTING_PRIV_FROM_TAG,
+ AST_REDIRECTING_PRIV_ORIG_NUMBER,
+ AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID,
+ AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN,
+ AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION,
+ AST_REDIRECTING_PRIV_ORIG_NAME,
+ AST_REDIRECTING_PRIV_ORIG_NAME_VALID,
+ AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET,
+ AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION,
+ AST_REDIRECTING_PRIV_ORIG_SUBADDRESS,
+ AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE,
+ AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN,
+ AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID,
+ AST_REDIRECTING_PRIV_ORIG_TAG,
};
int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
@@ -9448,6 +9729,63 @@ int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct
.tag = AST_REDIRECTING_TO_TAG,
.combined_presentation = AST_REDIRECTING_TO_ID_PRESENTATION,
};
+ static const struct ast_party_id_ies priv_orig_ies = {
+ .name.str = AST_REDIRECTING_PRIV_ORIG_NAME,
+ .name.char_set = AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET,
+ .name.presentation = AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION,
+ .name.valid = AST_REDIRECTING_PRIV_ORIG_NAME_VALID,
+
+ .number.str = AST_REDIRECTING_PRIV_ORIG_NUMBER,
+ .number.plan = AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN,
+ .number.presentation = AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION,
+ .number.valid = AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID,
+
+ .subaddress.str = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS,
+ .subaddress.type = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID,
+
+ .tag = AST_REDIRECTING_PRIV_ORIG_TAG,
+ .combined_presentation = 0,/* Not sent. */
+ };
+ static const struct ast_party_id_ies priv_from_ies = {
+ .name.str = AST_REDIRECTING_PRIV_FROM_NAME,
+ .name.char_set = AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET,
+ .name.presentation = AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION,
+ .name.valid = AST_REDIRECTING_PRIV_FROM_NAME_VALID,
+
+ .number.str = AST_REDIRECTING_PRIV_FROM_NUMBER,
+ .number.plan = AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN,
+ .number.presentation = AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION,
+ .number.valid = AST_REDIRECTING_PRIV_FROM_NUMBER_VALID,
+
+ .subaddress.str = AST_REDIRECTING_PRIV_FROM_SUBADDRESS,
+ .subaddress.type = AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID,
+
+ .tag = AST_REDIRECTING_PRIV_FROM_TAG,
+ .combined_presentation = 0,/* Not sent. */
+ };
+ static const struct ast_party_id_ies priv_to_ies = {
+ .name.str = AST_REDIRECTING_PRIV_TO_NAME,
+ .name.char_set = AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET,
+ .name.presentation = AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION,
+ .name.valid = AST_REDIRECTING_PRIV_TO_NAME_VALID,
+
+ .number.str = AST_REDIRECTING_PRIV_TO_NUMBER,
+ .number.plan = AST_REDIRECTING_PRIV_TO_NUMBER_PLAN,
+ .number.presentation = AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION,
+ .number.valid = AST_REDIRECTING_PRIV_TO_NUMBER_VALID,
+
+ .subaddress.str = AST_REDIRECTING_PRIV_TO_SUBADDRESS,
+ .subaddress.type = AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE,
+ .subaddress.odd_even_indicator = AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN,
+ .subaddress.valid = AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID,
+
+ .tag = AST_REDIRECTING_PRIV_TO_TAG,
+ .combined_presentation = 0,/* Not sent. */
+ };
/* Redirecting frame version */
if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
@@ -9479,6 +9817,27 @@ int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct
}
pos += res;
+ res = party_id_build_data(data + pos, datalen - pos, &redirecting->priv_orig,
+ "redirecting-priv-orig", &priv_orig_ies, update ? &update->priv_orig : NULL);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+
+ res = party_id_build_data(data + pos, datalen - pos, &redirecting->priv_from,
+ "redirecting-priv-from", &priv_from_ies, update ? &update->priv_from : NULL);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+
+ res = party_id_build_data(data + pos, datalen - pos, &redirecting->priv_to,
+ "redirecting-priv-to", &priv_to_ies, update ? &update->priv_to : NULL);
+ if (res < 0) {
+ return -1;
+ }
+ pos += res;
+
/* Redirecting reason */
if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
ast_log(LOG_WARNING, "No space left for redirecting reason\n");
@@ -9896,6 +10255,333 @@ int ast_redirecting_parse_data(const unsigned char *data, size_t datalen, struct
redirecting->to.tag[ie_len] = 0;
}
break;
+/* Private redirecting-orig party id name */
+ case AST_REDIRECTING_PRIV_ORIG_NAME:
+ ast_free(redirecting->priv_orig.name.str);
+ redirecting->priv_orig.name.str = ast_malloc(ie_len + 1);
+ if (redirecting->priv_orig.name.str) {
+ memcpy(redirecting->priv_orig.name.str, data + pos, ie_len);
+ redirecting->priv_orig.name.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_PRIV_ORIG_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-orig name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_orig.name.char_set = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_ORIG_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-orig name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_orig.name.presentation = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_ORIG_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-orig name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_orig.name.valid = data[pos];
+ break;
+/* Private redirecting-orig party id number */
+ case AST_REDIRECTING_PRIV_ORIG_NUMBER:
+ ast_free(redirecting->priv_orig.number.str);
+ redirecting->priv_orig.number.str = ast_malloc(ie_len + 1);
+ if (redirecting->priv_orig.number.str) {
+ memcpy(redirecting->priv_orig.number.str, data + pos, ie_len);
+ redirecting->priv_orig.number.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_PRIV_ORIG_NUMBER_PLAN:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-orig numbering plan (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_orig.number.plan = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_ORIG_NUMBER_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-orig number presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_orig.number.presentation = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_ORIG_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-orig number valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_orig.number.valid = data[pos];
+ break;
+/* Private redirecting-orig party id subaddress */
+ case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS:
+ ast_free(redirecting->priv_orig.subaddress.str);
+ redirecting->priv_orig.subaddress.str = ast_malloc(ie_len + 1);
+ if (redirecting->priv_orig.subaddress.str) {
+ memcpy(redirecting->priv_orig.subaddress.str, data + pos, ie_len);
+ redirecting->priv_orig.subaddress.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_TYPE:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-orig type of subaddress (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_orig.subaddress.type = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_ODD_EVEN:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING,
+ "Invalid private redirecting-orig subaddress odd-even indicator (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_orig.subaddress.odd_even_indicator = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_ORIG_SUBADDRESS_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-orig subaddress valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_orig.subaddress.valid = data[pos];
+ break;
+/* Private redirecting-orig party id tag */
+ case AST_REDIRECTING_PRIV_ORIG_TAG:
+ ast_free(redirecting->priv_orig.tag);
+ redirecting->priv_orig.tag = ast_malloc(ie_len + 1);
+ if (redirecting->priv_orig.tag) {
+ memcpy(redirecting->priv_orig.tag, data + pos, ie_len);
+ redirecting->priv_orig.tag[ie_len] = 0;
+ }
+ break;
+/* Private redirecting-from party id name */
+ case AST_REDIRECTING_PRIV_FROM_NAME:
+ ast_free(redirecting->priv_from.name.str);
+ redirecting->priv_from.name.str = ast_malloc(ie_len + 1);
+ if (redirecting->priv_from.name.str) {
+ memcpy(redirecting->priv_from.name.str, data + pos, ie_len);
+ redirecting->priv_from.name.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_PRIV_FROM_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-from name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_from.name.char_set = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_FROM_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-from name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_from.name.presentation = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_FROM_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-from name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_from.name.valid = data[pos];
+ break;
+/* Private redirecting-from party id number */
+ case AST_REDIRECTING_PRIV_FROM_NUMBER:
+ ast_free(redirecting->priv_from.number.str);
+ redirecting->priv_from.number.str = ast_malloc(ie_len + 1);
+ if (redirecting->priv_from.number.str) {
+ memcpy(redirecting->priv_from.number.str, data + pos, ie_len);
+ redirecting->priv_from.number.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_PRIV_FROM_NUMBER_PLAN:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-from numbering plan (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_from.number.plan = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_FROM_NUMBER_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-from number presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_from.number.presentation = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_FROM_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-from number valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_from.number.valid = data[pos];
+ break;
+/* Private redirecting-from party id subaddress */
+ case AST_REDIRECTING_PRIV_FROM_SUBADDRESS:
+ ast_free(redirecting->priv_from.subaddress.str);
+ redirecting->priv_from.subaddress.str = ast_malloc(ie_len + 1);
+ if (redirecting->priv_from.subaddress.str) {
+ memcpy(redirecting->priv_from.subaddress.str, data + pos, ie_len);
+ redirecting->priv_from.subaddress.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_PRIV_FROM_SUBADDRESS_TYPE:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-from type of subaddress (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_from.subaddress.type = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_FROM_SUBADDRESS_ODD_EVEN:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING,
+ "Invalid private redirecting-from subaddress odd-even indicator (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_from.subaddress.odd_even_indicator = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_FROM_SUBADDRESS_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-from subaddress valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_from.subaddress.valid = data[pos];
+ break;
+/* Private redirecting-from party id tag */
+ case AST_REDIRECTING_PRIV_FROM_TAG:
+ ast_free(redirecting->priv_from.tag);
+ redirecting->priv_from.tag = ast_malloc(ie_len + 1);
+ if (redirecting->priv_from.tag) {
+ memcpy(redirecting->priv_from.tag, data + pos, ie_len);
+ redirecting->priv_from.tag[ie_len] = 0;
+ }
+ break;
+/* Private redirecting-to party id name */
+ case AST_REDIRECTING_PRIV_TO_NAME:
+ ast_free(redirecting->priv_to.name.str);
+ redirecting->priv_to.name.str = ast_malloc(ie_len + 1);
+ if (redirecting->priv_to.name.str) {
+ memcpy(redirecting->priv_to.name.str, data + pos, ie_len);
+ redirecting->priv_to.name.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_PRIV_TO_NAME_CHAR_SET:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-to name char set (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_to.name.char_set = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_TO_NAME_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-to name presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_to.name.presentation = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_TO_NAME_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-to name valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_to.name.valid = data[pos];
+ break;
+/* Private redirecting-to party id number */
+ case AST_REDIRECTING_PRIV_TO_NUMBER:
+ ast_free(redirecting->priv_to.number.str);
+ redirecting->priv_to.number.str = ast_malloc(ie_len + 1);
+ if (redirecting->priv_to.number.str) {
+ memcpy(redirecting->priv_to.number.str, data + pos, ie_len);
+ redirecting->priv_to.number.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_PRIV_TO_NUMBER_PLAN:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-to numbering plan (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_to.number.plan = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_TO_NUMBER_PRESENTATION:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-to number presentation (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_to.number.presentation = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_TO_NUMBER_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-to number valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_to.number.valid = data[pos];
+ break;
+/* Private redirecting-to party id subaddress */
+ case AST_REDIRECTING_PRIV_TO_SUBADDRESS:
+ ast_free(redirecting->priv_to.subaddress.str);
+ redirecting->priv_to.subaddress.str = ast_malloc(ie_len + 1);
+ if (redirecting->priv_to.subaddress.str) {
+ memcpy(redirecting->priv_to.subaddress.str, data + pos, ie_len);
+ redirecting->priv_to.subaddress.str[ie_len] = 0;
+ }
+ break;
+ case AST_REDIRECTING_PRIV_TO_SUBADDRESS_TYPE:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-to type of subaddress (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_to.subaddress.type = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_TO_SUBADDRESS_ODD_EVEN:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING,
+ "Invalid private redirecting-to subaddress odd-even indicator (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_to.subaddress.odd_even_indicator = data[pos];
+ break;
+ case AST_REDIRECTING_PRIV_TO_SUBADDRESS_VALID:
+ if (ie_len != 1) {
+ ast_log(LOG_WARNING, "Invalid private redirecting-to subaddress valid (%u)\n",
+ (unsigned) ie_len);
+ break;
+ }
+ redirecting->priv_to.subaddress.valid = data[pos];
+ break;
+/* Private redirecting-to party id tag */
+ case AST_REDIRECTING_PRIV_TO_TAG:
+ ast_free(redirecting->priv_to.tag);
+ redirecting->priv_to.tag = ast_malloc(ie_len + 1);
+ if (redirecting->priv_to.tag) {
+ memcpy(redirecting->priv_to.tag, data + pos, ie_len);
+ redirecting->priv_to.tag[ie_len] = 0;
+ }
+ break;
/* Redirecting reason */
case AST_REDIRECTING_REASON:
if (ie_len != sizeof(value)) {
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c
index 368940fa1..e3543d8ec 100644
--- a/main/channel_internal_api.c
+++ b/main/channel_internal_api.c
@@ -930,6 +930,10 @@ struct ast_party_connected_line *ast_channel_connected(struct ast_channel *chan)
{
return &chan->connected;
}
+struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
+{
+ return ast_party_id_merge(&chan->connected.id, &chan->connected.priv);
+}
struct ast_party_dialed *ast_channel_dialed(struct ast_channel *chan)
{
return &chan->dialed;
@@ -938,6 +942,18 @@ struct ast_party_redirecting *ast_channel_redirecting(struct ast_channel *chan)
{
return &chan->redirecting;
}
+struct ast_party_id ast_channel_redirecting_effective_orig(struct ast_channel *chan)
+{
+ return ast_party_id_merge(&chan->redirecting.orig, &chan->redirecting.priv_orig);
+}
+struct ast_party_id ast_channel_redirecting_effective_from(struct ast_channel *chan)
+{
+ return ast_party_id_merge(&chan->redirecting.from, &chan->redirecting.priv_from);
+}
+struct ast_party_id ast_channel_redirecting_effective_to(struct ast_channel *chan)
+{
+ return ast_party_id_merge(&chan->redirecting.to, &chan->redirecting.priv_to);
+}
struct timeval *ast_channel_dtmf_tv(struct ast_channel *chan)
{
return &chan->dtmf_tv;
diff --git a/main/cli.c b/main/cli.c
index 7f71da924..e5118ede6 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -1399,6 +1399,7 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
int hour=0, min=0, sec=0;
struct ast_callid *callid;
char call_identifier_str[AST_CALLID_BUFFER_LENGTH] = "";
+ struct ast_party_id effective_connected_id;
#ifdef CHANNEL_TRACE
int trace_enabled;
#endif
@@ -1452,6 +1453,8 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
ast_callid_unref(callid);
}
+ effective_connected_id = ast_channel_connected_effective_id(c);
+
ast_str_append(&output, 0,
" -- General --\n"
" Name: %s\n"
@@ -1462,6 +1465,8 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
" Caller ID Name: %s\n"
"Connected Line ID: %s\n"
"Connected Line ID Name: %s\n"
+ "Eff. Connected Line ID: %s\n"
+ "Eff. Connected Line ID Name: %s\n"
" DNID Digits: %s\n"
" Language: %s\n"
" State: %s (%d)\n"
@@ -1493,6 +1498,8 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, "(N/A)"),
S_COR(ast_channel_connected(c)->id.number.valid, ast_channel_connected(c)->id.number.str, "(N/A)"),
S_COR(ast_channel_connected(c)->id.name.valid, ast_channel_connected(c)->id.name.str, "(N/A)"),
+ S_COR(effective_connected_id.number.valid, effective_connected_id.number.str, "(N/A)"),
+ S_COR(effective_connected_id.name.valid, effective_connected_id.name.str, "(N/A)"),
S_OR(ast_channel_dialed(c)->number.str, "(N/A)"),
ast_channel_language(c),
ast_state2str(ast_channel_state(c)), ast_channel_state(c), ast_channel_rings(c),
diff --git a/main/features.c b/main/features.c
index 48b733922..4cfbcfb68 100644
--- a/main/features.c
+++ b/main/features.c
@@ -7801,6 +7801,9 @@ int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
ast_party_connected_line_init(&connected_caller);
ast_party_connected_line_copy(&connected_caller, ast_channel_connected(target));
ast_channel_unlock(target);/* The pickup race is avoided so we do not need the lock anymore. */
+ /* Reset any earlier private connected id representation */
+ ast_party_id_reset(&connected_caller.priv);
+
connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
if (ast_channel_connected_line_sub(NULL, chan, &connected_caller, 0) &&
ast_channel_connected_line_macro(NULL, chan, &connected_caller, 0, 0)) {