예제 #1
0
  /** Close the session */
  public void close() {
    if (sLogger.isActivated()) {
      sLogger.debug("Close session");
    }

    // Cancel transfer
    mCancelTransfer = true;

    // Close the connection
    if (connection != null) {
      connection.close();
    }

    // Unblock request transaction
    if (mRequestTransaction != null) {
      mRequestTransaction.terminate();
    }

    // Unblock report transaction
    if (mReportTransaction != null) {
      mReportTransaction.terminate();
    }

    // Unblock MSRP transaction
    if (mMsrpTransaction != null) {
      mMsrpTransaction.terminate();
    }
  }
예제 #2
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
  }
예제 #3
0
  // Changed by Deutsche Telekom
  private void sendMsrpSendRequest(
      String txId,
      String to,
      String from,
      String msrpMsgId,
      String contentType,
      int dataSize,
      byte data[],
      long firstByte,
      long lastByte,
      long totalSize)
      throws NetworkException {
    ByteArrayOutputStream buffer = null;
    try {
      boolean isLastChunk = (lastByte == totalSize);
      // Create request
      buffer = new ByteArrayOutputStream(4000);
      buffer.reset();
      buffer.write(MsrpConstants.MSRP_HEADER.getBytes(UTF8));
      buffer.write(MsrpConstants.CHAR_SP);
      buffer.write(txId.getBytes(UTF8));
      buffer.write((" " + MsrpConstants.METHOD_SEND).getBytes(UTF8));
      buffer.write(NEW_LINE);

      String toHeader = MsrpConstants.HEADER_TO_PATH + ": " + to + MsrpConstants.NEW_LINE;
      buffer.write(toHeader.getBytes(UTF8));
      String fromHeader = MsrpConstants.HEADER_FROM_PATH + ": " + from + MsrpConstants.NEW_LINE;
      buffer.write(fromHeader.getBytes(UTF8));
      // Changed by Deutsche Telekom
      String msgIdHeader =
          MsrpConstants.HEADER_MESSAGE_ID + ": " + msrpMsgId + MsrpConstants.NEW_LINE;
      buffer.write(msgIdHeader.getBytes(UTF8));

      // Write byte range
      String byteRange =
          MsrpConstants.HEADER_BYTE_RANGE
              + ": "
              + firstByte
              + "-"
              + lastByte
              + "/"
              + totalSize
              + MsrpConstants.NEW_LINE;
      buffer.write(byteRange.getBytes(UTF8));

      // Write optional headers
      // Changed by Deutsche Telekom
      // According with GSMA guidelines
      if (mFailureReportOption) {
        String header = MsrpConstants.HEADER_FAILURE_REPORT + ": yes" + MsrpConstants.NEW_LINE;
        buffer.write(header.getBytes(UTF8));
      }
      if (mSuccessReportOption) {
        String header = MsrpConstants.HEADER_SUCCESS_REPORT + ": yes" + MsrpConstants.NEW_LINE;
        buffer.write(header.getBytes(UTF8));
      }

      // Write content type
      if (contentType != null) {
        String content =
            MsrpConstants.HEADER_CONTENT_TYPE + ": " + contentType + MsrpConstants.NEW_LINE;
        buffer.write(content.getBytes(UTF8));
      }

      // Write data
      if (data != null) {
        buffer.write(NEW_LINE);
        buffer.write(data, 0, dataSize);
        buffer.write(NEW_LINE);
      }

      // Write end of request
      buffer.write(MsrpConstants.END_MSRP_MSG.getBytes(UTF8));
      buffer.write(txId.getBytes(UTF8));
      if (isLastChunk) {
        // '$' -> last chunk
        buffer.write(MsrpConstants.FLAG_LAST_CHUNK);
      } else {
        // '+' -> more chunk
        buffer.write(MsrpConstants.FLAG_MORE_CHUNK);
      }
      buffer.write(NEW_LINE);

      // Send chunk
      if (mFailureReportOption) {
        if (mMsrpTransaction != null) {
          mMsrpTransaction.handleRequest();
          mRequestTransaction = null;
        } else {
          mRequestTransaction = new RequestTransaction(mRcsSettings);
        }
        connection.sendChunk(buffer.toByteArray());
        buffer.close();
        if (mRequestTransaction != null) {
          mRequestTransaction.waitResponse();
          if (!mRequestTransaction.isResponseReceived()) {
            throw new NetworkException("Failed to receive transaction response!");
          }
        }
      } else {
        connection.sendChunk(buffer.toByteArray());
        buffer.close();
        if (mMsrpTransaction != null) {
          mMsrpTransaction.handleRequest();
        }
      }
    } catch (IOException e) {
      throw new NetworkException("Failed to read chunk data!", e);

    } finally {
      CloseableUtils.tryToClose(buffer);
    }
  }
예제 #4
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);
    }
  }