* are ignored.
*/
if (dialog == null && sipRequest.getMethod().equals(Request.NOTIFY)) {
SIPClientTransaction pendingSubscribeClientTx = sipStack.findSubscribeTransaction(
sipRequest, listeningPoint);
if (sipStack.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
sipStack.getStackLogger().logDebug(
"PROCESSING NOTIFY DIALOG == null " + pendingSubscribeClientTx);
}
/*
* RFC 3265: Upon receiving a NOTIFY request, the subscriber should check that it
* matches at least one of its outstanding subscriptions; if not, it MUST return a
* "481 Subscription does not exist" response unless another 400- or -class response
* is more appropriate.
*/
if (sipProvider.isAutomaticDialogSupportEnabled() && pendingSubscribeClientTx == null
&& !sipStack.isDeliverUnsolicitedNotify()) {
/*
* This is the case of the UAC receiving a Stray NOTIFY for which it has not
* previously sent out a SUBSCRIBE and for which it does not have an established
* dialog.
*/
try {
if (sipStack.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
sipStack.getStackLogger().logDebug(
"Could not find Subscription for Notify Tx.");
}
Response errorResponse = sipRequest
.createResponse(Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST);
errorResponse.setReasonPhrase("Subscription does not exist");
sipProvider.sendResponse(errorResponse);
return;
} catch (Exception ex) {
sipStack.getStackLogger().logError(
"Exception while sending error response statelessly", ex);
return;
}
}
// If the server transaction cannot be found or if it
// aleady has a dialog attached to it then just assign the
// notify to this dialog and pass it up.
if (pendingSubscribeClientTx != null) {
// The response to the pending subscribe tx can try to create
// a dialog at the same time that the notify is trying to
// create a dialog. Thus we cannot process both at the
// same time.
transaction.setPendingSubscribe(pendingSubscribeClientTx);
// The transaction gets assigned to the dialog from the
// outgoing subscribe. First see if anybody claimed the
// default Dialog for the outgoing Subscribe request.
SIPDialog subscriptionDialog = (SIPDialog) pendingSubscribeClientTx
.getDefaultDialog();
// TODO -- refactor this. Can probably be written far cleaner.
if (subscriptionDialog == null || subscriptionDialog.getDialogId() == null
|| !subscriptionDialog.getDialogId().equals(dialogId)) {
// Notify came in before you could assign a response to
// the subscribe.
// grab the default dialog and assign it to the tags in
// the notify.
if (subscriptionDialog != null && subscriptionDialog.getDialogId() == null) {
subscriptionDialog.setDialogId(dialogId);
} else {
subscriptionDialog = pendingSubscribeClientTx.getDialog(dialogId);
}
if (sipStack.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
sipStack.getStackLogger().logDebug(
"PROCESSING NOTIFY Subscribe DIALOG " + subscriptionDialog);
}
// The user could have createed a dialog before sending out
// the SUBSCRIBE on the subscribe tx.
if (subscriptionDialog == null
&& (sipProvider.isAutomaticDialogSupportEnabled() || pendingSubscribeClientTx
.getDefaultDialog() != null)) {
Event event = (Event) sipRequest.getHeader(EventHeader.NAME);
if (sipStack.isEventForked(event.getEventType())) {
subscriptionDialog = SIPDialog.createFromNOTIFY(
pendingSubscribeClientTx, transaction);
}
}
if (subscriptionDialog != null) {
transaction.setDialog(subscriptionDialog, dialogId);
if ( subscriptionDialog.getState() != DialogState.CONFIRMED ) {
subscriptionDialog.setPendingRouteUpdateOn202Response(sipRequest);
}
subscriptionDialog.setState(DialogState.CONFIRMED.getValue());
sipStack.putDialog(subscriptionDialog);
pendingSubscribeClientTx.setDialog(subscriptionDialog, dialogId);
if (!transaction.isTransactionMapped()) {
this.sipStack.mapTransaction(transaction);
// Let the listener see it if it just got
// created.
// otherwise, we have already processed the tx
// so
// we dont want the listener to see it.
transaction.setPassToListener();
try {
this.sipStack.addTransaction(transaction);
} catch (Exception ex) {
}
}
}
} else {
// The subscription default dialog is our dialog.
// Found a subscrbe dialog for the NOTIFY
// So map the tx.
transaction.setDialog(subscriptionDialog, dialogId);
dialog = subscriptionDialog;
if (!transaction.isTransactionMapped()) {
this.sipStack.mapTransaction(transaction);
// Let the listener see it if it just got created.
// otherwise, we have already processed the tx so
// we dont want the listener to see it.
transaction.setPassToListener();
try {
this.sipStack.addTransaction(transaction);
} catch (Exception ex) {
}
}
sipStack.putDialog(subscriptionDialog);
if (pendingSubscribeClientTx != null) {
subscriptionDialog.addTransaction(pendingSubscribeClientTx);
pendingSubscribeClientTx.setDialog(subscriptionDialog, dialogId);
}
}
if (transaction != null
&& ((SIPServerTransaction) transaction).isTransactionMapped()) {