[Users] WeSIP b2bua problem
Ginés Gómez
gines at voztele.com
Thu Mar 8 23:24:46 CET 2007
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
>
More information about the sr-users
mailing list