Example #1
0
  /**
   * parse the String message
   *
   * @return SIPHeader (AcceptEncoding object)
   * @throws ParseException if the message does not respect the spec.
   */
  public SIPHeader parse() throws ParseException {
    AcceptEncodingList acceptEncodingList = new AcceptEncodingList();
    if (debug) dbg_enter("AcceptEncodingParser.parse");

    try {
      headerName(TokenTypes.ACCEPT_ENCODING);
      // empty body is fine for this header.
      if (lexer.lookAhead(0) == '\n') {
        AcceptEncoding acceptEncoding = new AcceptEncoding();
        acceptEncodingList.add(acceptEncoding);
      } else {
        while (lexer.lookAhead(0) != '\n') {
          AcceptEncoding acceptEncoding = new AcceptEncoding();
          if (lexer.lookAhead(0) != ';') {
            // Content-Coding:
            lexer.match(TokenTypes.ID);
            Token value = lexer.getNextToken();
            acceptEncoding.setEncoding(value.getTokenValue());
          }

          while (lexer.lookAhead(0) == ';') {
            this.lexer.match(';');
            this.lexer.SPorHT();
            this.lexer.match('q');
            this.lexer.SPorHT();
            this.lexer.match('=');
            this.lexer.SPorHT();
            lexer.match(TokenTypes.ID);
            Token value = lexer.getNextToken();
            try {
              float qv = Float.parseFloat(value.getTokenValue());
              acceptEncoding.setQValue(qv);
            } catch (NumberFormatException ex) {
              throw createParseException(ex.getMessage());
            } catch (InvalidArgumentException ex) {
              throw createParseException(ex.getMessage());
            }
            this.lexer.SPorHT();
          }

          acceptEncodingList.add(acceptEncoding);
          if (lexer.lookAhead(0) == ',') {
            this.lexer.match(',');
            this.lexer.SPorHT();
          }
        }
      }
      return acceptEncodingList;
    } finally {
      if (debug) dbg_leave("AcceptEncodingParser.parse");
    }
  }
  /**
   * Attach JAIN-SIP <tt>SipProvider</tt> and <tt>ListeningPoint</tt> to the stack either for clear
   * communications or TLS. Clear UDP and TCP <tt>ListeningPoint</tt>s are not handled separately as
   * the former is a fallback for the latter (depending on the size of the data transmitted). Both
   * <tt>ListeningPoint</tt>s must be bound to the same address and port in order for the related
   * <tt>SipProvider</tt> to be created. If a UDP or TCP <tt>ListeningPoint</tt> cannot bind, retry
   * for both on another port.
   *
   * @param preferredPort which port to try first to bind.
   * @param retries how many times should we try to find a free port to bind
   * @param secure whether to create the TLS SipProvider. or the clear UDP/TCP one.
   * @throws TransportNotSupportedException in case we try to create a provider for a transport not
   *     currently supported by jain-sip
   * @throws InvalidArgumentException if we try binding to an illegal port (which we won't)
   * @throws ObjectInUseException if another <tt>SipProvider</tt> is already associated with this
   *     <tt>ListeningPoint</tt>.
   * @throws TransportAlreadySupportedException if there is already a ListeningPoint associated to
   *     this <tt>SipProvider</tt> with the same transport of the <tt>ListeningPoint</tt>.
   * @throws TooManyListenersException if we try to add a new <tt>SipListener</tt> with a
   *     <tt>SipProvider</tt> when one was already registered.
   */
  private void createProvider(int preferredPort, int retries, boolean secure)
      throws TransportNotSupportedException, InvalidArgumentException, ObjectInUseException,
          TransportAlreadySupportedException, TooManyListenersException {
    String context = (secure ? "TLS: " : "clear UDP/TCP: ");

    if (retries < 0) {
      // very unlikely to happen with the default 50 retries
      logger.error(context + "couldn't find free ports to listen on.");
      return;
    }

    ListeningPoint tlsLP = null;
    ListeningPoint udpLP = null;
    ListeningPoint tcpLP = null;

    try {
      if (secure) {
        tlsLP =
            this.stack.createListeningPoint(
                NetworkUtils.IN_ADDR_ANY, preferredPort, ListeningPoint.TLS);
        if (logger.isTraceEnabled()) logger.trace("TLS secure ListeningPoint has been created.");

        this.secureJainSipProvider = this.stack.createSipProvider(tlsLP);
        this.secureJainSipProvider.addSipListener(this);
      } else {
        udpLP =
            this.stack.createListeningPoint(
                NetworkUtils.IN_ADDR_ANY, preferredPort, ListeningPoint.UDP);
        tcpLP =
            this.stack.createListeningPoint(
                NetworkUtils.IN_ADDR_ANY, preferredPort, ListeningPoint.TCP);
        if (logger.isTraceEnabled())
          logger.trace("UDP and TCP clear ListeningPoints have " + "been created.");

        this.clearJainSipProvider = this.stack.createSipProvider(udpLP);
        this.clearJainSipProvider.addListeningPoint(tcpLP);
        this.clearJainSipProvider.addSipListener(this);
      }

      if (logger.isTraceEnabled()) logger.trace(context + "SipProvider has been created.");
    } catch (InvalidArgumentException ex) {
      // makes sure we didn't leave an open listener
      // as both UDP and TCP listener have to bind to the same port
      if (tlsLP != null) this.stack.deleteListeningPoint(tlsLP);
      if (udpLP != null) this.stack.deleteListeningPoint(udpLP);
      if (tcpLP != null) this.stack.deleteListeningPoint(tcpLP);

      // FIXME: "Address already in use" is not working
      // as ex.getMessage() displays in the locale language in SC
      // (getMessage() is always supposed to be English though)
      // this should be a temporary workaround
      // if (ex.getMessage().indexOf("Address already in use") != -1)
      // another software is probably using the port
      if (ex.getCause() instanceof java.io.IOException) {
        if (logger.isDebugEnabled())
          logger.debug("Port " + preferredPort + " seems in use for either TCP or UDP.");

        // tries again on a new random port
        int currentlyTriedPort = NetworkUtils.getRandomPortNumber();
        if (logger.isDebugEnabled()) logger.debug("Retrying bind on port " + currentlyTriedPort);
        this.createProvider(currentlyTriedPort, retries - 1, secure);
      } else throw ex;
    }
  }
  /**
   * parse the String message
   *
   * @return SIPHeader (RetryAfter object)
   * @throws SIPParseException if the message does not respect the spec.
   */
  public SIPHeader parse() throws ParseException {

    if (debug) dbg_enter("RetryAfterParser.parse");

    RetryAfter retryAfter = new RetryAfter();
    try {
      headerName(TokenTypes.RETRY_AFTER);

      // mandatory delatseconds:
      String value = lexer.number();
      try {
        int ds = Integer.parseInt(value);
        retryAfter.setRetryAfter(ds);
      } catch (NumberFormatException ex) {
        throw createParseException(ex.getMessage());
      } catch (InvalidArgumentException ex) {
        throw createParseException(ex.getMessage());
      }

      this.lexer.SPorHT();
      if (lexer.lookAhead(0) == '(') {
        String comment = this.lexer.comment();
        retryAfter.setComment(comment);
      }
      this.lexer.SPorHT();

      while (lexer.lookAhead(0) == ';') {
        this.lexer.match(';');
        this.lexer.SPorHT();
        lexer.match(TokenTypes.ID);
        Token token = lexer.getNextToken();
        value = token.getTokenValue();
        if (value.equalsIgnoreCase("duration")) {
          this.lexer.match('=');
          this.lexer.SPorHT();
          value = lexer.number();
          try {
            int duration = Integer.parseInt(value);
            retryAfter.setDuration(duration);
          } catch (NumberFormatException ex) {
            throw createParseException(ex.getMessage());
          } catch (InvalidArgumentException ex) {
            throw createParseException(ex.getMessage());
          }
        } else {
          this.lexer.SPorHT();
          this.lexer.match('=');
          this.lexer.SPorHT();
          lexer.match(TokenTypes.ID);
          Token secondToken = lexer.getNextToken();
          String secondValue = secondToken.getTokenValue();
          retryAfter.setParameter(value, secondValue);
        }
        this.lexer.SPorHT();
      }
    } finally {
      if (debug) dbg_leave("RetryAfterParser.parse");
    }

    return retryAfter;
  }