[Users] WeSIP b2bua problem

tele tele at plexia.com
Fri Mar 9 10:50:02 CET 2007


Hi gines,

Ops i don't remember why i had force the ruri, probably a "no route"
exception. anyway the code only cancel the downstreamleg.
this one cancel the 'other leg':

 protected void doCancel(SipServletRequest req) throws ServletException,
IOException {
        req.getSession().setAttribute("FINISHED","OK");
        try {
                SipSession counterPartLeg = (SipSession)
req.getSession().getAttribute("COUNTERPART_LEG");
                SipServletRequest otherInvite = (SipServletRequest)
counterPartLeg.getAttribute("initialRequest");
                if (counterPartLeg.getAttribute("FINISHED")==null) {
                        otherInvite.createCancel().send();
                }
        } catch (IllegalStateException e) {
                SipSession counterPartLeg =
(SipSession)req.getSession().getAttribute("COUNTERPART_LEG");
                if (counterPartLeg.getAttribute("FINISHED")==null) {
                        counterPartLeg.createRequest("BYE").send();
                }
        }
}

i can see WeSIP try to send the correct CANCEL to the other leg.
this is the scenario:
        
       WeSIP
         |
UA ---> GW ---> PSTN

WeSIP - 192.168.1.10
GW - 192.168.1.11

Upstream call-id: 905071693-18135 at GW
Downstream call-id: 1111905071693-18135 at GW

other info, i'm using SPIRAL 'true', so in my openser.cfg i have:

        if(is_present_hf("X-WeSIP-SPIRAL")){
                t_relay();
        }else{
                as_relay_t("app_server_one");
        }

if you look on the wesip.log attached you can see WeSIP send the CANCEL
in the correct leg but never reach the GW.
I can see the same CANCEL come back to the WeSIP.

maybe the problem could be the related to the X-WeSIP-SPIRAL header, i
can see the CANCEL retrasmission in openser.log.

attached here openser.log and wesip.log

regards

:tele


On Thu, 2007-03-08 at 23:24 +0100, Ginés Gómez wrote:
> Hi,
> 
> 	the procedure for downstream cancel looks OK at 90% but there is  
> something I don't understand. Why do you set the Request URI of the  
> CANCEL request with 'cancelRequest.setRequestURI(requestUri)' ? The  
> 'downstreamRequest.createCancel()' will generate a CANCEL request  
> with the proper RURI. This could be the cause of the error. Another   
> possible cause is that you have received a final response to the  
> downstream dialog while processing the CANCEL. Can you capture the  
> IllegalStateException and try to send a BYE to the downstream to see  
> wether it works ?
> 
> Regards
> 
> Gines
> 	
> El 08/03/2007, a las 19:15, tele escribió:
> 
> > The C is my case, during ringing i cancel the call from caller or the
> > called.
> > so i'm try to do something like this:
> >
> > protected void doCancel(SipServletRequest req) throws  
> > ServletException,
> > IOException {
> >         SipSession downstremLeg =
> > (SipSession)req.getSession().getApplicationSession().getAttribute 
> > ("downstreamLeg");
> >         SipServletRequest downstreamRequest =
> > (SipServletRequest)downstreamLeg.getAttribute("initialRequest");
> >         SipServletRequest cancelRequest = (SipServletRequest)
> > downstreamRequest.createCancel();
> >         SipURI requestUri = sf.createSipURI(((SipURI)
> > req.getRequestURI()).getUser(),((SipURI)
> > req.getRequestURI()).getHost());
> >         cancelRequest.setRequestURI(requestUri);
> >         cancelRequest.send();
> > }
> >
> > get the initial invite generated in UAC for the downstream leg and
> > create a cancel request for the leg, and send it.
> > unfortunaly this not work and i'm occuring in exception:
> >
> > SipProcessor     [SipProcessor[4]] - error processing event...
> > java.lang.IllegalStateException
> >         at
> > com.voztele.sipservlet.core.SipResponse.send(SipResponse.java:144)
> >         at
> > com.voztele.sipservlet.valves.ConvergedHostValve.invokeSipRequest 
> > (ConvergedHostValve.java:283)
> >         at
> > com.voztele.sipservlet.valves.ConvergedHostValve.invokeSIP 
> > (ConvergedHostValve.java:126)
> > etc.......
> >
> > i think the logic for cancel the other leg is correct but i'm doing
> > something wrong :)
> >
> > regards
> >
> > :tele
> >
> >
> >
> > On Thu, 2007-03-08 at 13:30 +0100, Ginés Gómez wrote:
> >>
> >> C) You have not answered to the upstream INVITE with a final response
> >>
> >>    - The container will automatically send a 200OK to the CANCEL
> >>    - The container will automatically send a 487 response to the   
> >> INVITE
> >>    - The application will receive the CANCEL request in the doCancel
> >> method
> >>        - The application sends a CANCEL to the downstream dialog if
> >> it is not completed
> >>        - The application sends a BYE to the downstream dialog if it
> >> is completed
> >>    - Any attempt to answer (or proxy) the incoming INVITE will cause
> >> an IllegalStateException to be thrown
> >>
> >> Hope I was of some help
> >>
> >> Regards
> >>
> >> Gines
> >>
> >>
> >> El 08/03/2007, a las 12:31, tele escribió:
> >>
> >>> Hi,
> >>>
> >>> I'm so closer to complete the basic b2bua but i need last
> >>> clarification
> >>> about the CANCEL.
> >>>
> >>> The specification of servlet API said:
> >>>
> >>> Receiving CANCEL
> >>> When a CANCEL is received for a request which has been passed to an
> >>> application, and the appli-
> >>> cation has not responded yet or proxied the original request, the
> >>> container responds to the original
> >>> request with a 487 (Request Terminated) and to the CANCEL with a
> >>> 200 OK
> >>> final response, and it
> >>> notifies the application by passing it a SipServletRequest object
> >>> representing the CANCEL
> >>> request. The application should not attempt to respond to a request
> >>> after receiving a CANCEL for
> >>> it. Neither should it respond to the CANCEL notification.
> >>> Clearly, there is a race condition between the container generating
> >>> the
> >>> 487 response and the SIP
> >>> servlet generating its own response. This should be handled using
> >>> standard Java mechanisms for
> >>> resolving race conditions. If the application wins, it will not be
> >>> notified that a CANCEL request
> >>> was received. If the container wins and the servlet tries to send a
> >>> response before (or for that matter
> >>> after) being notified of the CANCEL, the container throws an
> >>> IllegalStateException.
> >>>
> >>> I should not override the method onCancel?
> >>> it's not clear to me what to do.
> >>>
> >>> anyway the CANCEL didn't go to the other 'leg'.
> >>>
> >>>
> >>> thanks!
> >>>
> >>>
> >>> :tele
> >>>
> >>>
> >>> On Wed, 2007-03-07 at 16:36 +0100, tele wrote:
> >>>> I've solve my stupid problem.
> >>>>
> >>>> The problem was in my change of Call-ID that i need for my
> >>>> requirements.
> >>>> In the code with problem i did the custom change after create  
> >>>> the new
> >>>> Request.
> >>>>
> >>>>                 SipServletRequest downstreamReq =
> >>>> sf.createRequest(req,false);
> >>>>
> >>>>                 //Retrieve SipApplicationSession and SipSessions
> >>>>                 SipApplicationSession sas =
> >>>> req.getSession().getApplicationSession();
> >>>>
> >>>>                 // change call-id
> >>>>                 String oldcid = downstreamReq.getCallId();
> >>>>                 downstreamReq.removeHeader("Call-ID");
> >>>>                 downstreamReq.addHeader("Call-ID","1111" + oldcid);
> >>>>
> >>>> do my change before create the downstreamReq solve my problem.
> >>>>
> >>>> :tele
> >>>>
> >>>>
> >>>> On Mon, 2007-03-05 at 22:50 +0100, tele wrote:
> >>>>> Hi gines,
> >>>>>
> >>>>> You have been very clear! now i've understand the "dialog
> >>>>> marking" but i
> >>>>> cannot get my b2bua test working.
> >>>>> i'll add more debug to see why the BYE generated is incorrect in
> >>>>> case of
> >>>>> hangup from the caller.
> >>>>>
> >>>>> hem... another question:
> >>>>> how can i get the Logger reference of the  Servlet for adding
> >>>>> more debug?
> >>>>> or i need to create a new logger with log4j and write log to a
> >>>>> new file.
> >>>>>
> >>>>> anyway attached there is the full source code for now.
> >>>>>
> >>>>> thank you very much :)
> >>>>>
> >>>>> regards,
> >>>>>
> >>>>> :tele
> >>>>>
> >>>>>
> >>>>> Ginés Gómez wrote:
> >>>>>> Hi ,
> >>>>>>
> >>>>>> I understand. I'll try to explain myself clearer. Let's go  
> >>>>>> back to
> >>>>>> your original code. This is extracted from the doInvite method.
> >>>>>> Here
> >>>>>> you save both call legs in the application session
> >>>>>> .....
> >>>>>>
> >>>>>> //Save reference to SipSessions in the SipApplication
> >>>>>> sas.setAttribute("upstreamLeg",upstreamLeg);
> >>>>>> sas.setAttribute("downstreamLeg",downstreamLeg);
> >>>>>> .....
> >>>>>>
> >>>>>> what I suggest is that you do the following (after saving in
> >>>>>> ApplicationSession)
> >>>>>>
> >>>>>> upstreamLeg.setAttribute("COUNTERPART_LEG",downstreamLeg);
> >>>>>> downstreamLeg.setAttribute("COUNTERPART_LEG",upstreamLeg);
> >>>>>>
> >>>>>> this way, at any time, you can always get a reference to the
> >>>>>> counterpart dialog doing
> >>>>>>
> >>>>>> req.getSession().getAttribute("COUNTERPART_LEG");
> >>>>>>
> >>>>>> then, when receiving the BYE
> >>>>>>
> >>>>>>>> protected void doBye(SipServletRequest req) throws
> >>>>>>>> ServletException,IOException{
> >>>>>>>>
> >>>>>>>>     //Answer positively
> >>>>>>>>     request.createResponse(200,"Have a nice day").send();
> >>>>>>>>
> >>>>>>>>     //Mark my dialog as finished
> >>>>>>>>     request.getSession().setAttribute("FINISHED","OK");
> >>>>>>>>
> >>>>>>>>     //Get the other leg and finish it in case it is not  
> >>>>>>>> finished
> >>>>>>>>
> >>>>>>>>     //Note how useful is to have in both SipSessions (that is,
> >>>>>>>> both
> >>>>>>>> legs) an attribute which refers the
> >>>>>>>>     //other leg involved in the B2BUA transaction.
> >>>>>>>>     SipSession counterPartLeg= (SipSession)
> >>>>>>>> request.getSession.getAttribute("COUNTERPART_LEG");
> >>>>>>>>     if (counterPartLeg.getAttribute("FINISHED")==null){
> >>>>>>>>     counterPartLeg.createRequest("BYE").send();
> >>>>>>>>     }
> >>>>>>>> }
> >>>>>>
> >>>>>> as you'll see what I do is sending BYE to the 'other' leg. I  
> >>>>>> don't
> >>>>>> care wether I'm processing upstream or downstream because the
> >>>>>> COUNTERPART_LEG attribute in the SipSession will always return a
> >>>>>> reference to the counterpart SipSession. Since the processing
> >>>>>> (answer
> >>>>>> OK, send BYE the other leg) is simetrical regardless the BYE was
> >>>>>> received from the upstream or the downstream the method will work
> >>>>>>
> >>>>>> :-)
> >>>>>>
> >>>>>> Regards
> >>>>>>
> >>>>>> Gines
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>>    protected void doBye(SipServletRequest req) throws
> >>>>>>> ServletException,
> >>>>>>> IOException {
> >>>>>>>         req.createResponse(200,"OK").send();
> >>>>>>>         SipSession downstreamLeg =
> >>>>>>> (SipSession)req.getSession().getApplicationSession
> >>>>>>> ().getAttribute("downstreamLeg");
> >>>>>>>
> >>>>>>>         SipServletRequest byeRequest =
> >>>>>>> downstreamLeg.createRequest("BYE");
> >>>>>>>         byeRequest.send();
> >>>>>>>    }
> >>>>>>>
> >>>>>>> this works only when the BYE come from called.
> >>>>>>>
> >>>>>>> maybe i can get the Id of session of the current request
> >>>>>>> arrived in
> >>>>>>> doBye with getId() and do a check for the other id in the
> >>>>>>> upstreamLeg
> >>>>>>> and downstreamLeg then if equals to any of this, generate the  
> >>>>>>> BYE
> >>>>>>> request in the other call-leg.
> >>>>>>>
> >>>>>>> pseudo code:
> >>>>>>>
> >>>>>>> String sessionId (SipSession)req.getSession().getId();
> >>>>>>> SipSession upSession =
> >>>>>>> (SipSession)req.getSession().getApplicationSession
> >>>>>>> ().getAttribute("upstreamLeg");
> >>>>>>>
> >>>>>>> SipSession downSession =
> >>>>>>> (SipSession)req.getSession().getApplicationSession
> >>>>>>> ().getAttribute("downstreamLeg");
> >>>>>>>
> >>>>>>>
> >>>>>>> if (sessionId == upSession.getId())
> >>>>>>> {
> >>>>>>>    // create and send BYE request in the upstreamLeg
> >>>>>>>    ....
> >>>>>>> } else {
> >>>>>>>    // create and send BYE request in the downstreamLeg
> >>>>>>>    ....
> >>>>>>> };
> >>>>>>>
> >>>>>>>
> >>>>>>> regards,
> >>>>>>>
> >>>>>>> :tele
> >>>>>>>
> >>>>>>>
> >>>>>>> On Mon, 2007-03-05 at 15:27 +0100, Ginés Gómez wrote:
> >>>>>>>> Anyway.... when doing B2BUA you tipically don't need to wait  
> >>>>>>>> for
> >>>>>>>> 200OK to generate BYE response. You can simply send a 200OK to
> >>>>>>>> any
> >>>>>>>> incoming BYE request (since there is no SDP involved in the BYE
> >>>>>>>> handshake) then finish the other leg.  The idea would be doing
> >>>>>>>> something like this (not 100% real code, some pseudocode here)
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> protected void doBye(SipServletRequest req) throws
> >>>>>>>> ServletException,IOException{
> >>>>>>>>
> >>>>>>>>     //Answer positively
> >>>>>>>>     request.createResponse(200,"Have a nice day").send();
> >>>>>>>>
> >>>>>>>>     //Mark my dialog as finished
> >>>>>>>>     request.getSession().setAttribute("FINISHED","OK");
> >>>>>>>>
> >>>>>>>>     //Get the other leg and finish it in case it is not  
> >>>>>>>> finished
> >>>>>>>>
> >>>>>>>>     //Note how useful is to have in both SipSessions (that is,
> >>>>>>>> both
> >>>>>>>> legs) an attribute which refers the
> >>>>>>>>     //other leg involved in the B2BUA transaction.
> >>>>>>>>     SipSession counterPartLeg= (SipSession)
> >>>>>>>> request.getSession.getAttribute("COUNTERPART_LEG");
> >>>>>>>>     if (counterPartLeg.getAttribute("FINISHED")==null){
> >>>>>>>>     counterPartLeg.createRequest("BYE").send();
> >>>>>>>>     }
> >>>>>>>> }
> >>>>>>>>
> >>>>>>>> Regards
> >>>>>>>>
> >>>>>>>> Gines
> >>>>>>>>
> >>>>>>>> El 05/03/2007, a las 14:36, tele escribió:
> >>>>>>>>
> >>>>>>>>> Hi Gines!
> >>>>>>>>>
> >>>>>>>>> It's almost clear to me how to do, this what i have done and
> >>>>>>>>> it works.
> >>>>>>>>>
> >>>>>>>>> now i need last clarification how forward the 200 OK from BYE
> >>>>>>>>> request, i
> >>>>>>>>> cannot get it working.
> >>>>>>>>> for forwarding the 200 ok from the BYE in the doBye request i
> >>>>>>>>> save
> >>>>>>>>> downstreamLeg.setAttribute("byereq", req) and then in the
> >>>>>>>>> doResponse i
> >>>>>>>>> get the bye request and create the response from it,
> >>>>>>>>> something like this but i'm wrong.
> >>>>>>>>>
> >>>>>>>>> if (resp.getStatus() == 200 && resp.getMethod 
> >>>>>>>>> ().equalsIgnoreCase
> >>>>>>>>> ("BYE"))
> >>>>>>>>> {
> >>>>>>>>>                         SipServletRequest upstreamRequest =
> >>>>>>>>> (SipServletRequest)upstreamLeg.getAttribute("byereq");
> >>>>>>>>>                         SipServletResponse upstreamResponse =
> >>>>>>>>> upstreamRequest.createResponse(resp.getStatus
> >>>>>>>>> (),resp.getReasonPhrase
> >>>>>>>>> ());
> >>>>>>>>>                         //Copy the content from the downstream
> >>>>>>>>> response
> >>>>>>>>> to the upstream response
> >>>>>>>>>                         if (resp.getContentType() != null) {
> >>>>>>>>>
> >>>>>>>>> upstreamResponse.setContent(resp.getRawContent(),
> >>>>>>>>> resp.getContentType());
> >>>>>>>>>                         }
> >>>>>>>>>                         upstreamResponse.send();
> >>>>>>>>> }
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> this is what i have done for working ACK.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>   protected void doAck(SipServletRequest req) throws
> >>>>>>>>> ServletException,
> >>>>>>>>> IOException {
> >>>>>>>>>         //Retrieve the upstream request to respond it
> >>>>>>>>>         SipSession downstreamLeg =
> >>>>>>>>> (SipSession)req.getSession().getApplicationSession
> >>>>>>>>> ().getAttribute
> >>>>>>>>> ("downstreamLeg");
> >>>>>>>>>         SipServletResponse downstreamResponse =
> >>>>>>>>> (SipServletResponse)
> >>>>>>>>> downstreamLeg.getAttribute("200ok");
> >>>>>>>>>         SipServletRequest ackRequest =
> >>>>>>>>> downstreamResponse.createAck();
> >>>>>>>>>         //Copy the content from the downstream response to the
> >>>>>>>>> upstream
> >>>>>>>>> response
> >>>>>>>>>         if (req.getContentType() != null) {
> >>>>>>>>>                 ackRequest.setContent(req.getRawContent(),
> >>>>>>>>> req.getContentType());
> >>>>>>>>>         }
> >>>>>>>>>         ackRequest.send();
> >>>>>>>>>    }
> >>>>>>>>>
> >>>>>>>>>    protected void doBye(SipServletRequest req) throws
> >>>>>>>>> ServletException,
> >>>>>>>>> IOException {
> >>>>>>>>>         SipSession downstreamLeg =
> >>>>>>>>> (SipSession)req.getSession().getApplicationSession
> >>>>>>>>> ().getAttribute
> >>>>>>>>> ("downstreamLeg");
> >>>>>>>>>         SipServletRequest byeRequest =
> >>>>>>>>> downstreamLeg.createRequest("BYE");
> >>>>>>>>>         // Copy the content from the downstream response to  
> >>>>>>>>> the
> >>>>>>>>> upstream
> >>>>>>>>> response
> >>>>>>>>>         if (req.getContentType() != null) {
> >>>>>>>>>                 byeRequest.setContent(req.getRawContent(),
> >>>>>>>>> req.getContentType());
> >>>>>>>>>         }
> >>>>>>>>>         byeRequest.send();
> >>>>>>>>>    }
> >>>>>>>>>
> >>>>>>>>>    protected void doResponse(SipServletResponse resp) throws
> >>>>>>>>> ServletException, IOException {
> >>>>>>>>>
> >>>>>>>>>                 if (resp.getStatus() == 200 &&
> >>>>>>>>> resp.getMethod().equalsIgnoreCase("INVITE")) {
> >>>>>>>>>                         SipSession downstreamLeg =  
> >>>>>>>>> (SipSession)
> >>>>>>>>> resp.getSession().getApplicationSession().getAttribute
> >>>>>>>>> ("downstreamLeg");
> >>>>>>>>>                         downstreamLeg.setAttribute
> >>>>>>>>> ("200ok",resp);
> >>>>>>>>>                 }
> >>>>>>>>>
> >>>>>>>>>                 //Retrieve the upstream request to respond it
> >>>>>>>>>                 SipSession upstreamLeg =
> >>>>>>>>> (SipSession)resp.getSession().getApplicationSession
> >>>>>>>>> ().getAttribute
> >>>>>>>>> ("upstreamLeg");
> >>>>>>>>>
> >>>>>>>>> }
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> On Mon, 2007-03-05 at 00:29 +0100, Ginés Gómez wrote:
> >>>>>>>>>> The problem is that you didn't implement the doACK method.
> >>>>>>>>>> Implement
> >>>>>>>>>> it following a similar technique as the one used in
> >>>>>>>>>> doResponse. Save
> >>>>>>>>>> the 200OK response in the downstream session so you can
> >>>>>>>>>> retrieve it
> >>>>>>>>>> when the ACK arrives from the upstream then generate ACK  
> >>>>>>>>>> using
> >>>>>>>>>> response.createACK() and copy the content using  
> >>>>>>>>>> getContentType/
> >>>>>>>>>> setContentType geContent/setContent if required
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>> Hope it helps
> >>>>>>>>>>
> >>>>>>>>>> Gines
> >>>>>>>>>>
> >>>>>>>>>>> Attached there is a .zip with all the log, trace and
> >>>>>>>>>>> configuration.
> >>>>>>>>>>>
> >>>>>>>>>>> thanks for the support,
> >>>>>>>>>>>
> >>>>>>>>>>> :tele
> >>>>>>>>>>> <wesip_test.zip>
> >>>>>>>>>>> _______________________________________________
> >>>>>>>>>>> Users mailing list
> >>>>>>>>>>> Users at openser.org
> >>>>>>>>>>> http://openser.org/cgi-bin/mailman/listinfo/users
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> _______________________________________________
> >>>>>>>>> Users mailing list
> >>>>>>>>> Users at openser.org
> >>>>>>>>> http://openser.org/cgi-bin/mailman/listinfo/users
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> _______________________________________________
> >>>>>>> Users mailing list
> >>>>>>> Users at openser.org
> >>>>>>> http://openser.org/cgi-bin/mailman/listinfo/users
> >>>>>>>
> >>>>>>
> >>>>>
> >>>>> _______________________________________________
> >>>>> Users mailing list
> >>>>> Users at openser.org
> >>>>> http://openser.org/cgi-bin/mailman/listinfo/users
> >>>>
> >>>>
> >>>> _______________________________________________
> >>>> Users mailing list
> >>>> Users at openser.org
> >>>> http://openser.org/cgi-bin/mailman/listinfo/users
> >>>
> >>>
> >>> _______________________________________________
> >>> Users mailing list
> >>> Users at openser.org
> >>> http://openser.org/cgi-bin/mailman/listinfo/users
> >>>
> >>
> >
> >
> > _______________________________________________
> > Users mailing list
> > Users at openser.org
> > http://openser.org/cgi-bin/mailman/listinfo/users
> >
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openser.log
Type: text/x-log
Size: 36066 bytes
Desc: not available
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20070309/aa0f6a82/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: wesip.log
Type: text/x-log
Size: 7343 bytes
Desc: not available
URL: <http://lists.sip-router.org/pipermail/sr-users/attachments/20070309/aa0f6a82/attachment-0001.bin>


More information about the sr-users mailing list