List<NameValuePair> parameters() { final List<NameValuePair> parameters = new ArrayList<NameValuePair>(); final String callSid = callInfo.sid().toString(); parameters.add(new BasicNameValuePair("CallSid", callSid)); final String accountSid = accountId.toString(); parameters.add(new BasicNameValuePair("AccountSid", accountSid)); final String from = (callInfo.from()); parameters.add(new BasicNameValuePair("From", from)); final String to = (callInfo.to()); parameters.add(new BasicNameValuePair("To", to)); final String state = callState.toString(); parameters.add(new BasicNameValuePair("CallStatus", state)); parameters.add(new BasicNameValuePair("ApiVersion", version)); final String direction = callInfo.direction(); parameters.add(new BasicNameValuePair("Direction", direction)); final String callerName = callInfo.fromName(); parameters.add(new BasicNameValuePair("CallerName", callerName)); final String forwardedFrom = callInfo.forwardedFrom(); parameters.add(new BasicNameValuePair("ForwardedFrom", forwardedFrom)); // logger.info("Type " + callInfo.type()); if (CreateCall.Type.SIP == callInfo.type()) { // Adding SIP OUT Headers and SipCallId for // https://bitbucket.org/telestax/telscale-restcomm/issue/132/implement-twilio-sip-out SipServletResponse lastResponse = callInfo.lastResponse(); // logger.info("lastResponse " + lastResponse); if (lastResponse != null) { final int statusCode = lastResponse.getStatus(); final String method = lastResponse.getMethod(); // See https://www.twilio.com/docs/sip/receiving-sip-headers // Headers on the final SIP response message (any 4xx or 5xx message or the final BYE/200) // are posted to the // Dial action URL. if ((statusCode >= 400 && "INVITE".equalsIgnoreCase(method)) || (statusCode >= 200 && statusCode < 300 && "BYE".equalsIgnoreCase(method))) { final String sipCallId = lastResponse.getCallId(); parameters.add(new BasicNameValuePair("DialSipCallId", sipCallId)); parameters.add(new BasicNameValuePair("DialSipResponseCode", "" + statusCode)); Iterator<String> headerIt = lastResponse.getHeaderNames(); while (headerIt.hasNext()) { String headerName = headerIt.next(); if (headerName.startsWith("X-")) { parameters.add( new BasicNameValuePair( "DialSipHeader_" + headerName, lastResponse.getHeader(headerName))); } } } } } return parameters; }
/** * Ensure that the servlet is not invoked if session is invalidated. * * <p>See http://jira.cipango.org/browse/CIPANGO-121 * * <pre> * Alice Proxy Bob * 1 | INVITE | | * |----------->| | * 2 | | INVITE | * | |--------->| * 3 | | 200 | * | |<---------| * 4 | 200 | | * |<-----------| | * 5 | ACK | | * |----------->| | * 6 | | ACK | * | |--------->| * 7 | BYE | | * |----------->| | * 8 | | BYE | * | |--------->| * 9 | | 200 | * | |<---------| * 10 | 200 | | * |<-----------| | * </pre> */ @Test public void testInvalidateBefore200() throws Exception { Endpoint bob = createEndpoint("bob"); UaRunnable callB = new UasScript.OkBye(bob.getUserAgent()); callB.start(); SipServletRequest request = _ua.createRequest(SipMethods.INVITE, bob.getUri()); request.setRequestURI(bob.getContact().getURI()); Call callA = _ua.createCall(request); assertThat(callA.waitForResponse(), isSuccess()); callA.createAck().send(); callA.createBye().send(); SipServletResponse response = callA.waitForResponse(); assertThat(response, isSuccess()); assertThat(response.getHeader("error"), is(nullValue())); }
@Override protected void doSuccessResponse(SipServletResponse resp) throws ServletException, IOException { logger.info("Got OK"); SipSession session = resp.getSession(); if (resp.getStatus() == SipServletResponse.SC_OK) { Boolean inviteSent = (Boolean) session.getAttribute("InviteSent"); if (inviteSent != null && inviteSent.booleanValue()) { return; } Address secondPartyAddress = (Address) resp.getSession().getAttribute("SecondPartyAddress"); if (secondPartyAddress != null) { SipServletRequest invite = sipFactory.createRequest( resp.getApplicationSession(), "INVITE", session.getRemoteParty(), secondPartyAddress); logger.info("Found second party -- sending INVITE to " + secondPartyAddress); String contentType = resp.getContentType(); if (contentType.trim().equals("application/sdp")) { invite.setContent(resp.getContent(), "application/sdp"); } session.setAttribute("LinkedSession", invite.getSession()); invite.getSession().setAttribute("LinkedSession", session); SipServletRequest ack = resp.createAck(); invite.getSession().setAttribute("FirstPartyAck", ack); invite.getSession().setAttribute("FirstPartyContent", resp.getContent()); Call call = (Call) session.getAttribute("call"); // The call links the two sessions, add the new session to the call call.addSession(invite.getSession()); invite.getSession().setAttribute("call", call); invite.send(); session.setAttribute("InviteSent", Boolean.TRUE); } else { String cSeqValue = resp.getHeader("CSeq"); if (cSeqValue.indexOf("INVITE") != -1) { logger.info("Got OK from second party -- sending ACK"); SipServletRequest secondPartyAck = resp.createAck(); SipServletRequest firstPartyAck = (SipServletRequest) resp.getSession().getAttribute("FirstPartyAck"); // if (resp.getContentType() != null && // resp.getContentType().equals("application/sdp")) { firstPartyAck.setContent(resp.getContent(), "application/sdp"); secondPartyAck.setContent( resp.getSession().getAttribute("FirstPartyContent"), "application/sdp"); // } firstPartyAck.send(); secondPartyAck.send(); } } } }