res_pjsip_caller_id.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2013, Digium, Inc.
00005  *
00006  * Mark Michelson <mmichelson@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*** MODULEINFO
00020    <depend>pjproject</depend>
00021    <depend>res_pjsip</depend>
00022    <depend>res_pjsip_session</depend>
00023    <support_level>core</support_level>
00024  ***/
00025 
00026 #include "asterisk.h"
00027 
00028 #include <pjsip.h>
00029 #include <pjsip_ua.h>
00030 
00031 #include "asterisk/res_pjsip.h"
00032 #include "asterisk/res_pjsip_session.h"
00033 #include "asterisk/channel.h"
00034 #include "asterisk/module.h"
00035 #include "asterisk/callerid.h"
00036 
00037 /*!
00038  * \internal
00039  * \brief Set an ast_party_id name and number based on an identity header.
00040  * \param hdr From, P-Asserted-Identity, or Remote-Party-ID header on incoming message
00041  * \param[out] id The ID to set data on
00042  */
00043 static void set_id_from_hdr(pjsip_fromto_hdr *hdr, struct ast_party_id *id)
00044 {
00045    char cid_name[AST_CHANNEL_NAME];
00046    char cid_num[AST_CHANNEL_NAME];
00047    pjsip_sip_uri *uri;
00048    pjsip_name_addr *id_name_addr = (pjsip_name_addr *) hdr->uri;
00049 
00050    uri = pjsip_uri_get_uri(id_name_addr);
00051    ast_copy_pj_str(cid_name, &id_name_addr->display, sizeof(cid_name));
00052    ast_copy_pj_str(cid_num, &uri->user, sizeof(cid_num));
00053 
00054    ast_free(id->name.str);
00055    id->name.str = ast_strdup(cid_name);
00056    if (!ast_strlen_zero(cid_name)) {
00057       id->name.valid = 1;
00058    }
00059    ast_free(id->number.str);
00060    id->number.str = ast_strdup(cid_num);
00061    if (!ast_strlen_zero(cid_num)) {
00062       id->number.valid = 1;
00063    }
00064 }
00065 
00066 /*!
00067  * \internal
00068  * \brief Get a P-Asserted-Identity or Remote-Party-ID header from an incoming message
00069  *
00070  * This function will parse the header as if it were a From header. This allows for us
00071  * to easily manipulate the URI, as well as add, modify, or remove parameters from the
00072  * header
00073  *
00074  * \param rdata The incoming message
00075  * \param header_name The name of the ID header to find
00076  * \retval NULL No ID header present or unable to parse ID header
00077  * \retval non-NULL The parsed ID header
00078  */
00079 static pjsip_fromto_hdr *get_id_header(pjsip_rx_data *rdata, const pj_str_t *header_name)
00080 {
00081    static const pj_str_t from = { "From", 4 };
00082    pj_str_t header_content;
00083    pjsip_fromto_hdr *parsed_hdr;
00084    pjsip_generic_string_hdr *ident = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
00085          header_name, NULL);
00086    int parsed_len;
00087 
00088    if (!ident) {
00089       return NULL;
00090    }
00091 
00092    pj_strdup_with_null(rdata->tp_info.pool, &header_content, &ident->hvalue);
00093 
00094    parsed_hdr = pjsip_parse_hdr(rdata->tp_info.pool, &from, header_content.ptr,
00095          pj_strlen(&header_content), &parsed_len);
00096 
00097    if (!parsed_hdr) {
00098       return NULL;
00099    }
00100 
00101    return parsed_hdr;
00102 }
00103 
00104 /*!
00105  * \internal
00106  * \brief Set an ast_party_id structure based on data in a P-Asserted-Identity header
00107  *
00108  * This makes use of \ref set_id_from_hdr for setting name and number. It uses
00109  * the contents of a Privacy header in order to set presentation information.
00110  *
00111  * \param rdata The incoming message
00112  * \param[out] id The ID to set
00113  * \retval 0 Successfully set the party ID
00114  * \retval non-zero Could not set the party ID
00115  */
00116 static int set_id_from_pai(pjsip_rx_data *rdata, struct ast_party_id *id)
00117 {
00118    static const pj_str_t pai_str = { "P-Asserted-Identity", 19 };
00119    static const pj_str_t privacy_str = { "Privacy", 7 };
00120    pjsip_fromto_hdr *pai_hdr = get_id_header(rdata, &pai_str);
00121    pjsip_generic_string_hdr *privacy;
00122 
00123    if (!pai_hdr) {
00124       return -1;
00125    }
00126 
00127    set_id_from_hdr(pai_hdr, id);
00128 
00129    if (!id->number.valid) {
00130       return -1;
00131    }
00132 
00133    privacy = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &privacy_str, NULL);
00134    if (privacy && !pj_stricmp2(&privacy->hvalue, "id")) {
00135       id->number.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
00136       id->name.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
00137    } else {
00138       id->number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
00139       id->name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
00140    }
00141 
00142    return 0;
00143 }
00144 
00145 /*!
00146  * \internal
00147  * \brief Set an ast_party_id structure based on data in a Remote-Party-ID header
00148  *
00149  * This makes use of \ref set_id_from_hdr for setting name and number. It uses
00150  * the privacy and screen parameters in order to set presentation information.
00151  *
00152  * \param rdata The incoming message
00153  * \param[out] id The ID to set
00154  * \retval 0 Succesfully set the party ID
00155  * \retval non-zero Could not set the party ID
00156  */
00157 static int set_id_from_rpid(pjsip_rx_data *rdata, struct ast_party_id *id)
00158 {
00159    static const pj_str_t rpid_str = { "Remote-Party-ID", 15 };
00160    static const pj_str_t privacy_str = { "privacy", 7 };
00161    static const pj_str_t screen_str = { "screen", 6 };
00162    pjsip_fromto_hdr *rpid_hdr = get_id_header(rdata, &rpid_str);
00163    pjsip_param *screen;
00164    pjsip_param *privacy;
00165 
00166    if (!rpid_hdr) {
00167       return -1;
00168    }
00169 
00170    set_id_from_hdr(rpid_hdr, id);
00171 
00172    if (!id->number.valid) {
00173       return -1;
00174    }
00175 
00176    privacy = pjsip_param_find(&rpid_hdr->other_param, &privacy_str);
00177    screen = pjsip_param_find(&rpid_hdr->other_param, &screen_str);
00178    if (privacy && !pj_stricmp2(&privacy->value, "full")) {
00179       id->number.presentation = AST_PRES_RESTRICTED;
00180       id->name.presentation = AST_PRES_RESTRICTED;
00181    } else {
00182       id->number.presentation = AST_PRES_ALLOWED;
00183       id->name.presentation = AST_PRES_ALLOWED;
00184    }
00185    if (screen && !pj_stricmp2(&screen->value, "yes")) {
00186       id->number.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
00187       id->name.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
00188    } else {
00189       id->number.presentation |= AST_PRES_USER_NUMBER_UNSCREENED;
00190       id->name.presentation |= AST_PRES_USER_NUMBER_UNSCREENED;
00191    }
00192 
00193    return 0;
00194 }
00195 
00196 /*!
00197  * \internal
00198  * \brief Set an ast_party_id structure based on data in a From
00199  *
00200  * This makes use of \ref set_id_from_hdr for setting name and number. It uses
00201  * no information from the message in order to set privacy. It relies on endpoint
00202  * configuration for privacy information.
00203  *
00204  * \param rdata The incoming message
00205  * \param[out] id The ID to set
00206  * \retval 0 Succesfully set the party ID
00207  * \retval non-zero Could not set the party ID
00208  */
00209 static int set_id_from_from(struct pjsip_rx_data *rdata, struct ast_party_id *id)
00210 {
00211    pjsip_fromto_hdr *from = pjsip_msg_find_hdr(rdata->msg_info.msg,
00212          PJSIP_H_FROM, rdata->msg_info.msg->hdr.next);
00213 
00214    if (!from) {
00215       /* This had better not happen */
00216       return -1;
00217    }
00218 
00219    set_id_from_hdr(from, id);
00220 
00221    if (!id->number.valid) {
00222       return -1;
00223    }
00224 
00225    return 0;
00226 }
00227 
00228 /*!
00229  * \internal
00230  * \brief Determine if a connected line update should be queued
00231  *
00232  * This uses information about the session and the ID that would be queued
00233  * in the connected line update in order to determine if we should queue
00234  * a connected line update.
00235  *
00236  * \param session The session whose channel we wish to queue the connected line update on
00237  * \param id The identification information that would be queued on the connected line update
00238  * \retval 0 We should not queue a connected line update
00239  * \retval non-zero We should queue a connected line update
00240  */
00241 static int should_queue_connected_line_update(const struct ast_sip_session *session, const struct ast_party_id *id)
00242 {
00243    /* Invalid number means no update */
00244    if (!id->number.valid) {
00245       return 0;
00246    }
00247 
00248    /* If the session has never communicated an update or if the
00249     * new ID has a different number than the session, then we
00250     * should queue an update
00251     */
00252    if (ast_strlen_zero(session->id.number.str) ||
00253          strcmp(session->id.number.str, id->number.str)) {
00254       return 1;
00255    }
00256 
00257    /* By making it to this point, it means the number is not enough
00258     * to determine if an update should be sent. Now we look at
00259     * the name
00260     */
00261 
00262    /* If the number couldn't warrant an update and the name is
00263     * invalid, then no update
00264     */
00265    if (!id->name.valid) {
00266       return 0;
00267    }
00268 
00269    /* If the name has changed or we don't have a name set for the
00270     * session, then we should send an update
00271     */
00272    if (ast_strlen_zero(session->id.name.str) ||
00273          strcmp(session->id.name.str, id->name.str)) {
00274       return 1;
00275    }
00276 
00277    /* Neither the name nor the number have changed. No update */
00278    return 0;
00279 }
00280 
00281 /*!
00282  * \internal
00283  * \brief Queue a connected line update on a session's channel.
00284  * \param session The session whose channel should have the connected line update queued upon.
00285  * \param id The identification information to place in the connected line update
00286  */
00287 static void queue_connected_line_update(struct ast_sip_session *session, const struct ast_party_id *id)
00288 {
00289    struct ast_party_connected_line connected;
00290    struct ast_party_caller caller;
00291 
00292    /* Fill connected line information */
00293    ast_party_connected_line_init(&connected);
00294    connected.id = *id;
00295    connected.id.tag = session->endpoint->id.self.tag;
00296    connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
00297 
00298    /* Save to channel driver copy */
00299    ast_party_id_copy(&session->id, &connected.id);
00300 
00301    /* Update our channel CALLERID() */
00302    ast_party_caller_init(&caller);
00303    caller.id = connected.id;
00304    caller.ani = connected.id;
00305    caller.ani2 = ast_channel_caller(session->channel)->ani2;
00306    ast_channel_set_caller_event(session->channel, &caller, NULL);
00307 
00308    /* Tell peer about the new connected line information. */
00309    ast_channel_queue_connected_line_update(session->channel, &connected, NULL);
00310 }
00311 
00312 /*!
00313  * \internal
00314  * \brief Make updates to connected line information based on an incoming request.
00315  *
00316  * This will get identity information from an incoming request. Once the identification is
00317  * retrieved, we will check if the new information warrants a connected line update and queue
00318  * a connected line update if so.
00319  *
00320  * \param session The session on which we received an incoming request
00321  * \param rdata The incoming request
00322  */
00323 static void update_incoming_connected_line(struct ast_sip_session *session, pjsip_rx_data *rdata)
00324 {
00325    struct ast_party_id id;
00326 
00327    if (!session->endpoint->id.trust_inbound) {
00328       return;
00329    }
00330 
00331    ast_party_id_init(&id);
00332    if (!set_id_from_pai(rdata, &id) || !set_id_from_rpid(rdata, &id)) {
00333       if (should_queue_connected_line_update(session, &id)) {
00334          queue_connected_line_update(session, &id);
00335       }
00336    }
00337    ast_party_id_free(&id);
00338 }
00339 
00340 /*!
00341  * \internal
00342  * \brief Session supplement callback on an incoming INVITE request
00343  *
00344  * If we are receiving an initial INVITE, then we will set the session's identity
00345  * based on the INVITE or configured endpoint values. If we are receiving a reinvite,
00346  * then we will potentially queue a connected line update via the \ref update_incoming_connected_line
00347  * function
00348  *
00349  * \param session The session that has received an INVITE
00350  * \param rdata The incoming INVITE
00351  */
00352 static int caller_id_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
00353 {
00354    if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED) {
00355       /*
00356        * Initial inbound INVITE.  Set the session ID directly
00357        * because the channel has not been created yet.
00358        */
00359       if (session->endpoint->id.trust_inbound
00360          && (!set_id_from_pai(rdata, &session->id)
00361             || !set_id_from_rpid(rdata, &session->id))) {
00362          ast_free(session->id.tag);
00363          session->id.tag = ast_strdup(session->endpoint->id.self.tag);
00364          return 0;
00365       }
00366       ast_party_id_copy(&session->id, &session->endpoint->id.self);
00367       if (!session->endpoint->id.self.number.valid) {
00368          set_id_from_from(rdata, &session->id);
00369       }
00370    } else if (session->channel) {
00371       /* Reinvite. Check for changes to the ID and queue a connected line
00372        * update if necessary
00373        */
00374       update_incoming_connected_line(session, rdata);
00375    }
00376    return 0;
00377 }
00378 
00379 /*!
00380  * \internal
00381  * \brief Session supplement callback on INVITE response
00382  *
00383  * INVITE responses could result in queuing connected line updates.
00384  *
00385  * \param session The session on which communication is happening
00386  * \param rdata The incoming INVITE response
00387  */
00388 static void caller_id_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
00389 {
00390    if (!session->channel) {
00391       return;
00392    }
00393 
00394    update_incoming_connected_line(session, rdata);
00395 }
00396 
00397 /*!
00398  * \internal
00399  * \brief Set name and number information on an identity header.
00400  * \param pool Memory pool to use for string duplication
00401  * \param id_hdr A From, P-Asserted-Identity, or Remote-Party-ID header to modify
00402  * \param id The identity information to apply to the header
00403  */
00404 static void modify_id_header(pj_pool_t *pool, pjsip_fromto_hdr *id_hdr, const struct ast_party_id *id)
00405 {
00406    pjsip_name_addr *id_name_addr;
00407    pjsip_sip_uri *id_uri;
00408 
00409    id_name_addr = (pjsip_name_addr *) id_hdr->uri;
00410    id_uri = pjsip_uri_get_uri(id_name_addr->uri);
00411 
00412    if (id->name.valid) {
00413       int name_buf_len = strlen(id->name.str) * 2 + 1;
00414       char *name_buf = ast_alloca(name_buf_len);
00415 
00416       ast_escape_quoted(id->name.str, name_buf, name_buf_len);
00417       pj_strdup2(pool, &id_name_addr->display, name_buf);
00418    }
00419 
00420    if (id->number.valid) {
00421       pj_strdup2(pool, &id_uri->user, id->number.str);
00422    }
00423 }
00424 
00425 /*!
00426  * \internal
00427  * \brief Create an identity header for an outgoing message
00428  * \param hdr_name The name of the header to create
00429  * \param tdata The message to place the header on
00430  * \param id The identification information for the new header
00431  * \return newly-created header
00432  */
00433 static pjsip_fromto_hdr *create_new_id_hdr(const pj_str_t *hdr_name, pjsip_tx_data *tdata, const struct ast_party_id *id)
00434 {
00435    pjsip_fromto_hdr *id_hdr;
00436    pjsip_fromto_hdr *base;
00437    pjsip_name_addr *id_name_addr;
00438    pjsip_sip_uri *id_uri;
00439 
00440    base = tdata->msg->type == PJSIP_REQUEST_MSG ? PJSIP_MSG_FROM_HDR(tdata->msg) :
00441       PJSIP_MSG_TO_HDR(tdata->msg);
00442    id_hdr = pjsip_from_hdr_create(tdata->pool);
00443    id_hdr->type = PJSIP_H_OTHER;
00444    pj_strdup(tdata->pool, &id_hdr->name, hdr_name);
00445    id_hdr->sname.slen = 0;
00446 
00447    id_name_addr = pjsip_uri_clone(tdata->pool, base->uri);
00448    id_uri = pjsip_uri_get_uri(id_name_addr->uri);
00449 
00450    if (id->name.valid) {
00451       int name_buf_len = strlen(id->name.str) * 2 + 1;
00452       char *name_buf = ast_alloca(name_buf_len);
00453 
00454       ast_escape_quoted(id->name.str, name_buf, name_buf_len);
00455       pj_strdup2(tdata->pool, &id_name_addr->display, name_buf);
00456    }
00457 
00458    pj_strdup2(tdata->pool, &id_uri->user, id->number.str);
00459 
00460    id_hdr->uri = (pjsip_uri *) id_name_addr;
00461    return id_hdr;
00462 }
00463 
00464 /*!
00465  * \internal
00466  * \brief Add a Privacy header to an outbound message
00467  *
00468  * When sending a P-Asserted-Identity header, if privacy is requested, then we
00469  * will need to indicate such by adding a Privacy header. Similarly, if no
00470  * privacy is requested, and a Privacy header already exists on the message,
00471  * then the old Privacy header should be removed.
00472  *
00473  * \param tdata The outbound message to add the Privacy header to
00474  * \param id The id information used to determine privacy
00475  */
00476 static void add_privacy_header(pjsip_tx_data *tdata, const struct ast_party_id *id)
00477 {
00478    static const pj_str_t pj_privacy_name = { "Privacy", 7 };
00479    static const pj_str_t pj_privacy_value = { "id", 2 };
00480    pjsip_hdr *old_privacy;
00481 
00482    old_privacy = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_privacy_name, NULL);
00483 
00484    if ((ast_party_id_presentation(id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
00485       if (old_privacy) {
00486          pj_list_erase(old_privacy);
00487       }
00488    } else if (!old_privacy) {
00489       pjsip_generic_string_hdr *privacy_hdr = pjsip_generic_string_hdr_create(
00490             tdata->pool, &pj_privacy_name, &pj_privacy_value);
00491       pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)privacy_hdr);
00492    }
00493 }
00494 
00495 /*!
00496  * \internal
00497  * \brief Add a P-Asserted-Identity header to an outbound message
00498  * \param tdata The message to add the header to
00499  * \param id The identification information used to populate the header
00500  */
00501 static void add_pai_header(pjsip_tx_data *tdata, const struct ast_party_id *id)
00502 {
00503    static const pj_str_t pj_pai_name = { "P-Asserted-Identity", 19 };
00504    pjsip_fromto_hdr *pai_hdr;
00505    pjsip_fromto_hdr *old_pai;
00506 
00507    /* Since inv_session reuses responses, we have to make sure there's not already
00508     * a P-Asserted-Identity present. If there is, we just modify the old one.
00509     */
00510    old_pai = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_pai_name, NULL);
00511    if (old_pai) {
00512       modify_id_header(tdata->pool, old_pai, id);
00513       add_privacy_header(tdata, id);
00514       return;
00515    }
00516 
00517    pai_hdr = create_new_id_hdr(&pj_pai_name, tdata, id);
00518    if (!pai_hdr) {
00519       return;
00520    }
00521    add_privacy_header(tdata, id);
00522 
00523    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)pai_hdr);
00524 }
00525 
00526 /*!
00527  * \internal
00528  * \brief Add privacy and screen parameters to a Remote-Party-ID header.
00529  *
00530  * If privacy is requested, then the privacy and screen parameters need to
00531  * reflect this. Similarly, if no privacy or screening is to be communicated,
00532  * we need to make sure that any previously set values are updated.
00533  *
00534  * \param tdata The message where the Remote-Party-ID header is
00535  * \param hdr The header on which the parameters are being added
00536  * \param id The identification information used to determine privacy
00537  */
00538 static void add_privacy_params(pjsip_tx_data *tdata, pjsip_fromto_hdr *hdr, const struct ast_party_id *id)
00539 {
00540    static const pj_str_t privacy_str = { "privacy", 7 };
00541    static const pj_str_t screen_str = { "screen", 6 };
00542    static const pj_str_t privacy_full_str = { "full", 4 };
00543    static const pj_str_t privacy_off_str = { "off", 3 };
00544    static const pj_str_t screen_yes_str = { "yes", 3 };
00545    static const pj_str_t screen_no_str = { "no", 2 };
00546    pjsip_param *old_privacy;
00547    pjsip_param *old_screen;
00548    pjsip_param *privacy;
00549    pjsip_param *screen;
00550    int presentation;
00551 
00552    old_privacy = pjsip_param_find(&hdr->other_param, &privacy_str);
00553    old_screen = pjsip_param_find(&hdr->other_param, &screen_str);
00554 
00555    if (!old_privacy) {
00556       privacy = PJ_POOL_ALLOC_T(tdata->pool, pjsip_param);
00557       privacy->name = privacy_str;
00558       pj_list_insert_before(&hdr->other_param, privacy);
00559    } else {
00560       privacy = old_privacy;
00561    }
00562 
00563    if (!old_screen) {
00564       screen = PJ_POOL_ALLOC_T(tdata->pool, pjsip_param);
00565       screen->name = screen_str;
00566       pj_list_insert_before(&hdr->other_param, screen);
00567    } else {
00568       screen = old_screen;
00569    }
00570 
00571    presentation = ast_party_id_presentation(id);
00572    if ((presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED) {
00573       privacy->value = privacy_off_str;
00574    } else {
00575       privacy->value = privacy_full_str;
00576    }
00577    if ((presentation & AST_PRES_NUMBER_TYPE) == AST_PRES_USER_NUMBER_PASSED_SCREEN) {
00578       screen->value = screen_yes_str;
00579    } else {
00580       screen->value = screen_no_str;
00581    }
00582 }
00583 
00584 /*!
00585  * \internal
00586  * \brief Add a Remote-Party-ID header to an outbound message
00587  * \param tdata The message to add the header to
00588  * \param id The identification information used to populate the header
00589  */
00590 static void add_rpid_header(pjsip_tx_data *tdata, const struct ast_party_id *id)
00591 {
00592    static const pj_str_t pj_rpid_name = { "Remote-Party-ID", 15 };
00593    pjsip_fromto_hdr *rpid_hdr;
00594    pjsip_fromto_hdr *old_rpid;
00595 
00596    /* Since inv_session reuses responses, we have to make sure there's not already
00597     * a P-Asserted-Identity present. If there is, we just modify the old one.
00598     */
00599    old_rpid = pjsip_msg_find_hdr_by_name(tdata->msg, &pj_rpid_name, NULL);
00600    if (old_rpid) {
00601       modify_id_header(tdata->pool, old_rpid, id);
00602       add_privacy_params(tdata, old_rpid, id);
00603       return;
00604    }
00605 
00606    rpid_hdr = create_new_id_hdr(&pj_rpid_name, tdata, id);
00607    if (!rpid_hdr) {
00608       return;
00609    }
00610    add_privacy_params(tdata, rpid_hdr, id);
00611    pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)rpid_hdr);
00612 }
00613 
00614 /*!
00615  * \internal
00616  * \brief Add any appropriate identification headers to an outbound SIP message
00617  *
00618  * This will determine if an outbound message should have identification headers and
00619  * will add the appropriately configured headers
00620  *
00621  * \param session The session on which we will be sending the message
00622  * \param tdata The outbound message
00623  * \param The identity information to place on the message
00624  */
00625 static void add_id_headers(const struct ast_sip_session *session, pjsip_tx_data *tdata, const struct ast_party_id *id)
00626 {
00627    if (!id->number.valid
00628       || (!session->endpoint->id.trust_outbound
00629          && (ast_party_id_presentation(id) & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
00630       return;
00631    }
00632    if (session->endpoint->id.send_pai) {
00633       add_pai_header(tdata, id);
00634    }
00635    if (session->endpoint->id.send_rpid) {
00636       add_rpid_header(tdata, id);
00637    }
00638 }
00639 
00640 /*!
00641  * \internal
00642  * \brief Session supplement callback for outgoing INVITE requests
00643  *
00644  * For an initial INVITE request, we may change the From header to appropriately
00645  * reflect the identity information. On all INVITEs (initial and reinvite) we may
00646  * add other identity headers such as P-Asserted-Identity and Remote-Party-ID based
00647  * on configuration and privacy settings
00648  *
00649  * \param session The session on which the INVITE will be sent
00650  * \param tdata The outbound INVITE request
00651  */
00652 static void caller_id_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
00653 {
00654    struct ast_party_id effective_id;
00655    struct ast_party_id connected_id;
00656 
00657    if (!session->channel) {
00658       return;
00659    }
00660 
00661    /* Must do a deep copy unless we hold the channel lock the entire time. */
00662    ast_party_id_init(&connected_id);
00663    ast_channel_lock(session->channel);
00664    effective_id = ast_channel_connected_effective_id(session->channel);
00665    ast_party_id_copy(&connected_id, &effective_id);
00666    ast_channel_unlock(session->channel);
00667 
00668    if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED) {
00669       /* Only change the From header on the initial outbound INVITE. Switching it
00670        * mid-call might confuse some UAs.
00671        */
00672       pjsip_fromto_hdr *from;
00673       pjsip_dialog *dlg;
00674 
00675       from = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_FROM, tdata->msg->hdr.next);
00676       dlg = session->inv_session->dlg;
00677 
00678       if (ast_strlen_zero(session->endpoint->fromuser)
00679          && (session->endpoint->id.trust_outbound
00680             || (ast_party_id_presentation(&connected_id) & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED)) {
00681          modify_id_header(tdata->pool, from, &connected_id);
00682          modify_id_header(dlg->pool, dlg->local.info, &connected_id);
00683       }
00684 
00685       ast_sip_add_usereqphone(session->endpoint, tdata->pool, from->uri);
00686       ast_sip_add_usereqphone(session->endpoint, dlg->pool, dlg->local.info->uri);
00687    }
00688    add_id_headers(session, tdata, &connected_id);
00689    ast_party_id_free(&connected_id);
00690 }
00691 
00692 /*!
00693  * \internal
00694  * \brief Session supplement for outgoing INVITE response
00695  *
00696  * This will add P-Asserted-Identity and Remote-Party-ID headers if necessary
00697  *
00698  * \param session The session on which the INVITE response is to be sent
00699  * \param tdata The outbound INVITE response
00700  */
00701 static void caller_id_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
00702 {
00703    struct ast_party_id effective_id;
00704    struct ast_party_id connected_id;
00705 
00706    if (!session->channel) {
00707       return;
00708    }
00709 
00710    /* Must do a deep copy unless we hold the channel lock the entire time. */
00711    ast_party_id_init(&connected_id);
00712    ast_channel_lock(session->channel);
00713    effective_id = ast_channel_connected_effective_id(session->channel);
00714    ast_party_id_copy(&connected_id, &effective_id);
00715    ast_channel_unlock(session->channel);
00716 
00717    add_id_headers(session, tdata, &connected_id);
00718    ast_party_id_free(&connected_id);
00719 }
00720 
00721 static struct ast_sip_session_supplement caller_id_supplement = {
00722    .method = "INVITE,UPDATE",
00723    .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL - 1000,
00724    .incoming_request = caller_id_incoming_request,
00725    .incoming_response = caller_id_incoming_response,
00726    .outgoing_request = caller_id_outgoing_request,
00727    .outgoing_response = caller_id_outgoing_response,
00728 };
00729 
00730 static int load_module(void)
00731 {
00732    CHECK_PJSIP_SESSION_MODULE_LOADED();
00733 
00734    ast_sip_session_register_supplement(&caller_id_supplement);
00735    return AST_MODULE_LOAD_SUCCESS;
00736 }
00737 
00738 static int unload_module(void)
00739 {
00740    ast_sip_session_unregister_supplement(&caller_id_supplement);
00741    return 0;
00742 }
00743 
00744 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Caller ID Support",
00745       .support_level = AST_MODULE_SUPPORT_CORE,
00746       .load = load_module,
00747       .unload = unload_module,
00748       .load_pri = AST_MODPRI_APP_DEPEND,
00749           );

Generated on Thu Apr 16 06:27:48 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6