Ejemplo n.º 1
0
  /**
   * WAP PDU解析 (基本ぱくり)
   *
   * <p>frameworks/base/telephony/java/com/android/internal/telephony/WapPushOverSms.java
   * WapPushOverSms#dispatchWapPdu()
   *
   * @return true:解析成功
   */
  public boolean decode() {
    if (dataIndex < 0) {
      WspTypeDecoder pduDecoder = new WspTypeDecoder(wapData);

      int index = 0;
      int transactionId = wapData[index++] & 0xFF;
      int pduType = wapData[index++] & 0xFF;
      int headerLength = 0;

      try {
        if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH)
            && (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
          errorMessage = "WapPdu: non-PUSH WAP PDU. Type = " + pduType;
          return false;
        }

        pduDecoder = new WspTypeDecoder(wapData);

        /**
         * Parse HeaderLen(unsigned integer). From wap-230-wsp-20010705-a section 8.1.2 The maximum
         * size of a uintvar is 32 bits. So it will be encoded in no more than 5 octets.
         */
        if (pduDecoder.decodeUintvarInteger(index) == false) {
          errorMessage = "WapPdu: Header Length error.";
          return false;
        }
        headerLength = (int) pduDecoder.getValue32();
        index += pduDecoder.getDecodedDataLength();

        int headerStartIndex = index;

        /**
         * Parse Content-Type. From wap-230-wsp-20010705-a section 8.4.2.24
         *
         * <p>Content-type-value = Constrained-media | Content-general-form Content-general-form =
         * Value-length Media-type Media-type = (Well-known-media | Extension-Media) *(Parameter)
         * Value-length = Short-length | (Length-quote Length) Short-length = <Any octet 0-30>
         * (octet <= WAP_PDU_SHORT_LENGTH_MAX) Length-quote = <Octet 31> (WAP_PDU_LENGTH_QUOTE)
         * Length = Uintvar-integer
         */
        if (pduDecoder.decodeContentType(index) == false) {
          errorMessage = "WapPdu: Header Content-Type error.";
          return false;
        }
        contentType = pduDecoder.getValueString();
        if (contentType == null) {
          binaryContentType = (int) pduDecoder.getValue32();
          contentType = convertMap(CONTENTTYPES, binaryContentType);
        } else {
          binaryContentType = convertMap(CONTENTTYPES, contentType);
        }
        index += pduDecoder.getDecodedDataLength();
        dataIndex = headerStartIndex + headerLength;

        /**
         * Parse X-Wap-Application-Id. From wap-230-wsp-20010705-a section 8.4.2.54
         *
         * <p>Application-id-value = Uri-value | App-assigned-code App-assigned-code = Integer-value
         */
        if (wapData[index] == 0xaf - 0x100) {
          if (pduDecoder.decodeXWapApplicationId(index + 1) == false) {
            errorMessage = "WapPdu: Header X-Wap-Application-Id error.";
            return false;
          }
          applicationId = pduDecoder.getValueString();
          if (applicationId == null) {
            binaryApplicationId = (int) pduDecoder.getValue32();
            applicationId = convertMap(APPIDS, binaryApplicationId);
          } else {
            binaryApplicationId = convertMap(APPIDS, applicationId);
          }
          index += pduDecoder.getDecodedDataLength() + 1;
        } else {
          errorMessage = "WapPdu: Header X-Wap-Application-Id not present." + wapData[index];
          return false;
        }
      } catch (IndexOutOfBoundsException e) {
        errorMessage = "WapPdu: PDU decode error.";
        return false;
      }
    }
    decodeBody();
    return true;
  }