Example #1
0
  /**
   * Receive MSRP response
   *
   * @param code Response code
   * @param txId Transaction ID
   * @param headers MSRP headers
   */
  public void receiveMsrpResponse(int code, String txId, Hashtable<String, String> headers) {
    // Consider media is established when we received something
    mIsEstablished = true;

    if (sLogger.isActivated()) {
      sLogger.info("Response received (code=" + code + ", transaction=" + txId + ")");
    }

    if (mFailureReportOption) {
      // Notify progress
      if (!mCancelTransfer && mProgress.size() > 0) {
        mMsrpEventListener.msrpTransferProgress(mProgress.elementAt(0), mTotalSize);
        mProgress.removeElementAt(0);
      }
    }

    // Notify request transaction
    if (mRequestTransaction != null) {
      mRequestTransaction.notifyResponse(code, headers);
    }

    // Notify MSRP transaction
    if (mMsrpTransaction != null) {
      mMsrpTransaction.handleResponse();
    }

    // Notify event listener
    if (code != 200) {
      // Changed by Deutsche Telekom
      String cpimMsgId = null;
      TypeMsrpChunk typeMsrpChunk = TypeMsrpChunk.Unknown;
      MsrpTransactionInfo msrpTransactionInfo = getMsrpTransactionInfo(txId);
      if (msrpTransactionInfo != null) {
        cpimMsgId = msrpTransactionInfo.mCpimMsgId;
        typeMsrpChunk = msrpTransactionInfo.mTypeMsrpChunk;
      }
      mMsrpEventListener.msrpTransferError(cpimMsgId, "error response " + code, typeMsrpChunk);

      // Changed by Deutsche Telekom
      // If an error is received it couldn't get any better nor worse; transaction has reached
      // final state
      removeMsrpTransactionInfo(txId);
    }

    // Don't remove transaction info in general from list as this could be a preliminary answer
  }
Example #2
0
  /**
   * Receive MSRP SEND request
   *
   * @param txId Transaction ID
   * @param headers Request headers
   * @param flag Continuation flag
   * @param data Received data
   * @param totalSize Total size of the content
   * @throws NetworkException
   * @throws PayloadException
   * @throws ContactManagerException
   */
  public void receiveMsrpSend(
      String txId, Hashtable<String, String> headers, int flag, byte[] data, long totalSize)
      throws PayloadException, NetworkException, ContactManagerException {
    mIsEstablished = true;
    if (sLogger.isActivated()) {
      sLogger.debug(
          new StringBuilder("SEND request received (flag=")
              .append(flag)
              .append(", transaction=")
              .append(txId)
              .append(", totalSize=")
              .append(totalSize)
              .append(")")
              .toString());
    }

    String msgId = headers.get(MsrpConstants.HEADER_MESSAGE_ID);
    boolean failureReportNeeded = true;
    String failureHeader = headers.get(MsrpConstants.HEADER_FAILURE_REPORT);
    if ((failureHeader != null) && failureHeader.equalsIgnoreCase("no")) {
      failureReportNeeded = false;
    }
    if (failureReportNeeded) {
      sendMsrpResponse(MsrpConstants.STATUS_200_OK, txId, headers);
    }
    if (data == null) {
      if (sLogger.isActivated()) {
        sLogger.debug("Empty chunk");
      }
      return;
    }
    mReceivedChunks.addChunk(data);

    if (flag == MsrpConstants.FLAG_LAST_CHUNK) {
      if (sLogger.isActivated()) {
        sLogger.info("Transfer terminated");
      }
      byte[] dataContent = mReceivedChunks.getReceivedData();
      mReceivedChunks.resetCache();

      String contentTypeHeader = headers.get(MsrpConstants.HEADER_CONTENT_TYPE);
      mMsrpEventListener.receiveMsrpData(msgId, dataContent, contentTypeHeader);

      boolean successReportNeeded = false;
      String reportHeader = headers.get(MsrpConstants.HEADER_SUCCESS_REPORT);
      if ((reportHeader != null) && reportHeader.equalsIgnoreCase("yes")) {
        successReportNeeded = true;
      }
      if (successReportNeeded) {
        sendMsrpReportRequest(txId, headers, dataContent.length, totalSize);
      }
    } else if (flag == MsrpConstants.FLAG_ABORT_CHUNK) {
      if (sLogger.isActivated()) {
        sLogger.info("Transfer aborted");
      }
      mMsrpEventListener.msrpTransferAborted();
    } else if (flag == MsrpConstants.FLAG_MORE_CHUNK) {
      if (sLogger.isActivated()) {
        sLogger.debug("Transfer in progress...");
      }
      byte[] dataContent = mReceivedChunks.getReceivedData();
      boolean resetCache =
          mMsrpEventListener.msrpTransferProgress(
              mReceivedChunks.getCurrentSize(), totalSize, dataContent);

      /*
       * Data are only consumed chunk by chunk in file transfer & image share. In a chat
       * session only the whole message is consumed after receiving the last chunk.
       */
      if (resetCache) {
        mReceivedChunks.resetCache();
      }
    }
  }
Example #3
0
  /**
   * Send chunks
   *
   * @param inputStream Input stream
   * @param msgId Message ID
   * @param contentType Content type to be sent
   * @param totalSize Total size of content
   * @param typeMsrpChunk Type of MSRP chunk
   * @throws NetworkException
   */
  public void sendChunks(
      InputStream inputStream,
      String msgId,
      String contentType,
      final long totalSize,
      TypeMsrpChunk typeMsrpChunk)
      throws NetworkException {
    if (sLogger.isActivated()) {
      sLogger.info("Send content (" + contentType + " - MSRP chunk type: " + typeMsrpChunk + ")");
    }
    this.mTotalSize = totalSize;
    try {
      byte data[] = new byte[MsrpConstants.CHUNK_MAX_SIZE];
      long firstByte = 1;
      long lastByte = 0;
      mCancelTransfer = false;
      if (mSuccessReportOption) {
        mReportTransaction = new ReportTransaction();
      } else {
        mReportTransaction = null;
      }
      if (mFailureReportOption) {
        mMsrpTransaction = new MsrpTransaction();
      } else {
        mMsrpTransaction = null;
      }

      // Changed by Deutsche Telekom
      // Calculate number of needed chunks
      final int totalChunks = (int) Math.ceil(totalSize / (double) MsrpConstants.CHUNK_MAX_SIZE);

      new Thread(
              new Runnable() {

                @Override
                public void run() {
                  if (mMsrpTransaction != null) {
                    while ((totalChunks - mMsrpTransaction.getNumberReceivedOk()) > 0
                        && !mCancelTransfer) {
                      mMsrpEventListener.msrpTransferProgress(
                          mMsrpTransaction.getNumberReceivedOk() * MsrpConstants.CHUNK_MAX_SIZE,
                          totalSize);
                      try {
                        Thread.sleep(500);
                      } catch (InterruptedException e) {
                        /* Nothing to be done here */
                      }
                    }
                  }
                }
              })
          .start();

      // Changed by Deutsche Telekom
      String newTransactionId = null;

      // Changed by Deutsche Telekom
      // RFC4975, section 7.1.1. Sending SEND Requests
      // When an endpoint has a message to deliver, it first generates a new
      // Message-ID. The value MUST be highly unlikely to be repeated by
      // another endpoint instance, or by the same instance in the future.
      // Message-ID value follows the definition in RFC4975, section 9
      String msrpMsgId = IdGenerator.generateMessageID();

      // Send data chunk by chunk
      for (int i = inputStream.read(data);
          (!mCancelTransfer) & (i > -1);
          i = inputStream.read(data)) {
        // Update upper byte range
        lastByte += i;

        // Changed by Deutsche Telekom
        newTransactionId = generateTransactionId();
        addMsrpTransactionInfo(newTransactionId, msrpMsgId, msgId, typeMsrpChunk);

        // Send a chunk
        // Changed by Deutsche Telekom
        sendMsrpSendRequest(
            newTransactionId,
            mTo,
            mFrom,
            msrpMsgId,
            contentType,
            i,
            data,
            firstByte,
            lastByte,
            totalSize);

        // Update lower byte range
        firstByte += i;

        // Progress management
        if (mFailureReportOption) {
          // Add value in progress vector
          mProgress.add(lastByte);
        } else {
          // Direct notification
          if (!mCancelTransfer) {
            mMsrpEventListener.msrpTransferProgress(lastByte, totalSize);
          }
        }
      }

      if (mCancelTransfer) {
        // Transfer has been aborted
        return;
      }

      // Waiting msrpTransaction
      if (mMsrpTransaction != null) {
        // Wait until all data have been reported
        mMsrpTransaction.waitAllResponses();

        // Notify event listener
        if (mMsrpTransaction.isAllResponsesReceived()) {
          mMsrpEventListener.msrpDataTransfered(msgId);
        } else {
          if (!mMsrpTransaction.isTerminated()) {
            // Changed by Deutsche Telekom
            mMsrpEventListener.msrpTransferError(msgId, "response timeout 408", typeMsrpChunk);
          }
        }
      }

      // Waiting reportTransaction
      if (mReportTransaction != null) {
        // Wait until all data have been reported
        while (!mReportTransaction.isTransactionFinished(totalSize)) {
          mReportTransaction.waitReport();
          if (mReportTransaction.getStatusCode() != 200) {
            // Error
            break;
          }
        }

        // Notify event listener
        if (mReportTransaction.getStatusCode() == 200) {
          mMsrpEventListener.msrpDataTransfered(msgId);
        } else {
          // Changed by Deutsche Telekom
          mMsrpEventListener.msrpTransferError(
              msgId, "error report " + mReportTransaction.getStatusCode(), typeMsrpChunk);
        }
      }

      // No transaction
      if (mMsrpTransaction == null && mReportTransaction == null) {
        // Notify event listener
        mMsrpEventListener.msrpDataTransfered(msgId);
      }
    } catch (IOException e) {
      throw new NetworkException(
          new StringBuilder("Send chunk failed for msgId : ").append(msgId).toString(), e);

    } finally {
      CloseableUtils.tryToClose(inputStream);
    }
  }