/* * Begin Third-Party Call Control. */ public void initiateCall() throws IOException { try { try { busyTreatment = new TreatmentManager("busy.au", 0); } catch (IOException e) { Logger.println("Invalid busy treatment: " + e.getMessage()); } Logger.writeFile("Call " + cp + ": Begin SIP third party call"); setState(CallState.INVITED); InetSocketAddress isa = callHandler.getReceiveAddress(); if (isa == null) { throw new IOException("can't get receiver socket!"); } // send INVITE to the CallParticipant clientTransaction = sipUtil.sendInvite(cp, isa); if (clientTransaction == null) { Logger.error("Error placing call: " + cp); setState(CallState.ENDED, "Reason='Error placing call'"); throw new IOException("Error placing call: " + cp); } CallIdHeader callIdHeader = (CallIdHeader) clientTransaction.getRequest().getHeader(CallIdHeader.NAME); sipCallId = callIdHeader.getCallId(); sipServerCallback = SipServer.getSipServerCallback(); sipServerCallback.addSipListener(sipCallId, this); } catch (java.text.ParseException e) { Logger.println("Call " + cp + " Error placing call " + cp + ": " + e.getMessage()); setState(CallState.ENDED, "Reason='Error placing call " + cp + " " + e.getMessage() + "'"); throw new IOException("Error placing call " + cp + " " + e.getMessage()); } catch (InvalidArgumentException e) { Logger.println("Call " + cp + " Error placing call " + cp + ": " + e.getMessage()); setState(CallState.ENDED, "Reason='Error placing call " + cp + " " + e.getMessage() + "'"); throw new IOException("Error placing call " + cp + " " + e.getMessage()); } catch (SipException e) { Logger.println("Call " + cp + " Error placing call " + cp + ": " + e.getMessage()); setState(CallState.ENDED, "Reason='Error placing call " + cp + " " + e.getMessage() + "'"); throw new IOException("Error placing call " + cp + " " + e.getMessage()); } }
public void unregister() throws IOException { if (!isRegistered) { return; } cancelPendingRegistrations(); isRegistered = false; if (this.registerRequest == null) { Log.info("Couldn't find the initial register request"); throw new IOException("Couldn't find the initial register request"); } Request unregisterRequest = (Request) registerRequest.clone(); try { unregisterRequest.getExpires().setExpires(0); CSeqHeader cSeqHeader = (CSeqHeader) unregisterRequest.getHeader(CSeqHeader.NAME); // [issue 1] - increment registration cseq number // reported by - Roberto Tealdi <*****@*****.**> cSeqHeader.setSequenceNumber(cSeqHeader.getSequenceNumber() + 1); } catch (InvalidArgumentException e) { Log.info("Unable to set Expires Header " + e.getMessage()); return; } ClientTransaction unregisterTransaction = null; try { unregisterTransaction = sipProvider.getNewClientTransaction(unregisterRequest); } catch (TransactionUnavailableException e) { throw new IOException("Unable to create a unregister transaction " + e.getMessage()); } try { unregisterTransaction.sendRequest(); } catch (SipException e) { Log.info("Faied to send unregister request " + e.getMessage()); return; } }
/** * handles a BYE request * * @param request the request * @param transId the transaction Id * @throws TransactionDoesNotExistException when the transaction record does not exist. */ private void handleBye(Request request, ServerTransaction st) { try { CallIdHeader callIdHeader = (CallIdHeader) request.getHeader("Call-Id"); String sipCallId = callIdHeader.getCallId(); if (sipCallId.equals(this.sipCallId)) { receivedBye = true; try { Logger.writeFile("Call " + cp + " has hung up."); // sipUtil.sendOK(clientTransaction, st, cp); sipUtil.sendOK(request, st); } catch (Exception e) { /* * We sometimes get a null ServerTransaction */ } cancelRequest("hung up"); sipServerCallback.removeSipListener(sipCallId); } else { /* * this should not happen since the message has been * delegated to this sip agent. */ throw new TransactionDoesNotExistException( cp + "BYE request received did not " + "match either party: " + request); } } catch (TransactionDoesNotExistException e) { Logger.error("Call " + cp + " Transaction not found " + e.getMessage()); } catch (SipException e) { Logger.exception("Call " + cp + " SIP Stack error", e); cancelRequest("handleBye: SIP Stack error " + e.getMessage()); } catch (Exception e) { Logger.exception("Call " + cp + " Unknown error ", e); cancelRequest("handleBye: SIP Stack error " + e.getMessage()); } }
public synchronized void processResponse(ResponseEvent responseReceivedEvent) { try { Response response = (Response) responseReceivedEvent.getResponse(); ClientTransaction clientTransaction = responseReceivedEvent.getClientTransaction(); int statusCode = response.getStatusCode(); FromHeader fromHeader = (FromHeader) response.getHeader(FromHeader.NAME); String displayName = fromHeader.getAddress().getDisplayName(); if (Logger.logLevel >= Logger.LOG_SIP) { Logger.println( "Response: statusCode " + statusCode + " state " + getCallState() + " fromHeader " + displayName + " call participant " + cp.getName()); } if (reasonCallTerminated != null) { /* * Ignore OK and Request Terminated. * XXX what's the symbol for 487? */ if (statusCode != Response.OK && statusCode != 487) { if (Logger.logLevel >= Logger.LOG_SIP) { Logger.println("Call " + cp + ": request cancelled, ignoring response"); } } CallIdHeader callIdHeader = (CallIdHeader) response.getHeader("Call-Id"); String sipCallId = callIdHeader.getCallId(); sipServerCallback.removeSipListener(sipCallId); return; } /* * Some type of global failure that prevents the * CallParticipant from being contacted, report failure. */ if (forceGatewayError) { statusCode = 500; forceGatewayError = false; } if (statusCode >= 500 && getState() == CallState.INVITED) { Logger.error( "Call " + cp + " gateway error: " + statusCode + " " + response.getReasonPhrase()); cancelRequest("gateway error: " + statusCode + " " + response.getReasonPhrase()); return; } else if (statusCode == Response.PROXY_AUTHENTICATION_REQUIRED || statusCode == Response.UNAUTHORIZED) { if (cp.getProxyCredentials() != null) { try { SipServer.handleChallenge(response, clientTransaction, cp.getProxyCredentials()) .sendRequest(); } catch (Exception e) { Logger.println("Proxy authentification failed " + e); } } return; } else if (statusCode >= 400) { // if we get a busy or an unknown error, play busy. Logger.println("Call " + cp + " got status code :" + statusCode); cp.setCallEndTreatment(null); cp.setConferenceJoinTreatment(null); cp.setConferenceLeaveTreatment(null); /* * play busy treatment, but deallocate any resources * held up by ringBack first, if any. */ // stopCallAnsweredTreatment(); if (statusCode == Response.BUSY_HERE) { try { if (busyTreatment != null) { addTreatment(busyTreatment); // busyTreatment.waitForTreatment(); } else { Logger.println("Unable to play busy treatment!!!"); } } catch (Exception e) { Logger.error("can't start busy treatment!" + sdpBody); } CallEvent callEvent = new CallEvent(CallEvent.BUSY_HERE); callEvent.setInfo(response.getReasonPhrase()); sendCallEventNotification(callEvent); } // sipUtil.sendBye(clientTransaction); cancelRequest(response.getReasonPhrase()); return; } /* state machine */ switch (getState()) { /* * CallParticipant picked up, send treatment if any, * and wait for it to finish. */ case CallState.INVITED: if (rejectCall) { Logger.error( "Call " + cp + " gateway error: " + statusCode + " " + response.getReasonPhrase()); cancelRequest("gateway error: " + statusCode + " " + response.getReasonPhrase()); return; } handleCallParticipantInvited(response, clientTransaction); break; /* * Call established, the ACK needs to be resent. * According to Ranga, this is done by the NIST SIP Stack. */ case CallState.ESTABLISHED: if (statusCode == Response.OK) { gotOk = true; Logger.writeFile("Call " + cp + " Got OK, ESTABLISHED"); if (ackSent == false) { sipUtil.sendAck(clientTransaction); ackSent = true; } } break; case CallState.ENDED: break; // ignore the response default: Logger.error("Process Response bad state " + getState() + "\n" + response); } } catch (SipException e) { Logger.exception("Call " + cp + " SIP Stack error ", e); cancelRequest("processResponse: SIP Stack error " + e.getMessage()); } catch (Exception e) { Logger.exception("processResponse: " + cp, e); cancelRequest("processResponse: SIP Stack error " + e.getMessage()); } }
/** * Process a request from a distant contact * * @param requestEvent the <tt>RequestEvent</tt> containing the newly received request. * @return <tt>true</tt> if the specified event has been handled by this processor and shouldn't * be offered to other processors registered for the same method; <tt>false</tt>, otherwise */ @Override public boolean processRequest(RequestEvent requestEvent) { synchronized (messageProcessors) { for (SipMessageProcessor listener : messageProcessors) if (!listener.processMessage(requestEvent)) return true; } // get the content String content = null; Request req = requestEvent.getRequest(); try { content = new String(req.getRawContent(), getCharset(req)); } catch (UnsupportedEncodingException ex) { if (logger.isDebugEnabled()) logger.debug("failed to convert the message charset"); content = new String(requestEvent.getRequest().getRawContent()); } // who sent this request ? FromHeader fromHeader = (FromHeader) requestEvent.getRequest().getHeader(FromHeader.NAME); if (fromHeader == null) { logger.error("received a request without a from header"); return false; } Contact from = opSetPersPresence.resolveContactID(fromHeader.getAddress().getURI().toString()); ContentTypeHeader ctheader = (ContentTypeHeader) req.getHeader(ContentTypeHeader.NAME); String ctype = null; String cencoding = null; if (ctheader == null) { ctype = DEFAULT_MIME_TYPE; } else { ctype = ctheader.getContentType() + "/" + ctheader.getContentSubType(); cencoding = ctheader.getParameter("charset"); } if (cencoding == null) cencoding = DEFAULT_MIME_ENCODING; Message newMessage = createMessage(content, ctype, cencoding, null); if (from == null) { if (logger.isDebugEnabled()) logger.debug( "received a message from an unknown contact: " + fromHeader.getAddress().getURI().toString()); // create the volatile contact from = opSetPersPresence.createVolatileContact(fromHeader.getAddress().getURI().toString()); } // answer ok try { Response ok = sipProvider.getMessageFactory().createResponse(Response.OK, requestEvent.getRequest()); SipStackSharing.getOrCreateServerTransaction(requestEvent).sendResponse(ok); } catch (ParseException exc) { logger.error("failed to build the response", exc); } catch (SipException exc) { logger.error("failed to send the response : " + exc.getMessage(), exc); } catch (InvalidArgumentException exc) { if (logger.isDebugEnabled()) logger.debug("Invalid argument for createResponse : " + exc.getMessage(), exc); } // fire an event MessageReceivedEvent msgReceivedEvt = new MessageReceivedEvent(newMessage, from, System.currentTimeMillis()); fireMessageEvent(msgReceivedEvt); return true; }