/** * Create a client transaction from a raw channel. * * @param transaction is the transport channel to encapsulate. */ public MessageChannel createMessageChannel(SIPTransaction transaction) { synchronized (clientTransactions) { // New client transaction to return SIPTransaction returnChannel = createClientTransaction(transaction.getMessageChannel()); clientTransactions.add(0, (SIPClientTransaction) returnChannel); ((SIPClientTransaction) returnChannel).setViaPort(transaction.getViaPort()); ((SIPClientTransaction) returnChannel).setViaHost(transaction.getViaHost()); // Add the transaction timer for the state machine. returnChannel.startTransactionTimer(); return returnChannel; } }
/** * Invoked when an error has ocurred with a transaction. * * @param transactionErrorEvent Error event. */ public synchronized void transactionErrorEvent(SIPTransactionErrorEvent transactionErrorEvent) { SIPTransaction transaction = (SIPTransaction) transactionErrorEvent.getSource(); if (transactionErrorEvent.getErrorID() == SIPTransactionErrorEvent.TRANSPORT_ERROR) { // Kill scanning of this transaction. transaction.setState(SIPTransaction.TERMINATED_STATE); if (transaction instanceof SIPServerTransaction) { // let the reaper get him ((SIPServerTransaction) transaction).collectionTime = 0; } transaction.disableTimeoutTimer(); transaction.disableRetransmissionTimer(); } }
/** Remove the transaction from transaction hash. */ protected void removeTransactionHash(SIPTransaction sipTransaction) { SIPRequest sipRequest = sipTransaction.getOriginalRequest(); if (sipRequest == null) return; if (sipTransaction instanceof SIPClientTransaction) { synchronized (clientTransactionTable) { String key = sipTransaction.getTransactionId(); clientTransactionTable.remove(key); } } else if (sipTransaction instanceof SIPServerTransaction) { synchronized (serverTransactionTable) { String key = sipTransaction.getTransactionId(); serverTransactionTable.remove(key); } } }
/** * Find the transaction corresponding to a given request. * * @param sipMessage request for which to retrieve the transaction. * @param isServer search the server transaction table if true. * @return the transaction object corresponding to the request or null if no such mapping exists. */ public SIPTransaction findTransaction(SIPMessage sipMessage, boolean isServer) { SIPTransaction retval = null; if (isServer) { Via via = sipMessage.getTopmostVia(); if (via.getBranch() != null) { String key = sipMessage.getTransactionId(); synchronized (this.serverTransactionTable) { retval = (SIPTransaction) serverTransactionTable.get(key); if (LogWriter.needsLogging) logMessage("looking for key " + key); if (retval != null && retval.isMessagePartOfTransaction(sipMessage)) return retval; } } // Need to scan the table for old style transactions (RFC 2543 // style) synchronized (this.serverTransactions) { Iterator<SIPServerTransaction> it = serverTransactions.iterator(); while (it.hasNext()) { SIPServerTransaction sipServerTransaction = (SIPServerTransaction) it.next(); if (sipServerTransaction.isMessagePartOfTransaction(sipMessage)) return sipServerTransaction; } } } else { Via via = sipMessage.getTopmostVia(); if (via.getBranch() != null) { String key = sipMessage.getTransactionId(); synchronized (this.clientTransactionTable) { retval = (SIPTransaction) clientTransactionTable.get(key); if (retval != null && retval.isMessagePartOfTransaction(sipMessage)) return retval; } } // Need to scan the table for old style transactions (RFC 2543 // style) synchronized (this.clientTransactions) { Iterator<SIPClientTransaction> it = clientTransactions.iterator(); while (it.hasNext()) { SIPClientTransaction clientTransaction = (SIPClientTransaction) it.next(); if (clientTransaction.isMessagePartOfTransaction(sipMessage)) return clientTransaction; } } } return null; }
/** Remove transaction. */ public void removeTransaction(SIPTransaction sipTransaction) { if (sipTransaction instanceof SIPServerTransaction) { synchronized (serverTransactions) { serverTransactions.remove(sipTransaction); } synchronized (serverTransactionTable) { String key = sipTransaction.getTransactionId(); serverTransactionTable.remove(key); } } else { synchronized (clientTransactions) { clientTransactions.remove(sipTransaction); } synchronized (clientTransactionTable) { String key = sipTransaction.getTransactionId(); clientTransactionTable.remove(key); } } }
/** * Creates a client transaction to handle a new request. Gets the real message channel from the * superclass, and then creates a new client transaction wrapped around this channel. * * @param nextHop Hop to create a channel to contact. */ public MessageChannel createMessageChannel(int sourcePort, Hop nextHop) throws UnknownHostException { synchronized (clientTransactions) { // New client transaction to return SIPTransaction returnChannel; // Create a new client transaction around the // superclass' message channel MessageChannel mc = super.createMessageChannel(sourcePort, nextHop); // Superclass will return null if no message processor // available for the transport. if (mc == null) return null; returnChannel = createClientTransaction(mc); clientTransactions.add(0, (SIPClientTransaction) returnChannel); ((SIPClientTransaction) returnChannel).setViaPort(nextHop.getPort()); ((SIPClientTransaction) returnChannel).setViaHost(nextHop.getHost()); // Add the transaction timer for the state machine. returnChannel.startTransactionTimer(); return returnChannel; } }
/** Hash table for quick lookup of transactions. */ protected void addTransactionHash(SIPTransaction sipTransaction) { SIPRequest sipRequest = sipTransaction.getOriginalRequest(); // Via via = sipRequest.getTopmostVia(); // Cannot cache old style requests. /** * if (via.getBranch() == null || ! via.getBranch().toUpperCase().startsWith * (SIPConstants.BRANCH_MAGIC_COOKIE.toUpperCase())){ return; } */ if (sipTransaction instanceof SIPClientTransaction) { synchronized (clientTransactionTable) { String key = sipRequest.getTransactionId(); clientTransactionTable.put(key, sipTransaction); } } else { synchronized (serverTransactionTable) { String key = sipRequest.getTransactionId(); serverTransactionTable.put(key, sipTransaction); } } }
/** * Actually proces the parsed message. * * @param sipMessage */ public void processMessage(SIPMessage sipMessage) { if (sipMessage instanceof SIPRequest) { SIPRequest sipRequest = (SIPRequest) sipMessage; // This is a request - process it. // So far so good -- we will commit this message if // all processing is OK. if (sipStack.logWriter.isLoggingEnabled(ServerLog.TRACE_MESSAGES)) { this.sipStack.serverLog.logMessage( sipMessage, this.getPeerHostPort().toString(), this.getHost() + ":" + this.myPort, false, receptionTime); } ServerRequestInterface sipServerRequest = sipStack.newSIPServerRequest(sipRequest, this); // Drop it if there is no request returned if (sipServerRequest == null) { if (sipStack.isLoggingEnabled()) { this.sipStack.logWriter.logWarning("Null request interface returned -- dropping request"); } return; } if (sipStack.isLoggingEnabled()) this.sipStack.logWriter.logDebug( "About to process " + sipRequest.getFirstLine() + "/" + sipServerRequest); try { sipServerRequest.processRequest(sipRequest, this); } finally { if (sipServerRequest instanceof SIPTransaction) { SIPServerTransaction sipServerTx = (SIPServerTransaction) sipServerRequest; if (!sipServerTx.passToListener()) { ((SIPTransaction) sipServerRequest).releaseSem(); } } } if (sipStack.isLoggingEnabled()) this.sipStack.logWriter.logDebug( "Done processing " + sipRequest.getFirstLine() + "/" + sipServerRequest); // So far so good -- we will commit this message if // all processing is OK. } else { // Handle a SIP Reply message. SIPResponse sipResponse = (SIPResponse) sipMessage; try { sipResponse.checkHeaders(); } catch (ParseException ex) { if (sipStack.isLoggingEnabled()) sipStack.logWriter.logError( "Dropping Badly formatted response message >>> " + sipResponse); return; } ServerResponseInterface sipServerResponse = sipStack.newSIPServerResponse(sipResponse, this); if (sipServerResponse != null) { try { if (sipServerResponse instanceof SIPClientTransaction && !((SIPClientTransaction) sipServerResponse).checkFromTag(sipResponse)) { if (sipStack.isLoggingEnabled()) sipStack.logWriter.logError( "Dropping response message with invalid tag >>> " + sipResponse); return; } sipServerResponse.processResponse(sipResponse, this); } finally { if (sipServerResponse instanceof SIPTransaction && !((SIPTransaction) sipServerResponse).passToListener()) ((SIPTransaction) sipServerResponse).releaseSem(); } // Normal processing of message. } else { if (sipStack.isLoggingEnabled()) { this.sipStack.logWriter.logDebug("null sipServerResponse!"); } } } }