public void processSubscribe(Request request, ServerTransaction serverTransaction) {
    logger.debug("Processing SUBSCRIBE in progress ");
    try {

      MessageFactory messageFactory = imUA.getMessageFactory();
      HeaderFactory headerFactory = imUA.getHeaderFactory();
      AddressFactory addressFactory = imUA.getAddressFactory();
      Dialog dialog = serverTransaction.getDialog();

      // ********** Terminating subscriptions **********
      ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(ExpiresHeader.NAME);
      if (expiresHeader != null && expiresHeader.getExpires() == 0) {
        if (dialog != null) {
          // Terminating an existing subscription
          Response response = messageFactory.createResponse(Response.OK, request);
          serverTransaction.sendResponse(response);
          IMNotifyProcessing imNotifyProcessing = imUA.getIMNotifyProcessing();
          imNotifyProcessing.sendNotify(response, null, dialog);
          return;
        } else {
          // Terminating an non existing subscription
          Response response =
              messageFactory.createResponse(Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST, request);
          serverTransaction.sendResponse(response);
          return;
        }
      }

      // ********** Non-terminating subscriptions ************

      // send a 202 Accepted while waiting for authorization from user
      Response response = messageFactory.createResponse(Response.ACCEPTED, request);
      // Tag:
      ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
      if (toHeader.getTag() == null)
        toHeader.setTag(new Integer((int) (Math.random() * 10000)).toString());
      serverTransaction.sendResponse(response);
      logger.debug(response.toString());

      // We have to ask the user to authorize the guy to be in his buddy
      // list
      String presentityURL = IMUtilities.getKey(request, "From");
      SipProvider sipProvider = imUA.getSipProvider();
      InstantMessagingGUI imGUI = imUA.getInstantMessagingGUI();
      boolean authorization = imGUI.getAuthorizationForBuddy(presentityURL);
      if (authorization) {
        logger.debug(
            "DEBUG: SubscribeProcessing, processSubscribe(), " + " Response 202 Accepted sent.");

        // We have to create or update the subscriber!
        PresenceManager presenceManager = imUA.getPresenceManager();
        String subscriberURL = IMUtilities.getKey(request, "From");

        if (dialog != null) presenceManager.addSubscriber(subscriberURL, response, dialog);
        else {
          logger.debug(
              "ERROR, IMSubscribeProcessing, processSubscribe(), the"
                  + " dialog for the SUBSCRIBE we received is null!!! No subscriber added....");
          return;
        }

        // Let's see if this buddy is in our buddy list
        // if not let's ask to add him!
        BuddyList buddyList = imGUI.getBuddyList();
        ListenerInstantMessaging listenerIM = imGUI.getListenerInstantMessaging();
        if (!buddyList.hasBuddy(subscriberURL)) {
          // Let's ask:
          listenerIM.addContact(subscriberURL);
        }

        /** ********************** send NOTIFY ************************* */
        // We send a NOTIFY for any of our status but offline
        String localStatus = listenerIM.getLocalStatus();
        if (!localStatus.equals("offline")) {
          IMNotifyProcessing imNotifyProcessing = imUA.getIMNotifyProcessing();
          Subscriber subscriber = presenceManager.getSubscriber(subscriberURL);
          // Response okSent=subscriber.getOkSent();

          subscriberURL = subscriber.getSubscriberName();

          String contactAddress = imUA.getIMAddress() + ":" + imUA.getIMPort();

          String subStatus = listenerIM.getLocalStatus();
          String status = null;
          if (subStatus.equals("offline")) status = "closed";
          else status = "open";
          String xmlBody =
              imNotifyProcessing.xmlPidfParser.createXMLBody(
                  status, subStatus, subscriberURL, contactAddress);
          imNotifyProcessing.sendNotify(response, xmlBody, dialog);
        }
      } else {
        // User did not authorize subscription. Terminate it!
        logger.debug(
            "DEBUG, IMSubsribeProcessing, processSubscribe(), " + " Subscription declined!");
        logger.debug(
            "DEBUG, IMSubsribeProcessing, processSubscribe(), "
                + " Sending a Notify with Subscribe-state=terminated");

        IMNotifyProcessing imNotifyProcessing = imUA.getIMNotifyProcessing();
        if (dialog != null) {
          imNotifyProcessing.sendNotify(response, null, dialog);
          logger.debug(
              "DEBUG, IMSubsribeProcessing, processSubscribe(), "
                  + " Sending a Notify with Subscribe-state=terminated");
        } else {
          logger.debug(
              "ERROR, IMSubscribeProcessing, processSubscribe(), the"
                  + " dialog for the SUBSCRIBE we received is null!!! \n"
                  + "   No terminating Notify sent");
        }
        imNotifyProcessing.sendNotify(response, null, dialog);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
Esempio n. 2
0
    @Override
    public void run() {
      try {
        logger.logEntry();

        // From
        FromHeader fromHeader = null;
        try {
          // this keep alive task only makes sense in case we have
          // a registrar so we deliberately use our AOR and do not
          // use the getOurSipAddress() method.
          fromHeader =
              provider
                  .getHeaderFactory()
                  .createFromHeader(
                      provider.getRegistrarConnection().getAddressOfRecord(),
                      SipMessageFactory.generateLocalTag());
        } catch (ParseException ex) {
          // this should never happen so let's just log and bail.
          logger.error("Failed to generate a from header for " + "our register request.", ex);
          return;
        }

        // Call ID Header
        CallIdHeader callIdHeader = provider.getDefaultJainSipProvider().getNewCallId();

        // CSeq Header
        CSeqHeader cSeqHeader = null;
        try {
          cSeqHeader =
              provider.getHeaderFactory().createCSeqHeader(getNextCSeqValue(), Request.OPTIONS);
        } catch (ParseException ex) {
          // Should never happen
          logger.error("Corrupt Sip Stack", ex);
          return;
        } catch (InvalidArgumentException ex) {
          // Should never happen
          logger.error("The application is corrupt", ex);
          return;
        }

        // To Header
        ToHeader toHeader = null;
        try {
          // this request isn't really going anywhere so we put our
          // own address in the To Header.
          toHeader = provider.getHeaderFactory().createToHeader(fromHeader.getAddress(), null);
        } catch (ParseException ex) {
          logger.error("Could not create a To header for address:" + fromHeader.getAddress(), ex);
          return;
        }

        // MaxForwardsHeader
        MaxForwardsHeader maxForwardsHeader = provider.getMaxForwardsHeader();
        // Request
        Request request = null;
        try {
          // create a host-only uri for the request uri header.
          String domain = ((SipURI) toHeader.getAddress().getURI()).getHost();

          // request URI
          SipURI requestURI = provider.getAddressFactory().createSipURI(null, domain);

          // Via Headers
          ArrayList<ViaHeader> viaHeaders = provider.getLocalViaHeaders(requestURI);

          request =
              provider
                  .getMessageFactory()
                  .createRequest(
                      requestURI,
                      Request.OPTIONS,
                      callIdHeader,
                      cSeqHeader,
                      fromHeader,
                      toHeader,
                      viaHeaders,
                      maxForwardsHeader);

          if (logger.isDebugEnabled()) logger.debug("Created OPTIONS request " + request);
        } catch (ParseException ex) {
          logger.error("Could not create an OPTIONS request!", ex);
          return;
        }

        Iterator<String> supportedMethods = provider.getSupportedMethods().iterator();

        // add to the allows header all methods that we support
        while (supportedMethods.hasNext()) {
          String method = supportedMethods.next();

          // don't support REGISTERs
          if (method.equals(Request.REGISTER)) continue;

          request.addHeader(provider.getHeaderFactory().createAllowHeader(method));
        }

        Iterator<String> events = provider.getKnownEventsList().iterator();

        synchronized (provider.getKnownEventsList()) {
          while (events.hasNext()) {
            String event = events.next();

            request.addHeader(provider.getHeaderFactory().createAllowEventsHeader(event));
          }
        }

        // Transaction
        ClientTransaction optionsTrans = null;
        try {
          optionsTrans = provider.getDefaultJainSipProvider().getNewClientTransaction(request);
        } catch (TransactionUnavailableException ex) {
          logger.error("Could not create options transaction!\n", ex);
          return;
        }
        try {
          optionsTrans.sendRequest();
          if (logger.isDebugEnabled()) logger.debug("sent request= " + request);
        } catch (SipException ex) {
          logger.error("Could not send out the options request!", ex);

          if (ex.getCause() instanceof IOException) {
            // IOException problem with network
            disconnect();
          }

          return;
        }
      } catch (Exception ex) {
        logger.error("Cannot send OPTIONS keep alive", ex);
      }
    }