[Asterisk-Dev] SIP : transfer and display update

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





Hello,

>>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
the
>>transfer.
>>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
header
>>and replaces extension.
>>On receiving of this refer, Asterisk makes reinvite to B and reinvite to
C
>>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
>>also.
>>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
peer).

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;
#endif
            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..*/
#endif
...




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

                        }
                        else{/*incoming*/
                              if (chan->colp)
                                    free(chan->colp);
                              chan->colp = strdup(fr->data);
                              res = ast_indicate(chan, fr->subclass);
                        }
                  }
            }
#endif
...


************chan.sip.c:sip_indicate()********
..
      case AST_CONTROL_COLP:
      if (ast->colp)
            transmit_reinvite_with_sdp(p);
            break;
..



Roman




More information about the asterisk-dev mailing list