public void errResponseReceived(final SipResponse sipResponse) { Dialog dialog = dialogManager.getDialog(sipResponse); if (dialog != null) { dialog.receivedOrSent300To699(); dialogManager.removeDialog(dialog.getId()); } int statusCode = sipResponse.getStatusCode(); if (statusCode == RFC3261.CODE_401_UNAUTHORIZED || statusCode == RFC3261.CODE_407_PROXY_AUTHENTICATION_REQUIRED && !challenged) { InviteClientTransaction inviteClientTransaction = (InviteClientTransaction) transactionManager.getClientTransaction(sipResponse); SipRequest sipRequest = inviteClientTransaction.getRequest(); String password = userAgent.getConfig().getPassword(); if (password != null && !"".equals(password.trim())) { challengeManager.handleChallenge(sipRequest, sipResponse); } challenged = true; return; } else { challenged = false; } SipListener sipListener = userAgent.getSipListener(); if (sipListener != null) { sipListener.error(sipResponse); } List<String> guiClosedCallIds = userAgent.getUac().getGuiClosedCallIds(); String callId = Utils.getMessageCallId(sipResponse); if (guiClosedCallIds.contains(callId)) { guiClosedCallIds.remove(callId); } userAgent.getMediaManager().setDatagramSocket(null); }
public void provResponseReceived(SipResponse sipResponse, Transaction transaction) { // dialog may have already been created if a previous 1xx has // already been received Dialog dialog = dialogManager.getDialog(sipResponse); boolean isFirstProvRespWithToTag = false; if (dialog == null) { SipHeaderFieldValue to = sipResponse.getSipHeaders().get(new SipHeaderFieldName(RFC3261.HDR_TO)); String toTag = to.getParam(new SipHeaderParamName(RFC3261.PARAM_TAG)); if (toTag != null) { dialog = dialogManager.createDialog(sipResponse); isFirstProvRespWithToTag = true; } else { // TODO maybe stop retransmissions } } if (dialog != null) { buildOrUpdateDialogForUac(sipResponse, transaction); } // // if (dialog == null && sipResponse.getStatusCode() != RFC3261.CODE_100_TRYING) { // logger.debug("dialog not found for prov response"); // isFirstProvRespWithToTag = true; // SipHeaderFieldValue to = sipResponse.getSipHeaders() // .get(new SipHeaderFieldName(RFC3261.HDR_TO)); // String toTag = to.getParam(new SipHeaderParamName(RFC3261.PARAM_TAG)); // if (toTag != null) { // dialog = buildOrUpdateDialogForUac(sipResponse, transaction); // } // } // TODO this notification is probably useless because dialog state modification // thereafter always notify dialog observers if (isFirstProvRespWithToTag) { SipListener sipListener = userAgent.getSipListener(); if (sipListener != null) { sipListener.ringing(sipResponse); } dialog.receivedOrSent1xx(); } List<String> guiClosedCallIds = userAgent.getUac().getGuiClosedCallIds(); String callId = Utils.getMessageCallId(sipResponse); if (guiClosedCallIds.contains(callId)) { SipRequest sipRequest = transaction.getRequest(); logger.debug( "cancel after prov response: sipRequest " + sipRequest + ", sipResponse " + sipResponse); userAgent.terminate(sipRequest); } }
/** * For the moment we consider that only one profile uri is used at a time. * * @throws SipUriSyntaxException */ public SipRequest register() throws SipUriSyntaxException { String domain = userAgent.getDomain(); String requestUri = RFC3261.SIP_SCHEME + RFC3261.SCHEME_SEPARATOR + domain; SipListener sipListener = userAgent.getSipListener(); profileUri = RFC3261.SIP_SCHEME + RFC3261.SCHEME_SEPARATOR + userAgent.getUserpart() + RFC3261.AT + domain; registerCallID = Utils.generateCallID(userAgent.getConfig().getLocalInetAddress()); SipRequest sipRequest = initialRequestManager.createInitialRequest( requestUri, RFC3261.METHOD_REGISTER, profileUri, registerCallID); if (sipListener != null) { sipListener.registering(sipRequest); } return sipRequest; }
public void successResponseReceived(SipResponse sipResponse, Transaction transaction) { SipHeaders responseHeaders = sipResponse.getSipHeaders(); String cseq = responseHeaders.get(new SipHeaderFieldName(RFC3261.HDR_CSEQ)).getValue(); String method = cseq.substring(cseq.trim().lastIndexOf(' ') + 1); if (!RFC3261.METHOD_INVITE.equals(method)) { return; } challenged = false; // 13.2.2.4 List<String> peers = userAgent.getPeers(); String responseTo = responseHeaders.get(new SipHeaderFieldName(RFC3261.HDR_TO)).getValue(); if (!peers.contains(responseTo)) { peers.add(responseTo); // timer used to purge dialogs which are not confirmed // after a given time ackTimer.schedule(new AckTimerTask(responseTo), 64 * RFC3261.TIMER_T1); } Dialog dialog = dialogManager.getDialog(sipResponse); if (dialog != null) { // dialog already created with a 180 for example dialog.setRouteSet(computeRouteSet(sipResponse.getSipHeaders())); } dialog = buildOrUpdateDialogForUac(sipResponse, transaction); SipListener sipListener = userAgent.getSipListener(); if (sipListener != null) { sipListener.calleePickup(sipResponse); } // added for media SessionDescription sessionDescription = sdpManager.parse(sipResponse.getBody()); try { mediaDestination = sdpManager.getMediaDestination(sessionDescription); } catch (NoCodecException e) { logger.error(e.getMessage(), e); } String remoteAddress = mediaDestination.getDestination(); int remotePort = mediaDestination.getPort(); Codec codec = mediaDestination.getCodec(); String localAddress = userAgent.getConfig().getLocalInetAddress().getHostAddress(); userAgent .getMediaManager() .successResponseReceived(localAddress, remoteAddress, remotePort, codec); // switch to confirmed state dialog.receivedOrSent2xx(); // generate ack // p. 82 §3 SipRequest ack = dialog.buildSubsequentRequest(RFC3261.METHOD_ACK); // update CSeq SipHeaders ackHeaders = ack.getSipHeaders(); SipHeaderFieldName cseqName = new SipHeaderFieldName(RFC3261.HDR_CSEQ); SipHeaderFieldValue ackCseq = ackHeaders.get(cseqName); SipRequest request = transaction.getRequest(); SipHeaders requestHeaders = request.getSipHeaders(); SipHeaderFieldValue requestCseq = requestHeaders.get(cseqName); ackCseq.setValue(requestCseq.toString().replace(RFC3261.METHOD_INVITE, RFC3261.METHOD_ACK)); // add Via with only the branchid parameter SipHeaderFieldValue via = new SipHeaderFieldValue(""); SipHeaderParamName branchIdName = new SipHeaderParamName(RFC3261.PARAM_BRANCH); via.addParam(branchIdName, Utils.generateBranchId()); ackHeaders.add(new SipHeaderFieldName(RFC3261.HDR_VIA), via, 0); // TODO authentication headers if (request.getBody() == null && sipResponse.getBody() != null) { // TODO add a real SDP answer ack.setBody(sipResponse.getBody()); } // TODO check if sdp is acceptable SipURI destinationUri = RequestManager.getDestinationUri(ack, logger); challengeManager.postProcess(ack); // TODO if header route is present, addrspec = toproute.nameaddress.addrspec String transport = RFC3261.TRANSPORT_UDP; Hashtable<String, String> params = destinationUri.getUriParameters(); if (params != null) { String reqUriTransport = params.get(RFC3261.PARAM_TRANSPORT); if (reqUriTransport != null) { transport = reqUriTransport; } } int port = destinationUri.getPort(); if (port == SipURI.DEFAULT_PORT) { port = RFC3261.TRANSPORT_DEFAULT_PORT; } SipURI sipUri = userAgent.getConfig().getOutboundProxy(); if (sipUri == null) { sipUri = destinationUri; } InetAddress inetAddress; try { inetAddress = InetAddress.getByName(sipUri.getHost()); } catch (UnknownHostException e) { logger.error("unknown host: " + sipUri.getHost(), e); return; } try { MessageSender sender = transportManager.createClientTransport(ack, inetAddress, port, transport); sender.sendMessage(ack); } catch (IOException e) { logger.error("input/output error", e); } List<String> guiClosedCallIds = userAgent.getUac().getGuiClosedCallIds(); String callId = Utils.getMessageCallId(sipResponse); if (guiClosedCallIds.contains(callId)) { userAgent.terminate(request); } }
public void terminate(SipRequest sipRequest) { String callId = Utils.getMessageCallId(sipRequest); if (!guiClosedCallIds.contains(callId)) { guiClosedCallIds.add(callId); } Dialog dialog = dialogManager.getDialog(callId); SipRequest inviteWithAuth = getInviteWithAuth(callId); if (dialog != null) { SipRequest originatingRequest; if (inviteWithAuth != null) { originatingRequest = inviteWithAuth; } else { originatingRequest = sipRequest; } ClientTransaction clientTransaction = transactionManager.getClientTransaction(originatingRequest); if (clientTransaction != null) { synchronized (clientTransaction) { DialogState dialogState = dialog.getState(); if (dialog.EARLY.equals(dialogState)) { initialRequestManager.createCancel(inviteWithAuth, midDialogRequestManager, profileUri); } else if (dialog.CONFIRMED.equals(dialogState)) { // clientTransaction not yet removed midDialogRequestManager.generateMidDialogRequest(dialog, RFC3261.METHOD_BYE, null); guiClosedCallIds.remove(callId); } } } else { // clientTransaction Terminated and removed logger.debug("clientTransaction null"); midDialogRequestManager.generateMidDialogRequest(dialog, RFC3261.METHOD_BYE, null); guiClosedCallIds.remove(callId); } } else { InviteClientTransaction inviteClientTransaction = (InviteClientTransaction) transactionManager.getClientTransaction(inviteWithAuth); if (inviteClientTransaction == null) { logger.error("cannot find invite client transaction" + " for call " + callId); } else { SipResponse sipResponse = inviteClientTransaction.getLastResponse(); if (sipResponse != null) { int statusCode = sipResponse.getStatusCode(); if (statusCode < RFC3261.CODE_200_OK) { initialRequestManager.createCancel(inviteWithAuth, midDialogRequestManager, profileUri); } } } } switch (userAgent.getMediaMode()) { case captureAndPlayback: userAgent.getMediaManager().stopSession(); SoundManager soundManager = userAgent.getSoundManager(); if (soundManager != null) { soundManager.closeLines(); } break; case echo: Echo echo = userAgent.getEcho(); if (echo != null) { echo.stop(); userAgent.setEcho(null); } break; case file: MediaManager mediaManager = userAgent.getMediaManager(); mediaManager.stopSession(); break; default: break; } }