[Asterisk-Dev] SIP : transfer and display update

Roman Sidler Roman.Sidler at ascom.ch
Fri Jun 10 17:46:26 MST 2005


>>I'm confused in the way Asterisk handles the transfer with SIP.
>>Just say that A makes call to B, holds B, then makes call to C and make
>>At the end B is in call with C.
>>On a SIP point of view, A sends a refer to Asterisk, with a refer-to
>>and replaces extension.
>>On receiving of this refer, Asterisk makes reinvite to B and reinvite to
>>with right sdp, so that B speaks to C.
>>The problem is that on its display, B is still with A, and C is still
with A
>>Is there any way so that * handles refer in a different way?
The ReInvite you mentioned is to update the RTP-Stream SDP-Attribute "c="
If you configure canreinvite=no, there's is no update.

As part of our COLP extension (#ifdef COLP) we need an asynchroneous
solution, not only for SIP.
We send an AST_CONTROL_COLP frame into new bridge.
We used the "Remote-Party-ID" header field, also used by CISCO.
To change "from" and "to" Field is a bad idea, because one of them is
mostly the proxy address.
Another problem is to the differ callerid (origin) and colp (connected

I'm planning to make a patch for this, when it runs 100% over IAX and
Q.931, SIP to SIP is ok.

******chan_sip.c:attempt_transfer()-> the tricky part
#ifdef COLP
            char **change_c = NULL;
            char **change_d = NULL;
            char *get_c = NULL;
            char *get_d = NULL;

            if (peerc->outgoing){
                  change_c = &peerc->callerid;
                  get_c = strdup(peerc->colp);
            else {
                  change_c = &peerc->colp;
                  get_c = strdup(peerc->callerid);

            if (peerd->outgoing) {
                  change_d = &peerd->callerid;
                  get_d = strdup(peerd->colp);
            else {
                  change_d = &peerd->colp;
                  get_d = strdup(peerd->callerid);

            if (!(*change_c && *change_d && get_c && get_d)) return res;

            /*Notify to channels*/
            struct ast_frame fc;
            memset(&fc, 0, sizeof(fc));
            fc.frametype = AST_FRAME_CONTROL;
            fc.subclass = AST_CONTROL_COLP;
            fc.data = get_c;
            fc.datalen = strlen(get_c)+1;

            struct ast_frame fd;
            memset(&fd, 0, sizeof(fd));
            fd.frametype = AST_FRAME_CONTROL;
            fd.subclass = AST_CONTROL_COLP;
            fd.data = get_d;
            fd.datalen = strlen(get_d)+1;
            if (ast_channel_masquerade(peerb, peerc)) {
                  ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n",
peerb->name, peerc->name);
                  res = -1;
#ifdef COLP
    /*note the order of masquerade and notifying COLP-frame*/
            ast_queue_frame(peerb, &fc);/*peerb masqueraded by peerc*/
            ast_queue_frame(peerd, &fd);/*peerd..*/

******in channel.c:ast_write()
#ifdef COLP
            else if (fr->subclass == AST_CONTROL_COLP){
                  if (fr->data && fr->datalen && *((char*)fr->data)){
                        if (chan->outgoing){
                              if (chan->callerid)
                              chan->callerid = strdup(fr->data);
                              res = ast_indicate(chan, fr->subclass);

                              if (chan->colp)
                              chan->colp = strdup(fr->data);
                              res = ast_indicate(chan, fr->subclass);

      case AST_CONTROL_COLP:
      if (ast->colp)


More information about the asterisk-dev mailing list