Yep, that looks like what I would expect it to look like. The only thing that immediately jumps out as unnecessary is the

    if (ref_by_val && !ast_strlen_zero(ref_by_val))

line. You can get rid of the initial NULL check because ast_strlen_zero() does that for you.

If you wanted to submit this for inclusion in Asterisk, feel free to upload a review to https://gerrit.asterisk.org. Instructions can be found on the wiki [1]. Before submitting, I'd also be sure to read the Asterisk coding guidelines [2] since the current code would have coding guidelines findings on it.

[1] https://wiki.asterisk.org/wiki/display/AST/Gerrit+Usage
[2] https://wiki.asterisk.org/wiki/display/AST/Coding+Guidelines

On 08/25/2015 04:35 PM, Dan Cropp wrote:

Thank you Mark for the tips.

Is the code below close to what you were thinking?

I ran some initial tests and it seems to be working. I can override the default Referred-By value by setting the SIPREFERREDBYHDR variable.

static void transfer_refer(struct ast_sip_session *session, const char *target)

{

pjsip_evsub *sub;

        enum ast_control_transfer message = AST_TRANSFER_SUCCESS;

pj_str_t tmp;

pjsip_tx_data *packet;

if (pjsip_xfer_create_uac(session->inv_session->dlg, NULL, &sub) != PJ_SUCCESS) {

             message = AST_TRANSFER_FAILED;

ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));

return;

        }

if (pjsip_xfer_initiate(sub, pj_cstr(&tmp, target), &packet) != PJ_SUCCESS) {

message = AST_TRANSFER_FAILED;

ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));

pjsip_evsub_terminate(sub, PJ_FALSE);

return;

        }

        /**** Start of changes ****/

pjsip_hdr *hdr;

        const pj_str_t str_ref_by = { "Referred-By", 11 };

const char *ref_by_val = pbx_builtin_getvar_helper(session->channel, "SIPREFERREDBYHDR");

pj_str_t tmp2;

        if (ref_by_val && !ast_strlen_zero(ref_by_val))

          {

hdr = (pjsip_hdr*)pjsip_generic_string_hdr_create(packet->pool, &str_ref_by, pj_cstr(&tmp2, ref_by_val));

          }

        else

          {

            /* Add Referred-By header */

hdr = (pjsip_hdr*)pjsip_generic_string_hdr_create(packet->pool, &str_ref_by, &session->inv_session->dlg->local.info_str);

          }

pjsip_msg_add_hdr(packet->msg, hdr);

        /**** End of changes ****/

pjsip_xfer_send_request(sub, packet);

ast_queue_control_data(session->channel, AST_CONTROL_TRANSFER, &message, sizeof(message));

}

*From:*asterisk-dev-boun...@lists.digium.com [mailto:asterisk-dev-boun...@lists.digium.com] *On Behalf Of *Mark Michelson
*Sent:* Tuesday, August 25, 2015 1:17 PM
*To:* Asterisk Developers Mailing List
*Subject:* Re: [asterisk-dev] Transfer cmd (PJSIP not sending Referred-By but chan_sip does)

That code gets you about 95% of the way there.

The biggest difference would be that the pjsip_msg_add_hdr() call may need to be broken up based on whether the SIPREFERREDBYHDR channel variable is set or not. To determine that, you can use the pbx_builtin_getvar_helper() function call declared in include/asterisk/pbx.h to retrieve the variable value, and the ast_strlen_zero() function to determine if the channel variable value is zero-length or not.

Other than that, you should be able to omit the call to pjsua_process_msg_data() since Asterisk doesn't use pjsua.

On 08/25/2015 12:35 PM, Dan Cropp wrote:

    In doing a little research, it seems the Referred-By header could
    be added after the pjsip_xfer_initiate.

    This is the approach PJSIP did for some code as far back as PJSIP 1.6.

        /*

         * Create REFER request.

         */

        status = pjsip_xfer_initiate(sub, dest, &tdata);

        if (status != PJ_SUCCESS) {

    pjsua_perror(THIS_FILE, "Unable to create REFER request", status);

    pjsip_dlg_dec_lock(dlg);

                    return status;

        }

        /* Add Referred-By header */

        gs_hdr = pjsip_generic_string_hdr_create(tdata->pool, &str_ref_by,

         &dlg->local.info_str);

        pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)gs_hdr);

        /* Add additional headers etc */

        pjsua_process_msg_data( tdata, msg_data);

        /* Send. */

        status = pjsip_xfer_send_request(sub, tdata);

        if (status != PJ_SUCCESS) {

    pjsua_perror(THIS_FILE, "Unable to send REFER request", status);

    pjsip_dlg_dec_lock(dlg);

                    return status;

        }

    Could anyone provider some insight into how difficult this might
    be for me to add and submit for approval?  Depending on the
    answer, my manager may be willing to let me work on this.

    I've developed in C/C++ for over 25 years so I'm plenty familiar
    with the language.

    I'm less familiar with the syntax and coding standards of
    Asterisk.  I know the group is very good at letting people know
    about their mistakes and how to fix them.

    Have a great day!

    Dan

    *From:*asterisk-dev-boun...@lists.digium.com
    <mailto:asterisk-dev-boun...@lists.digium.com>
    [mailto:asterisk-dev-boun...@lists.digium.com] *On Behalf Of *Dan
    Cropp
    *Sent:* Tuesday, August 25, 2015 10:50 AM
    *To:* Asterisk Developers Mailing List
    *Subject:* Re: [asterisk-dev] Transfer cmd (PJSIP not sending
    Referred-By but chan_sip does)

    Thank you Mark

    *From:*asterisk-dev-boun...@lists.digium.com
    <mailto:asterisk-dev-boun...@lists.digium.com>
    [mailto:asterisk-dev-boun...@lists.digium.com] *On Behalf Of *Mark
    Michelson
    *Sent:* Tuesday, August 25, 2015 10:30 AM
    *To:* Asterisk Developers Mailing List
    *Subject:* Re: [asterisk-dev] Transfer cmd (PJSIP not sending
    Referred-By but chan_sip does)

    The answer to this is actually pretty simple: adding Referred-By
    in outgoing SIP REFERs is simply not implemented in chan_pjsip's
    chan_pjsip_transfer() function.

    As far as the syntax required for the Transfer() application,
    that's probably a case where that needs to be clarified in
    documentation. There are lots of places in PJSIP configuration
    where we require full SIP URIs rather than just IP addresses or
    bare URIs (user@domain).

    On 08/25/2015 10:00 AM, Dan Cropp wrote:

        I asked the question on asterisk–users but did not receive a
        response, so I am sending the question here.

        I am running Asterisk 13.5.0.

        A call comes in, Asterisk answers it. After some actions, the
call needs to be Transferred (SIP REFER) to another number. The other switch is responsible for accepting the Transfer and
        tromboning the lines internally.  It will also send a BYE so
        Asterisk no longer has the call.

        The behavior works when I have the endpoint configured at
        chan_sip.  It does not work when the endpoint is configured as
        PJSIP.  I worked with the other switch vendor and he
        determined chan_sip includes the Referred-By header.  PJSIP
        does not include the Referred-By header.  The other switch
        requires the Referred-By header to be present.

        I tried setting the channel’s SIPREFERREDBYHDR variable before
        the Transfer command and that still did not force the
        Referred-By header to be part of the REFER packet.

        I tried the PJSIP_HEADER add and it still did not add the
        Referred-By header to the REFER packet.

        Is there a PJSIP setting to force the Referred-By to be part
        of the REFER packet?

        chan_sip (succeeds)

        19:27:32.512123 IP (tos 0x0, ttl 64, id 11492, offset 0, flags
        [none], proto UDP (17), length 630)

            192.168.xxx.xxx.sip > 192.168.yyy.yyy.sip: SIP, length: 602

                REFER sip:3...@192.168.yyy.yyy:5060 SIP/2.0

                Via: SIP/2.0/UDP
        192.168.xxx.xxx:5060;branch=z9hG4bK58f4bd1d

                Max-Forwards: 70

                From: <sip:3...@192.168.xxx.xxx>;tag=as44000cf4

                To: <sip:3...@192.168.yyy.yyy>;tag=7Iy0JkwDC

                Contact: <sip:3...@192.168.xxx.xxx:5060>

                Call-ID: jdeuqpak-00...@192.168.yyy.yyy
        <mailto:jdeuqpak-00...@192.168.yyy.yyy>

                CSeq: 102 REFER

                User-Agent: Asterisk PBX 13.5.0

                Date: Thu, 20 Aug 2015 19:27:32 GMT

                Refer-To: <sip:3...@192.168.yyy.yyy>

                Referred-By: <sip:3...@192.168.xxx.xxx:5060>

                Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER,
        SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE

                Supported: replaces, timer

                Content-Length: 0

        Pjsip

        18:46:58.386372 IP (tos 0x0, ttl 64, id 38690, offset 0, flags
        [DF], proto UDP (17), length 654)

            192.168.xxx.xxx.sip > 192.168.yyy.yyy.sip: SIP, length: 626

                REFER sip:3...@192.168.yyy.yyy:5060 SIP/2.0

                Via: SIP/2.0/UDP
        
192.168.xxx.xxx:5060;rport;branch=z9hG4bKPjec41c3b9-d734-482d-82c1-2a6f8d9452a3

                From:
        <sip:3...@192.168.xxx.xxx>;tag=3c10f423-e468-42ea-87a1-658ae106581c

                To: <sip:3...@192.168.yyy.yyy>;tag=WITKDakt

                Contact: <sip:192.168.xxx.xxx:5060>

                Call-ID: s6wk6l6q-00...@192.168.yyy.yyy
        <mailto:s6wk6l6q-00...@192.168.yyy.yyy>

                CSeq: 981 REFER

                Event: refer

                Expires: 600

                Supported: 100rel, timer, replaces, norefersub

                Accept: message/sipfrag;version=2.0

                Allow-Events: message-summary, presence, dialog, refer

                Refer-To: <sip:3...@192.168.yyy.yyy>

                Max-Forwards: 70

                User-Agent: Asterisk PBX 13.5.0

                Content-Length:  0

        One other slight oddity.

        To get chan_sip to Transfer

        3...@192.168.yyy.yyy <mailto:3...@192.168.yyy.yyy>

        To get PJSIP to Transfer with the correct Refer-To header, I
        had to include the <> and sip:

        <_sip:3...@192.168.yyy.__yyy_>

        Have a great day!

        Dan






-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev

Reply via email to