--- asterisk-1.6.1.20/channels/chan_sip.c.orig 2010-05-11 15:30:19.000000000 -0400 +++ asterisk-1.6.1.20/channels/chan_sip.c 2010-06-30 22:43:08.000000000 -0400 @@ -1239,6 +1239,7 @@ int method; /*!< SIP method that opened this dialog */ AST_DECLARE_STRING_FIELDS( AST_STRING_FIELD(callid); /*!< Global CallID */ + AST_STRING_FIELD(calledid); /*!< Called Party RPID Header String */ AST_STRING_FIELD(randdata); /*!< Random data */ AST_STRING_FIELD(accountcode); /*!< Account code */ AST_STRING_FIELD(realm); /*!< Authorization realm */ @@ -1934,6 +1935,7 @@ static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg); static int transmit_response(struct sip_pvt *p, const char *msg, const struct sip_request *req); static int transmit_response_reliable(struct sip_pvt *p, const char *msg, const struct sip_request *req); +static int transmit_response_with_calledrpid(struct sip_pvt *p, char *msg, struct sip_request *req); static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_request *req); static int transmit_response_with_sdp(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp); static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported); @@ -6092,8 +6094,12 @@ p->invitestate = INV_EARLY_MEDIA; if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) || (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) { - /* Send 180 ringing if out-of-band seems reasonable */ - transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); + /* Send 180 ringing if out-of-band seems reasonable */ + if (!ast_strlen_zero(p->calledid)) { + transmit_response_with_calledrpid(p, "180 Ringing", &p->initreq); + } else { + transmit_provisional_response(p, "180 Ringing", &p->initreq, 0); + } ast_set_flag(&p->flags[0], SIP_RINGING); if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES) break; @@ -9070,6 +9076,16 @@ add_header(req, "Date", tmpdat); } +/*! \brief transmit_response_with_calledrpid: Transmit response, no retransmits */ +static int transmit_response_with_calledrpid(struct sip_pvt *p, char *msg, struct sip_request *req) +{ + struct sip_request resp; + respprep(&resp, p, msg, req); + append_date(&resp); + add_header(&resp, "Remote-Party-ID", p->calledid); + return send_response(p, &resp, 0, 0); +} + /*! \brief Append date and content length before transmitting response */ static int transmit_response_with_date(struct sip_pvt *p, const char *msg, const struct sip_request *req) { @@ -9788,6 +9804,9 @@ return -1; } respprep(&resp, p, msg, req); + if (!ast_strlen_zero(p->calledid)) { + add_header(&resp, "Remote-Party-ID", p->calledid); + } if (p->rtp) { if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) { ast_debug(1, "Setting framing from config on incoming call\n"); @@ -24371,6 +24390,19 @@ "Adding the wrong headers may jeopardize the SIP dialog.\n" "Always returns 0\n"; +static char *app_sipcalledrpid = "SIPCalledRPID"; +static char *synopsis_sipcalledrpid = "Set the RPID header for Called Party Identification"; + +static char *descrip_sipcalledrpid = "" +" SIPCalledRPID(name,number): \n" +"Sets the Remote-Party-ID header information to be sent to a call\n" +"originator on further progress through this extension. Many SIP\n" +"phones use this header to display the name and number of the party\n" +"which has been called from the telephone. This progress may be\n" +"updated throughout the call progress whenever Asterisk sends a new\n" +"180 Ringing, 183 Call Progress, or 200 OK response to the calling\n" +"channel." +"Always returns 0\n"; /*! \brief Set the DTMFmode for an outbound SIP call (application) */ static int sip_dtmfmode(struct ast_channel *chan, void *data) @@ -24469,6 +24501,51 @@ return 0; } +/*! \brief Set the value of the RPID header for called party identification */ +static int sip_calledrpid(struct ast_channel *chan, void *data) +{ + struct sip_pvt *p; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(name); + AST_APP_ARG(number); + ); + const char *fromdomain; + char rpid[256]; + + if (ast_strlen_zero(data)) { + ast_log(LOG_WARNING, "No data sent to the application\n"); + return -1; + } + + AST_STANDARD_APP_ARGS(args, data); + + if (ast_strlen_zero(args.name)) { + ast_log(LOG_WARNING, "Called RPID requires a name\n"); + return -1; + } + + if (ast_strlen_zero(args.number)) { + ast_log(LOG_WARNING, "Called RPID requires a number\n"); + return -1; + } + + ast_channel_lock(chan); + + if (chan->tech != &sip_tech) { + ast_log(LOG_WARNING, "This application is only useful for calls originated from SIP UA's\n"); + ast_channel_unlock(chan); + return 0; + } + + p = chan->tech_pvt; + fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr)); + sprintf(rpid, "\"%s\" ;party=called;id-type=subscriber;screen=yes", args.name, args.number, fromdomain); + ast_string_field_set(p, calledid, rpid); + + ast_channel_unlock(chan); + return 0; +} + /*! \brief Transfer call before connect with a 302 redirect \note Called by the transfer() dialplan application through the sip_transfer() pbx interface function if the call is in ringing state @@ -24734,6 +24811,7 @@ /* Register dialplan applications */ ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); + ast_register_application(app_sipcalledrpid, sip_calledrpid, synopsis_sipcalledrpid, descrip_sipcalledrpid); /* Register dialplan functions */ ast_custom_function_register(&sip_header_function); @@ -24791,6 +24869,7 @@ ast_custom_function_unregister(&sippeer_function); ast_custom_function_unregister(&sip_header_function); ast_custom_function_unregister(&checksipdomain_function); + ast_unregister_application(app_sipcalledrpid); /* Unregister dial plan applications */ ast_unregister_application(app_dtmfmode);