Exemplo n.º 1
0
  /** Append header to mMessage. */
  private int appendHeader(int field) {
    switch (field) {
      case PduHeaders.MMS_VERSION:
        appendOctet(field);

        int version = mPduHeader.getOctet(field);
        if (0 == version) {
          appendShortInteger(PduHeaders.CURRENT_MMS_VERSION);
        } else {
          appendShortInteger(version);
        }

        break;

      case PduHeaders.MESSAGE_ID:
      case PduHeaders.TRANSACTION_ID:
        byte[] textString = mPduHeader.getTextString(field);
        if (null == textString) {
          return PDU_COMPOSE_FIELD_NOT_SET;
        }

        appendOctet(field);
        appendTextString(textString);
        break;

      case PduHeaders.TO:
      case PduHeaders.BCC:
      case PduHeaders.CC:
        EncodedStringValue[] addr = mPduHeader.getEncodedStringValues(field);

        if (null == addr) {
          return PDU_COMPOSE_FIELD_NOT_SET;
        }

        EncodedStringValue temp;
        for (int i = 0; i < addr.length; i++) {
          temp = appendAddressType(addr[i]);
          if (temp == null) {
            return PDU_COMPOSE_CONTENT_ERROR;
          }

          appendOctet(field);
          appendEncodedString(temp);
        }
        break;

      case PduHeaders.FROM:
        // Value-length (Address-present-token Encoded-string-value | Insert-address-token)
        appendOctet(field);

        EncodedStringValue from = mPduHeader.getEncodedStringValue(field);
        if ((from == null)
            || TextUtils.isEmpty(from.getString())
            || new String(from.getTextString()).equals(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR)) {
          // Length of from = 1
          append(1);
          // Insert-address-token = <Octet 129>
          append(PduHeaders.FROM_INSERT_ADDRESS_TOKEN);
        } else {
          mStack.newbuf();
          PositionMarker fstart = mStack.mark();

          // Address-present-token = <Octet 128>
          append(PduHeaders.FROM_ADDRESS_PRESENT_TOKEN);

          temp = appendAddressType(from);
          if (temp == null) {
            return PDU_COMPOSE_CONTENT_ERROR;
          }

          appendEncodedString(temp);

          int flen = fstart.getLength();
          mStack.pop();
          appendValueLength(flen);
          mStack.copy();
        }
        break;

      case PduHeaders.READ_STATUS:
      case PduHeaders.STATUS:
      case PduHeaders.REPORT_ALLOWED:
      case PduHeaders.PRIORITY:
      case PduHeaders.DELIVERY_REPORT:
      case PduHeaders.READ_REPORT:
        int octet = mPduHeader.getOctet(field);
        if (0 == octet) {
          return PDU_COMPOSE_FIELD_NOT_SET;
        }

        appendOctet(field);
        appendOctet(octet);
        break;

      case PduHeaders.DATE:
        long date = mPduHeader.getLongInteger(field);
        if (-1 == date) {
          return PDU_COMPOSE_FIELD_NOT_SET;
        }

        appendOctet(field);
        appendDateValue(date);
        break;

      case PduHeaders.SUBJECT:
        EncodedStringValue enString = mPduHeader.getEncodedStringValue(field);
        if (null == enString) {
          return PDU_COMPOSE_FIELD_NOT_SET;
        }

        appendOctet(field);
        appendEncodedString(enString);
        break;

      case PduHeaders.MESSAGE_CLASS:
        byte[] messageClass = mPduHeader.getTextString(field);
        if (null == messageClass) {
          return PDU_COMPOSE_FIELD_NOT_SET;
        }

        appendOctet(field);
        if (Arrays.equals(messageClass, PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes())) {
          appendOctet(PduHeaders.MESSAGE_CLASS_ADVERTISEMENT);
        } else if (Arrays.equals(messageClass, PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes())) {
          appendOctet(PduHeaders.MESSAGE_CLASS_AUTO);
        } else if (Arrays.equals(messageClass, PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes())) {
          appendOctet(PduHeaders.MESSAGE_CLASS_PERSONAL);
        } else if (Arrays.equals(
            messageClass, PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes())) {
          appendOctet(PduHeaders.MESSAGE_CLASS_INFORMATIONAL);
        } else {
          appendTextString(messageClass);
        }
        break;

      case PduHeaders.EXPIRY:
        long expiry = mPduHeader.getLongInteger(field);
        if (-1 == expiry) {
          return PDU_COMPOSE_FIELD_NOT_SET;
        }

        appendOctet(field);

        mStack.newbuf();
        PositionMarker expiryStart = mStack.mark();

        append(PduHeaders.VALUE_RELATIVE_TOKEN);
        appendLongInteger(expiry);

        int expiryLength = expiryStart.getLength();
        mStack.pop();
        appendValueLength(expiryLength);
        mStack.copy();
        break;

      default:
        return PDU_COMPOSE_FIELD_NOT_SUPPORTED;
    }

    return PDU_COMPOSE_SUCCESS;
  }
Exemplo n.º 2
0
  /**
   * Parse pdu headers.
   *
   * @param pduDataStream pdu data input stream
   * @return headers in PduHeaders structure, null when parse fail
   */
  protected PduHeaders parseHeaders(ByteArrayInputStream pduDataStream) {
    if (pduDataStream == null) {
      return null;
    }

    boolean keepParsing = true;
    PduHeaders headers = new PduHeaders();

    while (keepParsing && (pduDataStream.available() > 0)) {
      int headerField = extractByteValue(pduDataStream);
      switch (headerField) {
        case PduHeaders.MESSAGE_TYPE:
          {
            int messageType = extractByteValue(pduDataStream);
            switch (messageType) {
                // We don't support these kind of messages now.
              case PduHeaders.MESSAGE_TYPE_FORWARD_REQ:
              case PduHeaders.MESSAGE_TYPE_FORWARD_CONF:
              case PduHeaders.MESSAGE_TYPE_MBOX_STORE_REQ:
              case PduHeaders.MESSAGE_TYPE_MBOX_STORE_CONF:
              case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_REQ:
              case PduHeaders.MESSAGE_TYPE_MBOX_VIEW_CONF:
              case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_REQ:
              case PduHeaders.MESSAGE_TYPE_MBOX_UPLOAD_CONF:
              case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_REQ:
              case PduHeaders.MESSAGE_TYPE_MBOX_DELETE_CONF:
              case PduHeaders.MESSAGE_TYPE_MBOX_DESCR:
              case PduHeaders.MESSAGE_TYPE_DELETE_REQ:
              case PduHeaders.MESSAGE_TYPE_DELETE_CONF:
              case PduHeaders.MESSAGE_TYPE_CANCEL_REQ:
              case PduHeaders.MESSAGE_TYPE_CANCEL_CONF:
                return null;
            }
            try {
              headers.setOctet(messageType, headerField);
            } catch (IllegalArgumentException e) {
              log(
                  "Set invalid Octet value: "
                      + messageType
                      + " into the header filed: "
                      + headerField);
              return null;
            } catch (RuntimeException e) {
              log(headerField + "is not Octet header field!");
              return null;
            }
            break;
          }
          /* Octect value */
        case PduHeaders.REPORT_ALLOWED:
        case PduHeaders.ADAPTATION_ALLOWED:
        case PduHeaders.DELIVERY_REPORT:
        case PduHeaders.DRM_CONTENT:
        case PduHeaders.DISTRIBUTION_INDICATOR:
        case PduHeaders.QUOTAS:
        case PduHeaders.READ_REPORT:
        case PduHeaders.STORE:
        case PduHeaders.STORED:
        case PduHeaders.TOTALS:
        case PduHeaders.SENDER_VISIBILITY:
        case PduHeaders.READ_STATUS:
        case PduHeaders.CANCEL_STATUS:
        case PduHeaders.PRIORITY:
        case PduHeaders.STATUS:
        case PduHeaders.REPLY_CHARGING:
        case PduHeaders.MM_STATE:
        case PduHeaders.RECOMMENDED_RETRIEVAL_MODE:
        case PduHeaders.CONTENT_CLASS:
        case PduHeaders.RETRIEVE_STATUS:
        case PduHeaders.STORE_STATUS:
          /**
           * The following field has a different value when used in the M-Mbox-Delete.conf and
           * M-Delete.conf PDU. For now we ignore this fact, since we do not support these PDUs
           */
        case PduHeaders.RESPONSE_STATUS:
          {
            int value = extractByteValue(pduDataStream);

            try {
              headers.setOctet(value, headerField);
            } catch (IllegalArgumentException e) {
              log("Set invalid Octet value: " + value + " into the header filed: " + headerField);
              return null;
            } catch (RuntimeException e) {
              log(headerField + "is not Octet header field!");
              return null;
            }
            break;
          }

          /* Long-Integer */
        case PduHeaders.DATE:
        case PduHeaders.REPLY_CHARGING_SIZE:
        case PduHeaders.MESSAGE_SIZE:
          {
            try {
              long value = parseLongInteger(pduDataStream);
              headers.setLongInteger(value, headerField);
            } catch (RuntimeException e) {
              log(headerField + "is not Long-Integer header field!");
              return null;
            }
            break;
          }

          /* Integer-Value */
        case PduHeaders.MESSAGE_COUNT:
        case PduHeaders.START:
        case PduHeaders.LIMIT:
          {
            try {
              long value = parseIntegerValue(pduDataStream);
              headers.setLongInteger(value, headerField);
            } catch (RuntimeException e) {
              log(headerField + "is not Long-Integer header field!");
              return null;
            }
            break;
          }

          /* Text-String */
        case PduHeaders.TRANSACTION_ID:
        case PduHeaders.REPLY_CHARGING_ID:
        case PduHeaders.AUX_APPLIC_ID:
        case PduHeaders.APPLIC_ID:
        case PduHeaders.REPLY_APPLIC_ID:
          /**
           * The next three header fields are email addresses as defined in RFC2822, not including
           * the characters "<" and ">"
           */
        case PduHeaders.MESSAGE_ID:
        case PduHeaders.REPLACE_ID:
        case PduHeaders.CANCEL_ID:
          /**
           * The following field has a different value when used in the M-Mbox-Delete.conf and
           * M-Delete.conf PDU. For now we ignore this fact, since we do not support these PDUs
           */
        case PduHeaders.CONTENT_LOCATION:
          {
            byte[] value = parseWapString(pduDataStream, TYPE_TEXT_STRING);
            if (null != value) {
              try {
                headers.setTextString(value, headerField);
              } catch (NullPointerException e) {
                log("null pointer error!");
              } catch (RuntimeException e) {
                log(headerField + "is not Text-String header field!");
                return null;
              }
            }
            break;
          }

          /* Encoded-string-value */
        case PduHeaders.SUBJECT:
        case PduHeaders.RECOMMENDED_RETRIEVAL_MODE_TEXT:
        case PduHeaders.RETRIEVE_TEXT:
        case PduHeaders.STATUS_TEXT:
        case PduHeaders.STORE_STATUS_TEXT:
          /* the next one is not support
           * M-Mbox-Delete.conf and M-Delete.conf now */
        case PduHeaders.RESPONSE_TEXT:
          {
            EncodedStringValue value = parseEncodedStringValue(pduDataStream);
            if (null != value) {
              try {
                headers.setEncodedStringValue(value, headerField);
              } catch (NullPointerException e) {
                log("null pointer error!");
              } catch (RuntimeException e) {
                log(headerField + "is not Encoded-String-Value header field!");
                return null;
              }
            }
            break;
          }

          /* Addressing model */
        case PduHeaders.BCC:
        case PduHeaders.CC:
        case PduHeaders.TO:
          {
            EncodedStringValue value = parseEncodedStringValue(pduDataStream);
            if (null != value) {
              byte[] address = value.getTextString();
              if (null != address) {
                String str = new String(address);
                int endIndex = str.indexOf("/");
                if (endIndex > 0) {
                  str = str.substring(0, endIndex);
                }
                try {
                  value.setTextString(str.getBytes());
                } catch (NullPointerException e) {
                  log("null pointer error!");
                  return null;
                }
              }

              try {
                headers.appendEncodedStringValue(value, headerField);
              } catch (NullPointerException e) {
                log("null pointer error!");
              } catch (RuntimeException e) {
                log(headerField + "is not Encoded-String-Value header field!");
                return null;
              }
            }
            break;
          }

          /* Value-length
           * (Absolute-token Date-value | Relative-token Delta-seconds-value) */
        case PduHeaders.DELIVERY_TIME:
        case PduHeaders.EXPIRY:
        case PduHeaders.REPLY_CHARGING_DEADLINE:
          {
            /* parse Value-length */
            parseValueLength(pduDataStream);

            /* Absolute-token or Relative-token */
            int token = extractByteValue(pduDataStream);

            /* Date-value or Delta-seconds-value */
            long timeValue;
            try {
              timeValue = parseLongInteger(pduDataStream);
            } catch (RuntimeException e) {
              log(headerField + "is not Long-Integer header field!");
              return null;
            }
            if (PduHeaders.VALUE_RELATIVE_TOKEN == token) {
              /* need to convert the Delta-seconds-value
               * into Date-value */
              timeValue = System.currentTimeMillis() / 1000 + timeValue;
            }

            try {
              headers.setLongInteger(timeValue, headerField);
            } catch (RuntimeException e) {
              log(headerField + "is not Long-Integer header field!");
              return null;
            }
            break;
          }

        case PduHeaders.FROM:
          {
            /* From-value =
             * Value-length
             * (Address-present-token Encoded-string-value | Insert-address-token)
             */
            EncodedStringValue from = null;
            parseValueLength(pduDataStream); /* parse value-length */

            /* Address-present-token or Insert-address-token */
            int fromToken = extractByteValue(pduDataStream);

            /* Address-present-token or Insert-address-token */
            if (PduHeaders.FROM_ADDRESS_PRESENT_TOKEN == fromToken) {
              /* Encoded-string-value */
              from = parseEncodedStringValue(pduDataStream);
              if (null != from) {
                byte[] address = from.getTextString();
                if (null != address) {
                  String str = new String(address);
                  int endIndex = str.indexOf("/");
                  if (endIndex > 0) {
                    str = str.substring(0, endIndex);
                  }
                  try {
                    from.setTextString(str.getBytes());
                  } catch (NullPointerException e) {
                    log("null pointer error!");
                    return null;
                  }
                }
              }
            } else {
              try {
                from = new EncodedStringValue(PduHeaders.FROM_INSERT_ADDRESS_TOKEN_STR.getBytes());
              } catch (NullPointerException e) {
                log(headerField + "is not Encoded-String-Value header field!");
                return null;
              }
            }

            try {
              headers.setEncodedStringValue(from, PduHeaders.FROM);
            } catch (NullPointerException e) {
              log("null pointer error!");
            } catch (RuntimeException e) {
              log(headerField + "is not Encoded-String-Value header field!");
              return null;
            }
            break;
          }

        case PduHeaders.MESSAGE_CLASS:
          {
            /* Message-class-value = Class-identifier | Token-text */
            pduDataStream.mark(1);
            int messageClass = extractByteValue(pduDataStream);

            if (messageClass >= PduHeaders.MESSAGE_CLASS_PERSONAL) {
              /* Class-identifier */
              try {
                if (PduHeaders.MESSAGE_CLASS_PERSONAL == messageClass) {
                  headers.setTextString(
                      PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes(), PduHeaders.MESSAGE_CLASS);
                } else if (PduHeaders.MESSAGE_CLASS_ADVERTISEMENT == messageClass) {
                  headers.setTextString(
                      PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR.getBytes(),
                      PduHeaders.MESSAGE_CLASS);
                } else if (PduHeaders.MESSAGE_CLASS_INFORMATIONAL == messageClass) {
                  headers.setTextString(
                      PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR.getBytes(),
                      PduHeaders.MESSAGE_CLASS);
                } else if (PduHeaders.MESSAGE_CLASS_AUTO == messageClass) {
                  headers.setTextString(
                      PduHeaders.MESSAGE_CLASS_AUTO_STR.getBytes(), PduHeaders.MESSAGE_CLASS);
                }
              } catch (NullPointerException e) {
                log("null pointer error!");
              } catch (RuntimeException e) {
                log(headerField + "is not Text-String header field!");
                return null;
              }
            } else {
              /* Token-text */
              pduDataStream.reset();
              byte[] messageClassString = parseWapString(pduDataStream, TYPE_TEXT_STRING);
              if (null != messageClassString) {
                try {
                  headers.setTextString(messageClassString, PduHeaders.MESSAGE_CLASS);
                } catch (NullPointerException e) {
                  log("null pointer error!");
                } catch (RuntimeException e) {
                  log(headerField + "is not Text-String header field!");
                  return null;
                }
              }
            }
            break;
          }

        case PduHeaders.MMS_VERSION:
          {
            int version = parseShortInteger(pduDataStream);

            try {
              headers.setOctet(version, PduHeaders.MMS_VERSION);
            } catch (IllegalArgumentException e) {
              log("Set invalid Octet value: " + version + " into the header filed: " + headerField);
              return null;
            } catch (RuntimeException e) {
              log(headerField + "is not Octet header field!");
              return null;
            }
            break;
          }

        case PduHeaders.PREVIOUSLY_SENT_BY:
          {
            /* Previously-sent-by-value =
             * Value-length Forwarded-count-value Encoded-string-value */
            /* parse value-length */
            parseValueLength(pduDataStream);

            /* parse Forwarded-count-value */
            try {
              parseIntegerValue(pduDataStream);
            } catch (RuntimeException e) {
              log(headerField + " is not Integer-Value");
              return null;
            }

            /* parse Encoded-string-value */
            EncodedStringValue previouslySentBy = parseEncodedStringValue(pduDataStream);
            if (null != previouslySentBy) {
              try {
                headers.setEncodedStringValue(previouslySentBy, PduHeaders.PREVIOUSLY_SENT_BY);
              } catch (NullPointerException e) {
                log("null pointer error!");
              } catch (RuntimeException e) {
                log(headerField + "is not Encoded-String-Value header field!");
                return null;
              }
            }
            break;
          }

        case PduHeaders.PREVIOUSLY_SENT_DATE:
          {
            /* Previously-sent-date-value =
             * Value-length Forwarded-count-value Date-value */
            /* parse value-length */
            parseValueLength(pduDataStream);

            /* parse Forwarded-count-value */
            try {
              parseIntegerValue(pduDataStream);
            } catch (RuntimeException e) {
              log(headerField + " is not Integer-Value");
              return null;
            }

            /* Date-value */
            try {
              long perviouslySentDate = parseLongInteger(pduDataStream);
              headers.setLongInteger(perviouslySentDate, PduHeaders.PREVIOUSLY_SENT_DATE);
            } catch (RuntimeException e) {
              log(headerField + "is not Long-Integer header field!");
              return null;
            }
            break;
          }

        case PduHeaders.MM_FLAGS:
          {
            /* MM-flags-value =
             * Value-length
             * ( Add-token | Remove-token | Filter-token )
             * Encoded-string-value
             */

            /* parse Value-length */
            parseValueLength(pduDataStream);

            /* Add-token | Remove-token | Filter-token */
            extractByteValue(pduDataStream);

            /* Encoded-string-value */
            parseEncodedStringValue(pduDataStream);

            /* not store this header filed in "headers",
             * because now PduHeaders doesn't support it */
            break;
          }

          /* Value-length
           * (Message-total-token | Size-total-token) Integer-Value */
        case PduHeaders.MBOX_TOTALS:
        case PduHeaders.MBOX_QUOTAS:
          {
            /* Value-length */
            parseValueLength(pduDataStream);

            /* Message-total-token | Size-total-token */
            extractByteValue(pduDataStream);

            /*Integer-Value*/
            try {
              parseIntegerValue(pduDataStream);
            } catch (RuntimeException e) {
              log(headerField + " is not Integer-Value");
              return null;
            }

            /* not store these headers filed in "headers",
            because now PduHeaders doesn't support them */
            break;
          }

        case PduHeaders.ELEMENT_DESCRIPTOR:
          {
            parseContentType(pduDataStream, null);

            /* not store this header filed in "headers",
            because now PduHeaders doesn't support it */
            break;
          }

        case PduHeaders.CONTENT_TYPE:
          {
            HashMap<Integer, Object> map = new HashMap<Integer, Object>();
            byte[] contentType = parseContentType(pduDataStream, map);

            if (null != contentType) {
              try {
                headers.setTextString(contentType, PduHeaders.CONTENT_TYPE);
              } catch (NullPointerException e) {
                log("null pointer error!");
              } catch (RuntimeException e) {
                log(headerField + "is not Text-String header field!");
                return null;
              }
            }

            keepParsing = false;
            break;
          }

        case PduHeaders.CONTENT:
        case PduHeaders.ADDITIONAL_HEADERS:
        case PduHeaders.ATTRIBUTES:
        default:
          {
            log("Unknown header");
          }
      }
    }

    return headers;
  }