@Test
  public void testOKRingingLandOnSameNode() throws Exception {

    EventListener failureEventListener =
        new EventListener() {

          @Override
          public void uasAfterResponse(int statusCode, AppServer source) {}

          @Override
          public void uasAfterRequestReceived(String method, AppServer source) {
            // TODO Auto-generated method stub

          }

          @Override
          public void uacAfterRequestSent(String method, AppServer source) {
            // TODO Auto-generated method stub

          }

          @Override
          public void uacAfterResponse(int statusCode, AppServer source) {
            if (statusCode == 180) {
              ringingAppServer = source;
            } else {
              okAppServer = source;
            }
          }
        };
    for (AppServer as : servers) as.setEventListener(failureEventListener);
    shootist.callerSendsBye = true;

    String fromName = "sender";
    String fromHost = "sip-servlets.com";
    SipURI fromAddress = servers[0].protocolObjects.addressFactory.createSipURI(fromName, fromHost);

    String toUser = "******";
    String toHost = "sip-servlets.com";
    SipURI toAddress = servers[0].protocolObjects.addressFactory.createSipURI(toUser, toHost);

    SipURI ruri = servers[0].protocolObjects.addressFactory.createSipURI("usera", "127.0.0.1:5033");
    ruri.setLrParam();
    SipURI route =
        servers[0].protocolObjects.addressFactory.createSipURI("lbint", "127.0.0.1:5065");
    route.setParameter("node_host", "127.0.0.1");
    route.setParameter("node_port", "4060");
    route.setTransportParam(ListeningPoint.UDP);
    route.setLrParam();
    shootist.start();
    // servers[0].sipListener.sendSipRequest("INVITE", fromAddress, toAddress, null, null, false);
    servers[0].sipListener.sendSipRequest(
        "INVITE", fromAddress, toAddress, null, route, false, null, null, ruri);
    Thread.sleep(16000);
    assertTrue(
        shootist.inviteRequest.getHeader(RecordRouteHeader.NAME).toString().contains("node_host"));
    assertSame(ringingAppServer, okAppServer);
    assertNotNull(ringingAppServer);
    assertNotNull(okAppServer);
  }
  private FromHeader getFromHeader() throws IOException {

    if (fromHeader != null) {
      return fromHeader;
    }

    try {
      SipURI fromURI =
          (SipURI)
              addressFactory.createURI("sip:" + proxyCredentials.getUserName() + "@" + registrar);

      fromURI.setTransportParam(sipProvider.getListeningPoint().getTransport());

      fromURI.setPort(sipProvider.getListeningPoint().getPort());

      Address fromAddress = addressFactory.createAddress(fromURI);

      fromAddress.setDisplayName(proxyCredentials.getUserDisplay());

      fromHeader = headerFactory.createFromHeader(fromAddress, Integer.toString(hashCode()));

    } catch (ParseException e) {
      throw new IOException(
          "A ParseException occurred while creating From Header! " + e.getMessage());
    }

    return fromHeader;
  }
示例#3
0
  public ContactHeader getStackContactHeader() {
    try {
      ListeningPoint lp = (ListeningPoint) sipStack.getListeningPoints().next();
      String host = sipStack.getIPAddress();
      int port = lp.getPort();
      String transport = lp.getTransport();

      SipURI sipURI = addressFactory.createSipURI(null, host);
      sipURI.setPort(port);
      sipURI.setTransportParam(transport);
      Address contactAddress = addressFactory.createAddress(sipURI);

      return headerFactory.createContactHeader(contactAddress);
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
  private ContactHeader getRegistrationContactHeader() throws IOException {
    if (contactHeader != null) {
      return contactHeader;
    }

    try {
      SipURI contactURI =
          (SipURI)
              addressFactory.createURI(
                  "sip:" + proxyCredentials.getUserName() + "@" + proxyCredentials.getHost());

      contactURI.setTransportParam(sipProvider.getListeningPoint().getTransport());
      contactURI.setPort(sipProvider.getListeningPoint().getPort());
      Address contactAddress = addressFactory.createAddress(contactURI);
      contactAddress.setDisplayName(proxyCredentials.getUserDisplay());
      contactHeader = headerFactory.createContactHeader(contactAddress);
      return contactHeader;
    } catch (ParseException e) {
      throw new IOException(
          "A ParseException occurred while creating From Header! " + " " + e.getMessage());
    }
  }
  private void register() throws IOException {
    Log.info("Registering with " + registrar);
    FromHeader fromHeader = getFromHeader();
    Address fromAddress = fromHeader.getAddress();

    // Request URI
    SipURI requestURI = null;
    try {
      requestURI = addressFactory.createSipURI(null, registrar);

    } catch (ParseException e) {
      throw new IOException("Bad registrar address:" + registrar + " " + e.getMessage());
    }
    // requestURI.setPort(registrarPort);

    try {
      requestURI.setTransportParam(sipProvider.getListeningPoint().getTransport());

    } catch (ParseException e) {
      throw new IOException(
          sipProvider.getListeningPoint().getTransport()
              + " is not a valid transport! "
              + e.getMessage());
    }

    CallIdHeader callIdHeader = sipProvider.getNewCallId();
    CSeqHeader cSeqHeader = null;

    try {
      cSeqHeader = headerFactory.createCSeqHeader(1, Request.REGISTER);
    } catch (ParseException e) {
      // Should never happen
      throw new IOException("Corrupt Sip Stack " + e.getMessage());
    } catch (InvalidArgumentException e) {
      // Should never happen
      throw new IOException("The application is corrupt ");
    }

    ToHeader toHeader = null;
    try {
      String proxyWorkAround = System.getProperty("com.sun.mc.softphone.REGISTRAR_WORKAROUND");

      if (proxyWorkAround != null && proxyWorkAround.toUpperCase().equals("TRUE")) {

        SipURI toURI = (SipURI) (requestURI.clone());
        toURI.setUser(System.getProperty("user.name"));

        toHeader = headerFactory.createToHeader(addressFactory.createAddress(toURI), null);
      } else {
        toHeader = headerFactory.createToHeader(fromAddress, null);
      }
    } catch (ParseException e) {
      throw new IOException(
          "Could not create a To header for address:"
              + fromHeader.getAddress()
              + " "
              + e.getMessage());
    }

    ArrayList viaHeaders = getLocalViaHeaders();
    MaxForwardsHeader maxForwardsHeader = getMaxForwardsHeader();
    Request request = null;

    try {
      request =
          messageFactory.createRequest(
              requestURI,
              Request.REGISTER,
              callIdHeader,
              cSeqHeader,
              fromHeader,
              toHeader,
              viaHeaders,
              maxForwardsHeader);
    } catch (ParseException e) {
      throw new IOException("Could not create the register request! " + e.getMessage());
    }

    ExpiresHeader expHeader = null;

    for (int retry = 0; retry < 2; retry++) {
      try {
        expHeader = headerFactory.createExpiresHeader(expires);
      } catch (InvalidArgumentException e) {
        if (retry == 0) {
          continue;
        }
        throw new IOException(
            "Invalid registrations expiration parameter - " + expires + " " + e.getMessage());
      }
    }

    request.addHeader(expHeader);
    ContactHeader contactHeader = getRegistrationContactHeader();
    request.addHeader(contactHeader);

    try {
      SipURI routeURI =
          (SipURI) addressFactory.createURI("sip:" + proxyCredentials.getProxy() + ";lr");
      RouteHeader routeHeader =
          headerFactory.createRouteHeader(addressFactory.createAddress(routeURI));
      request.addHeader(routeHeader);

    } catch (Exception e) {

      Log.error("Creating registration route error ", e);
    }

    ClientTransaction regTrans = null;
    try {
      regTrans = sipProvider.getNewClientTransaction(request);
    } catch (TransactionUnavailableException e) {
      throw new IOException(
          "Could not create a register transaction!\n"
              + "Check that the Registrar address is correct! "
              + e.getMessage());
    }

    try {
      sipCallId = callIdHeader.getCallId();
      sipServerCallback.addSipListener(sipCallId, this);
      registerRequest = request;
      regTrans.sendRequest();

      Log.debug("Sent register request " + registerRequest);

      if (expires > 0) {
        scheduleReRegistration();
      }
    } catch (Exception e) {
      throw new IOException("Could not send out the register request! " + e.getMessage());
    }

    this.registerRequest = request;
  }
  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();
    }
  }
示例#8
0
  /** This is a listener method. */
  public void processRequest(RequestEvent requestEvent) {
    Request request = requestEvent.getRequest();
    SipProvider sipProvider = (SipProvider) requestEvent.getSource();
    ServerTransaction serverTransaction = requestEvent.getServerTransaction();
    try {

      if (ProxyDebug.debug)
        ProxyDebug.println(
            "\n****************************************************"
                + "\nRequest "
                + request.getMethod()
                + " received:\n"
                + request.toString());

      if (ProxyDebug.debug) ProxyUtilities.printTransaction(serverTransaction);

      /** **************************************************************************** */
      /** ********************* PROXY BEHAVIOR *********************************** */
      /** **************************************************************************** */

      /*
       * RFC 3261: 16.2: For all new requests, including any with unknown
       * methods, an element intending to proxy the request MUST:
       *
       * 1. Validate the request (Section 16.3)
       *
       * 2. Preprocess routing information (Section 16.4)
       *
       * 3. Determine target(s) for the request (Section 16.5)
       *
       * 4. Forward the request to each target (Section 16.6)
       *
       * 5. Process all responses (Section 16.7)
       */

      /** **************************************************************************** */
      /** *************************** 1. Validate the request (Section 16.3) ********* */
      /** **************************************************************************** */

      /*
       * Before an element can proxy a request, it MUST verify the
       * message's validity
       */

      RequestValidation requestValidation = new RequestValidation(this);
      if (!requestValidation.validateRequest(sipProvider, request, serverTransaction)) {
        // An appropriate response has been sent back by the request
        // validation step, so we just return. The request has been
        // processed!
        if (ProxyDebug.debug)
          ProxyDebug.println(
              "Proxy, processRequest(), the request has not been"
                  + " validated, so the request is discarded "
                  + " (an error code has normally been"
                  + " sent back)");
        return;
      }

      // Let's check if the ACK is for the proxy: if there is no Route
      // header: it is mandatory for the ACK to be forwarded
      if (request.getMethod().equals(Request.ACK)) {
        ListIterator routes = request.getHeaders(RouteHeader.NAME);

        if (routes == null || !routes.hasNext()) {
          if (ProxyDebug.debug)
            ProxyDebug.println(
                "Proxy, processRequest(), "
                    + "the request is an ACK"
                    + " targeted for the proxy, we ignore it");
          return;
        }
        /* added code */
        CallID call_id = (CallID) request.getHeader(CallID.CALL_ID);
        String call_id_str = call_id.getCallId();
        TimeThreadController.Start(call_id_str);
        /* end of added code */

      }

      if (serverTransaction == null) {
        String method = request.getMethod();
        // Methods that creates dialogs, so that can
        // generate transactions
        if (method.equals(Request.INVITE) || method.equals(Request.SUBSCRIBE)) {
          try {
            serverTransaction = sipProvider.getNewServerTransaction(request);
            TransactionsMapping transactionsMapping =
                (TransactionsMapping) serverTransaction.getDialog().getApplicationData();
            if (transactionsMapping == null) {
              transactionsMapping = new TransactionsMapping(serverTransaction);
            }
          } catch (TransactionAlreadyExistsException e) {
            if (ProxyDebug.debug)
              ProxyDebug.println(
                  "Proxy, processRequest(), this request" + " is a retransmission, we drop it!");
          }
        }
      }

      /** ************************************************************************ */
      /** **** 2. Preprocess routing information (Section 16.4) ****************** */
      /** ************************************************************************ */

      /*
       * The proxy MUST inspect the Request-URI of the request. If the
       * Request-URI of the request contains a value this proxy previously
       * placed into a Record-Route header field (see Section 16.6 item
       * 4), the proxy MUST replace the Request-URI in the request with
       * the last value from the Route header field, and remove that value
       * from the Route header field. The proxy MUST then proceed as if it
       * received this modified request. ..... (idem to below:) 16.12. The
       * proxy will inspect the URI in the topmost Route header field
       * value. If it indicates this proxy, the proxy removes it from the
       * Route header field (this route node has been reached).
       */

      ListIterator routes = request.getHeaders(RouteHeader.NAME);
      if (routes != null) {
        if (routes.hasNext()) {
          RouteHeader routeHeader = (RouteHeader) routes.next();
          Address routeAddress = routeHeader.getAddress();
          SipURI routeSipURI = (SipURI) routeAddress.getURI();

          String host = routeSipURI.getHost();
          int port = routeSipURI.getPort();

          if (sipStack.getIPAddress().equals(host)) {
            Iterator lps = sipStack.getListeningPoints();
            while (lps != null && lps.hasNext()) {
              ListeningPoint lp = (ListeningPoint) lps.next();
              if (lp.getPort() == port) {
                if (ProxyDebug.debug)
                  ProxyDebug.println(
                      "Proxy, processRequest(),"
                          + " we remove the first route form "
                          + " the RouteHeader;"
                          + " it matches the proxy");
                routes.remove();
                break;
              }
            }
          }
        }
      }

      /*
       * If the Request-URI contains a maddr parameter, the proxy MUST
       * check to see if its value is in the set of addresses or domains
       * the proxy is configured to be responsible for. If the Request-URI
       * has a maddr parameter with a value the proxy is responsible for,
       * and the request was received using the port and transport
       * indicated (explicitly or by default) in the Request-URI, the
       * proxy MUST strip the maddr and any non-default port or transport
       * parameter and continue processing as if those values had not been
       * present in the request.
       */

      URI requestURI = request.getRequestURI();
      if (requestURI.isSipURI()) {
        SipURI requestSipURI = (SipURI) requestURI;
        if (requestSipURI.getMAddrParam() != null) {
          // The domain the proxy is configured to be responsible for
          // is defined
          // by stack_domain parameter in the configuration file:
          if (configuration.hasDomain(requestSipURI.getMAddrParam())) {
            if (ProxyDebug.debug)
              ProxyDebug.println(
                  "Proxy, processRequest(),"
                      + " The maddr contains a domain we are responsible for,"
                      + " we remove the mAddr parameter from the original"
                      + " request");
            // We have to strip the madr parameter:
            requestSipURI.removeParameter("maddr");
            // We have to strip the port parameter:
            if (requestSipURI.getPort() != 5060 && requestSipURI.getPort() != -1) {
              requestSipURI.setPort(5060);
            }
            // We have to strip the transport parameter:
            requestSipURI.removeParameter("transport");
          } else {
            // The Maddr parameter is not a domain we have to take
            // care of, we pass this check...
          }
        } else {
          // No Maddr parameter, we pass this check...
        }
      } else {
        // No SipURI, so no Maddr parameter, we pass this check...
      }

      /** *************************************************************************** */
      /** *********** 3. Determine target(s) for the request (Section 16.5) ********* */
      /** ************************************************************************** */
      /*
       * The set of targets will either be predetermined by the contents
       * of the request or will be obtained from an abstract location
       * service. Each target in the set is represented as a URI.
       */

      Vector targetURIList = new Vector();
      URI targetURI;

      /*
       * If the Request-URI of the request contains an maddr parameter,
       * the Request-URI MUST be placed into the target set as the only
       * target URI, and the proxy MUST proceed to Section 16.6.
       */

      if (requestURI.isSipURI()) {
        SipURI requestSipURI = (SipURI) requestURI;
        if (requestSipURI.getMAddrParam() != null) {
          targetURI = requestURI;
          targetURIList.addElement(targetURI);
          if (ProxyDebug.debug)
            ProxyDebug.println(
                "Proxy, processRequest(),"
                    + " the only target is the Request-URI (mAddr parameter)");

          // 4. Forward the request statefully:
          requestForwarding.forwardRequest(
              targetURIList, sipProvider, request, serverTransaction, true);

          return;
        }
      }

      /*
       * If the domain of the Request-URI indicates a domain this element
       * is not responsible for, the Request-URI MUST be placed into the
       * target set as the only target, and the element MUST proceed to
       * the task of Request Forwarding (Section 16.6).
       */

      if (requestURI.isSipURI()) {
        SipURI requestSipURI = (SipURI) requestURI;
        if (!configuration.hasDomain(requestSipURI.getHost())) {
          if (ProxyDebug.debug)
            ProxyDebug.println(
                "Proxy, processRequest(),"
                    + " we are not responsible for the domain: Let's check if we have"
                    + " a registration for this domain from another proxy");

          // We have to check if another proxy did not registered
          // to us, in this case we have to use the contacts provided
          // by the registered proxy to create the targets:
          if (registrar.hasDomainRegistered(request)) {
            targetURIList = registrar.getDomainContactsURI(request);
            if (targetURIList != null && !targetURIList.isEmpty()) {
              if (ProxyDebug.debug) {
                ProxyDebug.println(
                    "Proxy, processRequest(), we have"
                        + " a registration for this domain from another proxy");
              }
              // 4. Forward the request statefully:
              requestForwarding.forwardRequest(
                  targetURIList, sipProvider, request, serverTransaction, true);
              return;

            } else {
              targetURIList = new Vector();
              ProxyDebug.println(
                  "Proxy, processRequest(),"
                      + " we are not responsible for the domain: the only target"
                      + " URI is given by the request-URI");
              targetURI = requestURI;
              targetURIList.addElement(targetURI);
            }
          } else {
            ProxyDebug.println(
                "Proxy, processRequest(),"
                    + " we are not responsible for the domain: the only target"
                    + " URI is given by the request-URI");
            targetURI = requestURI;
            targetURIList.addElement(targetURI);
          }

          // 4. Forward the request statelessly:
          requestForwarding.forwardRequest(
              targetURIList, sipProvider, request, serverTransaction, false);

          return;
        } else {
          ProxyDebug.println(
              "Proxy, processRequest(),"
                  + " we are responsible for the domain... Let's find the contact...");
        }
      }

      // we use a SIP registrar:
      if (request.getMethod().equals(Request.REGISTER)) {
        if (ProxyDebug.debug) ProxyDebug.println("Incoming request Register");
        // we call the RegisterProcessing:
        registrar.processRegister(request, sipProvider, serverTransaction);
        // Henrik: let the presenceserver do some processing too
        if (isPresenceServer()) {
          presenceServer.processRegisterRequest(sipProvider, request, serverTransaction);
        }

        return;
      }

      /*
       * If we receive a subscription targeted to a user that is
       * publishing its state here, send to presence server
       */
      if (isPresenceServer() && (request.getMethod().equals(Request.SUBSCRIBE))) {
        ProxyDebug.println("Incoming request Subscribe");

        if (presenceServer.isStateAgent(request)) {
          Request clonedRequest = (Request) request.clone();
          presenceServer.processSubscribeRequest(sipProvider, clonedRequest, serverTransaction);
        } else {
          // Do we know this guy?

          targetURIList = registrar.getContactsURI(request);
          if (targetURIList == null) {
            // If not respond that we dont know him.
            ProxyDebug.println(
                "Proxy: received a Subscribe request to "
                    + " a user in our domain that was not found, "
                    + " responded 404");
            Response response = messageFactory.createResponse(Response.NOT_FOUND, request);
            if (serverTransaction != null) serverTransaction.sendResponse(response);
            else sipProvider.sendResponse(response);
            return;
          } else {
            ProxyDebug.println(
                "Trying to forward subscribe to "
                    + targetURIList.toString()
                    + "\n"
                    + request.toString());
            requestForwarding.forwardRequest(
                targetURIList, sipProvider, request, serverTransaction, false);
          }
        }
        return;
      }

      /** Received a Notify. TOADD: Check if it match active VirtualSubscriptions and update it */
      if (isPresenceServer() && (request.getMethod().equals(Request.NOTIFY))) {
        System.out.println("Incoming request Notify");

        Response response = messageFactory.createResponse(481, request);
        response.setReasonPhrase("Subscription does not exist");
        if (serverTransaction != null) serverTransaction.sendResponse(response);
        else sipProvider.sendResponse(response);
        ProxyDebug.println("Proxy: received a Notify request. Probably wrong, responded 481");
        return;
      }

      if (isPresenceServer() && (request.getMethod().equalsIgnoreCase("PUBLISH"))) {

        System.out.println("Incoming request Publish");

        ProxyDebug.println("Proxy: received a Publish request.");
        Request clonedRequest = (Request) request.clone();

        if (presenceServer.isStateAgent(clonedRequest)) {
          ProxyDebug.println("PresenceServer.isStateAgent");
        } else {
          ProxyDebug.println("PresenceServer is NOT StateAgent");
        }

        if (presenceServer.isStateAgent(clonedRequest)) {
          presenceServer.processPublishRequest(sipProvider, clonedRequest, serverTransaction);
        } else {
          Response response = messageFactory.createResponse(Response.NOT_FOUND, request);
          if (serverTransaction != null) serverTransaction.sendResponse(response);
          else sipProvider.sendResponse(response);
        }
        return;
      }

      // Forward to next hop but dont reply OK right away for the
      // BYE. Bye is end-to-end not hop by hop!
      if (request.getMethod().equals(Request.BYE)) {

        if (serverTransaction == null) {
          if (ProxyDebug.debug) ProxyDebug.println("Proxy, null server transaction for BYE");
          return;
        }

        /* added code */
        CallID call_id = (CallID) request.getHeader(CallID.CALL_ID);
        String call_id_str = call_id.getCallId();
        long end_time = TimeThreadController.Stop(call_id_str);

        To tou = (To) request.getHeader(ToHeader.NAME);
        From fromu = (From) request.getHeader(FromHeader.NAME);

        String FromUser = fromu.getUserAtHostPort();
        String ToUser = tou.getUserAtHostPort();

        StringBuffer sb = new StringBuffer(FromUser);
        int endsAt = sb.indexOf("@");
        String FromUsername = sb.substring(0, endsAt);
        sb = new StringBuffer(ToUser);
        endsAt = sb.indexOf("@");
        String ToUsername = sb.substring(0, endsAt);
        BillStrategyApply bill = new BillStrategyApply(new StandardBillPolicy());
        long start_time = TimeThreadController.getStartTime();
        java.sql.Timestamp s = new java.sql.Timestamp(start_time);
        System.out.println("START TIME POU BIKE :" + s.toString());
        BigDecimal cost = bill.executeStrategy(1, 2, start_time, end_time);
        ProcessBill.updateCallDB(FromUsername, ToUsername, start_time, end_time, cost);

        /* end of added code */

        Dialog d = serverTransaction.getDialog();
        TransactionsMapping transactionsMapping = (TransactionsMapping) d.getApplicationData();
        Dialog peerDialog = (Dialog) transactionsMapping.getPeerDialog(serverTransaction);
        Request clonedRequest = (Request) request.clone();
        FromHeader from = (FromHeader) clonedRequest.getHeader(FromHeader.NAME);
        from.removeParameter("tag");
        ToHeader to = (ToHeader) clonedRequest.getHeader(ToHeader.NAME);
        to.removeParameter("tag");
        ViaHeader via = this.getStackViaHeader();
        clonedRequest.addHeader(via);
        if (peerDialog.getState() != null) {
          ClientTransaction newct = sipProvider.getNewClientTransaction(clonedRequest);
          transactionsMapping.addMapping(serverTransaction, newct);
          peerDialog.sendRequest(newct);
          return;
        } else {
          // the peer dialog is not yet established so bail out.
          // this is a client error - client is sending BYE
          // before dialog establishment.
          if (ProxyDebug.debug) ProxyDebug.println("Proxy, bad dialog state - BYE dropped");
          return;
        }
      }

      /*
       * If the target set for the request has not been predetermined as
       * described above, this implies that the element is responsible for
       * the domain in the Request-URI, and the element MAY use whatever
       * mechanism it desires to determine where to send the request. ...
       * When accessing the location service constructed by a registrar,
       * the Request-URI MUST first be canonicalized as described in
       * Section 10.3 before being used as an index.
       */
      if (requestURI.isSipURI()) {
        SipURI requestSipURI = (SipURI) requestURI;
        Iterator iterator = requestSipURI.getParameterNames();
        if (ProxyDebug.debug)
          ProxyDebug.println("Proxy, processRequest(), we canonicalized" + " the request-URI");
        while (iterator != null && iterator.hasNext()) {
          String name = (String) iterator.next();
          requestSipURI.removeParameter(name);
        }
      }

      if (registrar.hasRegistration(request)) {

        targetURIList = registrar.getContactsURI(request);

        // We fork only INVITE
        if (targetURIList != null
            && targetURIList.size() > 1
            && !request.getMethod().equals("INVITE")) {
          if (ProxyDebug.debug)
            ProxyDebug.println(
                "Proxy, processRequest(), the request "
                    + " to fork is not an INVITE, so we will process"
                    + " it with the first target as the only target.");
          targetURI = (URI) targetURIList.firstElement();
          targetURIList = new Vector();
          targetURIList.addElement(targetURI);
          // 4. Forward the request statefully to the target:
          requestForwarding.forwardRequest(
              targetURIList, sipProvider, request, serverTransaction, true);
          return;
        }

        if (targetURIList != null && !targetURIList.isEmpty()) {
          if (ProxyDebug.debug)
            ProxyDebug.println(
                "Proxy, processRequest(), the target set"
                    + " is the set of the contacts URI from the "
                    + " location service");

          To to = (To) request.getHeader(ToHeader.NAME);
          From from = (From) request.getHeader(FromHeader.NAME);

          String FromUser = from.getUserAtHostPort();
          String ToUser = to.getUserAtHostPort();

          StringBuffer sb = new StringBuffer(FromUser);
          int endsAt = sb.indexOf("@");
          String FromUsername = sb.substring(0, endsAt);
          sb = new StringBuffer(ToUser);
          endsAt = sb.indexOf("@");
          String ToUsername = sb.substring(0, endsAt);

          if (!block.CheckBlock(FromUsername, ToUsername)) {
            Response response =
                messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, request);
            if (serverTransaction != null) serverTransaction.sendResponse(response);
            else sipProvider.sendResponse(response);
            return;
          }
          /*
           * // ECE355 Changes - Aug. 2005. // Call registry service,
           * get response (uri - wsdl). // if response is not null
           * then // do our staff // send to caller decline message by
           * building a decline msg // and attach wsdl uri in the
           * message body // else .. continue the logic below ...
           *
           *
           * // Lets assume that wsdl_string contains the message with
           * all the // service names and uri's for each service in
           * the required format
           *
           * // Query for web services for the receiver of INVITE //
           * Use WebServices class to get services for org
           *
           * String messageBody = "" ; WebServicesQuery wsq = null ;
           * wsq = WebServicesQuery.getInstance();
           *
           * // Get services info for receiver // A receiver is
           * represented as an organization in the Service Registry
           *
           * To to = (To)request.getHeader(ToHeader.NAME); String
           * toAddress = to.getUserAtHostPort();
           *
           * // Remove all characters after the @ sign from To address
           * StringBuffer sb = new StringBuffer(toAddress); int endsAt
           * = sb.indexOf("@"); String orgNamePattern =
           * sb.substring(0, endsAt);
           *
           *
           * Collection serviceInfoColl =
           * wsq.findServicesForOrg(orgNamePattern);
           *
           * // If services are found for this receiver (Org), build
           * DECLINE message and // send to client if (serviceInfoColl
           * != null) { if (serviceInfoColl.size()!= 0 ){
           * System.out.println("Found " + serviceInfoColl.size() +
           * " services for o rg " + orgNamePattern) ; // Build
           * message body for DECLINE message with Service Info
           * messageBody = serviceInfoColl.size()+ " -- " ;
           *
           * Iterator servIter = serviceInfoColl.iterator(); while
           * (servIter.hasNext()) { ServiceInfo servInfo =
           * (ServiceInfo)servIter.next(); messageBody = messageBody +
           * servInfo.getDescription()+ " " + servInfo.getWsdluri() +
           * " " + servInfo.getEndPoint()+ " -- ";
           *
           *
           * System.out.println("Name: " + servInfo.getName()) ;
           * System.out.println("Providing Organization: " +
           * servInfo.getProvidingOrganization()) ;
           * System.out.println("Description: " +
           * servInfo.getDescription()) ;
           * System.out.println("Service End Point " +
           * servInfo.getEndPoint()) ; System.out.println("wsdl wri "
           * + servInfo.getWsdluri()) ;
           * System.out.println("---------------------------------");
           *
           *
           *
           * }
           *
           * System.out.println("ServiceInfo - Message Body  " +
           * messageBody) ;
           *
           * // Build and send DECLINE message with web service info
           *
           * ContentTypeHeader contentTypeHeader = new ContentType(
           * "text", "plain");
           *
           * Response response = messageFactory.createResponse(
           * Response.DECLINE, request, contentTypeHeader,
           * messageBody);
           *
           *
           *
           * if (serverTransaction != null)
           * serverTransaction.sendResponse(response); else
           * sipProvider.sendResponse(response); return; } else
           * System.out.println("There are no services for org " +
           * orgNamePattern) ;
           *
           * }
           *
           * // End of ECE355 change
           */

          // 4. Forward the request statefully to each target Section
          // 16.6.:
          requestForwarding.forwardRequest(
              targetURIList, sipProvider, request, serverTransaction, true);

          return;
        } else {
          // Let's continue and try the default hop.
        }
      }

      // The registrar cannot help to decide the targets, so let's use
      // our router: the default hop!
      ProxyDebug.println(
          "Proxy, processRequest(), the registrar cannot help"
              + " to decide the targets, so let's use our router: the default hop");
      Router router = sipStack.getRouter();
      if (router != null) {
        ProxyHop hop = (ProxyHop) router.getOutboundProxy();
        if (hop != null) {
          if (ProxyDebug.debug)
            ProxyDebug.println(
                "Proxy, processRequest(), the target set" + " is the defaut hop: outbound proxy");

          // Bug fix contributed by Joe Provino
          String user = null;

          if (requestURI.isSipURI()) {
            SipURI requestSipURI = (SipURI) requestURI;
            user = requestSipURI.getUser();
          }

          SipURI hopURI = addressFactory.createSipURI(user, hop.getHost());
          hopURI.setTransportParam(hop.getTransport());
          hopURI.setPort(hop.getPort());
          targetURI = hopURI;
          targetURIList.addElement(targetURI);

          // 4. Forward the request statelessly to each target Section
          // 16.6.:
          requestForwarding.forwardRequest(
              targetURIList, sipProvider, request, serverTransaction, false);

          return;
        }
      }

      /*
       * If the target set remains empty after applying all of the above,
       * the proxy MUST return an error response, which SHOULD be the 480
       * (Temporarily Unavailable) response.
       */
      Response response = messageFactory.createResponse(Response.TEMPORARILY_UNAVAILABLE, request);
      if (serverTransaction != null) serverTransaction.sendResponse(response);
      else sipProvider.sendResponse(response);

      if (ProxyDebug.debug)
        ProxyDebug.println(
            "Proxy, processRequest(), unable to set "
                + " the targets, 480 (Temporarily Unavailable) replied:\n"
                + response.toString());

    } catch (Exception ex) {
      try {
        if (ProxyDebug.debug) {
          ProxyDebug.println("Proxy, processRequest(), internal error, " + "exception raised:");
          ProxyDebug.logException(ex);
          ex.printStackTrace();
        }

        // This is an internal error:
        // Let's return a 500 SERVER_INTERNAL_ERROR
        Response response = messageFactory.createResponse(Response.SERVER_INTERNAL_ERROR, request);
        if (serverTransaction != null) serverTransaction.sendResponse(response);
        else sipProvider.sendResponse(response);

        if (ProxyDebug.debug)
          ProxyDebug.println(
              "Proxy, processRequest(),"
                  + " 500 SERVER_INTERNAL_ERROR replied:\n"
                  + response.toString());
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
  public void processMessage(Request request, ServerTransaction serverTransaction) {
    try {
      SipProvider sipProvider = imUA.getSipProvider();
      MessageFactory messageFactory = imUA.getMessageFactory();
      HeaderFactory headerFactory = imUA.getHeaderFactory();
      AddressFactory addressFactory = imUA.getAddressFactory();

      InstantMessagingGUI instantMessagingGUI = imUA.getInstantMessagingGUI();
      ListenerInstantMessaging listenerInstantMessaging =
          instantMessagingGUI.getListenerInstantMessaging();
      ChatSessionManager chatSessionManager = listenerInstantMessaging.getChatSessionManager();
      ChatSession chatSession = null;
      String fromURL = IMUtilities.getKey(request, "From");
      if (chatSessionManager.hasAlreadyChatSession(fromURL))
        chatSession = chatSessionManager.getChatSession(fromURL);
      else chatSession = chatSessionManager.createChatSession(fromURL);

      DebugIM.println("IMMessageProcessing, processMEssage(), ChatSession:" + chatSession);
      DebugIM.println("Processing MESSAGE in progress...");

      // Send an OK
      Response response = messageFactory.createResponse(Response.OK, request);
      // 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);
      response.setHeader(contactHeader);
      ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
      if (toHeader.getTag() == null) {
        // It is the first message without a TO tag
        toHeader.setTag(new Integer((int) (Math.random() * 10000)).toString());
      }

      if (chatSession.isEstablishedSession()) {
        DebugIM.println("The Session already exists");
        serverTransaction.sendResponse(response);
        DebugIM.println("OK replied to the MESSAGE:\n" + response.toString());
      } else {
        DebugIM.println("The Session does not exists yet. ");
        serverTransaction.sendResponse(response);
        DebugIM.println("OK replied to the MESSAGE:\n" + response.toString());

        Dialog dialog = serverTransaction.getDialog();
        if (dialog == null) {
          DebugIM.println("ERROR, IMProcessing, processMessage(), the dialog is null");
          return;
        }
        // We need to store the dialog:
        chatSession.setDialog(dialog);
        chatSession.setEstablishedSession(true);
        DebugIM.println("The DIALOG object has been stored in the ChatSession");
      }

      Object content = request.getContent();
      String text = null;
      if (content instanceof String) text = (String) content;
      else if (content instanceof byte[]) {
        text = new String((byte[]) content);
      } else {
      }
      if (text != null) {
        chatSession.displayRemoteText(text);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  public void sendMessage(
      String localSipURL, String remoteSipURL, String text, ChatSession chatSession) {
    try {
      DebugIM.println("IMMessageProcessing, ChatSession:" + chatSession);
      DebugIM.println("Sending a MESSAGE in progress to " + remoteSipURL);

      SipProvider sipProvider = imUA.getSipProvider();
      MessageFactory messageFactory = imUA.getMessageFactory();
      HeaderFactory headerFactory = imUA.getHeaderFactory();
      AddressFactory addressFactory = imUA.getAddressFactory();

      String proxyAddress = imUA.getProxyAddress();
      SipURI requestURI = null;
      if (proxyAddress != null) {
        requestURI = addressFactory.createSipURI(null, proxyAddress);
        requestURI.setPort(imUA.getProxyPort());
        requestURI.setTransportParam(imUA.getIMProtocol());
      } else {
        requestURI = (SipURI) addressFactory.createURI(remoteSipURL);
        requestURI.setTransportParam(imUA.getIMProtocol());
      }

      // 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(), imUA.getIMProtocol(), branchId);
      Vector viaList = new Vector();
      viaList.addElement(viaHeader);

      // MaxForwards header:
      MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);
      Dialog dialog = chatSession.getDialog();
      if (chatSession.isEstablishedSession()) {
        DebugIM.println(
            "DEBUG, IMMessageProcessing, sendMessage(), we get"
                + " the DIALOG from the ChatSession");

        Address localAddress = dialog.getLocalParty();
        Address remoteAddress = dialog.getRemoteParty();
        //  if (dialog.isServer()) {
        // We received the first MESSAGE
        fromHeader = headerFactory.createFromHeader(localAddress, dialog.getLocalTag());
        toHeader = headerFactory.createToHeader(remoteAddress, dialog.getRemoteTag());
        //  }
        //  else {

        //   }
        int cseq = dialog.getLocalSequenceNumber();
        DebugIM.println("the cseq number got from the dialog:" + cseq);
        cseqHeader = headerFactory.createCSeqHeader(cseq, "MESSAGE");

        callIdHeader = dialog.getCallId();

      } else {
        DebugIM.println(
            "DEBUG, IMMessageProcessing, sendMessage(), the "
                + " session has not been established yet! We create the first message");

        // To header:
        Address toAddress = addressFactory.createAddress(remoteSipURL);

        // From Header:
        Address fromAddress = addressFactory.createAddress(localSipURL);

        // We have to initiate the dialog: means to create the From tag
        String localTag = Utils.generateTag();
        fromHeader = headerFactory.createFromHeader(fromAddress, localTag);
        toHeader = headerFactory.createToHeader(toAddress, null);

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

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

      // Content-Type:
      ContentTypeHeader contentTypeHeader = headerFactory.createContentTypeHeader("text", "plain");
      contentTypeHeader.setParameter("charset", "UTF-8");

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

      // 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);

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

      ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);

      if (chatSession.isEstablishedSession()) {
        dialog.sendRequest(clientTransaction);
        DebugIM.println(
            "IMessageProcessing, sendMessage(), MESSAGE sent" + " using the dialog:\n" + request);
      } else {
        clientTransaction.sendRequest();
        DebugIM.println(
            "IMessageProcessing, sendMessage(), MESSAGE sent"
                + " using a new client transaction:\n"
                + request);
      }

    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }