summaryrefslogtreecommitdiffstats
path: root/telephony
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-02-20 07:38:31 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-02-20 07:38:31 -0800
commit15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b (patch)
treed03d027a7ed97af616904e02a7b420babf40d44f /telephony
parent3001a035439d8134a7d70d796376d1dfbff3cdcd (diff)
downloadframeworks_base-15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b.zip
frameworks_base-15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b.tar.gz
frameworks_base-15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b.tar.bz2
auto import from //branches/cupcake/...@132569
Diffstat (limited to 'telephony')
-rw-r--r--telephony/java/com/android/internal/telephony/WapPushOverSms.java211
-rw-r--r--telephony/java/com/android/internal/telephony/WspTypeDecoder.java344
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java157
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java79
4 files changed, 609 insertions, 182 deletions
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
new file mode 100644
index 0000000..66fa943
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.content.Intent;
+import android.provider.Telephony.Sms.Intents;
+import android.util.Config;
+import android.util.Log;
+import com.android.internal.telephony.gsm.GSMPhone;
+import com.android.internal.telephony.gsm.SimUtils;
+
+
+/**
+ * WAP push handler class.
+ *
+ * @hide
+ */
+public class WapPushOverSms {
+ private static final String LOG_TAG = "WAP PUSH";
+
+ private final GSMPhone mPhone;
+ private WspTypeDecoder pduDecoder;
+
+
+ public WapPushOverSms(GSMPhone phone) {
+ mPhone = phone;
+ }
+
+ /**
+ * Dispatches inbound messages that are in the WAP PDU format. See
+ * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
+ *
+ * @param pdu The WAP PDU, made up of one or more SMS PDUs
+ */
+ public void dispatchWapPdu(byte[] pdu) {
+
+ if (Config.LOGD) Log.d(LOG_TAG, "Rx: " + SimUtils.bytesToHexString(pdu));
+
+ int index = 0;
+ int transactionId = pdu[index++] & 0xFF;
+ int pduType = pdu[index++] & 0xFF;
+ int headerLength = 0;
+
+ if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) &&
+ (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) {
+ if (Config.LOGD) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
+ return;
+ }
+
+ pduDecoder = new WspTypeDecoder(pdu);
+
+ /**
+ * 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) {
+ if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Length error.");
+ return;
+ }
+ headerLength = (int)pduDecoder.getValue32();
+ index += pduDecoder.getDecodedDataLength();
+
+ int headerStartIndex = index;
+
+ /**
+ * Parse Content-Type.
+ * From wap-230-wsp-20010705-a section 8.4.2.24
+ *
+ * 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) {
+ if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
+ return;
+ }
+ int binaryContentType;
+ String mimeType = pduDecoder.getValueString();
+ if (mimeType == null) {
+ binaryContentType = (int)pduDecoder.getValue32();
+ switch (binaryContentType) {
+ case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML:
+ mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML;
+ break;
+ case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML:
+ mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML;
+ break;
+ case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI:
+ mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI;
+ break;
+ case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL:
+ mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL;
+ break;
+ case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO:
+ mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO;
+ break;
+ case WspTypeDecoder.CONTENT_TYPE_B_MMS:
+ mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS;
+ break;
+ default:
+ if (Config.LOGD) {
+ Log.w(LOG_TAG,
+ "Received PDU. Unsupported Content-Type = " + binaryContentType);
+ }
+ return;
+ }
+ } else {
+ if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML)) {
+ binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML;
+ } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML)) {
+ binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML;
+ } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI)) {
+ binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI;
+ } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL)) {
+ binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL;
+ } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO)) {
+ binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO;
+ } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS)) {
+ binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_MMS;
+ } else {
+ if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Unknown Content-Type = " + mimeType);
+ return;
+ }
+ }
+ index += pduDecoder.getDecodedDataLength();
+
+ int dataIndex = headerStartIndex + headerLength;
+ boolean dispatchedByApplication = false;
+ switch (binaryContentType) {
+ case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO:
+ dispatchWapPdu_PushCO(pdu, transactionId, pduType);
+ dispatchedByApplication = true;
+ break;
+ case WspTypeDecoder.CONTENT_TYPE_B_MMS:
+ dispatchWapPdu_MMS(pdu, transactionId, pduType, dataIndex);
+ dispatchedByApplication = true;
+ break;
+ default:
+ break;
+ }
+ if (dispatchedByApplication == false) {
+ dispatchWapPdu_default(pdu, transactionId, pduType, mimeType, dataIndex);
+ }
+ }
+
+
+
+ private void dispatchWapPdu_default(
+ byte[] pdu, int transactionId, int pduType, String mimeType, int dataIndex) {
+ byte[] data;
+
+ data = new byte[pdu.length - dataIndex];
+ System.arraycopy(pdu, dataIndex, data, 0, data.length);
+
+ Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
+ intent.setType(mimeType);
+ intent.putExtra("transactionId", transactionId);
+ intent.putExtra("pduType", pduType);
+ intent.putExtra("data", data);
+
+ mPhone.getContext().sendBroadcast(
+ intent, "android.permission.RECEIVE_WAP_PUSH");
+ }
+
+ private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType) {
+ Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
+ intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO);
+ intent.putExtra("transactionId", transactionId);
+ intent.putExtra("pduType", pduType);
+ intent.putExtra("data", pdu);
+
+ mPhone.getContext().sendBroadcast(
+ intent, "android.permission.RECEIVE_WAP_PUSH");
+ }
+
+ private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType, int dataIndex) {
+ byte[] data;
+
+ data = new byte[pdu.length - dataIndex];
+ System.arraycopy(pdu, dataIndex, data, 0, data.length);
+
+ Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
+ intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS);
+ intent.putExtra("transactionId", transactionId);
+ intent.putExtra("pduType", pduType);
+ intent.putExtra("data", data);
+
+ mPhone.getContext().sendBroadcast(
+ intent, "android.permission.RECEIVE_MMS");
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
new file mode 100644
index 0000000..2984fa8
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+
+/**
+ * Implement the WSP data type decoder.
+ *
+ * @hide
+ */
+public class WspTypeDecoder {
+
+ private static final int WAP_PDU_SHORT_LENGTH_MAX = 30;
+ private static final int WAP_PDU_LENGTH_QUOTE = 31;
+
+ public static final int PDU_TYPE_PUSH = 0x06;
+ public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07;
+
+ public static final int CONTENT_TYPE_B_DRM_RIGHTS_XML = 0x4a;
+ public static final int CONTENT_TYPE_B_DRM_RIGHTS_WBXML = 0x4b;
+ public static final int CONTENT_TYPE_B_PUSH_SI = 0x2e;
+ public static final int CONTENT_TYPE_B_PUSH_SL = 0x30;
+ public static final int CONTENT_TYPE_B_PUSH_CO = 0x32;
+ public static final int CONTENT_TYPE_B_MMS = 0x3e;
+
+ public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML =
+ "application/vnd.oma.drm.rights+xml";
+ public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML =
+ "application/vnd.oma.drm.rights+wbxml";
+ public static final String CONTENT_MIME_TYPE_B_PUSH_SI = "application/vnd.wap.sic";
+ public static final String CONTENT_MIME_TYPE_B_PUSH_SL = "application/vnd.wap.slc";
+ public static final String CONTENT_MIME_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
+ public static final String CONTENT_MIME_TYPE_B_MMS = "application/vnd.wap.mms-message";
+
+ public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
+
+
+ byte[] wspData;
+ int dataLength;
+ long unsigned32bit;
+ String stringValue;
+
+ public WspTypeDecoder(byte[] pdu) {
+ wspData = pdu;
+ }
+
+ /**
+ * Decode the "Text-string" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Text-string" in this pdu
+ *
+ * @return false when error(not a Text-string) occur
+ * return value can be retrieved by getValueString() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeTextString(int startIndex) {
+ int index = startIndex;
+ while (wspData[index] != 0) {
+ index++;
+ }
+ dataLength = index - startIndex + 1;
+ if (wspData[startIndex] == 127) {
+ stringValue = new String(wspData, startIndex+1, dataLength - 2);
+ } else {
+ stringValue = new String(wspData, startIndex, dataLength - 1);
+ }
+ return true;
+ }
+
+ /**
+ * Decode the "Short-integer" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Short-integer" in this pdu
+ *
+ * @return false when error(not a Short-integer) occur
+ * return value can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeShortInteger(int startIndex) {
+ if ((wspData[startIndex] & 0x80) == 0) {
+ return false;
+ }
+ unsigned32bit = wspData[startIndex] & 0x7f;
+ dataLength = 1;
+ return true;
+ }
+
+ /**
+ * Decode the "Long-integer" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Long-integer" in this pdu
+ *
+ * @return false when error(not a Long-integer) occur
+ * return value can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeLongInteger(int startIndex) {
+ int lengthMultiOctet = wspData[startIndex] & 0xff;
+
+ if (lengthMultiOctet > WAP_PDU_SHORT_LENGTH_MAX) {
+ return false;
+ }
+ unsigned32bit = 0;
+ for (int i=1; i<=lengthMultiOctet; i++) {
+ unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex+i] & 0xff);
+ }
+ dataLength = 1+lengthMultiOctet;
+ return true;
+ }
+
+ /**
+ * Decode the "Integer-Value" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Integer-Value" in this pdu
+ *
+ * @return false when error(not a Integer-Value) occur
+ * return value can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeIntegerValue(int startIndex) {
+ if (decodeShortInteger(startIndex) == true) {
+ return true;
+ }
+ return decodeLongInteger(startIndex);
+ }
+
+ /**
+ * Decode the "Uintvar-integer" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Uintvar-integer" in this pdu
+ *
+ * @return false when error(not a Uintvar-integer) occur
+ * return value can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeUintvarInteger(int startIndex) {
+ int index = startIndex;
+
+ unsigned32bit = 0;
+ while ((wspData[index] & 0x80) != 0) {
+ if ((index - startIndex) >= 4) {
+ return false;
+ }
+ unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f);
+ index++;
+ }
+ unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f);
+ dataLength = index - startIndex + 1;
+ return true;
+ }
+
+ /**
+ * Decode the "Value-length" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Value-length" in this pdu
+ *
+ * @return false when error(not a Value-length) occur
+ * return value can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeValueLength(int startIndex) {
+ if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) {
+ return false;
+ }
+ if (wspData[startIndex] < WAP_PDU_LENGTH_QUOTE) {
+ unsigned32bit = wspData[startIndex];
+ dataLength = 1;
+ } else {
+ decodeUintvarInteger(startIndex+1);
+ dataLength ++;
+ }
+ return true;
+ }
+
+ /**
+ * Decode the "Extension-media" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Extension-media" in this pdu
+ *
+ * @return false when error(not a Extension-media) occur
+ * return value can be retrieved by getValueString() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeExtensionMedia(int startIndex) {
+ int index = startIndex;
+ while (wspData[index] != 0) {
+ index++;
+ }
+ dataLength = index - startIndex + 1;
+ stringValue = new String(wspData, startIndex, dataLength - 1);
+ return true;
+ }
+
+ /**
+ * Decode the "Constrained-encoding" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Constrained-encoding" in this pdu
+ *
+ * @return false when error(not a Constrained-encoding) occur
+ * return value can be retrieved first by getValueString() and second by getValue32() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeConstrainedEncoding(int startIndex) {
+ if (decodeShortInteger(startIndex) == true) {
+ stringValue = null;
+ return true;
+ }
+ return decodeExtensionMedia(startIndex);
+ }
+
+ /**
+ * Decode the "Content-type" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Content-type" in this pdu
+ *
+ * @return false when error(not a Content-type) occur
+ * return value can be retrieved first by getValueString() and second by getValue32()
+ * method length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeContentType(int startIndex) {
+ int mediaPrefixLength;
+ long mediaFieldLength;
+
+ if (decodeValueLength(startIndex) == false) {
+ return decodeConstrainedEncoding(startIndex);
+ }
+ mediaPrefixLength = getDecodedDataLength();
+ mediaFieldLength = getValue32();
+ if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
+ dataLength += mediaPrefixLength;
+ stringValue = null;
+ return true;
+ }
+ if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
+ dataLength += mediaPrefixLength;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Decode the "Content length" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Content length" in this pdu
+ *
+ * @return false when error(not a Content length) occur
+ * return value can be retrieved by getValue32() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeContentLength(int startIndex) {
+ return decodeIntegerValue(startIndex);
+ }
+
+ /**
+ * Decode the "Content location" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Content location" in this pdu
+ *
+ * @return false when error(not a Content location) occur
+ * return value can be retrieved by getValueString() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeContentLocation(int startIndex) {
+ return decodeTextString(startIndex);
+ }
+
+ /**
+ * Decode the "X-Wap-Application-Id" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "X-Wap-Application-Id" in this pdu
+ *
+ * @return false when error(not a X-Wap-Application-Id) occur
+ * return value can be retrieved first by getValueString() and second by getValue32()
+ * method length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeXWapApplicationId(int startIndex) {
+ if (decodeIntegerValue(startIndex) == true) {
+ stringValue = null;
+ return true;
+ }
+ return decodeTextString(startIndex);
+ }
+
+ /**
+ * Decode the "X-Wap-Content-URI" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "X-Wap-Content-URI" in this pdu
+ *
+ * @return false when error(not a X-Wap-Content-URI) occur
+ * return value can be retrieved by getValueString() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeXWapContentURI(int startIndex) {
+ return decodeTextString(startIndex);
+ }
+
+ /**
+ * Decode the "X-Wap-Initiator-URI" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "X-Wap-Initiator-URI" in this pdu
+ *
+ * @return false when error(not a X-Wap-Initiator-URI) occur
+ * return value can be retrieved by getValueString() method
+ * length of data in pdu can be retrieved by getValue32() method
+ */
+ public boolean decodeXWapInitiatorURI(int startIndex) {
+ return decodeTextString(startIndex);
+ }
+
+ /**
+ * The data length of latest operation.
+ */
+ public int getDecodedDataLength() {
+ return dataLength;
+ }
+
+ /**
+ * The 32-bits result of latest operation.
+ */
+ public long getValue32() {
+ return unsigned32bit;
+ }
+
+ /**
+ * The String result of latest operation.
+ */
+ public String getValueString() {
+ return stringValue;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java
index 4176004..6eea1d4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java
@@ -37,6 +37,7 @@ import android.provider.Settings;
import android.provider.Telephony.Sms.Intents;
import android.telephony.gsm.SmsMessage;
import android.telephony.gsm.SmsManager;
+import com.android.internal.telephony.WapPushOverSms;
import android.telephony.ServiceState;
import android.util.Config;
import com.android.internal.util.HexDump;
@@ -62,37 +63,6 @@ final class SMSDispatcher extends Handler {
/** Default timeout for SMS sent query */
private static final int DEFAULT_SMS_TIMOUEOUT = 6000;
- private static final int WAP_PDU_TYPE_PUSH = 0x06;
-
- private static final int WAP_PDU_TYPE_CONFIRMED_PUSH = 0x07;
-
- private static final byte DRM_RIGHTS_XML = (byte)0xca;
-
- private static final String DRM_RIGHTS_XML_MIME_TYPE = "application/vnd.oma.drm.rights+xml";
-
- private static final byte DRM_RIGHTS_WBXML = (byte)0xcb;
-
- private static final String DRM_RIGHTS_WBXML_MIME_TYPE =
- "application/vnd.oma.drm.rights+wbxml";
-
- private static final byte WAP_SI_MIME_PORT = (byte)0xae;
-
- private static final String WAP_SI_MIME_TYPE = "application/vnd.wap.sic";
-
- private static final byte WAP_SL_MIME_PORT = (byte)0xb0;
-
- private static final String WAP_SL_MIME_TYPE = "application/vnd.wap.slc";
-
- private static final byte WAP_CO_MIME_PORT = (byte)0xb2;
-
- private static final String WAP_CO_MIME_TYPE = "application/vnd.wap.coc";
-
- private static final int WAP_PDU_SHORT_LENGTH_MAX = 30;
-
- private static final int WAP_PDU_LENGTH_QUOTE = 31;
-
- private static final String MMS_MIME_TYPE = "application/vnd.wap.mms-message";
-
private static final String[] RAW_PROJECTION = new String[] {
"pdu",
"sequence",
@@ -124,6 +94,8 @@ final class SMSDispatcher extends Handler {
private final GSMPhone mPhone;
+ private final WapPushOverSms mWapPush;
+
private final Context mContext;
private final ContentResolver mResolver;
@@ -208,6 +180,7 @@ final class SMSDispatcher extends Handler {
SMSDispatcher(GSMPhone phone) {
mPhone = phone;
+ mWapPush = new WapPushOverSms(phone);
mContext = phone.getContext();
mResolver = mContext.getContentResolver();
mCm = phone.mCM;
@@ -538,7 +511,7 @@ final class SMSDispatcher extends Handler {
if (destPort != -1) {
if (destPort == SmsHeader.PORT_WAP_PUSH) {
- dispatchWapPdu(sms.getUserData());
+ mWapPush.dispatchWapPdu(sms.getUserData());
}
// The message was sent to a port, so concoct a URI for it
dispatchPortAddressedPdus(pdus, destPort);
@@ -621,7 +594,7 @@ final class SMSDispatcher extends Handler {
}
// Handle the PUSH
- dispatchWapPdu(output.toByteArray());
+ mWapPush.dispatchWapPdu(output.toByteArray());
break;
}
@@ -663,122 +636,6 @@ final class SMSDispatcher extends Handler {
intent, "android.permission.RECEIVE_SMS");
}
- /**
- * Dispatches inbound messages that are in the WAP PDU format. See
- * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
- *
- * @param pdu The WAP PDU, made up of one or more SMS PDUs
- */
- private void dispatchWapPdu(byte[] pdu) {
- int index = 0;
- int transactionId = pdu[index++] & 0xFF;
- int pduType = pdu[index++] & 0xFF;
- int headerLength = 0;
-
- if ((pduType != WAP_PDU_TYPE_PUSH) &&
- (pduType != WAP_PDU_TYPE_CONFIRMED_PUSH)) {
- Log.w(TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
- return;
- }
-
- /**
- * 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.
- */
- int temp = 0;
- do {
- temp = pdu[index++];
- headerLength = headerLength << 7;
- headerLength |= temp & 0x7F;
- } while ((temp & 0x80) != 0);
-
- int headerStartIndex = index;
-
- /**
- * Parse Content-Type.
- * From wap-230-wsp-20010705-a section 8.4.2.24
- *
- * 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
- */
- // Parse Value-length.
- if ((pdu[index] & 0xff) <= WAP_PDU_SHORT_LENGTH_MAX) {
- // Short-length.
- index++;
- } else if (pdu[index] == WAP_PDU_LENGTH_QUOTE) {
- // Skip Length-quote.
- index++;
- // Skip Length.
- // Now we assume 8bit is enough to store the content-type length.
- index++;
- }
- String mimeType;
- switch (pdu[headerStartIndex])
- {
- case DRM_RIGHTS_XML:
- mimeType = DRM_RIGHTS_XML_MIME_TYPE;
- break;
- case DRM_RIGHTS_WBXML:
- mimeType = DRM_RIGHTS_WBXML_MIME_TYPE;
- break;
- case WAP_SI_MIME_PORT:
- // application/vnd.wap.sic
- mimeType = WAP_SI_MIME_TYPE;
- break;
- case WAP_SL_MIME_PORT:
- mimeType = WAP_SL_MIME_TYPE;
- break;
- case WAP_CO_MIME_PORT:
- mimeType = WAP_CO_MIME_TYPE;
- break;
- default:
- int start = index;
-
- // Skip text-string.
- // Now we assume the mimetype is Extension-Media.
- while (pdu[index++] != '\0') {
- ;
- }
- mimeType = new String(pdu, start, index-start-1);
- break;
- }
-
- // XXX Skip the remainder of the header for now
- int dataIndex = headerStartIndex + headerLength;
- byte[] data;
- if (pdu[headerStartIndex] == WAP_CO_MIME_PORT)
- {
- // because SMSDispatcher can't parse push headers "Content-Location" and
- // X-Wap-Content-URI, so pass the whole push to CO application.
- data = pdu;
- } else
- {
- data = new byte[pdu.length - dataIndex];
- System.arraycopy(pdu, dataIndex, data, 0, data.length);
- }
-
- // Notify listeners about the WAP PUSH
- Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
- intent.setType(mimeType);
- intent.putExtra("transactionId", transactionId);
- intent.putExtra("pduType", pduType);
- intent.putExtra("data", data);
-
- if (mimeType.equals(MMS_MIME_TYPE)) {
- mPhone.getContext().sendBroadcast(
- intent, "android.permission.RECEIVE_MMS");
- } else {
- mPhone.getContext().sendBroadcast(
- intent, "android.permission.RECEIVE_WAP_PUSH");
- }
- }
/**
* Send a multi-part text based SMS.
@@ -913,7 +770,7 @@ final class SMSDispatcher extends Handler {
sendSms(tracker);
}
}
-
+
/**
* Send a SMS
*
diff --git a/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java
index f37d1eb..995173b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java
@@ -35,6 +35,7 @@ import android.database.ContentObserver;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
+import android.os.PowerManager;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.SystemClock;
@@ -141,6 +142,9 @@ final class ServiceStateTracker extends Handler
// Already sent the event-log for no gprs register
private boolean mReportedGprsNoReg = false;
+ // Wake lock used while setting time of day.
+ private PowerManager.WakeLock mWakeLock;
+ private static final String WAKELOCK_TAG = "ServiceStateTracker";
// Keep track of SPN display rules, so we only broadcast intent if something changes.
private String curSpn = null;
@@ -230,7 +234,11 @@ final class ServiceStateTracker extends Handler
cellLoc = new GsmCellLocation();
newCellLoc = new GsmCellLocation();
- cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
+ PowerManager powerManager =
+ (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
+
+ cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
@@ -1348,42 +1356,49 @@ final class ServiceStateTracker extends Handler
return;
}
- if (getAutoTime()) {
- long millisSinceNitzReceived
- = SystemClock.elapsedRealtime() - nitzReceiveTime;
+ try {
+ mWakeLock.acquire();
- if (millisSinceNitzReceived < 0) {
- // Sanity check: something is wrong
- Log.i(LOG_TAG, "NITZ: not setting time, clock has rolled "
- + "backwards since NITZ time was received, "
- + nitz);
- return;
- }
+ if (getAutoTime()) {
+ long millisSinceNitzReceived
+ = SystemClock.elapsedRealtime() - nitzReceiveTime;
+
+ if (millisSinceNitzReceived < 0) {
+ // Sanity check: something is wrong
+ Log.i(LOG_TAG, "NITZ: not setting time, clock has rolled "
+ + "backwards since NITZ time was received, "
+ + nitz);
+ return;
+ }
- if (millisSinceNitzReceived > Integer.MAX_VALUE) {
- // If the time is this far off, something is wrong > 24 days!
- Log.i(LOG_TAG, "NITZ: not setting time, processing has taken "
- + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
- + " days");
- return;
- }
+ if (millisSinceNitzReceived > Integer.MAX_VALUE) {
+ // If the time is this far off, something is wrong > 24 days!
+ Log.i(LOG_TAG, "NITZ: not setting time, processing has taken "
+ + (millisSinceNitzReceived / (1000 * 60 * 60 * 24))
+ + " days");
+ return;
+ }
- // Note: with range checks above, cast to int is safe
- c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
+ // Note: with range checks above, cast to int is safe
+ c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived);
- Log.i(LOG_TAG, "NITZ: Setting time of day to " + c.getTime()
- + " NITZ receive delay(ms): " + millisSinceNitzReceived
- + " gained(ms): "
- + (c.getTimeInMillis() - System.currentTimeMillis())
- + " from " + nitz);
+ Log.i(LOG_TAG, "NITZ: Setting time of day to " + c.getTime()
+ + " NITZ receive delay(ms): " + millisSinceNitzReceived
+ + " gained(ms): "
+ + (c.getTimeInMillis() - System.currentTimeMillis())
+ + " from " + nitz);
- setAndBroadcastNetworkSetTime(c.getTimeInMillis());
- }
- SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
- saveNitzTime(c.getTimeInMillis());
- if (Config.LOGV) {
- long end = SystemClock.elapsedRealtime();
- Log.v(LOG_TAG, "NITZ: end=" + end + " dur=" + (end - start));
+ SystemClock.setCurrentTimeMillis(c.getTimeInMillis());
+ Log.i(LOG_TAG, "NITZ: after Setting time of day");
+ }
+ SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis()));
+ saveNitzTime(c.getTimeInMillis());
+ if (Config.LOGV) {
+ long end = SystemClock.elapsedRealtime();
+ Log.v(LOG_TAG, "NITZ: end=" + end + " dur=" + (end - start));
+ }
+ } finally {
+ mWakeLock.release();
}
} catch (RuntimeException ex) {
Log.e(LOG_TAG, "NITZ: Parsing NITZ time " + nitz, ex);