Esempio n. 1
0
  public void processResponse(ResponseEvent responseReceivedEvent) {

    // Log.info("Registering response...." + sipCallId);

    Response response = (Response) responseReceivedEvent.getResponse();
    int statusCode = response.getStatusCode();
    String method = ((CSeqHeader) response.getHeader(CSeqHeader.NAME)).getMethod();

    Log.debug("Got response " + response);

    if (statusCode == Response.OK) {
      isRegistered = true;

      Log.info(
          "Voice bridge successfully registered with "
              + registrar
              + " for "
              + proxyCredentials.getXmppUserName());
      PluginImpl.sipRegisterStatus = "Registered ok with " + proxyCredentials.getHost();

      sipServerCallback.removeSipListener(sipCallId);

    } else if (statusCode == Response.UNAUTHORIZED
        || statusCode == Response.PROXY_AUTHENTICATION_REQUIRED) {

      if (method.equals(Request.REGISTER)) {
        CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);

        if (cseq.getSequenceNumber() < 2) {

          ClientTransaction regTrans =
              SipService.handleChallenge(
                  response, responseReceivedEvent.getClientTransaction(), proxyCredentials);

          if (regTrans != null) {
            try {
              regTrans.sendRequest();

            } catch (Exception e) {

              Log.info("Registration failed, cannot send transaction " + e);
              PluginImpl.sipRegisterStatus = "Registration error " + e.toString();
            }

          } else {
            Log.info("Registration failed, cannot create transaction");
            PluginImpl.sipRegisterStatus = "Registration cannot create transaction";
          }

        } else {
          Log.info("Registration failed " + responseReceivedEvent);
          PluginImpl.sipRegisterStatus = "Registration failed";
        }
      }

    } else {
      Log.info("Unrecognized response:  " + response);
    }
  }
Esempio n. 2
0
  public void processResponse(ResponseEvent responseReceivedEvent) {
    System.out.println("Got a response");
    Response response = (Response) responseReceivedEvent.getResponse();
    Transaction tid = responseReceivedEvent.getClientTransaction();

    System.out.println(
        "Response received with client transaction id " + tid + ":\n" + response.getStatusCode());
    if (tid == null) {
      System.out.println("Stray response -- dropping ");
      return;
    }
    System.out.println("transaction state is " + tid.getState());
    System.out.println("Dialog = " + tid.getDialog());
    System.out.println("Dialog State is " + tid.getDialog().getState());

    try {
      if (response.getStatusCode() == Response.OK
          && ((CSeqHeader) response.getHeader(CSeqHeader.NAME))
              .getMethod()
              .equals(Request.INVITE)) {
        // Request cancel = inviteTid.createCancel();
        // ClientTransaction ct =
        //  sipProvider.getNewClientTransaction(cancel);
        // ct.sendRequest();
        Dialog dialog = tid.getDialog();
        CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
        Request ackRequest = dialog.createAck(cseq.getSeqNumber());
        System.out.println("Sending ACK");
        dialog.sendAck(ackRequest);

        // Send a Re INVITE but this time force it
        // to use UDP as the transport. Else, it will
        // Use whatever transport was used to create
        // the dialog.
        if (reInviteCount == 0) {
          Request inviteRequest = dialog.createRequest(Request.INVITE);
          ((SipURI) inviteRequest.getRequestURI()).removeParameter("transport");
          ((ViaHeader) inviteRequest.getHeader(ViaHeader.NAME)).setTransport("udp");
          inviteRequest.addHeader(contactHeader);
          try {
            Thread.sleep(100);
          } catch (Exception ex) {
          }
          ClientTransaction ct = udpProvider.getNewClientTransaction(inviteRequest);
          dialog.sendRequest(ct);
          reInviteCount++;
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
      System.exit(0);
    }
  }
Esempio n. 3
0
  public void unregister() throws IOException {
    if (!isRegistered) {
      return;
    }

    cancelPendingRegistrations();
    isRegistered = false;

    if (this.registerRequest == null) {
      Log.info("Couldn't find the initial register request");
      throw new IOException("Couldn't find the initial register request");
    }

    Request unregisterRequest = (Request) registerRequest.clone();

    try {
      unregisterRequest.getExpires().setExpires(0);
      CSeqHeader cSeqHeader = (CSeqHeader) unregisterRequest.getHeader(CSeqHeader.NAME);
      // [issue 1] - increment registration cseq number
      // reported by - Roberto Tealdi <*****@*****.**>
      cSeqHeader.setSequenceNumber(cSeqHeader.getSequenceNumber() + 1);
    } catch (InvalidArgumentException e) {
      Log.info("Unable to set Expires Header " + e.getMessage());
      return;
    }

    ClientTransaction unregisterTransaction = null;

    try {
      unregisterTransaction = sipProvider.getNewClientTransaction(unregisterRequest);
    } catch (TransactionUnavailableException e) {
      throw new IOException("Unable to create a unregister transaction " + e.getMessage());
    }
    try {
      unregisterTransaction.sendRequest();
    } catch (SipException e) {
      Log.info("Faied to send unregister request " + e.getMessage());
      return;
    }
  }
Esempio n. 4
0
  /** This is a listener method. */
  public void processResponse(ResponseEvent responseEvent) {
    try {

      Response response = responseEvent.getResponse();
      SipProvider sipProvider = (SipProvider) responseEvent.getSource();
      ClientTransaction clientTransaction = responseEvent.getClientTransaction();

      ProxyDebug.println(
          "\n***************************************************************"
              + "\n***************************************************************"
              + "\nResponse "
              + response.getStatusCode()
              + " "
              + response.getReasonPhrase()
              + " received:\n"
              + response.toString());
      ProxyDebug.println("Processing Response in progress");

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

      // Henrik - added handling of responses addressed to server
      // If we use a presenceserver, and if statuscode was OK...
      CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);

      if (cseqHeader.getMethod().equals("SUBSCRIBE")) {
        presenceServer.processSubscribeResponse((Response) response.clone(), clientTransaction);
      } else if (cseqHeader.getMethod().equals("NOTIFY")) {
        // presenceServer.processNotifyResponse((Response)response.clone(),
        // clientTransaction);
      }

      responseForwarding.forwardResponse(sipProvider, response, clientTransaction);

    } catch (Exception ex) {
      if (ProxyDebug.debug) {
        ProxyDebug.println("Proxy, processResponse(), internal error, " + "exception raised:");
        ProxyDebug.logException(ex);
      }
    }
  }
  public void processResponse(ResponseEvent responseEvent) {
    Response response = responseEvent.getResponse();
    ClientTransaction clientTransaction = responseEvent.getClientTransaction();
    CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);

    logger.debug("***** Response: " + response.getStatusCode() + " received by UA *****");
    logger.debug(response);
    logger.debug("***** Response dispatched *****");

    if (response.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED
        || response.getStatusCode() == Response.UNAUTHORIZED) {
      if (clientTransaction == null) {
        logger.info("Bad username ?");
      } else {
        try {
          logger.debug("IMUserAgent, processResponse(), Credentials to provide!");
          // WE start the authentication process!!!
          // Let's get the Request related to this response:
          Request clonedRequest = (Request) clientTransaction.getRequest().clone();
          if (clonedRequest == null) {
            logger.debug(
                "IMUserAgent, processResponse(), the request "
                    + " that caused the 407 has not been retrieved!!! Return cancelled!");
          } else {
            // Let's increase the Cseq:
            cseqHeader = (CSeqHeader) clonedRequest.getHeader(CSeqHeader.NAME);
            cseqHeader.setSequenceNumber(cseqHeader.getSequenceNumber() + 1);
            // Let's add a Proxy-Authorization header:
            // We send the informations stored:
            FromHeader fromHeader = (FromHeader) clonedRequest.getHeader(FromHeader.NAME);
            String fromURI = fromHeader.getAddress().getURI().toString();
            Header header;
            if (fromURI.equals(getLocalURI())) {
              header = authenticationProcess.getHeader(response);
            } else {
              String fromAddress = IMUtilities.getUsernameFromURI(fromURI);
              logger.info("Fetching credentials dor user: "******"ERROR, user not found");
                header = null;
              }
            }

            if (header == null) {
              logger.debug(
                  "IMUserAgent, processResponse(), Proxy-Authorization "
                      + " header is null, the request is not resent");
            } else {
              clonedRequest.setHeader(header);

              ClientTransaction newClientTransaction =
                  getSipProvider().getNewClientTransaction(clonedRequest);

              newClientTransaction.sendRequest();
              logger.debug(
                  "IMUserAgent, processResponse(), REGISTER "
                      + "with credentials sent:\n"
                      + clonedRequest);
            }
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    } else {
      if (cseqHeader.getMethod().equals("REGISTER")) {
        //	logger.info("REGISTER Response received");
        sipRC.processResponse(responseEvent);
      } else if (cseqHeader.getMethod().equals("ACK")) {

      } else if (cseqHeader.getMethod().equals("MESSAGE")) {
        sipMC.processResponse(responseEvent);
      }
    }
  }
  public void processResponse(ResponseEvent responseReceivedEvent) {
    /// System.out.println("=> BUNDLE: br.ufes.inf.ngn.televoto.client.logic | CLASS: LogicListener
    // | METOD: processResponse ");//By Ju
    try {
      Response myResponse = responseReceivedEvent.getResponse();
      logger.info("<<< " + myResponse.toString());

      ClientTransaction thisClientTransaction = responseReceivedEvent.getClientTransaction();

      int myStatusCode = myResponse.getStatusCode();

      switch (status) {
        case WAIT_PROV:
          if (!thisClientTransaction.equals(myClientTransaction))
            myClientTransaction = thisClientTransaction;

          if (myStatusCode < 200) {
            status = WAIT_FINAL;
            myDialog = thisClientTransaction.getDialog();
          } else if (myStatusCode < 300) {
            myDialog = thisClientTransaction.getDialog();
            CSeqHeader originalCSeq =
                (CSeqHeader) myClientTransaction.getRequest().getHeader(CSeqHeader.NAME);
            long numseq = originalCSeq.getSeqNumber();
            Request myAck = myDialog.createAck(numseq);
            myAck.addHeader(myContactHeader);
            myDialog.sendAck(myAck);
            // logger.info(">>> "+myAck.toString());
            status = ESTABLISHED;
            byte[] cont = (byte[]) myResponse.getContent();
            answerInfo = mySdpManager.getSdp(cont);

          } else {
            if (myStatusCode == 401) {

            } else {
              status = IDLE;
              CSeqHeader originalCSeq =
                  (CSeqHeader) myClientTransaction.getRequest().getHeader(CSeqHeader.NAME);
              long numseq = originalCSeq.getSeqNumber();
              Request myAck = myDialog.createAck(numseq);
              myAck.addHeader(myContactHeader);
              myDialog.sendAck(myAck);
              // logger.info(">>> "+myAck.toString());
            }
          }
          break;

        case WAIT_FINAL:
          if (!thisClientTransaction.equals(myClientTransaction))
            myClientTransaction = thisClientTransaction;

          if (myStatusCode < 200) {
            status = WAIT_FINAL;
            myDialog = thisClientTransaction.getDialog();
          } else if (myStatusCode < 300) {
            if (useQueue.equals("yes")) {
              status = IDLE;
            } else {
              status = ESTABLISHED;
            }

            myDialog = thisClientTransaction.getDialog();
            CSeqHeader originalCSeq =
                (CSeqHeader) myClientTransaction.getRequest().getHeader(CSeqHeader.NAME);
            long numseq = originalCSeq.getSeqNumber();
            Request myAck = myDialog.createAck(numseq); // Aquiiii
            myAck.addHeader(myContactHeader);
            myDialog.sendAck(myAck);
            // logger.info(">>> "+myAck.toString());
            byte[] cont = (byte[]) myResponse.getContent();
            answerInfo = mySdpManager.getSdp(cont);

          } else {
            // Cancelando requisição ao cliente
            Request myCancelRequest = myClientTransaction.createCancel();
            ClientTransaction myCancelClientTransaction =
                mySipProvider.getNewClientTransaction(myCancelRequest);
            myCancelClientTransaction.sendRequest();
            // logger.info(">>> " + myCancelRequest.toString());
            status = IDLE;
          }
          break;

        case REGISTERING:
          if (!thisClientTransaction.equals(myClientTransaction))
            myClientTransaction = thisClientTransaction;

          if (myStatusCode == 200) {
            status = IDLE;
            if (!Unregistring) {

              System.out.println(myName + ": Registrado");

              // inserir captura de timestamp
              // logger.info(myName + ";INVITE;" +  getTime());
              // Random gerador = new Random();
              // int temp = gerador.nextInt(10);
              // System.out.println(myName + ": Esperando " + temp + "segundos");
              // Thread.sleep(temp);

              System.out.println(myName + ": chamando " + destination);

              SdpInfo offerInfo = new SdpInfo();
              offerInfo.IpAddress = myIP;
              offerInfo.aport = myAudioPort;
              offerInfo.aformat = 0;
              byte[] content = mySdpManager.createSdp(offerInfo);

              // Via
              // ViaHeader comentei
              myViaHeader = myHeaderFactory.createViaHeader(myIP, myPort, "udp", null);
              myViaHeader.setRPort();
              ArrayList viaHeaders = new ArrayList();
              viaHeaders.add(myViaHeader);

              // From
              Address addressOfRecord = myAddressFactory.createAddress("<sip:" + myUserID + ">");
              FromHeader myFromHeader = myHeaderFactory.createFromHeader(addressOfRecord, "456249");

              // To
              String dstURI[] = destination.split("@");
              String dstSipAlias = dstURI[0];
              Address destinationAddress =
                  myAddressFactory.createAddress("<sip:" + destination + ">");
              javax.sip.address.URI myRequestURI = destinationAddress.getURI();
              ToHeader myToHeader = myHeaderFactory.createToHeader(destinationAddress, null);

              // MaxForwards
              MaxForwardsHeader myMaxForwardsHeader = myHeaderFactory.createMaxForwardsHeader(70);

              // Call-ID
              CallIdHeader myCallIdHeader = mySipProvider.getNewCallId();

              // CSeq
              Random random = new Random();
              CSeqHeader myCSeqHeader =
                  myHeaderFactory.createCSeqHeader(random.nextInt(1000) * 1L, "INVITE");

              // Create SIP request
              Request myRequest =
                  myMessageFactory.createRequest(
                      myRequestURI,
                      "INVITE",
                      myCallIdHeader,
                      myCSeqHeader,
                      myFromHeader,
                      myToHeader,
                      viaHeaders,
                      myMaxForwardsHeader);

              // Contact
              Address contactAddress =
                  myAddressFactory.createAddress(
                      "<sip:" + mySipAlias + "@" + myIP + ":" + myPort + ";transport=udp>");
              myContactHeader = myHeaderFactory.createContactHeader(contactAddress);
              myRequest.addHeader(myContactHeader);

              // Allow
              Allow myAllow = new Allow();
              myAllow.setMethod(
                  "INVITE, ACK, CANCEL, BYE, MESSAGE, OPTIONS, NOTIFY, PRACK, UPDATE, REFER");
              myRequest.addHeader(myAllow);

              // Privacy
              Privacy myPrivacy = new Privacy("none");
              myRequest.addHeader(myPrivacy);

              // PPreferredIdentity
              HeaderFactoryImpl myHeaderFactoryImpl = new HeaderFactoryImpl();
              PPreferredIdentityHeader myPPreferredIdentityHeader =
                  myHeaderFactoryImpl.createPPreferredIdentityHeader(
                      myAddressFactory.createAddress("sip:" + myName + '@' + myServer));
              myRequest.addHeader(myPPreferredIdentityHeader);

              // Route
              Address routeAddress =
                  myAddressFactory.createAddress("sip:orig@scscf." + myServer + ":6060;lr");
              // RouteHeader comentei
              myRouteHeader = myHeaderFactory.createRouteHeader(routeAddress);
              myRequest.addHeader(myRouteHeader);

              // Para proxy funcionar
              SipURI outboundProxyURI = myAddressFactory.createSipURI("proxy", myProxyIP);
              outboundProxyURI.setLrParam();
              outboundProxyURI.setPort(myProxyPort);
              myRouteHeader =
                  myHeaderFactory.createRouteHeader(
                      myAddressFactory.createAddress(outboundProxyURI));
              myRequest.addFirst(myRouteHeader);

              // Content Type
              ContentTypeHeader contentTypeHeader =
                  myHeaderFactory.createContentTypeHeader("application", "sdp");
              myRequest.setContent(content, contentTypeHeader);

              // ClientTransaction comentei aqui
              myClientTransaction = mySipProvider.getNewClientTransaction(myRequest);
              myClientTransaction.setRetransmitTimer(700);
              myClientTransaction.sendRequest();

              status = WAIT_PROV;

              logger.info(">>> " + myRequest.toString());

            } else {
              this.setOff(mySipStack);
            }
          } else {
            if (myStatusCode == 403) {

              System.out.println("Problemas com credenciais!!!!\n");
            } else if (myStatusCode == 401) {

              myName = (String) this.getLocalName();
              myUserID = (String) this.getLocalName() + "@" + myServer;

              Address contactAddress =
                  myAddressFactory.createAddress("sip:" + myName + '@' + myIP + ":" + myPort);
              myContactHeader = myHeaderFactory.createContactHeader(contactAddress);

              myViaHeader = myHeaderFactory.createViaHeader(myIP, myPort, "udp", null);

              fromAddress = myAddressFactory.createAddress(myName + " <sip:" + myUserID + ">");

              Address registrarAddress = myAddressFactory.createAddress("sip:" + myServer);
              Address registerToAddress = fromAddress;
              Address registerFromAddress = fromAddress;

              ToHeader myToHeader = myHeaderFactory.createToHeader(registerToAddress, null);
              FromHeader myFromHeader =
                  myHeaderFactory.createFromHeader(registerFromAddress, "647554");

              ArrayList myViaHeaders = new ArrayList();
              myViaHeaders.add(myViaHeader);

              // System.out.println("myClientTransaction.getRequest():"+
              // myClientTransaction.getRequest());
              CSeqHeader originalCSeq =
                  (CSeqHeader) myClientTransaction.getRequest().getHeader(CSeqHeader.NAME);
              long numseq = originalCSeq.getSeqNumber();
              MaxForwardsHeader myMaxForwardsHeader = myHeaderFactory.createMaxForwardsHeader(70);
              CSeqHeader myCSeqHeader = myHeaderFactory.createCSeqHeader(numseq + 1L, "REGISTER");

              CallIdHeader myCallID =
                  (CallIdHeader) myClientTransaction.getRequest().getHeader(CallIdHeader.NAME);
              CallIdHeader myCallIDHeader = myCallID;
              SipURI myRequestURI = (SipURI) registrarAddress.getURI();
              Request myRegisterRequest =
                  myMessageFactory.createRequest(
                      myRequestURI,
                      "REGISTER",
                      myCallIDHeader,
                      myCSeqHeader,
                      myFromHeader,
                      myToHeader,
                      myViaHeaders,
                      myMaxForwardsHeader);
              myRegisterRequest.addHeader(myContactHeader);

              // Expires
              ExpiresHeader myExpiresHeader;
              if (Unregistring) {
                myExpiresHeader = myHeaderFactory.createExpiresHeader(0);
                myContactHeader.setExpires(0);
              } else {
                myExpiresHeader = myHeaderFactory.createExpiresHeader(60000);
              }
              myRegisterRequest.addHeader(myExpiresHeader);

              // Allow
              Allow myAllow = new Allow();
              myAllow.setMethod(
                  "INVITE, ACK, CANCEL, BYE, MESSAGE, OPTIONS, NOTIFY, PRACK, UPDATE, REFER");
              myRegisterRequest.addHeader(myAllow);

              // Privacy
              Privacy myPrivacy = new Privacy("none");
              myRegisterRequest.addHeader(myPrivacy);

              // PPreferredIdentity
              HeaderFactoryImpl myHeaderFactoryImpl = new HeaderFactoryImpl();
              PPreferredIdentityHeader myPPreferredIdentityHeader =
                  myHeaderFactoryImpl.createPPreferredIdentityHeader(
                      myAddressFactory.createAddress("sip:" + myName + '@' + myServer));
              myRegisterRequest.addHeader(myPPreferredIdentityHeader);

              // Supported
              Supported mySupported = new Supported("path");
              myRegisterRequest.addHeader(mySupported);

              myWWWAuthenticateHeader =
                  Utils.makeAuthHeader(
                      myHeaderFactory, myResponse, myRegisterRequest, myUserID, myPassword);
              myRegisterRequest.addHeader(myWWWAuthenticateHeader);

              myClientTransaction = mySipProvider.getNewClientTransaction(myRegisterRequest);
              myClientTransaction.sendRequest();

              // logger.info(">>> "+myRegisterRequest.toString());
              // System.out.println(">>> " + myRegisterRequest.toString());
              status = REGISTERING;
            }
          }
          break;
      }
    } catch (Exception excep) {
      excep.printStackTrace();
    }
  }
    public void processResponse(ResponseEvent responseReceivedEvent) {
      System.out.println("Got a response");
      Response response = (Response) responseReceivedEvent.getResponse();
      ClientTransaction tid = responseReceivedEvent.getClientTransaction();
      CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);

      System.out.println(
          "Response received : Status Code = " + response.getStatusCode() + " " + cseq);

      if (tid == null) {

        // RFC3261: MUST respond to every 2xx
        if (ackRequest != null && dialog != null) {
          System.out.println("re-sending ACK");
          try {
            dialog.sendAck(ackRequest);
          } catch (SipException se) {
            se.printStackTrace();
            fail("Unxpected exception ");
          }
        }
        return;
      }
      // If the caller is supposed to send the bye
      if (callerSendsBye && !byeTaskRunning) {
        byeTaskRunning = true;
        new Timer().schedule(new ByeTask(dialog), 4000);
      }
      System.out.println("transaction state is " + tid.getState());
      System.out.println("Dialog = " + tid.getDialog());
      System.out.println("Dialog State is " + tid.getDialog().getState());

      assertSame("Checking dialog identity", tid.getDialog(), this.dialog);

      try {
        if (response.getStatusCode() == Response.OK) {
          if (cseq.getMethod().equals(Request.INVITE)) {
            System.out.println("Dialog after 200 OK  " + dialog);
            System.out.println("Dialog State after 200 OK  " + dialog.getState());
            Request ackRequest = dialog.createAck(cseq.getSeqNumber());
            System.out.println("Sending ACK");
            dialog.sendAck(ackRequest);

            // JvB: test REFER, reported bug in tag handling
            //                      Request referRequest = dialog.createRequest("REFER");
            //                      //simulating a balancer that will forward the request to the
            // recovery node
            //                      SipURI referRequestURI = addressFactory.createSipURI(null,
            // "127.0.0.1:5080");
            //                      referRequest.setRequestURI(referRequestURI);
            //                      dialog.sendRequest(
            // sipProvider.getNewClientTransaction(referRequest));
            //
          } else if (cseq.getMethod().equals(Request.CANCEL)) {
            if (dialog.getState() == DialogState.CONFIRMED) {
              // oops cancel went in too late. Need to hang up the
              // dialog.
              System.out.println("Sending BYE -- cancel went in too late !!");
              Request byeRequest = dialog.createRequest(Request.BYE);
              ClientTransaction ct = sipProvider.getNewClientTransaction(byeRequest);
              dialog.sendRequest(ct);
            }

          } else if (cseq.getMethod().equals(Request.BYE)) {
            okToByeReceived = true;
          }
        }
      } catch (Exception ex) {
        ex.printStackTrace();
        System.exit(0);
      }
    }
  /*
   * (non-Javadoc)
   *
   * @see gov.nist.javax.sip.clientauthutils.AuthenticationHelper#handleChallenge(javax.sip.message.Response,
   *      javax.sip.ClientTransaction, javax.sip.SipProvider)
   */
  public ClientTransaction handleChallenge(
      Response challenge,
      ClientTransaction challengedTransaction,
      SipProvider transactionCreator,
      int cacheTime)
      throws SipException, NullPointerException {
    try {
      if (sipStack.isLoggingEnabled()) {
        sipStack.getStackLogger().logDebug("handleChallenge: " + challenge);
      }

      SIPRequest challengedRequest = ((SIPRequest) challengedTransaction.getRequest());

      Request reoriginatedRequest = null;
      /*
       * If the challenged request is part of a Dialog and the
       * Dialog is confirmed the re-originated request should be
       * generated as an in-Dialog request.
       */
      if (challengedRequest.getToTag() != null
          || challengedTransaction.getDialog() == null
          || challengedTransaction.getDialog().getState() != DialogState.CONFIRMED) {
        reoriginatedRequest = (Request) challengedRequest.clone();
      } else {
        /*
         * Re-originate the request by consulting the dialog. In particular
         * the route set could change between the original request and the
         * in-dialog challenge.
         */
        reoriginatedRequest =
            challengedTransaction.getDialog().createRequest(challengedRequest.getMethod());
        Iterator<String> headerNames = challengedRequest.getHeaderNames();
        while (headerNames.hasNext()) {
          String headerName = headerNames.next();
          if (reoriginatedRequest.getHeader(headerName) != null) {
            ListIterator<Header> iterator = reoriginatedRequest.getHeaders(headerName);
            while (iterator.hasNext()) {
              reoriginatedRequest.addHeader(iterator.next());
            }
          }
        }
      }

      // remove the branch id so that we could use the request in a new
      // transaction
      removeBranchID(reoriginatedRequest);

      if (challenge == null || reoriginatedRequest == null) {
        throw new NullPointerException("A null argument was passed to handle challenge.");
      }

      ListIterator authHeaders = null;

      if (challenge.getStatusCode() == Response.UNAUTHORIZED) {
        authHeaders = challenge.getHeaders(WWWAuthenticateHeader.NAME);
      } else if (challenge.getStatusCode() == Response.PROXY_AUTHENTICATION_REQUIRED) {
        authHeaders = challenge.getHeaders(ProxyAuthenticateHeader.NAME);
      } else {
        throw new IllegalArgumentException("Unexpected status code ");
      }

      if (authHeaders == null) {
        throw new IllegalArgumentException(
            "Could not find WWWAuthenticate or ProxyAuthenticate headers");
      }

      // Remove all authorization headers from the request (we'll re-add them
      // from cache)
      reoriginatedRequest.removeHeader(AuthorizationHeader.NAME);
      reoriginatedRequest.removeHeader(ProxyAuthorizationHeader.NAME);

      // rfc 3261 says that the cseq header should be augmented for the new
      // request. do it here so that the new dialog (created together with
      // the new client transaction) takes it into account.
      // Bug report - Fredrik Wickstrom
      CSeqHeader cSeq = (CSeqHeader) reoriginatedRequest.getHeader((CSeqHeader.NAME));
      try {
        cSeq.setSeqNumber(cSeq.getSeqNumber() + 1l);
      } catch (InvalidArgumentException ex) {
        throw new SipException("Invalid CSeq -- could not increment : " + cSeq.getSeqNumber());
      }

      /* Resolve this to the next hop based on the previous lookup. If we are not using
       * lose routing (RFC2543) then just attach hop as a maddr param.
       */
      if (challengedRequest.getRouteHeaders() == null) {
        Hop hop = ((SIPClientTransaction) challengedTransaction).getNextHop();
        SipURI sipUri = (SipURI) reoriginatedRequest.getRequestURI();
        sipUri.setMAddrParam(hop.getHost());
        if (hop.getPort() != -1) sipUri.setPort(hop.getPort());
      }
      ClientTransaction retryTran = transactionCreator.getNewClientTransaction(reoriginatedRequest);

      WWWAuthenticateHeader authHeader = null;
      SipURI requestUri = (SipURI) challengedTransaction.getRequest().getRequestURI();
      while (authHeaders.hasNext()) {
        authHeader = (WWWAuthenticateHeader) authHeaders.next();
        String realm = authHeader.getRealm();
        AuthorizationHeader authorization = null;
        String sipDomain;
        if (this.accountManager instanceof SecureAccountManager) {
          UserCredentialHash credHash =
              ((SecureAccountManager) this.accountManager)
                  .getCredentialHash(challengedTransaction, realm);
          URI uri = reoriginatedRequest.getRequestURI();
          sipDomain = credHash.getSipDomain();
          authorization =
              this.getAuthorization(
                  reoriginatedRequest.getMethod(),
                  uri.toString(),
                  (reoriginatedRequest.getContent() == null)
                      ? ""
                      : new String(reoriginatedRequest.getRawContent()),
                  authHeader,
                  credHash);
        } else {
          UserCredentials userCreds =
              ((AccountManager) this.accountManager).getCredentials(challengedTransaction, realm);
          sipDomain = userCreds.getSipDomain();
          if (userCreds == null)
            throw new SipException("Cannot find user creds for the given user name and realm");

          // we haven't yet authenticated this realm since we were
          // started.

          authorization =
              this.getAuthorization(
                  reoriginatedRequest.getMethod(),
                  reoriginatedRequest.getRequestURI().toString(),
                  (reoriginatedRequest.getContent() == null)
                      ? ""
                      : new String(reoriginatedRequest.getRawContent()),
                  authHeader,
                  userCreds);
        }
        sipStack
            .getStackLogger()
            .logDebug("Created authorization header: " + authorization.toString());

        if (cacheTime != 0)
          cachedCredentials.cacheAuthorizationHeader(sipDomain, authorization, cacheTime);

        reoriginatedRequest.addHeader(authorization);
      }

      if (sipStack.isLoggingEnabled()) {
        sipStack.getStackLogger().logDebug("Returning authorization transaction." + retryTran);
      }
      return retryTran;
    } catch (SipException ex) {
      throw ex;
    } catch (Exception ex) {
      sipStack.getStackLogger().logError("Unexpected exception ", ex);
      throw new SipException("Unexpected exception ", ex);
    }
  }
  /**
   * Implements {@link MethodProcessor#processResponse(ResponseEvent)}. Handles only responses to
   * SUBSCRIBE requests because they are the only requests concerning event package subscribers (and
   * the only requests sent by them, for that matter) and if the processing of a given response
   * requires event package-specific handling, delivers the response to the matching
   * <tt>Subscription</tt> instance. Examples of such event package-specific handling include
   * letting the respective <tt>Subscription</tt> handle the success or failure in the establishment
   * of a subscription.
   *
   * @param responseEvent a <tt>ResponseEvent</tt> specifying the SIP <tt>Response</tt> to be
   *     processed
   * @return <tt>true</tt> if the SIP <tt>Response</tt> specified by <tt>responseEvent</tt> was
   *     processed; otherwise, <tt>false</tt>
   */
  @Override
  public boolean processResponse(ResponseEvent responseEvent) {
    Response response = responseEvent.getResponse();

    CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
    if (cseqHeader == null) {
      logger.error("An incoming response did not contain a CSeq header");
      return false;
    }
    if (!Request.SUBSCRIBE.equals(cseqHeader.getMethod())) return false;

    ClientTransaction clientTransaction = responseEvent.getClientTransaction();
    Request request = clientTransaction.getRequest();

    /*
     * Don't handle responses to requests not coming from this event
     * package.
     */
    if (request != null) {
      EventHeader eventHeader = (EventHeader) request.getHeader(EventHeader.NAME);
      if ((eventHeader == null) || !eventPackage.equalsIgnoreCase(eventHeader.getEventType()))
        return false;
    }

    // Find the subscription.
    CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME);
    String callId = callIdHeader.getCallId();
    Subscription subscription = getSubscription(callId);

    // if it's the response to an unsubscribe message, we just ignore it
    // whatever the response is however if we need to handle a
    // challenge, we do it
    ExpiresHeader expHeader = response.getExpires();
    int statusCode = response.getStatusCode();
    SipProvider sourceProvider = (SipProvider) responseEvent.getSource();
    if (((expHeader != null) && (expHeader.getExpires() == 0))
        || (subscription == null)) // this handle the unsubscription
    // case where we removed the contact
    // from subscribedContacts
    {
      boolean processed = false;

      if ((statusCode == Response.UNAUTHORIZED)
          || (statusCode == Response.PROXY_AUTHENTICATION_REQUIRED)) {
        try {
          processAuthenticationChallenge(clientTransaction, response, sourceProvider);
          processed = true;
        } catch (OperationFailedException e) {
          logger.error("can't handle the challenge", e);
        }
      } else if ((statusCode != Response.OK) && (statusCode != Response.ACCEPTED)) processed = true;

      // any other cases (200/202) will imply a NOTIFY, so we will
      // handle the end of a subscription there
      return processed;
    }

    if ((statusCode >= Response.OK) && (statusCode < Response.MULTIPLE_CHOICES)) {
      // OK (200/202)
      if ((statusCode == Response.OK) || (statusCode == Response.ACCEPTED)) {
        if (expHeader == null) {
          // not conform to rfc3265
          logger.error("no Expires header in this response");
          return false;
        }

        SubscriptionRefreshTask refreshTask = new SubscriptionRefreshTask(subscription);
        subscription.setTimerTask(refreshTask);

        int refreshDelay = expHeader.getExpires();
        // try to keep a margin if the refresh delay allows it
        if (refreshDelay >= (2 * refreshMargin)) refreshDelay -= refreshMargin;
        timer.schedule(refreshTask, refreshDelay * 1000);

        // do it to remember the dialog in case of a polling
        // subscription (which means no call to finalizeSubscription)
        subscription.setDialog(clientTransaction.getDialog());

        subscription.processSuccessResponse(responseEvent, statusCode);
      }
    } else if ((statusCode >= Response.MULTIPLE_CHOICES) && (statusCode < Response.BAD_REQUEST)) {
      if (logger.isInfoEnabled())
        logger.info(
            "Response to subscribe to "
                + subscription.getAddress()
                + ": "
                + response.getReasonPhrase());
    } else if (statusCode >= Response.BAD_REQUEST) {
      // if the response is a 423 response, just re-send the request
      // with a valid expires value
      if (statusCode == Response.INTERVAL_TOO_BRIEF) {
        MinExpiresHeader min = (MinExpiresHeader) response.getHeader(MinExpiresHeader.NAME);

        if (min == null) {
          logger.error("no minimal expires value in this 423 " + "response");
          return false;
        }

        ExpiresHeader exp = request.getExpires();

        try {
          exp.setExpires(min.getExpires());
        } catch (InvalidArgumentException e) {
          logger.error("can't set the new expires value", e);
          return false;
        }

        ClientTransaction transac = null;
        try {
          transac = protocolProvider.getDefaultJainSipProvider().getNewClientTransaction(request);
        } catch (TransactionUnavailableException e) {
          logger.error("can't create the client transaction", e);
          return false;
        }

        try {
          transac.sendRequest();
        } catch (SipException e) {
          logger.error("can't send the new request", e);
          return false;
        }

        return true;
        // UNAUTHORIZED (401/407)
      } else if ((statusCode == Response.UNAUTHORIZED)
          || (statusCode == Response.PROXY_AUTHENTICATION_REQUIRED)) {
        try {
          processAuthenticationChallenge(clientTransaction, response, sourceProvider);
        } catch (OperationFailedException e) {
          logger.error("can't handle the challenge", e);

          removeSubscription(callId, subscription);
          subscription.processFailureResponse(responseEvent, statusCode);
        }
        // 408 480 486 600 603 : non definitive reject
        // others: definitive reject (or not implemented)
      } else {
        if (logger.isDebugEnabled()) logger.debug("error received from the network:\n" + response);

        removeSubscription(callId, subscription);
        subscription.processFailureResponse(responseEvent, statusCode);
      }
    }

    return true;
  }