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(a)openser.org
>>>>>>>
http://openser.org/cgi-bin/mailman/listinfo/users
>>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Users mailing list
>>>>> Users(a)openser.org
>>>>>
http://openser.org/cgi-bin/mailman/listinfo/users
>>>>>
>>>>
>>>
>>>
>>> _______________________________________________
>>> Users mailing list
>>> Users(a)openser.org
>>>
http://openser.org/cgi-bin/mailman/listinfo/users
>>>
>>
>
> _______________________________________________
> Users mailing list
> Users(a)openser.org
>
http://openser.org/cgi-bin/mailman/listinfo/users
_______________________________________________
Users mailing list
Users(a)openser.org
http://openser.org/cgi-bin/mailman/listinfo/users
_______________________________________________
Users mailing list
Users(a)openser.org