/*! * \internal * \brief Session supplement callback on an incoming INVITE request * * If we are receiving an initial INVITE, then we will set the session's identity * based on the INVITE or configured endpoint values. If we are receiving a reinvite, * then we will potentially queue a connected line update via the \ref update_incoming_connected_line * function * * \param session The session that has received an INVITE * \param rdata The incoming INVITE */ static int caller_id_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata) { if (!session->channel) { /* * Since we have no channel this must be the initial inbound * INVITE. Set the session ID directly because the channel * has not been created yet. */ if (session->endpoint->id.trust_inbound && (!set_id_from_pai(rdata, &session->id) || !set_id_from_rpid(rdata, &session->id))) { ast_free(session->id.tag); session->id.tag = ast_strdup(session->endpoint->id.self.tag); return 0; } ast_party_id_copy(&session->id, &session->endpoint->id.self); if (!session->endpoint->id.self.number.valid) { set_id_from_from(rdata, &session->id); } } else { /* * ReINVITE or UPDATE. Check for changes to the ID and queue * a connected line update if necessary. */ update_incoming_connected_line(session, rdata); } return 0; }
/*! * \internal * \brief Session supplement callback on an incoming INVITE request * * If we are receiving an initial INVITE, then we will set the session's identity * based on the INVITE or configured endpoint values. If we are receiving a reinvite, * then we will potentially queue a connected line update via the \ref update_incoming_connected_line * function * * \param session The session that has received an INVITE * \param rdata The incoming INVITE */ static int caller_id_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata) { if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED) { /* * Initial inbound INVITE. Set the session ID directly * because the channel has not been created yet. */ if (session->endpoint->id.trust_inbound && (!set_id_from_pai(rdata, &session->id) || !set_id_from_rpid(rdata, &session->id))) { ast_free(session->id.tag); session->id.tag = ast_strdup(session->endpoint->id.self.tag); return 0; } ast_party_id_copy(&session->id, &session->endpoint->id.self); if (!session->endpoint->id.self.number.valid) { set_id_from_from(rdata, &session->id); } } else if (session->channel) { /* Reinvite. Check for changes to the ID and queue a connected line * update if necessary */ update_incoming_connected_line(session, rdata); } return 0; }
/*! * \internal * \brief Queue a connected line update on a session's channel. * \param session The session whose channel should have the connected line update queued upon. * \param id The identification information to place in the connected line update */ static void queue_connected_line_update(struct ast_sip_session *session, const struct ast_party_id *id) { struct ast_party_connected_line connected; struct ast_set_party_connected_line update_connected; ast_party_connected_line_init(&connected); ast_party_id_copy(&connected.id, id); memset(&update_connected, 0, sizeof(update_connected)); update_connected.id.number = 1; update_connected.id.name = 1; ast_set_party_id_all(&update_connected.priv); connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; ast_party_id_copy(&session->id, &connected.id); ast_channel_queue_connected_line_update(session->channel, &connected, &update_connected); ast_party_connected_line_free(&connected); }
static void copy_redirecting_id(struct ast_party_id *dst, const struct ast_party_id *src, struct ast_set_party_id *update) { ast_party_id_copy(dst, src); if (dst->number.valid) { update->number = 1; } if (dst->name.valid) { update->name = 1; } }
/*! * \internal * \brief Session supplement callback for outgoing INVITE requests * * On all INVITEs (initial and reinvite) we may add other identity headers * such as P-Asserted-Identity and Remote-Party-ID based on configuration * and privacy settings * * \param session The session on which the INVITE will be sent * \param tdata The outbound INVITE request */ static void caller_id_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata) { struct ast_party_id effective_id; struct ast_party_id connected_id; if (!session->channel) { return; } ast_party_id_init(&connected_id); ast_channel_lock(session->channel); effective_id = ast_channel_connected_effective_id(session->channel); ast_party_id_copy(&connected_id, &effective_id); ast_channel_unlock(session->channel); add_id_headers(session, tdata, &connected_id); ast_party_id_free(&connected_id); }
/*! * \internal * \brief Session supplement for outgoing INVITE response * * This will add P-Asserted-Identity and Remote-Party-ID headers if necessary * * \param session The session on which the INVITE response is to be sent * \param tdata The outbound INVITE response */ static void caller_id_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata) { struct ast_party_id effective_id; struct ast_party_id connected_id; if (!session->channel) { return; } /* Must do a deep copy unless we hold the channel lock the entire time. */ ast_party_id_init(&connected_id); ast_channel_lock(session->channel); effective_id = ast_channel_connected_effective_id(session->channel); ast_party_id_copy(&connected_id, &effective_id); ast_channel_unlock(session->channel); add_id_headers(session, tdata, &connected_id); ast_party_id_free(&connected_id); }
/*! * \internal * \brief Session supplement callback for outgoing INVITE requests * * For an initial INVITE request, we may change the From header to appropriately * reflect the identity information. On all INVITEs (initial and reinvite) we may * add other identity headers such as P-Asserted-Identity and Remote-Party-ID based * on configuration and privacy settings * * \param session The session on which the INVITE will be sent * \param tdata The outbound INVITE request */ static void caller_id_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata) { struct ast_party_id effective_id; struct ast_party_id connected_id; if (!session->channel) { return; } /* Must do a deep copy unless we hold the channel lock the entire time. */ ast_party_id_init(&connected_id); ast_channel_lock(session->channel); effective_id = ast_channel_connected_effective_id(session->channel); ast_party_id_copy(&connected_id, &effective_id); ast_channel_unlock(session->channel); if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED) { /* Only change the From header on the initial outbound INVITE. Switching it * mid-call might confuse some UAs. */ pjsip_fromto_hdr *from; pjsip_dialog *dlg; from = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_FROM, tdata->msg->hdr.next); dlg = session->inv_session->dlg; if (ast_strlen_zero(session->endpoint->fromuser) && (session->endpoint->id.trust_outbound || (ast_party_id_presentation(&connected_id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED)) { modify_id_header(tdata->pool, from, &connected_id); modify_id_header(dlg->pool, dlg->local.info, &connected_id); } ast_sip_add_usereqphone(session->endpoint, tdata->pool, from->uri); ast_sip_add_usereqphone(session->endpoint, dlg->pool, dlg->local.info->uri); } add_id_headers(session, tdata, &connected_id); ast_party_id_free(&connected_id); }
/*! * \internal * \brief Queue a connected line update on a session's channel. * \param session The session whose channel should have the connected line update queued upon. * \param id The identification information to place in the connected line update */ static void queue_connected_line_update(struct ast_sip_session *session, const struct ast_party_id *id) { struct ast_party_connected_line connected; struct ast_party_caller caller; /* Fill connected line information */ ast_party_connected_line_init(&connected); connected.id = *id; connected.id.tag = session->endpoint->id.self.tag; connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; /* Save to channel driver copy */ ast_party_id_copy(&session->id, &connected.id); /* Update our channel CALLERID() */ ast_party_caller_init(&caller); caller.id = connected.id; caller.ani = connected.id; caller.ani2 = ast_channel_caller(session->channel)->ani2; ast_channel_set_caller_event(session->channel, &caller, NULL); /* Tell peer about the new connected line information. */ ast_channel_queue_connected_line_update(session->channel, &connected, NULL); }