* Process the invite request.
*/
public void processSubscribe(RequestEvent requestEvent,
ServerTransaction serverTransaction) {
SipProvider sipProvider = (SipProvider) requestEvent.getSource();
Request request = requestEvent.getRequest();
try {
logger.info("notifier: got an Subscribe sending OK");
logger.info("notifier: " + request);
logger.info("notifier : dialog = " + requestEvent.getDialog());
EventHeader eventHeader = (EventHeader) request.getHeader(EventHeader.NAME);
if (eventHeader == null) {
logger.info("Cannot find event header.... dropping request.");
return;
}
// Always create a ServerTransaction, best as early as possible in the code
Response response = null;
ServerTransaction st = requestEvent.getServerTransaction();
if (st == null) {
st = sipProvider.getNewServerTransaction(request);
}
// Check if it is an initial SUBSCRIBE or a refresh / unsubscribe
boolean isInitial = requestEvent.getDialog() == null;
if (isInitial) {
// JvB: need random tags to test forking
String toTag = Integer.toHexString((int) (Math.random() * Integer.MAX_VALUE));
response = messageFactory.createResponse(202, request);
ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
// Sanity check: to header should not ahve a tag. Else the dialog
// should have matched
if (toHeader.getTag() != null) {
System.err
.println("####ERROR: To-tag!=null but no dialog match! My dialog="
+ dialog.getState());
}
toHeader.setTag(toTag); // Application is supposed to set.
this.dialog = st.getDialog();
// subscribe dialogs do not terminate on bye.
this.dialog.terminateOnBye(false);
if (dialog != null) {
logger.info("Dialog " + dialog);
logger.info("Dialog state " + dialog.getState());
}
} else {
response = messageFactory.createResponse(200, request);
}
// Both 2xx response to SUBSCRIBE and NOTIFY need a Contact
Address address = addressFactory.createAddress("Notifier <sip:127.0.0.1>");
((SipURI) address.getURI()).setPort(udpProvider.getListeningPoint("udp")
.getPort());
ContactHeader contactHeader = headerFactory.createContactHeader(address);
response.addHeader(contactHeader);
// Expires header is mandatory in 2xx responses to SUBSCRIBE
ExpiresHeader expires = (ExpiresHeader) request.getHeader(ExpiresHeader.NAME);
if (expires == null) {
expires = headerFactory.createExpiresHeader(30); // rather short
}
response.addHeader(expires);
/*
* NOTIFY requests MUST contain a "Subscription-State" header with a value of
* "active", "pending", or "terminated". The "active" value indicates that the
* subscription has been accepted and has been authorized (in most cases; see
* section 5.2.). The "pending" value indicates that the subscription has been
* received, but that policy information is insufficient to accept or deny the
* subscription at this time. The "terminated" value indicates that the
* subscription is not active.
*/
Address fromAddress = ((ToHeader) response.getHeader(ToHeader.NAME)).getAddress();
String fromTag = ((ToHeader) response.getHeader(ToHeader.NAME)).getTag();
FromHeader fromHeader = headerFactory.createFromHeader(fromAddress, fromTag);
Address toAddress = ((FromHeader) response.getHeader(FromHeader.NAME)).getAddress();
String toTag = ((FromHeader) response.getHeader(FromHeader.NAME)).getTag();
ToHeader toHeader = headerFactory.createToHeader(toAddress, toTag);
CallIdHeader callId = (CallIdHeader) response.getHeader(CallIdHeader.NAME);
ContactHeader requestContact = (ContactHeader) request
.getHeader(ContactHeader.NAME);
SipURI notifyRuri = (SipURI) requestContact.getAddress().getURI();
CSeqHeader cSeq = headerFactory.createCSeqHeader(1L, Request.NOTIFY);
String ipAddress = sipProvider.getListeningPoint("udp").getIPAddress();
int port = sipProvider.getListeningPoint("udp").getPort();
ViaHeader viaHeader = headerFactory.createViaHeader(ipAddress, port, "udp", null);
LinkedList llist = new LinkedList<ViaHeader>();
llist.add(viaHeader);
MaxForwardsHeader maxForwards = headerFactory.createMaxForwardsHeader(70);
Request notifyRequest = messageFactory.createRequest(notifyRuri, Request.NOTIFY,
callId, cSeq, fromHeader, toHeader, llist, maxForwards);
notifyRequest.addHeader(contactHeader);
// Mark the contact header, to check that the remote contact is updated
((SipURI) contactHeader.getAddress().getURI()).setParameter("id", "not");
// Initial state is pending, second time we assume terminated (Expires==0)
SubscriptionStateHeader sstate = headerFactory
.createSubscriptionStateHeader(isInitial ? SubscriptionStateHeader.PENDING
: SubscriptionStateHeader.TERMINATED);
// Need a reason for terminated
if (sstate.getState().equalsIgnoreCase("terminated")) {
sstate.setReasonCode("deactivated");
}
notifyRequest.addHeader(sstate);
notifyRequest.setHeader(eventHeader);
notifyRequest.setHeader(contactHeader);
// notifyRequest.setHeader(routeHeader);
ClientTransaction ct = udpProvider.getNewClientTransaction(notifyRequest);
/*
* We deliberately send the NOTIFY first before the 202 is sent.