public void sendBye(String localSipURL, String remoteSipURL, ChatSession chatSession) {
    // Send a Bye only if there were exchanged messages!!!
    if (chatSession.isEstablishedSession()) {
      try {
        logger.debug("Sending a BYE in progress to " + remoteSipURL);

        SipProvider sipProvider = imUA.getSipProvider();

        javax.sip.Dialog dialog = chatSession.getDialog();

        Request request = dialog.createRequest(Request.BYE);

        // ProxyAuthorization header if not null:
        ProxyAuthorizationHeader proxyAuthHeader = imUA.getProxyAuthorizationHeader();
        if (proxyAuthHeader != null) request.setHeader(proxyAuthHeader);

        ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);

        dialog.sendRequest(clientTransaction);
        logger.debug("BYE sent:\n" + request);

      } catch (Exception ex) {
        ex.printStackTrace();
      }
    } else {
      logger.debug("BYE not sent because of no exchanged messages!!!");
    }
  }
예제 #2
0
  /**
   * Populates a specific <tt>Request</tt> instance with the headers common to dialog-creating
   * <tt>Request</tt>s and ones sent inside existing dialogs and specific to the general event
   * package subscription functionality that this instance and a specific <tt>Subscription</tt>
   * represent.
   *
   * @param req the <tt>Request</tt> instance to be populated with common headers and ones specific
   *     to the event package of a specific <tt>Subscription</tt>
   * @param subscription the <tt>Subscription</tt> which is to be described in the specified
   *     <tt>Request</tt> i.e. its properties are to be used to populate the specified
   *     <tt>Request</tt>
   * @param expires the subscription duration to be set into the Expires header of the specified
   *     SUBSCRIBE <tt>Request</tt>
   * @throws OperationFailedException if we fail parsing or populating the subscription request.
   */
  protected void populateSubscribeRequest(Request req, Subscription subscription, int expires)
      throws OperationFailedException {
    HeaderFactory headerFactory = protocolProvider.getHeaderFactory();

    // Event
    EventHeader evHeader;
    try {
      evHeader = headerFactory.createEventHeader(eventPackage);

      String eventId = subscription.getEventId();
      if (eventId != null) evHeader.setEventId(eventId);
    } catch (ParseException e) {
      // these two should never happen.
      logger.error("An unexpected error occurred while" + "constructing the EventHeader", e);
      throw new OperationFailedException(
          "An unexpected error occurred while" + "constructing the EventHeader",
          OperationFailedException.INTERNAL_ERROR,
          e);
    }
    req.setHeader(evHeader);

    // Accept
    AcceptHeader accept;
    try {
      accept = headerFactory.createAcceptHeader("application", contentSubType);
    } catch (ParseException e) {
      logger.error("wrong accept header", e);
      throw new OperationFailedException(
          "An unexpected error occurred while" + "constructing the AcceptHeader",
          OperationFailedException.INTERNAL_ERROR,
          e);
    }
    req.setHeader(accept);

    // Expires
    ExpiresHeader expHeader;
    try {
      expHeader = headerFactory.createExpiresHeader(expires);
    } catch (InvalidArgumentException e) {
      logger.error("Invalid expires value: " + expires, e);
      throw new OperationFailedException(
          "An unexpected error occurred while" + "constructing the ExpiresHeader",
          OperationFailedException.INTERNAL_ERROR,
          e);
    }
    req.setHeader(expHeader);
  }
예제 #3
0
  /**
   * Place to put some hacks if needed on incoming requests.
   *
   * @param event the incoming request event.
   * @return status <code>true</code> if we don't need to process this message, just discard it and
   *     <code>false</code> otherwise.
   */
  private boolean applyNonConformanceHacks(RequestEvent event) {
    Request request = event.getRequest();
    try {
      /*
       * Max-Forwards is required, yet there are UAs which do not
       * place it. SipProvider#getNewServerTransaction(Request)
       * will throw an exception in the case of a missing
       * Max-Forwards header and this method will eventually just
       * log it thus ignoring the whole event.
       */
      if (request.getHeader(MaxForwardsHeader.NAME) == null) {
        // it appears that some buggy providers do send requests
        // with no Max-Forwards headers, as we are at application level
        // and we know there will be no endless loops
        // there is no problem of adding headers and process normally
        // this messages
        MaxForwardsHeader maxForwards =
            SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70);
        request.setHeader(maxForwards);
      }
    } catch (Throwable ex) {
      logger.warn("Cannot apply incoming request modification!", ex);
    }

    try {
      // using asterisk voice mail initial notify for messages
      // is ok, but on the fly received messages their notify comes
      // without subscription-state, so we add it in order to be able to
      // process message.
      if (request.getMethod().equals(Request.NOTIFY)
          && request.getHeader(EventHeader.NAME) != null
          && ((EventHeader) request.getHeader(EventHeader.NAME))
              .getEventType()
              .equals(OperationSetMessageWaitingSipImpl.EVENT_PACKAGE)
          && request.getHeader(SubscriptionStateHeader.NAME) == null) {
        request.addHeader(
            new HeaderFactoryImpl().createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE));
      }
    } catch (Throwable ex) {
      logger.warn("Cannot apply incoming request modification!", ex);
    }

    try {
      // receiving notify message without subscription state
      // used for keep-alive pings, they have done their job
      // and are no more need. Skip processing them to avoid
      // filling logs with unneeded exceptions.
      if (request.getMethod().equals(Request.NOTIFY)
          && request.getHeader(SubscriptionStateHeader.NAME) == null) {
        return true;
      }
    } catch (Throwable ex) {
      logger.warn("Cannot apply incoming request modification!", ex);
    }

    return false;
  }
예제 #4
0
  /**
   * Creates a new SUBSCRIBE request in the form of a <tt>ClientTransaction</tt> with the parameters
   * of a specific <tt>Subscription</tt>.
   *
   * @param subscription the <tt>Subscription</tt> to be described in a SUBSCRIBE request
   * @param dialog the <tt>Dialog</tt> with which this request should be associated
   * @param expires the subscription duration of the SUBSCRIBE request to be created
   * @return a new <tt>ClientTransaction</tt> initialized with a new SUBSCRIBE request which matches
   *     the parameters of the specified <tt>Subscription</tt> and is associated with the specified
   *     <tt>Dialog</tt>
   * @throws OperationFailedException if the message could not be generated
   */
  private ClientTransaction createSubscription(
      Subscription subscription, Dialog dialog, int expires) throws OperationFailedException {
    Request req = messageFactory.createRequest(dialog, Request.SUBSCRIBE);

    // Address
    Address toAddress = dialog.getRemoteTarget();
    // no Contact field
    if (toAddress == null) toAddress = dialog.getRemoteParty();

    // MaxForwards
    MaxForwardsHeader maxForwards = protocolProvider.getMaxForwardsHeader();
    req.setHeader(maxForwards);

    /*
     * Create the transaction and then add the via header as recommended by
     * the jain-sip documentation at
     * http://snad.ncsl.nist.gov/proj/iptel/jain-sip-1.2/javadoc
     * /javax/sip/Dialog.html#createRequest(String).
     */
    ClientTransaction transac = null;
    try {
      transac = protocolProvider.getDefaultJainSipProvider().getNewClientTransaction(req);
    } catch (TransactionUnavailableException ex) {
      logger.error(
          "Failed to create subscriptionTransaction.\n"
              + "This is most probably a network connection error.",
          ex);
      throw new OperationFailedException(
          "Failed to create the subscription transaction",
          OperationFailedException.NETWORK_FAILURE);
    }

    populateSubscribeRequest(req, subscription, expires);

    return transac;
  }
  public void sendSubscribe(String localURL, String buddyURI, boolean EXPIRED) {
    try {
      logger.debug("Sending SUBSCRIBE in progress to the buddy: " + buddyURI);
      int proxyPort = imUA.getProxyPort();
      String proxyAddress = imUA.getProxyAddress();
      String imProtocol = imUA.getIMProtocol();
      SipStack sipStack = imUA.getSipStack();
      SipProvider sipProvider = imUA.getSipProvider();
      MessageFactory messageFactory = imUA.getMessageFactory();
      HeaderFactory headerFactory = imUA.getHeaderFactory();
      AddressFactory addressFactory = imUA.getAddressFactory();

      // Request-URI:
      // URI requestURI=addressFactory.createURI(buddyURI);
      SipURI requestURI = addressFactory.createSipURI(null, proxyAddress);
      requestURI.setPort(proxyPort);
      requestURI.setTransportParam(imProtocol);

      // Call-Id:
      CallIdHeader callIdHeader = null;

      // CSeq:
      CSeqHeader cseqHeader = null;

      // To header:
      ToHeader toHeader = null;

      // From Header:
      FromHeader fromHeader = null;

      // Via header
      String branchId = Utils.generateBranchId();
      ViaHeader viaHeader =
          headerFactory.createViaHeader(
              imUA.getIMAddress(), imUA.getIMPort(), imProtocol, branchId);
      Vector viaList = new Vector();
      viaList.addElement(viaHeader);

      PresenceManager presenceManager = imUA.getPresenceManager();
      Presentity presentity = presenceManager.getPresentity(buddyURI);
      Dialog dialog = null;
      if (presentity != null) dialog = presentity.getDialog();

      if (dialog != null) {

        // We have to remove the subscriber and the Presentity related
        // with this Buddy...
        presenceManager.removePresentity(buddyURI);
        Subscriber subscriber = presenceManager.getSubscriber(buddyURI);
        if (subscriber == null) {
          // It means that the guy does not have us in his buddy list
          // nothing to do!!!
        } else {
          presenceManager.removeSubscriber(buddyURI);
        }

        Address localAddress = dialog.getLocalParty();
        Address remoteAddress = dialog.getRemoteParty();

        fromHeader = headerFactory.createFromHeader(localAddress, dialog.getLocalTag());
        toHeader = headerFactory.createToHeader(remoteAddress, dialog.getRemoteTag());

        long cseq = dialog.getLocalSeqNumber();
        cseqHeader = headerFactory.createCSeqHeader(cseq, "MESSAGE");

        callIdHeader = dialog.getCallId();
      } else {
        String localTag = Utils.generateTag();

        Address toAddress = addressFactory.createAddress(buddyURI);
        Address fromAddress = addressFactory.createAddress(localURL);

        fromHeader = headerFactory.createFromHeader(fromAddress, localTag);
        toHeader = headerFactory.createToHeader(toAddress, null);

        // CSeq:
        cseqHeader = headerFactory.createCSeqHeader(1L, "SUBSCRIBE");

        callIdCounter++;
        // Call-ID:
        callIdHeader =
            (CallIdHeader)
                headerFactory.createCallIdHeader("nist-sip-im-subscribe-callId" + callIdCounter);
      }

      // MaxForwards header:
      MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);

      Request request =
          messageFactory.createRequest(
              requestURI,
              "SUBSCRIBE",
              callIdHeader,
              cseqHeader,
              fromHeader,
              toHeader,
              viaList,
              maxForwardsHeader);

      RouteHeader rh = this.imUA.getRouteToProxy();
      request.setHeader(rh);

      // Contact header:
      SipURI sipURI = addressFactory.createSipURI(null, imUA.getIMAddress());
      sipURI.setPort(imUA.getIMPort());
      sipURI.setTransportParam(imUA.getIMProtocol());
      Address contactAddress = addressFactory.createAddress(sipURI);
      ContactHeader contactHeader = headerFactory.createContactHeader(contactAddress);
      request.setHeader(contactHeader);

      ExpiresHeader expiresHeader = null;
      if (EXPIRED) {
        expiresHeader = headerFactory.createExpiresHeader(0);
      } else {
        expiresHeader = headerFactory.createExpiresHeader(presenceManager.getExpiresTime());
      }
      request.setHeader(expiresHeader);

      // WE have to add a new Header: "Event"
      Header eventHeader = headerFactory.createHeader("Event", "presence");
      request.setHeader(eventHeader);

      // Add Acceptw Header
      Header acceptHeader = headerFactory.createHeader("Accept", "application/pidf+xml");
      request.setHeader(acceptHeader);

      // ProxyAuthorization header if not null:
      ProxyAuthorizationHeader proxyAuthHeader = imUA.getProxyAuthorizationHeader();
      if (proxyAuthHeader != null) request.setHeader(proxyAuthHeader);

      ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);

      if (dialog != null) {
        dialog.sendRequest(clientTransaction);
      } else {
        clientTransaction.sendRequest();
      }

      logger.debug("IMSubscribeProcessing, sendSubscribe(), SUBSCRIBE sent:\n" + request);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  public void sendPublish(String localURI, String status) {
    try {
      logger.debug("Sending PUBLISH in progress");
      int proxyPort = imUA.getProxyPort();
      String proxyAddress = imUA.getProxyAddress();
      String imProtocol = imUA.getIMProtocol();
      SipStack sipStack = imUA.getSipStack();
      SipProvider sipProvider = imUA.getSipProvider();
      MessageFactory messageFactory = imUA.getMessageFactory();
      HeaderFactory headerFactory = imUA.getHeaderFactory();
      AddressFactory addressFactory = imUA.getAddressFactory();

      // Request-URI:
      if (localURI.startsWith("sip:")) localURI = localURI.substring(4, localURI.length());
      SipURI requestURI = addressFactory.createSipURI(null, localURI);
      requestURI.setPort(proxyPort);
      requestURI.setTransportParam(imProtocol);

      // Via header
      String branchId = Utils.generateBranchId();
      ViaHeader viaHeader =
          headerFactory.createViaHeader(
              imUA.getIMAddress(), imUA.getIMPort(), imProtocol, branchId);
      Vector viaList = new Vector();
      viaList.addElement(viaHeader);

      // To header:
      System.out.println("XXX localURI=" + localURI);
      Address localAddress = addressFactory.createAddress("sip:" + localURI);
      ToHeader toHeader = headerFactory.createToHeader(localAddress, null);

      // From header:
      String localTag = Utils.generateTag();
      FromHeader fromHeader = headerFactory.createFromHeader(localAddress, localTag);

      // Call-ID:
      CallIdHeader callIdHeader = headerFactory.createCallIdHeader(callIdCounter + localURI);

      // CSeq:
      CSeqHeader cseqHeader = headerFactory.createCSeqHeader(1L, "PUBLISH");

      // MaxForwards header:
      MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);

      // Create Request
      Request request =
          messageFactory.createRequest(
              requestURI,
              "PUBLISH",
              callIdHeader,
              cseqHeader,
              fromHeader,
              toHeader,
              viaList,
              maxForwardsHeader);

      // Expires header: (none, let server chose)

      // Event header:
      Header header = headerFactory.createHeader("Event", "presence");
      request.setHeader(header);

      RouteHeader routeHeader = this.imUA.getRouteToProxy();

      request.setHeader(routeHeader);

      // Content and Content-Type header:
      String basic;
      if (status.equals("offline")) basic = "closed";
      else basic = "open";

      String content =
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
              + "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\""
              + " entity=\""
              + localURI
              + "\">\n"
              + " <tuple id=\""
              + entity
              + "\">\n"
              + "  <status>\n"
              + "   <basic>"
              + basic
              + "</basic>\n"
              + "  </status>\n"
              + "  <note>"
              + status
              + "</note>\n"
              + " </tuple>\n"
              + "</presence>";

      ContentTypeHeader contentTypeHeader =
          headerFactory.createContentTypeHeader("application", "pidf+xml");
      request.setContent(content, contentTypeHeader);

      // Content-Length header:
      ContentLengthHeader contentLengthHeader =
          headerFactory.createContentLengthHeader(content.length());
      request.setContentLength(contentLengthHeader);

      // Send request
      ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);
      clientTransaction.sendRequest();

    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
예제 #7
0
  /**
   * Attach any custom headers pre configured for the account. Added only to message Requests. The
   * header account properties are of form: ConfigHeader.N.Name=HeaderName
   * ConfigHeader.N.Value=HeaderValue ConfigHeader.N.Method=SIP_MethodName (optional) Where N is the
   * index of the header, multiple custom headers can be added. Name is the header name to use and
   * Value is its value. The optional property is whether to use a specific request method to attach
   * headers to or if missing we will attach it to all requests.
   *
   * @param message the message that we'd like to attach custom headers to.
   * @param protocolProvider the protocol provider to check for configured custom headers.
   */
  static void attachConfigHeaders(
      Message message, ProtocolProviderServiceSipImpl protocolProvider) {
    if (message instanceof Response) return;

    Request request = (Request) message;

    Map<String, String> props = protocolProvider.getAccountID().getAccountProperties();

    Map<String, Map<String, String>> headers = new HashMap<String, Map<String, String>>();

    // parse the properties into the map where the index is the key
    for (Map.Entry<String, String> entry : props.entrySet()) {
      String pName = entry.getKey();
      String prefStr = entry.getValue();
      String name;
      String ix;

      if (!pName.startsWith(ACC_PROPERTY_CONFIG_HEADER) || prefStr == null) continue;

      prefStr = prefStr.trim();

      if (pName.contains(".")) {
        pName = pName.replaceAll(ACC_PROPERTY_CONFIG_HEADER + ".", "");
        name = pName.substring(pName.lastIndexOf('.') + 1).trim();

        if (!pName.contains(".")) continue;

        ix = pName.substring(0, pName.lastIndexOf('.')).trim();
      } else continue;

      Map<String, String> headerValues = headers.get(ix);

      if (headerValues == null) {
        headerValues = new HashMap<String, String>();
        headers.put(ix, headerValues);
      }

      headerValues.put(name, prefStr);
    }

    // process the found custom headers
    for (Map<String, String> headerValues : headers.values()) {
      String method = headerValues.get(ACC_PROPERTY_CONFIG_HEADER_METHOD);

      // if there is a method setting and is different from
      // current request method skip this header
      // if any of the required properties are missing skip (Name & Value)
      if ((method != null && !request.getMethod().equalsIgnoreCase(method))
          || !headerValues.containsKey(ACC_PROPERTY_CONFIG_HEADER_NAME)
          || !headerValues.containsKey(ACC_PROPERTY_CONFIG_HEADER_VALUE)) continue;

      try {
        String name = headerValues.get(ACC_PROPERTY_CONFIG_HEADER_NAME);
        String value = processParams(headerValues.get(ACC_PROPERTY_CONFIG_HEADER_VALUE), request);

        Header h = request.getHeader(name);

        // makes possible overriding already created headers which
        // are not custom one
        // RouteHeader is used by ProxyRouter/DefaultRouter and we
        // cannot use it as custom header if we want to add it
        if ((h != null && !(h instanceof CustomHeader)) || name.equals(SIPHeaderNames.ROUTE)) {
          request.setHeader(protocolProvider.getHeaderFactory().createHeader(name, value));
        } else request.addHeader(new CustomHeaderList(name, value));
      } catch (Exception e) {
        logger.error("Cannot create custom header", e);
      }
    }
  }