/** 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); } } }
/** * Handles a new SIP request. It finds a server transaction to handle this message. If none * exists, it creates a new transaction. * * @param requestReceived Request to handle. * @param requestMessageChannel Channel that received message. * @return A server transaction. */ protected ServerRequestInterface newSIPServerRequest( SIPRequest requestReceived, MessageChannel requestMessageChannel) { // Iterator through all server transactions Iterator<SIPServerTransaction> transactionIterator; // Next transaction in the set SIPServerTransaction nextTransaction; // Transaction to handle this request SIPServerTransaction currentTransaction; String key = requestReceived.getTransactionId(); currentTransaction = (SIPServerTransaction) serverTransactionTable.get(key); if (currentTransaction == null || !currentTransaction.isMessagePartOfTransaction(requestReceived)) { // Loop through all server transactions synchronized (serverTransactions) { transactionIterator = serverTransactions.iterator(); currentTransaction = null; while (transactionIterator.hasNext() && currentTransaction == null) { nextTransaction = (SIPServerTransaction) transactionIterator.next(); // If this transaction should handle this request, if (nextTransaction.isMessagePartOfTransaction(requestReceived)) { // Mark this transaction as the one // to handle this message currentTransaction = nextTransaction; } } // If no transaction exists to handle this message if (currentTransaction == null) { currentTransaction = findPendingTransaction(requestReceived); if (currentTransaction != null) return currentTransaction; currentTransaction = createServerTransaction(requestMessageChannel); currentTransaction.setOriginalRequest(requestReceived); if (!isDialogCreated(requestReceived.getMethod())) { // Dialog is not created - can we find the state? // If so, then create a transaction and add it. String dialogId = requestReceived.getDialogId(true); SIPDialog dialog = getDialog(dialogId); // Sequence numbers are supposed to increment. // avoid processing old sequence numbers and // delivering the same request up to the // application if the request has already been seen. // Special handling applies to ACK processing. if (dialog != null && (requestReceived.getMethod().equals(Request.ACK) || requestReceived.getCSeq().getSequenceNumber() > dialog.getRemoteSequenceNumber())) { // Found a dialog. if (LogWriter.needsLogging) logWriter.logMessage("adding server transaction " + currentTransaction); serverTransactions.add(0, currentTransaction); addTransactionHash(currentTransaction); currentTransaction.startTransactionTimer(); currentTransaction.isMapped = true; } } else { // Create the transaction but dont map it. String dialogId = requestReceived.getDialogId(true); SIPDialog dialog = getDialog(dialogId); // This is a dialog creating request that is part of an // existing dialog (eg. re-Invite). Re-invites get a non // null server transaction Id (unlike the original // invite). if (dialog != null && requestReceived.getCSeq().getSequenceNumber() > dialog.getRemoteSequenceNumber()) { currentTransaction.map(); if (LogWriter.needsLogging) logWriter.logMessage("adding server transaction " + currentTransaction); serverTransactions.add(0, currentTransaction); addTransactionHash(currentTransaction); currentTransaction.startTransactionTimer(); currentTransaction.toListener = true; } } } } } // Set ths transaction's encapsulated request // interface from the superclass currentTransaction.setRequestInterface( super.newSIPServerRequest(requestReceived, currentTransaction)); return currentTransaction; }