Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 245667) +++ channels/chan_sip.c (working copy) @@ -540,6 +540,26 @@ via multiple Variable: name=value sequences. + + + Send an SIP UPDATE or INFO to the phone to show the Callerid name and num after a Bridge action. + + + + + Peer to receive the update. + + + Name of the caller/callee. + + + Number of the caller/callee. + + + + Show name and number on display after a Action Bridge. + + ***/ static int min_expiry = DEFAULT_MIN_EXPIRY; /*!< Minimum accepted registration time */ @@ -8623,7 +8643,7 @@ lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), 1); - if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) { + if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI) || ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI_INFO)) { if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { ast_str_set(&tmp, -1, "%s", anonymous_string); } else { @@ -22642,6 +22662,8 @@ ast_set_flag(&mask[0], SIP_SENDRPID); if (!strcasecmp(v->value, "pai")) { ast_set_flag(&flags[0], SIP_SENDRPID_PAI); + } else if (!strcasecmp(v->value, "paiinfo")) { + ast_set_flag(&flags[0], SIP_SENDRPID_PAI_INFO); } else if (!strcasecmp(v->value, "rpid")) { ast_set_flag(&flags[0], SIP_SENDRPID_RPID); } else if (ast_true(v->value)) { @@ -24947,6 +24969,98 @@ return 0; } + +/*! \brief transmit_phone_display_info: Change the name/number displayed on a phone ---*/ +static int transmit_phone_display_info(struct sip_pvt *p, const char *name, const char *num) +{ + char domain[INET_ADDRSTRLEN]; + struct sip_request req; + struct ast_str *msg = ast_str_alloca(256); + int len, lid_pres; + const char *anonymous_string = "\"Anonymous\" "; + + if (!p || !p->owner || !name || !num || !num[0]) return 0; + + if (p->fromdomain[0]) { + ast_copy_string(domain, p->fromdomain, sizeof(domain)); + } else { + ast_copy_string(domain, ast_inet_ntoa(p->ourip.sin_addr), sizeof(domain)); + if (!strlen(domain)) + ast_copy_string(domain, "0.0.0.0", sizeof(domain)); + } + if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI)) { + lid_pres = (p->owner) ? p->owner->connected.id.number_presentation : AST_PRES_NUMBER_NOT_AVAILABLE; + if ((lid_pres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED) { + ast_str_set(&msg, -1, "%s", anonymous_string); + } else { + ast_str_set(&msg, -1, "\"%s\" ", name[0]?name:num, num, domain); + } + + if (ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE)) { + reqprep(&req, p, SIP_INVITE, 0, 1); + } + else { + reqprep(&req, p, SIP_UPDATE, 0, 1); + } + add_header(&req, "Allow", ALLOWED_METHODS); + add_header(&req, "P-Asserted-Identity", ast_str_buffer(msg)); + add_sdp(&req, p, FALSE, FALSE, FALSE); + } + else if (ast_test_flag(&p->flags[0], SIP_SENDRPID_PAI_INFO)) { + + ast_str_set(&msg, -1, "%s %s ", name[0]?name:num, num); + len = strlen("To: \r\n") + strlen(ast_str_buffer(msg)); + + reqprep(&req, p, SIP_INFO, 0, 1); + add_header(&req, "Content-Type", "message/sipfrag"); + add_header_contentLength(&req, len); + add_header(&req, "\r\nTo", ast_str_buffer(msg)); + } + else return 0; + + copy_request(&p->initreq, &req); + parse_request(&p->initreq); + if (sip_debug_test_pvt(p)) { + ast_verbose("%d headers, %d lines\n", p->initreq.headers, p->initreq.lines); + } + p->lastinvite = p->ocseq; + ast_set_flag(&p->flags[0], SIP_OUTGOING); + return send_request(p, &req, 1, p->ocseq); +} + +static int manager_calleridupdate( struct mansession *s, const struct message *m ) { + struct ast_channel *chan; + struct sip_pvt *p; + + const char *channame = astman_get_header(m, "Channel"); + const char *cid_name = astman_get_header(m, "Cidname"); + const char *cid_num = astman_get_header(m, "CidNum"); + + if (ast_strlen_zero(channame)) { + astman_send_error(s, m, "Channel name not specified"); + return 0; + } + if (!cid_name) { + astman_send_error(s, m, "CidName not specified"); + return 0; + } + if (ast_strlen_zero(cid_num)) { + astman_send_error(s, m, "CidNum not specified"); + return 0; + } + chan = ast_channel_get_by_name(channame); + if (!chan) { + astman_send_error(s, m, "No such channel"); + return 0; + } + p = chan->tech_pvt; + if (ast_test_flag(&p->flags[0], SIP_SENDRPID)) { + transmit_phone_display_info(p, cid_name, cid_num); + } + + return 0; +} + /*! \brief Send a poke to all known peers */ static void sip_poke_all_peers(void) { @@ -25304,6 +25418,7 @@ ast_manager_register_xml("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer); ast_manager_register_xml("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry); ast_manager_register_xml("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify); ++ ast_manager_register_xml("SIPCallerIdUpdate", EVENT_FLAG_AGENT, manager_calleridupdate); sip_poke_all_peers(); sip_send_all_registers(); sip_send_all_mwi_subscriptions(); @@ -25368,6 +25483,7 @@ ast_manager_unregister("SIPqualifypeer"); ast_manager_unregister("SIPshowregistry"); ast_manager_unregister("SIPnotify"); + ast_manager_unregister("SIPCallerIdUpdate"); /* Kill TCP/TLS server threads */ if (sip_tcp_desc.master) Index: channels/sip/include/sip.h =================================================================== --- channels/sip/include/sip.h (revision 245667) +++ channels/sip/include/sip.h (working copy) @@ -285,10 +285,11 @@ #define SIP_PROG_INBAND_NO (1 << 25) #define SIP_PROG_INBAND_YES (2 << 25) -#define SIP_SENDRPID (3 << 29) /*!< DP: Remote Party-ID Support */ +#define SIP_SENDRPID (7 << 29) /*!< DP: Remote Party-ID Support */ #define SIP_SENDRPID_NO (0 << 29) #define SIP_SENDRPID_PAI (1 << 29) /*!< Use "P-Asserted-Identity" for rpid */ #define SIP_SENDRPID_RPID (2 << 29) /*!< Use "Remote-Party-ID" for rpid */ +#define SIP_SENDRPID_PAI_INFO (4 << 29) /*!< Use "P-Asserted-Identity" for rpid or SIP INFO after Bridge action */ #define SIP_G726_NONSTANDARD (1 << 31) /*!< DP: Use non-standard packing for G726-32 data */ /*! \brief Flags to copy from peer/user to dialog */