summaryrefslogtreecommitdiffstats
path: root/telephony/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'telephony/java/com')
-rw-r--r--telephony/java/com/android/internal/telephony/AdnRecord.java2
-rw-r--r--telephony/java/com/android/internal/telephony/AdnRecordCache.java19
-rw-r--r--telephony/java/com/android/internal/telephony/BaseCommands.java40
-rw-r--r--telephony/java/com/android/internal/telephony/CommandsInterface.java24
-rw-r--r--telephony/java/com/android/internal/telephony/IWapPushManager.aidl52
-rw-r--r--telephony/java/com/android/internal/telephony/IccCard.java23
-rw-r--r--telephony/java/com/android/internal/telephony/IccConstants.java1
-rw-r--r--telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java58
-rw-r--r--telephony/java/com/android/internal/telephony/IccUtils.java49
-rw-r--r--telephony/java/com/android/internal/telephony/Phone.java11
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java15
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneProxy.java4
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java72
-rw-r--r--telephony/java/com/android/internal/telephony/SimRegionCache.java51
-rw-r--r--telephony/java/com/android/internal/telephony/WapPushManagerParams.java70
-rw-r--r--telephony/java/com/android/internal/telephony/WapPushOverSms.java274
-rw-r--r--telephony/java/com/android/internal/telephony/WspTypeDecoder.java511
-rw-r--r--telephony/java/com/android/internal/telephony/cat/AppInterface.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java)17
-rw-r--r--telephony/java/com/android/internal/telephony/cat/BerTlv.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java)20
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CatException.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/StkException.java)8
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CatLog.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java)8
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java)6
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CatService.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/StkService.java)280
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CommandDetails.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CommandParams.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java)75
-rw-r--r--telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/Duration.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/Duration.java)4
-rw-r--r--telephony/java/com/android/internal/telephony/cat/FontSize.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/IconLoader.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java)16
-rw-r--r--telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java)4
-rw-r--r--telephony/java/com/android/internal/telephony/cat/Input.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/Input.java)8
-rw-r--r--telephony/java/com/android/internal/telephony/cat/Item.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/Item.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/Menu.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/Menu.java)4
-rw-r--r--telephony/java/com/android/internal/telephony/cat/PresentationType.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/ResponseData.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java)14
-rw-r--r--telephony/java/com/android/internal/telephony/cat/ResultCode.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/ResultException.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java)4
-rw-r--r--telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java)28
-rw-r--r--telephony/java/com/android/internal/telephony/cat/TextAlignment.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/TextAttribute.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/TextColor.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/TextMessage.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/Tone.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/Tone.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/ToneSettings.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java)2
-rw-r--r--telephony/java/com/android/internal/telephony/cat/ValueParser.java (renamed from telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java)6
-rw-r--r--telephony/java/com/android/internal/telephony/cat/package.html5
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CDMAPhone.java9
-rwxr-xr-x[-rw-r--r--]telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java64
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java11
-rwxr-xr-x[-rw-r--r--]telephony/java/com/android/internal/telephony/cdma/RuimRecords.java44
-rw-r--r--[-rwxr-xr-x]telephony/java/com/android/internal/telephony/cdma/SmsMessage.java177
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/sms/BearerData.java1
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java27
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java12
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GSMPhone.java17
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java80
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java3
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java1
-rwxr-xr-xtelephony/java/com/android/internal/telephony/gsm/SIMRecords.java90
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java11
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java3
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsMessage.java39
-rwxr-xr-x[-rw-r--r--]telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java25
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/stk/package.html5
-rw-r--r--[-rwxr-xr-x]telephony/java/com/android/internal/telephony/sip/SipPhone.java5
68 files changed, 1873 insertions, 564 deletions
diff --git a/telephony/java/com/android/internal/telephony/AdnRecord.java b/telephony/java/com/android/internal/telephony/AdnRecord.java
index 1bf2d3c..a01b00d 100644
--- a/telephony/java/com/android/internal/telephony/AdnRecord.java
+++ b/telephony/java/com/android/internal/telephony/AdnRecord.java
@@ -283,7 +283,7 @@ public class AdnRecord implements Parcelable {
private void
parseRecord(byte[] record) {
try {
- alphaTag = IccUtils.adnStringFieldToString(
+ alphaTag = IccUtils.adnStringFieldToStringKsc5601Support(
record, 0, record.length - FOOTER_SIZE_BYTES);
int footerOffset = record.length - FOOTER_SIZE_BYTES;
diff --git a/telephony/java/com/android/internal/telephony/AdnRecordCache.java b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
index c8c0658..a175d49 100644
--- a/telephony/java/com/android/internal/telephony/AdnRecordCache.java
+++ b/telephony/java/com/android/internal/telephony/AdnRecordCache.java
@@ -186,7 +186,12 @@ public final class AdnRecordCache extends Handler implements IccConstants {
}
ArrayList<AdnRecord> oldAdnList;
- oldAdnList = getRecordsIfLoaded(efid);
+
+ if (efid == EF_PBR) {
+ oldAdnList = mUsimPhoneBookManager.loadEfFilesFromUsim();
+ } else {
+ oldAdnList = getRecordsIfLoaded(efid);
+ }
if (oldAdnList == null) {
sendErrorResponse(response, "Adn list not exist for EF:" + efid);
@@ -208,6 +213,17 @@ public final class AdnRecordCache extends Handler implements IccConstants {
return;
}
+ if (efid == EF_PBR) {
+ AdnRecord foundAdn = oldAdnList.get(index-1);
+ efid = foundAdn.efid;
+ extensionEF = foundAdn.extRecord;
+ index = foundAdn.recordNumber;
+
+ newAdn.efid = efid;
+ newAdn.extRecord = extensionEF;
+ newAdn.recordNumber = index;
+ }
+
Message pendingResponse = userWriteResponse.get(efid);
if (pendingResponse != null) {
@@ -331,6 +347,7 @@ public final class AdnRecordCache extends Handler implements IccConstants {
if (ar.exception == null) {
adnLikeFiles.get(efid).set(index - 1, adn);
+ mUsimPhoneBookManager.invalidateCache();
}
Message response = userWriteResponse.get(efid);
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index b962375..815fbfb 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -73,10 +73,10 @@ public abstract class BaseCommands implements CommandsInterface {
protected Registrant mSmsOnSimRegistrant;
protected Registrant mSmsStatusRegistrant;
protected Registrant mSsnRegistrant;
- protected Registrant mStkSessionEndRegistrant;
- protected Registrant mStkProCmdRegistrant;
- protected Registrant mStkEventRegistrant;
- protected Registrant mStkCallSetUpRegistrant;
+ protected Registrant mCatSessionEndRegistrant;
+ protected Registrant mCatProCmdRegistrant;
+ protected Registrant mCatEventRegistrant;
+ protected Registrant mCatCallSetUpRegistrant;
protected Registrant mIccSmsFullRegistrant;
protected Registrant mEmergencyCallbackModeRegistrant;
protected Registrant mIccRefreshRegistrant;
@@ -395,36 +395,36 @@ public abstract class BaseCommands implements CommandsInterface {
mSsnRegistrant.clear();
}
- public void setOnStkSessionEnd(Handler h, int what, Object obj) {
- mStkSessionEndRegistrant = new Registrant (h, what, obj);
+ public void setOnCatSessionEnd(Handler h, int what, Object obj) {
+ mCatSessionEndRegistrant = new Registrant (h, what, obj);
}
- public void unSetOnStkSessionEnd(Handler h) {
- mStkSessionEndRegistrant.clear();
+ public void unSetOnCatSessionEnd(Handler h) {
+ mCatSessionEndRegistrant.clear();
}
- public void setOnStkProactiveCmd(Handler h, int what, Object obj) {
- mStkProCmdRegistrant = new Registrant (h, what, obj);
+ public void setOnCatProactiveCmd(Handler h, int what, Object obj) {
+ mCatProCmdRegistrant = new Registrant (h, what, obj);
}
- public void unSetOnStkProactiveCmd(Handler h) {
- mStkProCmdRegistrant.clear();
+ public void unSetOnCatProactiveCmd(Handler h) {
+ mCatProCmdRegistrant.clear();
}
- public void setOnStkEvent(Handler h, int what, Object obj) {
- mStkEventRegistrant = new Registrant (h, what, obj);
+ public void setOnCatEvent(Handler h, int what, Object obj) {
+ mCatEventRegistrant = new Registrant (h, what, obj);
}
- public void unSetOnStkEvent(Handler h) {
- mStkEventRegistrant.clear();
+ public void unSetOnCatEvent(Handler h) {
+ mCatEventRegistrant.clear();
}
- public void setOnStkCallSetUp(Handler h, int what, Object obj) {
- mStkCallSetUpRegistrant = new Registrant (h, what, obj);
+ public void setOnCatCallSetUp(Handler h, int what, Object obj) {
+ mCatCallSetUpRegistrant = new Registrant (h, what, obj);
}
- public void unSetOnStkCallSetUp(Handler h) {
- mStkCallSetUpRegistrant.clear();
+ public void unSetOnCatCallSetUp(Handler h) {
+ mCatCallSetUpRegistrant.clear();
}
public void setOnIccSmsFull(Handler h, int what, Object obj) {
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 5de9aa9..b8bf8af 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -374,48 +374,48 @@ public interface CommandsInterface {
void unSetOnSuppServiceNotification(Handler h);
/**
- * Sets the handler for Session End Notifications for STK.
+ * Sets the handler for Session End Notifications for CAT.
* Unlike the register* methods, there's only one notification handler
*
* @param h Handler for notification message.
* @param what User-defined message code.
* @param obj User object.
*/
- void setOnStkSessionEnd(Handler h, int what, Object obj);
- void unSetOnStkSessionEnd(Handler h);
+ void setOnCatSessionEnd(Handler h, int what, Object obj);
+ void unSetOnCatSessionEnd(Handler h);
/**
- * Sets the handler for Proactive Commands for STK.
+ * Sets the handler for Proactive Commands for CAT.
* Unlike the register* methods, there's only one notification handler
*
* @param h Handler for notification message.
* @param what User-defined message code.
* @param obj User object.
*/
- void setOnStkProactiveCmd(Handler h, int what, Object obj);
- void unSetOnStkProactiveCmd(Handler h);
+ void setOnCatProactiveCmd(Handler h, int what, Object obj);
+ void unSetOnCatProactiveCmd(Handler h);
/**
- * Sets the handler for Event Notifications for STK.
+ * Sets the handler for Event Notifications for CAT.
* Unlike the register* methods, there's only one notification handler
*
* @param h Handler for notification message.
* @param what User-defined message code.
* @param obj User object.
*/
- void setOnStkEvent(Handler h, int what, Object obj);
- void unSetOnStkEvent(Handler h);
+ void setOnCatEvent(Handler h, int what, Object obj);
+ void unSetOnCatEvent(Handler h);
/**
- * Sets the handler for Call Set Up Notifications for STK.
+ * Sets the handler for Call Set Up Notifications for CAT.
* Unlike the register* methods, there's only one notification handler
*
* @param h Handler for notification message.
* @param what User-defined message code.
* @param obj User object.
*/
- void setOnStkCallSetUp(Handler h, int what, Object obj);
- void unSetOnStkCallSetUp(Handler h);
+ void setOnCatCallSetUp(Handler h, int what, Object obj);
+ void unSetOnCatCallSetUp(Handler h);
/**
* Enables/disbables supplementary service related notifications from
diff --git a/telephony/java/com/android/internal/telephony/IWapPushManager.aidl b/telephony/java/com/android/internal/telephony/IWapPushManager.aidl
new file mode 100644
index 0000000..d5ecb94
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IWapPushManager.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 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;
+
+interface IWapPushManager {
+ /**
+ * Processes WAP push message and triggers the receiver application registered
+ * in the application ID table.
+ */
+ int processMessage(String app_id, String content_type, in Intent intent);
+
+ /**
+ * Add receiver application into the application ID table.
+ * Returns true if inserting the information is successfull. Inserting the duplicated
+ * record in the application ID table is not allowed. Use update/delete method.
+ */
+ boolean addPackage(String x_app_id, String content_type,
+ String package_name, String class_name,
+ int app_type, boolean need_signature, boolean further_processing);
+
+ /**
+ * Updates receiver application that is last added.
+ * Returns true if updating the information is successfull.
+ */
+ boolean updatePackage(String x_app_id, String content_type,
+ String package_name, String class_name,
+ int app_type, boolean need_signature, boolean further_processing);
+
+ /**
+ * Delites receiver application information.
+ * Returns true if deleting is successfull.
+ */
+ boolean deletePackage(String x_app_id, String content_type,
+ String package_name, String class_name);
+}
+
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index d3a34ec..e270ce9 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -487,6 +487,12 @@ public abstract class IccCard {
CommandsInterface.SERVICE_CLASS_DATA +
CommandsInterface.SERVICE_CLASS_FAX;
+ if (!mPhone.mIsTheCurrentActivePhone) {
+ Log.e(mLogTag, "Received message " + msg + "[" + msg.what
+ + "] while being destroyed. Ignoring.");
+ return;
+ }
+
switch (msg.what) {
case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
mState = null;
@@ -626,7 +632,13 @@ public abstract class IccCard {
index = mIccCardStatus.getGsmUmtsSubscriptionAppIndex();
}
- IccCardApplication app = mIccCardStatus.getApplication(index);
+ IccCardApplication app;
+ if (index >= 0 && index < IccCardStatus.CARD_MAX_APPS) {
+ app = mIccCardStatus.getApplication(index);
+ } else {
+ Log.e(mLogTag, "[IccCard] Invalid Subscription Application index:" + index);
+ return IccCard.State.ABSENT;
+ }
if (app == null) {
Log.e(mLogTag, "[IccCard] Subscription Application in not present");
@@ -672,12 +684,11 @@ public abstract class IccCard {
* @return true if a ICC card is present
*/
public boolean hasIccCard() {
- boolean isIccPresent;
- if (mPhone.getPhoneName().equals("GSM")) {
- return mIccCardStatus.getCardState().isCardPresent();
- } else {
- // TODO: Make work with a CDMA device with a RUIM card.
+ if (mIccCardStatus == null) {
return false;
+ } else {
+ // Returns ICC card status for both GSM and CDMA mode
+ return mIccCardStatus.getCardState().isCardPresent();
}
}
diff --git a/telephony/java/com/android/internal/telephony/IccConstants.java b/telephony/java/com/android/internal/telephony/IccConstants.java
index acc9197..b12d2d4 100644
--- a/telephony/java/com/android/internal/telephony/IccConstants.java
+++ b/telephony/java/com/android/internal/telephony/IccConstants.java
@@ -52,6 +52,7 @@ public interface IccConstants {
static final int EF_SPN_CPHS = 0x6f14;
static final int EF_SPN_SHORT_CPHS = 0x6f18;
static final int EF_INFO_CPHS = 0x6f16;
+ static final int EF_CSP_CPHS = 0x6f15;
// CDMA RUIM file ids from 3GPP2 C.S0023-0
static final int EF_CST = 0x6f32;
diff --git a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 9f8e57f..45562ca 100644
--- a/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -24,6 +24,7 @@ import android.os.Message;
import android.os.ServiceManager;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* SimPhoneBookInterfaceManager to provide an inter-process communication to
@@ -62,15 +63,15 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
logd("GET_RECORD_SIZE Size " + recordSize[0] +
" total " + recordSize[1] +
" #record " + recordSize[2]);
- mLock.notifyAll();
}
+ notifyPending(ar);
}
break;
case EVENT_UPDATE_DONE:
ar = (AsyncResult) msg.obj;
synchronized (mLock) {
success = (ar.exception == null);
- mLock.notifyAll();
+ notifyPending(ar);
}
break;
case EVENT_LOAD_DONE:
@@ -84,11 +85,20 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
records.clear();
}
}
- mLock.notifyAll();
+ notifyPending(ar);
}
break;
}
}
+
+ private void notifyPending(AsyncResult ar) {
+ if (ar.userObj == null) {
+ return;
+ }
+ AtomicBoolean status = (AtomicBoolean) ar.userObj;
+ status.set(true);
+ mLock.notifyAll();
+ }
};
public IccPhoneBookInterfaceManager(PhoneBase phone) {
@@ -144,18 +154,18 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
if (DBG) logd("updateAdnRecordsInEfBySearch: efid=" + efid +
" ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" +
" ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);
+
+ efid = updateEfForIccType(efid);
+
synchronized(mLock) {
checkThread();
success = false;
- Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE);
+ AtomicBoolean status = new AtomicBoolean(false);
+ Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber);
AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- logd("interrupted while trying to update by search");
- }
+ waitForResult(status);
}
return success;
}
@@ -194,14 +204,11 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
synchronized(mLock) {
checkThread();
success = false;
- Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE);
+ AtomicBoolean status = new AtomicBoolean(false);
+ Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, status);
AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber);
adnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- logd("interrupted while trying to update by index");
- }
+ waitForResult(status);
}
return success;
}
@@ -240,15 +247,12 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
synchronized(mLock) {
checkThread();
- Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE);
+ AtomicBoolean status = new AtomicBoolean(false);
+ Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, status);
adnCache.requestLoadAllAdnLike(efid, adnCache.extensionEfForEf(efid), response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- logd("interrupted while trying to load from the SIM");
- }
+ waitForResult(status);
}
- return records;
+ return records;
}
protected void checkThread() {
@@ -262,6 +266,16 @@ public abstract class IccPhoneBookInterfaceManager extends IIccPhoneBook.Stub {
}
}
+ protected void waitForResult(AtomicBoolean status) {
+ while (!status.get()) {
+ try {
+ mLock.wait();
+ } catch (InterruptedException e) {
+ logd("interrupted while trying to update by search");
+ }
+ }
+ }
+
private int updateEfForIccType(int efid) {
// Check if we are trying to read ADN records
if (efid == IccConstants.EF_ADN) {
diff --git a/telephony/java/com/android/internal/telephony/IccUtils.java b/telephony/java/com/android/internal/telephony/IccUtils.java
index 71936f1..2244ac4 100644
--- a/telephony/java/com/android/internal/telephony/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/IccUtils.java
@@ -51,6 +51,8 @@ public class IccUtils {
ret.append((char)('0' + v));
v = (data[i] >> 4) & 0xf;
+ // Some PLMNs have 'f' as high nibble, ignore it
+ if (v == 0xf) continue;
if (v > 9) break;
ret.append((char)('0' + v));
}
@@ -148,6 +150,47 @@ public class IccUtils {
*/
public static String
adnStringFieldToString(byte[] data, int offset, int length) {
+ String s = adnStringFieldToStringUcs2Helper(data, offset, length);
+ if (s == null) {
+ s = adnStringFieldToStringGsm8BitHelper(data, offset, length);
+ }
+ return s;
+ }
+
+ /**
+ * Almost identical to the method {@link #adnStringFieldToString}.
+ *
+ * Exception:
+ * If the SIM is Korean (MCC equals "450"), KSC5601 encoding will be
+ * assumed (instead of GSM8Bit). This could lead to unintended consequences,
+ * if the ADN alphaTag was saved with GSM8Bit. This is considered an
+ * acceptable risk.
+ */
+ public static String
+ adnStringFieldToStringKsc5601Support(byte[] data, int offset, int length) {
+ String s = adnStringFieldToStringUcs2Helper(data, offset, length);
+
+ if (s == null) {
+ if (SimRegionCache.getRegion() == SimRegionCache.MCC_KOREAN) {
+ try {
+ int len = offset;
+ byte stop = (byte)0xFF;
+ while (len < length && data[len] != stop) {
+ len++;
+ }
+ return new String(data, offset, len, "KSC5601");
+ } catch (UnsupportedEncodingException e) {
+ Log.e(LOG_TAG, "implausible UnsupportedEncodingException", e);
+ }
+ }
+
+ return adnStringFieldToStringGsm8BitHelper(data, offset, length);
+ }
+ return s;
+ }
+
+ private static String
+ adnStringFieldToStringUcs2Helper(byte[] data, int offset, int length) {
if (length >= 1) {
if (data[offset] == (byte) 0x80) {
int ucslen = (length - 1) / 2;
@@ -223,6 +266,11 @@ public class IccUtils {
return ret.toString();
}
+ return null;
+ }
+
+ private static String
+ adnStringFieldToStringGsm8BitHelper(byte[] data, int offset, int length) {
return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length);
}
@@ -398,7 +446,6 @@ public class IccUtils {
int colorNumber = data[valueIndex++] & 0xFF;
int clutOffset = ((data[valueIndex++] & 0xFF) << 8)
| (data[valueIndex++] & 0xFF);
- length = length - 6;
int[] colorIndexArray = getCLUT(data, clutOffset, colorNumber);
if (true == transparency) {
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index c7d4ead..2638057 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -1717,4 +1717,15 @@ public interface Phone {
void unsetOnEcbModeExitResponse(Handler h);
+ /**
+ * TODO: Adding a function for each property is not good.
+ * A fucntion of type getPhoneProp(propType) where propType is an
+ * enum of GSM+CDMA+LTE props would be a better approach.
+ *
+ * Get "Restriction of menu options for manual PLMN selection" bit
+ * status from EF_CSP data, this belongs to "Value Added Services Group".
+ * @return true if this bit is set or EF_CSP data is unavailable,
+ * false otherwise
+ */
+ boolean isCspPlmnEnabled();
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 9c6b432..f15d5b2 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -1020,6 +1020,13 @@ public abstract class PhoneBase extends Handler implements Phone {
}
}
+ public boolean isCspPlmnEnabled() {
+ // This function should be overridden by the class GSMPhone.
+ // Not implemented in CDMAPhone.
+ logUnexpectedGsmMethodCall("isCspPlmnEnabled");
+ return false;
+ }
+
/**
* Common error logger method for unexpected calls to CDMA-only methods.
*/
@@ -1028,4 +1035,12 @@ public abstract class PhoneBase extends Handler implements Phone {
Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
"called, CDMAPhone inactive.");
}
+
+ /**
+ * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
+ */
+ private void logUnexpectedGsmMethodCall(String name) {
+ Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
+ "called, GSMPhone inactive.");
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index 6f08868..77f1e6c 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -843,4 +843,8 @@ public class PhoneProxy extends Handler implements Phone {
public void unsetOnEcbModeExitResponse(Handler h){
mActivePhone.unsetOnEcbModeExitResponse(h);
}
+
+ public boolean isCspPlmnEnabled() {
+ return mActivePhone.isCspPlmnEnabled();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 09a4506..e059555 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -141,6 +141,7 @@ class RILRequest {
this.mNext = sPool;
sPool = this;
sPoolSize++;
+ mResult = null;
}
}
}
@@ -370,6 +371,11 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.onError(GENERIC_FAILURE, null);
rr.release();
}
+ } finally {
+ // Note: We are "Done" only if there are no outstanding
+ // requests or replies. Thus this code path will only release
+ // the wake lock on errors.
+ releaseWakeLockIfDone();
}
if (!alreadySubtracted && mRequestMessagesPending > 0) {
@@ -1989,26 +1995,30 @@ public final class RIL extends BaseCommands implements CommandsInterface {
sendScreenState(true);
}
- private void setRadioStateFromRILInt(int state) {
- RadioState newState;
+ private RadioState getRadioStateFromInt(int stateInt) {
+ RadioState state;
/* RIL_RadioState ril.h */
- switch(state) {
- case 0: newState = RadioState.RADIO_OFF; break;
- case 1: newState = RadioState.RADIO_UNAVAILABLE; break;
- case 2: newState = RadioState.SIM_NOT_READY; break;
- case 3: newState = RadioState.SIM_LOCKED_OR_ABSENT; break;
- case 4: newState = RadioState.SIM_READY; break;
- case 5: newState = RadioState.RUIM_NOT_READY; break;
- case 6: newState = RadioState.RUIM_READY; break;
- case 7: newState = RadioState.RUIM_LOCKED_OR_ABSENT; break;
- case 8: newState = RadioState.NV_NOT_READY; break;
- case 9: newState = RadioState.NV_READY; break;
+ switch(stateInt) {
+ case 0: state = RadioState.RADIO_OFF; break;
+ case 1: state = RadioState.RADIO_UNAVAILABLE; break;
+ case 2: state = RadioState.SIM_NOT_READY; break;
+ case 3: state = RadioState.SIM_LOCKED_OR_ABSENT; break;
+ case 4: state = RadioState.SIM_READY; break;
+ case 5: state = RadioState.RUIM_NOT_READY; break;
+ case 6: state = RadioState.RUIM_READY; break;
+ case 7: state = RadioState.RUIM_LOCKED_OR_ABSENT; break;
+ case 8: state = RadioState.NV_NOT_READY; break;
+ case 9: state = RadioState.NV_READY; break;
default:
throw new RuntimeException(
- "Unrecognized RIL_RadioState: " +state);
+ "Unrecognized RIL_RadioState: " + stateInt);
}
+ return state;
+ }
+
+ private void switchToRadioState(RadioState newState) {
if (mInitialRadioStateChange) {
if (newState.isOn()) {
@@ -2067,6 +2077,12 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(RILRequest rr) {
Message msg;
+ if (mSocket == null) {
+ rr.onError(RADIO_NOT_AVAILABLE, null);
+ rr.release();
+ return;
+ }
+
msg = mSender.obtainMessage(EVENT_SEND, rr);
acquireWakeLock();
@@ -2398,7 +2414,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_RESTRICTED_STATE_CHANGED: ret = responseInts(p); break;
case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: ret = responseCdmaSms(p); break;
- case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseString(p); break;
+ case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: ret = responseRaw(p); break;
case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: ret = responseVoid(p); break;
case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_UNSOL_CDMA_CALL_WAITING: ret = responseCdmaCallWaiting(p); break;
@@ -2420,9 +2436,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
switch(response) {
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
/* has bonus radio state int */
- setRadioStateFromRILInt(p.readInt());
+ RadioState newState = getRadioStateFromInt(p.readInt());
+ if (RILJ_LOGD) unsljLogMore(response, newState.toString());
- if (RILJ_LOGD) unsljLogMore(response, mState.toString());
+ switchToRadioState(newState);
break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
if (RILJ_LOGD) unsljLog(response);
@@ -2540,8 +2557,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_STK_SESSION_END:
if (RILJ_LOGD) unsljLog(response);
- if (mStkSessionEndRegistrant != null) {
- mStkSessionEndRegistrant.notifyRegistrant(
+ if (mCatSessionEndRegistrant != null) {
+ mCatSessionEndRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
@@ -2549,8 +2566,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_STK_PROACTIVE_COMMAND:
if (RILJ_LOGD) unsljLogRet(response, ret);
- if (mStkProCmdRegistrant != null) {
- mStkProCmdRegistrant.notifyRegistrant(
+ if (mCatProCmdRegistrant != null) {
+ mCatProCmdRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
@@ -2558,8 +2575,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_STK_EVENT_NOTIFY:
if (RILJ_LOGD) unsljLogRet(response, ret);
- if (mStkEventRegistrant != null) {
- mStkEventRegistrant.notifyRegistrant(
+ if (mCatEventRegistrant != null) {
+ mCatEventRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
@@ -2567,8 +2584,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_STK_CALL_SETUP:
if (RILJ_LOGD) unsljLogRet(response, ret);
- if (mStkCallSetUpRegistrant != null) {
- mStkCallSetUpRegistrant.notifyRegistrant(
+ if (mCatCallSetUpRegistrant != null) {
+ mCatCallSetUpRegistrant.notifyRegistrant(
new AsyncResult (null, ret, null));
}
break;
@@ -3469,6 +3486,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
RILRequest rr = RILRequest.obtain(
RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
send(rr);
}
@@ -3482,6 +3501,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
rr.mp.writeInt(1);
rr.mp.writeInt(ttyMode);
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " : " + ttyMode);
+
send(rr);
}
diff --git a/telephony/java/com/android/internal/telephony/SimRegionCache.java b/telephony/java/com/android/internal/telephony/SimRegionCache.java
new file mode 100644
index 0000000..2cf6d25
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/SimRegionCache.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 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.os.SystemProperties;
+
+public class SimRegionCache {
+ public static final int MCC_UNSET = Integer.MIN_VALUE;
+ public static final int MCC_KOREAN = 450;
+
+ private static int regionFromMcc = MCC_UNSET;
+
+ /**
+ * Returns the region as read from the MCC of the SIM card.
+ * If the property {@link TelephonyProperties#
+ * PROPERTY_ICC_OPERATOR_NUMERIC}
+ * returns null or an empty String, the value is {@link #MCC_UNSET}
+ *
+ * @return the cached region, if set.
+ */
+ public static int getRegion() {
+ if (regionFromMcc == MCC_UNSET) {
+ String plmn = SystemProperties.get(
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC,
+ null);
+
+ if (plmn != null && plmn.length() >= 3) {
+ try {
+ regionFromMcc = Integer.parseInt(plmn.substring(0, 3));
+ } catch(Exception e) {
+ // Nothing that can be done here.
+ }
+ }
+ }
+ return regionFromMcc;
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/WapPushManagerParams.java b/telephony/java/com/android/internal/telephony/WapPushManagerParams.java
new file mode 100644
index 0000000..11e5ff9
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/WapPushManagerParams.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 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;
+
+/**
+ * WapPushManager constant value definitions
+ */
+public class WapPushManagerParams {
+ /**
+ * Application type activity
+ */
+ public static final int APP_TYPE_ACTIVITY = 0;
+
+ /**
+ * Application type service
+ */
+ public static final int APP_TYPE_SERVICE = 1;
+
+ /**
+ * Process Message return value
+ * Message is handled
+ */
+ public static final int MESSAGE_HANDLED = 0x1;
+
+ /**
+ * Process Message return value
+ * Application ID or content type was not found in the application ID table
+ */
+ public static final int APP_QUERY_FAILED = 0x2;
+
+ /**
+ * Process Message return value
+ * Receiver application signature check failed
+ */
+ public static final int SIGNATURE_NO_MATCH = 0x4;
+
+ /**
+ * Process Message return value
+ * Receiver application was not found
+ */
+ public static final int INVALID_RECEIVER_NAME = 0x8;
+
+ /**
+ * Process Message return value
+ * Unknown exception
+ */
+ public static final int EXCEPTION_CAUGHT = 0x10;
+
+ /**
+ * Process Message return value
+ * Need further processing after WapPushManager message processing
+ */
+ public static final int FURTHER_PROCESSING = 0x8000;
+
+}
+
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
index 168b63b..7704667 100644
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
@@ -14,16 +14,20 @@
* limitations under the License.
*/
+
package com.android.internal.telephony;
import android.app.Activity;
import android.content.Context;
+import android.content.ComponentName;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.provider.Telephony;
import android.provider.Telephony.Sms.Intents;
import android.util.Config;
import android.util.Log;
-
+import android.os.IBinder;
+import android.os.RemoteException;
/**
* WAP push handler class.
@@ -43,11 +47,83 @@ public class WapPushOverSms {
*/
private final int WAKE_LOCK_TIMEOUT = 5000;
+ private final int BIND_RETRY_INTERVAL = 1000;
+ /**
+ * A handle to WapPushManager interface
+ */
+ private WapPushConnection mWapConn = null;
+ private class WapPushConnection implements ServiceConnection {
+ private IWapPushManager mWapPushMan;
+ private Context mOwner;
+
+ public WapPushConnection(Context ownerContext) {
+ mOwner = ownerContext;
+ }
+
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mWapPushMan = IWapPushManager.Stub.asInterface(service);
+ if (Config.DEBUG) Log.v(LOG_TAG, "wappush manager connected to " +
+ mOwner.hashCode());
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ mWapPushMan = null;
+ if (Config.DEBUG) Log.v(LOG_TAG, "wappush manager disconnected.");
+ // WapPushManager must be always attached.
+ rebindWapPushManager();
+ }
+
+ /**
+ * bind WapPushManager
+ */
+ public void bindWapPushManager() {
+ if (mWapPushMan != null) return;
+
+ final ServiceConnection wapPushConnection = this;
+
+ mOwner.bindService(new Intent(IWapPushManager.class.getName()),
+ wapPushConnection, Context.BIND_AUTO_CREATE);
+ }
+
+ /**
+ * rebind WapPushManager
+ * This method is called when WapPushManager is disconnected unexpectedly.
+ */
+ private void rebindWapPushManager() {
+ if (mWapPushMan != null) return;
+
+ final ServiceConnection wapPushConnection = this;
+ new Thread() {
+ public void run() {
+ while (mWapPushMan == null) {
+ mOwner.bindService(new Intent(IWapPushManager.class.getName()),
+ wapPushConnection, Context.BIND_AUTO_CREATE);
+ try {
+ Thread.sleep(BIND_RETRY_INTERVAL);
+ } catch (InterruptedException e) {
+ if (Config.DEBUG) Log.v(LOG_TAG, "sleep interrupted.");
+ }
+ }
+ }
+ }.start();
+ }
+
+ /**
+ * Returns interface to WapPushManager
+ */
+ public IWapPushManager getWapPushManager() {
+ return mWapPushMan;
+ }
+ }
+
public WapPushOverSms(Phone phone, SMSDispatcher smsDispatcher) {
mSmsDispatcher = smsDispatcher;
mContext = phone.getContext();
+ mWapConn = new WapPushConnection(mContext);
+ mWapConn.bindWapPushManager();
}
+
/**
* 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.
@@ -59,7 +135,7 @@ public class WapPushOverSms {
*/
public int dispatchWapPdu(byte[] pdu) {
- if (Config.LOGD) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
+ if (Config.DEBUG) Log.d(LOG_TAG, "Rx: " + IccUtils.bytesToHexString(pdu));
int index = 0;
int transactionId = pdu[index++] & 0xFF;
@@ -68,7 +144,7 @@ public class WapPushOverSms {
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);
+ if (Config.DEBUG) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType);
return Intents.RESULT_SMS_HANDLED;
}
@@ -81,7 +157,7 @@ public class WapPushOverSms {
* 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.");
+ if (Config.DEBUG) Log.w(LOG_TAG, "Received PDU. Header Length error.");
return Intents.RESULT_SMS_GENERIC_ERROR;
}
headerLength = (int)pduDecoder.getValue32();
@@ -102,141 +178,99 @@ public class WapPushOverSms {
* Length = Uintvar-integer
*/
if (pduDecoder.decodeContentType(index) == false) {
- if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
+ if (Config.DEBUG) Log.w(LOG_TAG, "Received PDU. Header Content-Type error.");
return Intents.RESULT_SMS_GENERIC_ERROR;
}
- int binaryContentType;
+
String mimeType = pduDecoder.getValueString();
- if (mimeType == null) {
- binaryContentType = (int)pduDecoder.getValue32();
- // TODO we should have more generic way to map binaryContentType code to mimeType.
- 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;
- case WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF:
- mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF;
- break;
- case WspTypeDecoder.CONTENT_TYPE_B_SUPL_INIT:
- mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_SUPL_INIT;
- break;
- default:
- if (Config.LOGD) {
- Log.w(LOG_TAG,
- "Received PDU. Unsupported Content-Type = " + binaryContentType);
- }
- return Intents.RESULT_SMS_HANDLED;
- }
- } 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 (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF)) {
- binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF;
- } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_SUPL_INIT)) {
- binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_SUPL_INIT;
- } else {
- if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Unknown Content-Type = " + mimeType);
- return Intents.RESULT_SMS_HANDLED;
- }
- }
+ long binaryContentType = pduDecoder.getValue32();
index += pduDecoder.getDecodedDataLength();
- boolean dispatchedByApplication = false;
- switch (binaryContentType) {
- case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO:
- dispatchWapPdu_PushCO(pdu, transactionId, pduType, headerStartIndex, headerLength);
- dispatchedByApplication = true;
- break;
- case WspTypeDecoder.CONTENT_TYPE_B_MMS:
- dispatchWapPdu_MMS(pdu, transactionId, pduType, headerStartIndex, headerLength);
- dispatchedByApplication = true;
- break;
- default:
- break;
- }
- if (dispatchedByApplication == false) {
- dispatchWapPdu_default(pdu, transactionId, pduType, mimeType,
- headerStartIndex, headerLength);
- }
- return Activity.RESULT_OK;
- }
-
- private void dispatchWapPdu_default(byte[] pdu, int transactionId, int pduType,
- String mimeType, int headerStartIndex, int headerLength) {
byte[] header = new byte[headerLength];
System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
- int dataIndex = headerStartIndex + headerLength;
- byte[] data;
- data = new byte[pdu.length - dataIndex];
- System.arraycopy(pdu, dataIndex, data, 0, data.length);
+ byte[] intentData;
- Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
- intent.setType(mimeType);
- intent.putExtra("transactionId", transactionId);
- intent.putExtra("pduType", pduType);
- intent.putExtra("header", header);
- intent.putExtra("data", data);
+ if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
+ intentData = pdu;
+ } else {
+ int dataIndex = headerStartIndex + headerLength;
+ intentData = new byte[pdu.length - dataIndex];
+ System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
+ }
- mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
- }
+ /**
+ * Seek for application ID field in WSP header.
+ * If application ID is found, WapPushManager substitute the message
+ * processing. Since WapPushManager is optional module, if WapPushManager
+ * is not found, legacy message processing will be continued.
+ */
+ if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
+ index = (int) pduDecoder.getValue32();
+ pduDecoder.decodeXWapApplicationId(index);
+ String wapAppId = pduDecoder.getValueString();
+ if (wapAppId == null) {
+ wapAppId = Integer.toString((int) pduDecoder.getValue32());
+ }
- private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType,
- int headerStartIndex, int headerLength) {
- byte[] header = new byte[headerLength];
- System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
+ String contentType = ((mimeType == null) ?
+ Long.toString(binaryContentType) : mimeType);
+ if (Config.DEBUG) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType);
- 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("header", header);
- intent.putExtra("data", pdu);
+ try {
+ boolean processFurther = true;
+ IWapPushManager wapPushMan = mWapConn.getWapPushManager();
- mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
- }
+ if (wapPushMan == null) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "wap push manager not found!");
+ } else {
+ Intent intent = new Intent();
+ intent.putExtra("transactionId", transactionId);
+ intent.putExtra("pduType", pduType);
+ intent.putExtra("header", header);
+ intent.putExtra("data", intentData);
+ intent.putExtra("contentTypeParameters",
+ pduDecoder.getContentParameters());
- private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType,
- int headerStartIndex, int headerLength) {
- byte[] header = new byte[headerLength];
- System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
- int dataIndex = headerStartIndex + headerLength;
- byte[] data = new byte[pdu.length - dataIndex];
- System.arraycopy(pdu, dataIndex, data, 0, data.length);
+ int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
+ if (Config.DEBUG) Log.v(LOG_TAG, "procRet:" + procRet);
+ if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
+ && (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
+ processFurther = false;
+ }
+ }
+ if (!processFurther) {
+ return Intents.RESULT_SMS_HANDLED;
+ }
+ } catch (RemoteException e) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "remote func failed...");
+ }
+ }
+ if (Config.DEBUG) Log.v(LOG_TAG, "fall back to existing handler");
+
+ if (mimeType == null) {
+ if (Config.DEBUG) Log.w(LOG_TAG, "Header Content-Type error.");
+ return Intents.RESULT_SMS_GENERIC_ERROR;
+ }
+
+ String permission;
+
+ if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
+ permission = "android.permission.RECEIVE_MMS";
+ } else {
+ permission = "android.permission.RECEIVE_WAP_PUSH";
+ }
Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
- intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS);
+ intent.setType(mimeType);
intent.putExtra("transactionId", transactionId);
intent.putExtra("pduType", pduType);
intent.putExtra("header", header);
- intent.putExtra("data", data);
+ intent.putExtra("data", intentData);
+ intent.putExtra("contentTypeParameters", pduDecoder.getContentParameters());
+
+ mSmsDispatcher.dispatch(intent, permission);
- mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_MMS");
+ return Activity.RESULT_OK;
}
}
-
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
index 5dc89f0..c8dd718 100644
--- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
+++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -16,11 +16,12 @@
package com.android.internal.telephony;
+import java.util.HashMap;
/**
- * Implement the WSP data type decoder.
+ * Implement the WSP data type decoder.
*
- * @hide
+ * @hide
*/
public class WspTypeDecoder {
@@ -30,37 +31,177 @@ public class WspTypeDecoder {
public static final int PDU_TYPE_PUSH = 0x06;
public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07;
- // TODO we should have mapping between those binary code and mime type string.
- // see http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
-
- 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 int CONTENT_TYPE_B_VND_DOCOMO_PF = 0x0310;
- public static final int CONTENT_TYPE_B_SUPL_INIT = 0x312;
-
- 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 String CONTENT_MIME_TYPE_B_VND_DOCOMO_PF = "application/vnd.docomo.pf";
- public static final String CONTENT_MIME_TYPE_B_SUPL_INIT = "application/vnd.omaloc-supl-init";
+ private final static HashMap<Integer, String> WELL_KNOWN_MIME_TYPES =
+ new HashMap<Integer, String>();
+
+ private final static HashMap<Integer, String> WELL_KNOWN_PARAMETERS =
+ new HashMap<Integer, String>();
public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
+ private static final int Q_VALUE = 0x00;
+
+ static {
+ WELL_KNOWN_MIME_TYPES.put(0x00, "*/*");
+ WELL_KNOWN_MIME_TYPES.put(0x01, "text/*");
+ WELL_KNOWN_MIME_TYPES.put(0x02, "text/html");
+ WELL_KNOWN_MIME_TYPES.put(0x03, "text/plain");
+ WELL_KNOWN_MIME_TYPES.put(0x04, "text/x-hdml");
+ WELL_KNOWN_MIME_TYPES.put(0x05, "text/x-ttml");
+ WELL_KNOWN_MIME_TYPES.put(0x06, "text/x-vCalendar");
+ WELL_KNOWN_MIME_TYPES.put(0x07, "text/x-vCard");
+ WELL_KNOWN_MIME_TYPES.put(0x08, "text/vnd.wap.wml");
+ WELL_KNOWN_MIME_TYPES.put(0x09, "text/vnd.wap.wmlscript");
+ WELL_KNOWN_MIME_TYPES.put(0x0A, "text/vnd.wap.wta-event");
+ WELL_KNOWN_MIME_TYPES.put(0x0B, "multipart/*");
+ WELL_KNOWN_MIME_TYPES.put(0x0C, "multipart/mixed");
+ WELL_KNOWN_MIME_TYPES.put(0x0D, "multipart/form-data");
+ WELL_KNOWN_MIME_TYPES.put(0x0E, "multipart/byterantes");
+ WELL_KNOWN_MIME_TYPES.put(0x0F, "multipart/alternative");
+ WELL_KNOWN_MIME_TYPES.put(0x10, "application/*");
+ WELL_KNOWN_MIME_TYPES.put(0x11, "application/java-vm");
+ WELL_KNOWN_MIME_TYPES.put(0x12, "application/x-www-form-urlencoded");
+ WELL_KNOWN_MIME_TYPES.put(0x13, "application/x-hdmlc");
+ WELL_KNOWN_MIME_TYPES.put(0x14, "application/vnd.wap.wmlc");
+ WELL_KNOWN_MIME_TYPES.put(0x15, "application/vnd.wap.wmlscriptc");
+ WELL_KNOWN_MIME_TYPES.put(0x16, "application/vnd.wap.wta-eventc");
+ WELL_KNOWN_MIME_TYPES.put(0x17, "application/vnd.wap.uaprof");
+ WELL_KNOWN_MIME_TYPES.put(0x18, "application/vnd.wap.wtls-ca-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x19, "application/vnd.wap.wtls-user-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x1A, "application/x-x509-ca-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x1B, "application/x-x509-user-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x1C, "image/*");
+ WELL_KNOWN_MIME_TYPES.put(0x1D, "image/gif");
+ WELL_KNOWN_MIME_TYPES.put(0x1E, "image/jpeg");
+ WELL_KNOWN_MIME_TYPES.put(0x1F, "image/tiff");
+ WELL_KNOWN_MIME_TYPES.put(0x20, "image/png");
+ WELL_KNOWN_MIME_TYPES.put(0x21, "image/vnd.wap.wbmp");
+ WELL_KNOWN_MIME_TYPES.put(0x22, "application/vnd.wap.multipart.*");
+ WELL_KNOWN_MIME_TYPES.put(0x23, "application/vnd.wap.multipart.mixed");
+ WELL_KNOWN_MIME_TYPES.put(0x24, "application/vnd.wap.multipart.form-data");
+ WELL_KNOWN_MIME_TYPES.put(0x25, "application/vnd.wap.multipart.byteranges");
+ WELL_KNOWN_MIME_TYPES.put(0x26, "application/vnd.wap.multipart.alternative");
+ WELL_KNOWN_MIME_TYPES.put(0x27, "application/xml");
+ WELL_KNOWN_MIME_TYPES.put(0x28, "text/xml");
+ WELL_KNOWN_MIME_TYPES.put(0x29, "application/vnd.wap.wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x2A, "application/x-x968-cross-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x2B, "application/x-x968-ca-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x2C, "application/x-x968-user-cert");
+ WELL_KNOWN_MIME_TYPES.put(0x2D, "text/vnd.wap.si");
+ WELL_KNOWN_MIME_TYPES.put(0x2E, "application/vnd.wap.sic");
+ WELL_KNOWN_MIME_TYPES.put(0x2F, "text/vnd.wap.sl");
+ WELL_KNOWN_MIME_TYPES.put(0x30, "application/vnd.wap.slc");
+ WELL_KNOWN_MIME_TYPES.put(0x31, "text/vnd.wap.co");
+ WELL_KNOWN_MIME_TYPES.put(0x32, "application/vnd.wap.coc");
+ WELL_KNOWN_MIME_TYPES.put(0x33, "application/vnd.wap.multipart.related");
+ WELL_KNOWN_MIME_TYPES.put(0x34, "application/vnd.wap.sia");
+ WELL_KNOWN_MIME_TYPES.put(0x35, "text/vnd.wap.connectivity-xml");
+ WELL_KNOWN_MIME_TYPES.put(0x36, "application/vnd.wap.connectivity-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x37, "application/pkcs7-mime");
+ WELL_KNOWN_MIME_TYPES.put(0x38, "application/vnd.wap.hashed-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x39, "application/vnd.wap.signed-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x3A, "application/vnd.wap.cert-response");
+ WELL_KNOWN_MIME_TYPES.put(0x3B, "application/xhtml+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x3C, "application/wml+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x3D, "text/css");
+ WELL_KNOWN_MIME_TYPES.put(0x3E, "application/vnd.wap.mms-message");
+ WELL_KNOWN_MIME_TYPES.put(0x3F, "application/vnd.wap.rollover-certificate");
+ WELL_KNOWN_MIME_TYPES.put(0x40, "application/vnd.wap.locc+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x41, "application/vnd.wap.loc+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x42, "application/vnd.syncml.dm+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x43, "application/vnd.syncml.dm+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x44, "application/vnd.syncml.notification");
+ WELL_KNOWN_MIME_TYPES.put(0x45, "application/vnd.wap.xhtml+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x46, "application/vnd.wv.csp.cir");
+ WELL_KNOWN_MIME_TYPES.put(0x47, "application/vnd.oma.dd+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x48, "application/vnd.oma.drm.message");
+ WELL_KNOWN_MIME_TYPES.put(0x49, "application/vnd.oma.drm.content");
+ WELL_KNOWN_MIME_TYPES.put(0x4A, "application/vnd.oma.drm.rights+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x4B, "application/vnd.oma.drm.rights+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x4C, "application/vnd.wv.csp+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x4D, "application/vnd.wv.csp+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x4E, "application/vnd.syncml.ds.notification");
+ WELL_KNOWN_MIME_TYPES.put(0x4F, "audio/*");
+ WELL_KNOWN_MIME_TYPES.put(0x50, "video/*");
+ WELL_KNOWN_MIME_TYPES.put(0x51, "application/vnd.oma.dd2+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x52, "application/mikey");
+ WELL_KNOWN_MIME_TYPES.put(0x53, "application/vnd.oma.dcd");
+ WELL_KNOWN_MIME_TYPES.put(0x54, "application/vnd.oma.dcdc");
+
+ WELL_KNOWN_MIME_TYPES.put(0x0201, "application/vnd.uplanet.cacheop-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0202, "application/vnd.uplanet.signal");
+ WELL_KNOWN_MIME_TYPES.put(0x0203, "application/vnd.uplanet.alert-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0204, "application/vnd.uplanet.list-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0205, "application/vnd.uplanet.listcmd-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0206, "application/vnd.uplanet.channel-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0207, "application/vnd.uplanet.provisioning-status-uri");
+ WELL_KNOWN_MIME_TYPES.put(0x0208, "x-wap.multipart/vnd.uplanet.header-set");
+ WELL_KNOWN_MIME_TYPES.put(0x0209, "application/vnd.uplanet.bearer-choice-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x020A, "application/vnd.phonecom.mmc-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x020B, "application/vnd.nokia.syncset+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x020C, "image/x-up-wpng");
+ WELL_KNOWN_MIME_TYPES.put(0x0300, "application/iota.mmc-wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0301, "application/iota.mmc-xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0302, "application/vnd.syncml+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0303, "application/vnd.syncml+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0304, "text/vnd.wap.emn+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0305, "text/calendar");
+ WELL_KNOWN_MIME_TYPES.put(0x0306, "application/vnd.omads-email+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0307, "application/vnd.omads-file+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0308, "application/vnd.omads-folder+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0309, "text/directory;profile=vCard");
+ WELL_KNOWN_MIME_TYPES.put(0x030A, "application/vnd.wap.emn+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x030B, "application/vnd.nokia.ipdc-purchase-response");
+ WELL_KNOWN_MIME_TYPES.put(0x030C, "application/vnd.motorola.screen3+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x030D, "application/vnd.motorola.screen3+gzip");
+ WELL_KNOWN_MIME_TYPES.put(0x030E, "application/vnd.cmcc.setting+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x030F, "application/vnd.cmcc.bombing+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0310, "application/vnd.docomo.pf");
+ WELL_KNOWN_MIME_TYPES.put(0x0311, "application/vnd.docomo.ub");
+ WELL_KNOWN_MIME_TYPES.put(0x0312, "application/vnd.omaloc-supl-init");
+ WELL_KNOWN_MIME_TYPES.put(0x0313, "application/vnd.oma.group-usage-list+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0314, "application/oma-directory+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x0315, "application/vnd.docomo.pf2");
+ WELL_KNOWN_MIME_TYPES.put(0x0316, "application/vnd.oma.drm.roap-trigger+wbxml");
+ WELL_KNOWN_MIME_TYPES.put(0x0317, "application/vnd.sbm.mid2");
+ WELL_KNOWN_MIME_TYPES.put(0x0318, "application/vnd.wmf.bootstrap");
+ WELL_KNOWN_MIME_TYPES.put(0x0319, "application/vnc.cmcc.dcd+xml");
+ WELL_KNOWN_MIME_TYPES.put(0x031A, "application/vnd.sbm.cid");
+ WELL_KNOWN_MIME_TYPES.put(0x031B, "application/vnd.oma.bcast.provisioningtrigger");
+
+ WELL_KNOWN_PARAMETERS.put(0x00, "Q");
+ WELL_KNOWN_PARAMETERS.put(0x01, "Charset");
+ WELL_KNOWN_PARAMETERS.put(0x02, "Level");
+ WELL_KNOWN_PARAMETERS.put(0x03, "Type");
+ WELL_KNOWN_PARAMETERS.put(0x07, "Differences");
+ WELL_KNOWN_PARAMETERS.put(0x08, "Padding");
+ WELL_KNOWN_PARAMETERS.put(0x09, "Type");
+ WELL_KNOWN_PARAMETERS.put(0x0E, "Max-Age");
+ WELL_KNOWN_PARAMETERS.put(0x10, "Secure");
+ WELL_KNOWN_PARAMETERS.put(0x11, "SEC");
+ WELL_KNOWN_PARAMETERS.put(0x12, "MAC");
+ WELL_KNOWN_PARAMETERS.put(0x13, "Creation-date");
+ WELL_KNOWN_PARAMETERS.put(0x14, "Modification-date");
+ WELL_KNOWN_PARAMETERS.put(0x15, "Read-date");
+ WELL_KNOWN_PARAMETERS.put(0x16, "Size");
+ WELL_KNOWN_PARAMETERS.put(0x17, "Name");
+ WELL_KNOWN_PARAMETERS.put(0x18, "Filename");
+ WELL_KNOWN_PARAMETERS.put(0x19, "Start");
+ WELL_KNOWN_PARAMETERS.put(0x1A, "Start-info");
+ WELL_KNOWN_PARAMETERS.put(0x1B, "Comment");
+ WELL_KNOWN_PARAMETERS.put(0x1C, "Domain");
+ WELL_KNOWN_PARAMETERS.put(0x1D, "Path");
+ }
+ public static final String CONTENT_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
+ public static final String CONTENT_TYPE_B_MMS = "application/vnd.wap.mms-message";
byte[] wspData;
int dataLength;
long unsigned32bit;
String stringValue;
+ HashMap<String, String> contentParameters;
+
public WspTypeDecoder(byte[] pdu) {
wspData = pdu;
}
@@ -71,17 +212,17 @@ public class WspTypeDecoder {
* @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
+ * return value can be retrieved by getValueString() method length of data in pdu can be
+ * retrieved by getDecodedDataLength() method
*/
public boolean decodeTextString(int startIndex) {
int index = startIndex;
while (wspData[index] != 0) {
index++;
}
- dataLength = index - startIndex + 1;
+ dataLength = index - startIndex + 1;
if (wspData[startIndex] == 127) {
- stringValue = new String(wspData, startIndex+1, dataLength - 2);
+ stringValue = new String(wspData, startIndex + 1, dataLength - 2);
} else {
stringValue = new String(wspData, startIndex, dataLength - 1);
}
@@ -89,13 +230,33 @@ public class WspTypeDecoder {
}
/**
+ * Decode the "Token-text" type for WSP pdu
+ *
+ * @param startIndex The starting position of the "Token-text" in this pdu
+ *
+ * @return always true
+ * return value can be retrieved by getValueString() method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
+ */
+ public boolean decodeTokenText(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 "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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeShortInteger(int startIndex) {
if ((wspData[startIndex] & 0x80) == 0) {
@@ -113,7 +274,7 @@ public class WspTypeDecoder {
*
* @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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeLongInteger(int startIndex) {
int lengthMultiOctet = wspData[startIndex] & 0xff;
@@ -122,10 +283,10 @@ public class WspTypeDecoder {
return false;
}
unsigned32bit = 0;
- for (int i=1; i<=lengthMultiOctet; i++) {
- unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex+i] & 0xff);
+ for (int i = 1; i <= lengthMultiOctet; i++) {
+ unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex + i] & 0xff);
}
- dataLength = 1+lengthMultiOctet;
+ dataLength = 1 + lengthMultiOctet;
return true;
}
@@ -136,7 +297,7 @@ public class WspTypeDecoder {
*
* @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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeIntegerValue(int startIndex) {
if (decodeShortInteger(startIndex) == true) {
@@ -152,10 +313,10 @@ public class WspTypeDecoder {
*
* @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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeUintvarInteger(int startIndex) {
- int index = startIndex;
+ int index = startIndex;
unsigned32bit = 0;
while ((wspData[index] & 0x80) != 0) {
@@ -177,7 +338,7 @@ public class WspTypeDecoder {
*
* @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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeValueLength(int startIndex) {
if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) {
@@ -187,22 +348,22 @@ public class WspTypeDecoder {
unsigned32bit = wspData[startIndex];
dataLength = 1;
} else {
- decodeUintvarInteger(startIndex+1);
- dataLength ++;
+ 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 on error, such as if there is no Extension-media at startIndex.
- * Side-effects: updates stringValue (available with getValueString()), which will be
- * null on error. The length of the data in the PDU is available with getValue32(), 0
- * on error.
- */
+ * Decode the "Extension-media" type for WSP PDU.
+ *
+ * @param startIndex The starting position of the "Extension-media" in this PDU.
+ *
+ * @return false on error, such as if there is no Extension-media at startIndex.
+ * Side-effects: updates stringValue (available with
+ * getValueString()), which will be null on error. The length of the
+ * data in the PDU is available with getValue32(), 0 on error.
+ */
public boolean decodeExtensionMedia(int startIndex) {
int index = startIndex;
dataLength = 0;
@@ -214,7 +375,7 @@ public class WspTypeDecoder {
index++;
}
- dataLength = index - startIndex + 1;
+ dataLength = index - startIndex + 1;
stringValue = new String(wspData, startIndex, dataLength - 1);
return rtrn;
@@ -227,7 +388,7 @@ public class WspTypeDecoder {
*
* @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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeConstrainedEncoding(int startIndex) {
if (decodeShortInteger(startIndex) == true) {
@@ -242,29 +403,160 @@ public class WspTypeDecoder {
*
* @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
+ * @return false when error(not a Content-type) occurs
+ * If a content type exists in the headers (either as inline string, or as well-known
+ * value), getValueString() will return it. If a 'well known value' is encountered that
+ * cannot be mapped to a string mime type, getValueString() will return null, and
+ * getValue32() will return the unknown content type value.
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
+ * Any content type parameters will be accessible via getContentParameters()
*/
public boolean decodeContentType(int startIndex) {
int mediaPrefixLength;
- long mediaFieldLength;
-
- if (decodeValueLength(startIndex) == false) {
- return decodeConstrainedEncoding(startIndex);
+ contentParameters = new HashMap<String, String>();
+
+ try {
+ if (decodeValueLength(startIndex) == false) {
+ boolean found = decodeConstrainedEncoding(startIndex);
+ if (found) {
+ expandWellKnownMimeType();
+ }
+ return found;
+ }
+ int headersLength = (int) unsigned32bit;
+ mediaPrefixLength = getDecodedDataLength();
+ if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
+ dataLength += mediaPrefixLength;
+ int readLength = dataLength;
+ stringValue = null;
+ expandWellKnownMimeType();
+ long wellKnownValue = unsigned32bit;
+ String mimeType = stringValue;
+ if (readContentParameters(startIndex + dataLength,
+ (headersLength - (dataLength - mediaPrefixLength)), 0)) {
+ dataLength += readLength;
+ unsigned32bit = wellKnownValue;
+ stringValue = mimeType;
+ return true;
+ }
+ return false;
+ }
+ if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
+ dataLength += mediaPrefixLength;
+ int readLength = dataLength;
+ expandWellKnownMimeType();
+ long wellKnownValue = unsigned32bit;
+ String mimeType = stringValue;
+ if (readContentParameters(startIndex + dataLength,
+ (headersLength - (dataLength - mediaPrefixLength)), 0)) {
+ dataLength += readLength;
+ unsigned32bit = wellKnownValue;
+ stringValue = mimeType;
+ return true;
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //something doesn't add up
+ return false;
}
- mediaPrefixLength = getDecodedDataLength();
- mediaFieldLength = getValue32();
- if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) {
- dataLength += mediaPrefixLength;
- stringValue = null;
+ return false;
+ }
+
+ private boolean readContentParameters(int startIndex, int leftToRead, int accumulator) {
+
+ int totalRead = 0;
+
+ if (leftToRead > 0) {
+ byte nextByte = wspData[startIndex];
+ String value = null;
+ String param = null;
+ if ((nextByte & 0x80) == 0x00 && nextByte > 31) { // untyped
+ decodeTokenText(startIndex);
+ param = stringValue;
+ totalRead += dataLength;
+ } else { // typed
+ if (decodeIntegerValue(startIndex)) {
+ totalRead += dataLength;
+ int wellKnownParameterValue = (int) unsigned32bit;
+ param = WELL_KNOWN_PARAMETERS.get(wellKnownParameterValue);
+ if (param == null) {
+ param = "unassigned/0x" + Long.toHexString(wellKnownParameterValue);
+ }
+ // special case for the "Q" parameter, value is a uintvar
+ if (wellKnownParameterValue == Q_VALUE) {
+ if (decodeUintvarInteger(startIndex + totalRead)) {
+ totalRead += dataLength;
+ value = String.valueOf(unsigned32bit);
+ contentParameters.put(param, value);
+ return readContentParameters(startIndex + totalRead, leftToRead
+ - totalRead, accumulator + totalRead);
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+
+ if (decodeNoValue(startIndex + totalRead)) {
+ totalRead += dataLength;
+ value = null;
+ } else if (decodeIntegerValue(startIndex + totalRead)) {
+ totalRead += dataLength;
+ int intValue = (int) unsigned32bit;
+ if (intValue == 0) {
+ value = "";
+ } else {
+ value = String.valueOf(intValue);
+ }
+ } else {
+ decodeTokenText(startIndex + totalRead);
+ totalRead += dataLength;
+ value = stringValue;
+ if (value.startsWith("\"")) {
+ // quoted string, so remove the quote
+ value = value.substring(1);
+ }
+ }
+ contentParameters.put(param, value);
+ return readContentParameters(startIndex + totalRead, leftToRead - totalRead,
+ accumulator + totalRead);
+
+ } else {
+ dataLength = accumulator;
return true;
}
- if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) {
- dataLength += mediaPrefixLength;
+ }
+
+ /**
+ * Check if the next byte is No-Value
+ *
+ * @param startIndex The starting position of the "Content length" in this pdu
+ *
+ * @return true if and only if the next byte is 0x00
+ */
+ private boolean decodeNoValue(int startIndex) {
+ if (wspData[startIndex] == 0) {
+ dataLength = 1;
return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Populate stringValue with the mime type corresponding to the value in unsigned32bit
+ *
+ * Sets unsigned32bit to -1 if stringValue is already populated
+ */
+ private void expandWellKnownMimeType() {
+ if (stringValue == null) {
+ int binaryContentType = (int) unsigned32bit;
+ stringValue = WELL_KNOWN_MIME_TYPES.get(binaryContentType);
+ } else {
+ unsigned32bit = -1;
}
- return false;
}
/**
@@ -274,7 +566,7 @@ public class WspTypeDecoder {
*
* @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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeContentLength(int startIndex) {
return decodeIntegerValue(startIndex);
@@ -287,7 +579,7 @@ public class WspTypeDecoder {
*
* @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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeContentLocation(int startIndex) {
return decodeTextString(startIndex);
@@ -300,7 +592,8 @@ public class WspTypeDecoder {
*
* @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
+ * method
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeXWapApplicationId(int startIndex) {
if (decodeIntegerValue(startIndex) == true) {
@@ -311,13 +604,77 @@ public class WspTypeDecoder {
}
/**
+ * Seek for the "X-Wap-Application-Id" field for WSP pdu
+ *
+ * @param startIndex The starting position of seek pointer
+ * @param endIndex Valid seek area end point
+ *
+ * @return false when error(not a X-Wap-Application-Id) occur
+ * return value can be retrieved by getValue32()
+ */
+ public boolean seekXWapApplicationId(int startIndex, int endIndex) {
+ int index = startIndex;
+
+ try {
+ for (index = startIndex; index <= endIndex; ) {
+ /**
+ * 8.4.1.1 Field name
+ * Field name is integer or text.
+ */
+ if (decodeIntegerValue(index)) {
+ int fieldValue = (int) getValue32();
+
+ if (fieldValue == PARAMETER_ID_X_WAP_APPLICATION_ID) {
+ unsigned32bit = index + 1;
+ return true;
+ }
+ } else {
+ if (!decodeTextString(index)) return false;
+ }
+ index += getDecodedDataLength();
+ if (index > endIndex) return false;
+
+ /**
+ * 8.4.1.2 Field values
+ * Value Interpretation of First Octet
+ * 0 - 30 This octet is followed by the indicated number (0 - 30)
+ of data octets
+ * 31 This octet is followed by a uintvar, which indicates the number
+ * of data octets after it
+ * 32 - 127 The value is a text string, terminated by a zero octet
+ (NUL character)
+ * 128 - 255 It is an encoded 7-bit value; this header has no more data
+ */
+ byte val = wspData[index];
+ if (0 <= val && val <= WAP_PDU_SHORT_LENGTH_MAX) {
+ index += wspData[index] + 1;
+ } else if (val == WAP_PDU_LENGTH_QUOTE) {
+ if (index + 1 >= endIndex) return false;
+ index++;
+ if (!decodeUintvarInteger(index)) return false;
+ index += getDecodedDataLength();
+ } else if (WAP_PDU_LENGTH_QUOTE < val && val <= 127) {
+ if (!decodeTextString(index)) return false;
+ index += getDecodedDataLength();
+ } else {
+ index++;
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //seek application ID failed. WSP header might be corrupted
+ return false;
+ }
+ return false;
+ }
+
+ /**
* 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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeXWapContentURI(int startIndex) {
return decodeTextString(startIndex);
@@ -330,7 +687,7 @@ public class WspTypeDecoder {
*
* @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
+ * length of data in pdu can be retrieved by getDecodedDataLength() method
*/
public boolean decodeXWapInitiatorURI(int startIndex) {
return decodeTextString(startIndex);
@@ -356,4 +713,18 @@ public class WspTypeDecoder {
public String getValueString() {
return stringValue;
}
+
+ /**
+ * Any parameters encountered as part of a decodeContentType() invocation.
+ *
+ * @return a map of content parameters keyed by their names, or null if
+ * decodeContentType() has not been called If any unassigned
+ * well-known parameters are encountered, the key of the map will be
+ * 'unassigned/0x...', where '...' is the hex value of the
+ * unassigned parameter. If a parameter has No-Value the value will be null.
+ *
+ */
+ public HashMap<String, String> getContentParameters() {
+ return contentParameters;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
index 58f1f97..2eb6ccb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java
+++ b/telephony/java/com/android/internal/telephony/cat/AppInterface.java
@@ -14,29 +14,29 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
- * Interface for communication between STK App and STK Telephony
+ * Interface for communication between STK App and CAT Telephony
*
* {@hide}
*/
public interface AppInterface {
/*
- * Intent's actions which are broadcasted by the Telephony once a new STK
+ * Intent's actions which are broadcasted by the Telephony once a new CAT
* proactive command, session end arrive.
*/
- public static final String STK_CMD_ACTION =
+ public static final String CAT_CMD_ACTION =
"android.intent.action.stk.command";
- public static final String STK_SESSION_END_ACTION =
+ public static final String CAT_SESSION_END_ACTION =
"android.intent.action.stk.session_end";
/*
* Callback function from app to telephony to pass a result code and user's
- * input back to the SIM.
+ * input back to the ICC.
*/
- void onCmdResponse(StkResponseMessage resMsg);
+ void onCmdResponse(CatResponseMessage resMsg);
/*
* Enumeration for representing "Type of Command" of proactive commands.
@@ -58,7 +58,8 @@ public interface AppInterface {
SET_UP_EVENT_LIST(0x05),
SET_UP_IDLE_MODE_TEXT(0x28),
SET_UP_MENU(0x25),
- SET_UP_CALL(0x10);
+ SET_UP_CALL(0x10),
+ PROVIDE_LOCAL_INFORMATION(0x26);
private int mValue;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java b/telephony/java/com/android/internal/telephony/cat/BerTlv.java
index 19d3279..774bfa3 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java
+++ b/telephony/java/com/android/internal/telephony/cat/BerTlv.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import java.util.List;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
index 5425a43..5155bb2 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatCmdMessage.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * Class used to pass STK messages from telephony to application. Application
+ * Class used to pass CAT messages from telephony to application. Application
* should call getXXX() to get commands's specific values.
*
*/
-public class StkCmdMessage implements Parcelable {
+public class CatCmdMessage implements Parcelable {
// members
CommandDetails mCmdDet;
private TextMessage mTextMsg;
@@ -50,7 +50,7 @@ public class StkCmdMessage implements Parcelable {
public TextMessage callMsg;
}
- StkCmdMessage(CommandParams cmdParams) {
+ CatCmdMessage(CommandParams cmdParams) {
mCmdDet = cmdParams.cmdDet;
switch(getCmdType()) {
case SET_UP_MENU:
@@ -88,7 +88,7 @@ public class StkCmdMessage implements Parcelable {
}
}
- public StkCmdMessage(Parcel in) {
+ public CatCmdMessage(Parcel in) {
mCmdDet = in.readParcelable(null);
mTextMsg = in.readParcelable(null);
mMenu = in.readParcelable(null);
@@ -130,13 +130,13 @@ public class StkCmdMessage implements Parcelable {
}
}
- public static final Parcelable.Creator<StkCmdMessage> CREATOR = new Parcelable.Creator<StkCmdMessage>() {
- public StkCmdMessage createFromParcel(Parcel in) {
- return new StkCmdMessage(in);
+ public static final Parcelable.Creator<CatCmdMessage> CREATOR = new Parcelable.Creator<CatCmdMessage>() {
+ public CatCmdMessage createFromParcel(Parcel in) {
+ return new CatCmdMessage(in);
}
- public StkCmdMessage[] newArray(int size) {
- return new StkCmdMessage[size];
+ public CatCmdMessage[] newArray(int size) {
+ return new CatCmdMessage[size];
}
};
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java b/telephony/java/com/android/internal/telephony/cat/CatException.java
index 86de366..1bf1369 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatException.java
@@ -14,18 +14,18 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.util.AndroidException;
/**
- * Base class for all the exceptions in STK service.
+ * Base class for all the exceptions in CAT service.
*
* {@hide}
*/
-class StkException extends AndroidException {
- public StkException() {
+class CatException extends AndroidException {
+ public CatException() {
super();
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java b/telephony/java/com/android/internal/telephony/cat/CatLog.java
index bd6bc8f..e19ff43 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatLog.java
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.util.Log;
-public abstract class StkLog {
+public abstract class CatLog {
static final boolean DEBUG = true;
public static void d(Object caller, String msg) {
@@ -27,7 +27,7 @@ public abstract class StkLog {
}
String className = caller.getClass().getName();
- Log.d("STK", className.substring(className.lastIndexOf('.') + 1) + ": "
+ Log.d("CAT", className.substring(className.lastIndexOf('.') + 1) + ": "
+ msg);
}
@@ -36,6 +36,6 @@ public abstract class StkLog {
return;
}
- Log.d("STK", caller + ": " + msg);
+ Log.d("CAT", caller + ": " + msg);
}
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
index 04a52e6..cfcac36 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatResponseMessage.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
-public class StkResponseMessage {
+public class CatResponseMessage {
CommandDetails cmdDet = null;
ResultCode resCode = ResultCode.OK;
int usersMenuSelection = 0;
@@ -24,7 +24,7 @@ public class StkResponseMessage {
boolean usersYesNoSelection = false;
boolean usersConfirm = false;
- public StkResponseMessage(StkCmdMessage cmdMsg) {
+ public CatResponseMessage(CatCmdMessage cmdMsg) {
this.cmdDet = cmdMsg.mCmdDet;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java b/telephony/java/com/android/internal/telephony/cat/CatService.java
index 29ed95c..36059ad 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java
+++ b/telephony/java/com/android/internal/telephony/cat/CatService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.content.Context;
import android.content.Intent;
@@ -22,12 +22,13 @@ import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
+import android.os.SystemProperties;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.gsm.SimCard;
-import com.android.internal.telephony.gsm.SIMFileHandler;
-import com.android.internal.telephony.gsm.SIMRecords;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccFileHandler;
+import com.android.internal.telephony.IccRecords;
import android.util.Config;
@@ -111,17 +112,19 @@ class RilMessage {
*
* {@hide}
*/
-public class StkService extends Handler implements AppInterface {
+public class CatService extends Handler implements AppInterface {
// Class members
- private static SIMRecords mSimRecords;
+ private static IccRecords mIccRecords;
// Service members.
- private static StkService sInstance;
+ // Protects singleton instance lazy initialization.
+ private static final Object sInstanceLock = new Object();
+ private static CatService sInstance;
private CommandsInterface mCmdIf;
private Context mContext;
- private StkCmdMessage mCurrntCmd = null;
- private StkCmdMessage mMenuCmd = null;
+ private CatCmdMessage mCurrntCmd = null;
+ private CatCmdMessage mMenuCmd = null;
private RilMessageDecoder mMsgDecoder = null;
@@ -136,7 +139,7 @@ public class StkService extends Handler implements AppInterface {
static final int MSG_ID_RIL_MSG_DECODED = 10;
// Events to signal SIM presence or absent in the device.
- private static final int MSG_ID_SIM_LOADED = 20;
+ private static final int MSG_ID_ICC_RECORDS_LOADED = 20;
private static final int DEV_ID_KEYPAD = 0x01;
private static final int DEV_ID_DISPLAY = 0x02;
@@ -146,10 +149,10 @@ public class StkService extends Handler implements AppInterface {
private static final int DEV_ID_NETWORK = 0x83;
/* Intentionally private for singleton */
- private StkService(CommandsInterface ci, SIMRecords sr, Context context,
- SIMFileHandler fh, SimCard sc) {
- if (ci == null || sr == null || context == null || fh == null
- || sc == null) {
+ private CatService(CommandsInterface ci, IccRecords ir, Context context,
+ IccFileHandler fh, IccCard ic) {
+ if (ci == null || ir == null || context == null || fh == null
+ || ic == null) {
throw new NullPointerException(
"Service: Input parameters must not be null");
}
@@ -160,33 +163,33 @@ public class StkService extends Handler implements AppInterface {
mMsgDecoder = RilMessageDecoder.getInstance(this, fh);
// Register ril events handling.
- mCmdIf.setOnStkSessionEnd(this, MSG_ID_SESSION_END, null);
- mCmdIf.setOnStkProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
- mCmdIf.setOnStkEvent(this, MSG_ID_EVENT_NOTIFY, null);
- mCmdIf.setOnStkCallSetUp(this, MSG_ID_CALL_SETUP, null);
+ mCmdIf.setOnCatSessionEnd(this, MSG_ID_SESSION_END, null);
+ mCmdIf.setOnCatProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null);
+ mCmdIf.setOnCatEvent(this, MSG_ID_EVENT_NOTIFY, null);
+ mCmdIf.setOnCatCallSetUp(this, MSG_ID_CALL_SETUP, null);
//mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null);
- mSimRecords = sr;
+ mIccRecords = ir;
// Register for SIM ready event.
- mSimRecords.registerForRecordsLoaded(this, MSG_ID_SIM_LOADED, null);
+ mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);
mCmdIf.reportStkServiceIsRunning(null);
- StkLog.d(this, "StkService: is running");
+ CatLog.d(this, "Is running");
}
public void dispose() {
- mSimRecords.unregisterForRecordsLoaded(this);
- mCmdIf.unSetOnStkSessionEnd(this);
- mCmdIf.unSetOnStkProactiveCmd(this);
- mCmdIf.unSetOnStkEvent(this);
- mCmdIf.unSetOnStkCallSetUp(this);
+ mIccRecords.unregisterForRecordsLoaded(this);
+ mCmdIf.unSetOnCatSessionEnd(this);
+ mCmdIf.unSetOnCatProactiveCmd(this);
+ mCmdIf.unSetOnCatEvent(this);
+ mCmdIf.unSetOnCatCallSetUp(this);
this.removeCallbacksAndMessages(null);
}
protected void finalize() {
- StkLog.d(this, "Service finalized");
+ CatLog.d(this, "Service finalized");
}
private void handleRilMsg(RilMessage rilMsg) {
@@ -241,55 +244,53 @@ public class StkService extends Handler implements AppInterface {
*
*/
private void handleProactiveCommand(CommandParams cmdParams) {
- StkLog.d(this, cmdParams.getCommandType().name());
+ CatLog.d(this, cmdParams.getCommandType().name());
- StkCmdMessage cmdMsg = new StkCmdMessage(cmdParams);
+ CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams);
switch (cmdParams.getCommandType()) {
- case SET_UP_MENU:
- if (removeMenu(cmdMsg.getMenu())) {
- mMenuCmd = null;
- } else {
- mMenuCmd = cmdMsg;
- }
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0,
- null);
- break;
- case DISPLAY_TEXT:
- // when application is not required to respond, send an immediate
- // response.
- if (!cmdMsg.geTextMessage().responseNeeded) {
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false,
- 0, null);
- }
- break;
- case REFRESH:
- // ME side only handles refresh commands which meant to remove IDLE
- // MODE TEXT.
- cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT
- .value();
- break;
- case SET_UP_IDLE_MODE_TEXT:
- sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false,
- 0, null);
- break;
- case LAUNCH_BROWSER:
- case SELECT_ITEM:
- case GET_INPUT:
- case GET_INKEY:
- case SEND_DTMF:
- case SEND_SMS:
- case SEND_SS:
- case SEND_USSD:
- case PLAY_TONE:
- case SET_UP_CALL:
- // nothing to do on telephony!
- break;
- default:
- StkLog.d(this, "Unsupported command");
- return;
+ case SET_UP_MENU:
+ if (removeMenu(cmdMsg.getMenu())) {
+ mMenuCmd = null;
+ } else {
+ mMenuCmd = cmdMsg;
+ }
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ break;
+ case DISPLAY_TEXT:
+ // when application is not required to respond, send an immediate response.
+ if (!cmdMsg.geTextMessage().responseNeeded) {
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ }
+ break;
+ case REFRESH:
+ // ME side only handles refresh commands which meant to remove IDLE
+ // MODE TEXT.
+ cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
+ break;
+ case SET_UP_IDLE_MODE_TEXT:
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ break;
+ case PROVIDE_LOCAL_INFORMATION:
+ sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
+ return;
+ case LAUNCH_BROWSER:
+ case SELECT_ITEM:
+ case GET_INPUT:
+ case GET_INKEY:
+ case SEND_DTMF:
+ case SEND_SMS:
+ case SEND_SS:
+ case SEND_USSD:
+ case PLAY_TONE:
+ case SET_UP_CALL:
+ // nothing to do on telephony!
+ break;
+ default:
+ CatLog.d(this, "Unsupported command");
+ return;
}
mCurrntCmd = cmdMsg;
- Intent intent = new Intent(AppInterface.STK_CMD_ACTION);
+ Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
intent.putExtra("STK CMD", cmdMsg);
mContext.sendBroadcast(intent);
}
@@ -299,10 +300,10 @@ public class StkService extends Handler implements AppInterface {
*
*/
private void handleSessionEnd() {
- StkLog.d(this, "SESSION END");
+ CatLog.d(this, "SESSION END");
mCurrntCmd = mMenuCmd;
- Intent intent = new Intent(AppInterface.STK_SESSION_END_ACTION);
+ Intent intent = new Intent(AppInterface.CAT_SESSION_END_ACTION);
mContext.sendBroadcast(intent);
}
@@ -315,6 +316,11 @@ public class StkService extends Handler implements AppInterface {
}
ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ Input cmdInput = null;
+ if (mCurrntCmd != null) {
+ cmdInput = mCurrntCmd.geInput();
+ }
+
// command details
int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
if (cmdDet.compRequired) {
@@ -327,7 +333,13 @@ public class StkService extends Handler implements AppInterface {
buf.write(cmdDet.commandQualifier);
// device identities
- tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
+ // According to TS102.223/TS31.111 section 6.8 Structure of
+ // TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
+ // the ME should set the CR(comprehension required) flag to
+ // comprehension not required.(CR=0)"
+ // Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
+ // the CR flag is not set.
+ tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value();
buf.write(tag);
buf.write(0x02); // length
buf.write(DEV_ID_TERMINAL); // source device id
@@ -348,17 +360,65 @@ public class StkService extends Handler implements AppInterface {
// Fill optional data for each corresponding command
if (resp != null) {
resp.format(buf);
+ } else {
+ encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
}
byte[] rawData = buf.toByteArray();
String hexString = IccUtils.bytesToHexString(rawData);
if (Config.LOGD) {
- StkLog.d(this, "TERMINAL RESPONSE: " + hexString);
+ CatLog.d(this, "TERMINAL RESPONSE: " + hexString);
}
mCmdIf.sendTerminalResponse(hexString, null);
}
+ private void encodeOptionalTags(CommandDetails cmdDet,
+ ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
+ switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) {
+ case GET_INKEY:
+ // ETSI TS 102 384,27.22.4.2.8.4.2.
+ // If it is a response for GET_INKEY command and the response timeout
+ // occured, then add DURATION TLV for variable timeout case.
+ if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
+ (cmdInput != null) && (cmdInput.duration != null)) {
+ getInKeyResponse(buf, cmdInput);
+ }
+ break;
+ case PROVIDE_LOCAL_INFORMATION:
+ if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
+ (resultCode.value() == ResultCode.OK.value())) {
+ getPliResponse(buf);
+ }
+ break;
+ default:
+ CatLog.d(this, "encodeOptionalTags() Unsupported Cmd:" + cmdDet.typeOfCommand);
+ break;
+ }
+ }
+
+ private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) {
+ int tag = ComprehensionTlvTag.DURATION.value();
+
+ buf.write(tag);
+ buf.write(0x02); // length
+ buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds)
+ buf.write(cmdInput.duration.timeInterval); // Time Duration
+ }
+
+ private void getPliResponse(ByteArrayOutputStream buf) {
+
+ // Locale Language Setting
+ String lang = SystemProperties.get("persist.sys.language");
+
+ if (lang != null) {
+ // tag
+ int tag = ComprehensionTlvTag.LANGUAGE.value();
+ buf.write(tag);
+ ResponseData.writeLength(buf, lang.length());
+ buf.write(lang.getBytes(), 0, lang.length());
+ }
+ }
private void sendMenuSelection(int menuId, boolean helpRequired) {
@@ -446,37 +506,39 @@ public class StkService extends Handler implements AppInterface {
}
/**
- * Used for instantiating/updating the Service from the GsmPhone constructor.
+ * Used for instantiating/updating the Service from the GsmPhone or CdmaPhone constructor.
*
* @param ci CommandsInterface object
- * @param sr SIMRecords object
+ * @param ir IccRecords object
* @param context phone app context
- * @param fh SIM file handler
- * @param sc GSM SIM card
+ * @param fh Icc file handler
+ * @param ic Icc card
* @return The only Service object in the system
*/
- public static StkService getInstance(CommandsInterface ci, SIMRecords sr,
- Context context, SIMFileHandler fh, SimCard sc) {
- if (sInstance == null) {
- if (ci == null || sr == null || context == null || fh == null
- || sc == null) {
- return null;
+ public static CatService getInstance(CommandsInterface ci, IccRecords ir,
+ Context context, IccFileHandler fh, IccCard ic) {
+ synchronized (sInstanceLock) {
+ if (sInstance == null) {
+ if (ci == null || ir == null || context == null || fh == null
+ || ic == null) {
+ return null;
+ }
+ HandlerThread thread = new HandlerThread("Cat Telephony service");
+ thread.start();
+ sInstance = new CatService(ci, ir, context, fh, ic);
+ CatLog.d(sInstance, "NEW sInstance");
+ } else if ((ir != null) && (mIccRecords != ir)) {
+ CatLog.d(sInstance, "Reinitialize the Service with SIMRecords");
+ mIccRecords = ir;
+
+ // re-Register for SIM ready event.
+ mIccRecords.registerForRecordsLoaded(sInstance, MSG_ID_ICC_RECORDS_LOADED, null);
+ CatLog.d(sInstance, "sr changed reinitialize and return current sInstance");
+ } else {
+ CatLog.d(sInstance, "Return current sInstance");
}
- HandlerThread thread = new HandlerThread("Stk Telephony service");
- thread.start();
- sInstance = new StkService(ci, sr, context, fh, sc);
- StkLog.d(sInstance, "NEW sInstance");
- } else if ((sr != null) && (mSimRecords != sr)) {
- StkLog.d(sInstance, "Reinitialize the Service with SIMRecords");
- mSimRecords = sr;
-
- // re-Register for SIM ready event.
- mSimRecords.registerForRecordsLoaded(sInstance, MSG_ID_SIM_LOADED, null);
- StkLog.d(sInstance, "sr changed reinitialize and return current sInstance");
- } else {
- StkLog.d(sInstance, "Return current sInstance");
+ return sInstance;
}
- return sInstance;
}
/**
@@ -496,7 +558,7 @@ public class StkService extends Handler implements AppInterface {
case MSG_ID_PROACTIVE_COMMAND:
case MSG_ID_EVENT_NOTIFY:
case MSG_ID_REFRESH:
- StkLog.d(this, "ril message arrived");
+ CatLog.d(this, "ril message arrived");
String data = null;
if (msg.obj != null) {
AsyncResult ar = (AsyncResult) msg.obj;
@@ -513,20 +575,20 @@ public class StkService extends Handler implements AppInterface {
case MSG_ID_CALL_SETUP:
mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null));
break;
- case MSG_ID_SIM_LOADED:
+ case MSG_ID_ICC_RECORDS_LOADED:
break;
case MSG_ID_RIL_MSG_DECODED:
handleRilMsg((RilMessage) msg.obj);
break;
case MSG_ID_RESPONSE:
- handleCmdResponse((StkResponseMessage) msg.obj);
+ handleCmdResponse((CatResponseMessage) msg.obj);
break;
default:
- throw new AssertionError("Unrecognized STK command: " + msg.what);
+ throw new AssertionError("Unrecognized CAT command: " + msg.what);
}
}
- public synchronized void onCmdResponse(StkResponseMessage resMsg) {
+ public synchronized void onCmdResponse(CatResponseMessage resMsg) {
if (resMsg == null) {
return;
}
@@ -535,7 +597,7 @@ public class StkService extends Handler implements AppInterface {
msg.sendToTarget();
}
- private boolean validateResponse(StkResponseMessage resMsg) {
+ private boolean validateResponse(CatResponseMessage resMsg) {
if (mCurrntCmd != null) {
return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet));
}
@@ -548,13 +610,13 @@ public class StkService extends Handler implements AppInterface {
return true;
}
} catch (NullPointerException e) {
- StkLog.d(this, "Unable to get Menu's items size");
+ CatLog.d(this, "Unable to get Menu's items size");
return true;
}
return false;
}
- private void handleCmdResponse(StkResponseMessage resMsg) {
+ private void handleCmdResponse(CatResponseMessage resMsg) {
// Make sure the response details match the last valid command. An invalid
// response is a one that doesn't have a corresponding proactive command
// and sending it can "confuse" the baseband/ril.
@@ -563,7 +625,7 @@ public class StkService extends Handler implements AppInterface {
// by the framework inside the history stack. That activity will be
// available for relaunch using the latest application dialog
// (long press on the home button). Relaunching that activity can send
- // the same command's result again to the StkService and can cause it to
+ // the same command's result again to the CatService and can cause it to
// get out of sync with the SIM.
if (!validateResponse(resMsg)) {
return;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
index e81ff98..e3f0798 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandDetails.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
index 3da652f..22a5c8c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandParams.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
index ce4c459..12204a0 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java
+++ b/telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.gsm.SIMFileHandler;
+import com.android.internal.telephony.IccFileHandler;
import java.util.Iterator;
import java.util.List;
@@ -52,8 +52,11 @@ class CommandParamsFactory extends Handler {
static final int REFRESH_NAA_INIT = 0x03;
static final int REFRESH_UICC_RESET = 0x04;
+ // Command Qualifier values for PLI command
+ static final int LANGUAGE_SETTING = 0x04;
+
static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller,
- SIMFileHandler fh) {
+ IccFileHandler fh) {
if (sInstance != null) {
return sInstance;
}
@@ -63,7 +66,7 @@ class CommandParamsFactory extends Handler {
return null;
}
- private CommandParamsFactory(RilMessageDecoder caller, SIMFileHandler fh) {
+ private CommandParamsFactory(RilMessageDecoder caller, IccFileHandler fh) {
mCaller = caller;
mIconLoader = IconLoader.getInstance(this, fh);
}
@@ -79,7 +82,7 @@ class CommandParamsFactory extends Handler {
try {
cmdDet = ValueParser.retrieveCommandDetails(ctlvCmdDet);
} catch (ResultException e) {
- StkLog.d(this, "Failed to procees command details");
+ CatLog.d(this, "Failed to procees command details");
}
}
}
@@ -112,7 +115,10 @@ class CommandParamsFactory extends Handler {
AppInterface.CommandType cmdType = AppInterface.CommandType
.fromInt(cmdDet.typeOfCommand);
if (cmdType == null) {
- sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
+ // This PROACTIVE COMMAND is presently not handled. Hence set
+ // result code as BEYOND_TERMINAL_CAPABILITY in TR.
+ mCmdParams = new CommandParams(cmdDet);
+ sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
return;
}
@@ -155,10 +161,13 @@ class CommandParamsFactory extends Handler {
case PLAY_TONE:
cmdPending = processPlayTone(cmdDet, ctlvs);
break;
+ case PROVIDE_LOCAL_INFORMATION:
+ cmdPending = processProvideLocalInfo(cmdDet, ctlvs);
+ break;
default:
// unsupported proactive commands
mCmdParams = new CommandParams(cmdDet);
- sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
+ sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
return;
}
} catch (ResultException e) {
@@ -259,7 +268,7 @@ class CommandParamsFactory extends Handler {
List<ComprehensionTlv> ctlvs)
throws ResultException {
- StkLog.d(this, "process DisplayText");
+ CatLog.d(this, "process DisplayText");
TextMessage textMsg = new TextMessage();
IconId iconId = null;
@@ -319,7 +328,7 @@ class CommandParamsFactory extends Handler {
private boolean processSetUpIdleModeText(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process SetUpIdleModeText");
+ CatLog.d(this, "process SetUpIdleModeText");
TextMessage textMsg = new TextMessage();
IconId iconId = null;
@@ -362,7 +371,7 @@ class CommandParamsFactory extends Handler {
private boolean processGetInkey(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process GetInkey");
+ CatLog.d(this, "process GetInkey");
Input input = new Input();
IconId iconId = null;
@@ -380,6 +389,12 @@ class CommandParamsFactory extends Handler {
iconId = ValueParser.retrieveIconId(ctlv);
}
+ // parse duration
+ ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
+ if (ctlv != null) {
+ input.duration = ValueParser.retrieveDuration(ctlv);
+ }
+
input.minLen = 1;
input.maxLen = 1;
@@ -412,7 +427,7 @@ class CommandParamsFactory extends Handler {
private boolean processGetInput(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process GetInput");
+ CatLog.d(this, "process GetInput");
Input input = new Input();
IconId iconId = null;
@@ -476,7 +491,7 @@ class CommandParamsFactory extends Handler {
private boolean processRefresh(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) {
- StkLog.d(this, "process Refresh");
+ CatLog.d(this, "process Refresh");
// REFRESH proactive command is rerouted by the baseband and handled by
// the telephony layer. IDLE TEXT should be removed for a REFRESH command
@@ -505,7 +520,7 @@ class CommandParamsFactory extends Handler {
private boolean processSelectItem(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process SelectItem");
+ CatLog.d(this, "process SelectItem");
Menu menu = new Menu();
IconId titleIconId = null;
@@ -534,7 +549,7 @@ class CommandParamsFactory extends Handler {
ctlv = searchForTag(ComprehensionTlvTag.ITEM_ID, ctlvs);
if (ctlv != null) {
- // STK items are listed 1...n while list start at 0, need to
+ // CAT items are listed 1...n while list start at 0, need to
// subtract one.
menu.defaultItem = ValueParser.retrieveItemId(ctlv) - 1;
}
@@ -602,7 +617,7 @@ class CommandParamsFactory extends Handler {
private boolean processEventNotify(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process EventNotify");
+ CatLog.d(this, "process EventNotify");
TextMessage textMsg = new TextMessage();
IconId iconId = null;
@@ -645,7 +660,7 @@ class CommandParamsFactory extends Handler {
private boolean processSetUpEventList(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) {
- StkLog.d(this, "process SetUpEventList");
+ CatLog.d(this, "process SetUpEventList");
//
// ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.EVENT_LIST,
// ctlvs);
@@ -670,10 +685,10 @@ class CommandParamsFactory extends Handler {
* asynchronous processing is required.
* @throws ResultException
*/
- private boolean processLaunchBrowser(CommandDetails cmdDet,
+ private boolean processLaunchBrowser(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process LaunchBrowser");
+ CatLog.d(this, "process LaunchBrowser");
TextMessage confirmMsg = new TextMessage();
IconId iconId = null;
@@ -744,10 +759,10 @@ class CommandParamsFactory extends Handler {
* asynchronous processing is required.t
* @throws ResultException
*/
- private boolean processPlayTone(CommandDetails cmdDet,
+ private boolean processPlayTone(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process PlayTone");
+ CatLog.d(this, "process PlayTone");
Tone tone = null;
TextMessage textMsg = new TextMessage();
@@ -810,9 +825,9 @@ class CommandParamsFactory extends Handler {
* @return true if the command is processing is pending and additional
* asynchronous processing is required.
*/
- private boolean processSetupCall(CommandDetails cmdDet,
+ private boolean processSetupCall(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
- StkLog.d(this, "process SetupCall");
+ CatLog.d(this, "process SetupCall");
Iterator<ComprehensionTlv> iter = ctlvs.iterator();
ComprehensionTlv ctlv = null;
@@ -863,4 +878,20 @@ class CommandParamsFactory extends Handler {
}
return false;
}
+
+ private boolean processProvideLocalInfo(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
+ throws ResultException {
+ CatLog.d(this, "process ProvideLocalInfo");
+ switch (cmdDet.commandQualifier) {
+ case LANGUAGE_SETTING:
+ CatLog.d(this, "PLI [LANGUAGE_SETTING]");
+ mCmdParams = new CommandParams(cmdDet);
+ break;
+ default:
+ CatLog.d(this, "PLI[" + cmdDet.commandQualifier + "] Command Not Supported");
+ mCmdParams = new CommandParams(cmdDet);
+ throw new ResultException(ResultCode.BEYOND_TERMINAL_CAPABILITY);
+ }
+ return false;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
index ffde6a3..99f662d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java
+++ b/telephony/java/com/android/internal/telephony/cat/ComprehensionTlv.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import java.util.ArrayList;
import java.util.List;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java b/telephony/java/com/android/internal/telephony/cat/Duration.java
index 9d8cc97..e8cd404 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java
+++ b/telephony/java/com/android/internal/telephony/cat/Duration.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * Class for representing "Duration" object for STK.
+ * Class for representing "Duration" object for CAT.
*
* {@hide}
*/
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java b/telephony/java/com/android/internal/telephony/cat/FontSize.java
index bd4f49f..02c7ea0 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java
+++ b/telephony/java/com/android/internal/telephony/cat/FontSize.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java b/telephony/java/com/android/internal/telephony/cat/IconLoader.java
index fc02d2a..2fa1811 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java
+++ b/telephony/java/com/android/internal/telephony/cat/IconLoader.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
-import com.android.internal.telephony.gsm.SIMFileHandler;
+import com.android.internal.telephony.IccFileHandler;
import android.graphics.Bitmap;
import android.graphics.Color;
@@ -40,7 +40,7 @@ class IconLoader extends Handler {
private ImageDescriptor mId = null;
private Bitmap mCurrentIcon = null;
private int mRecordNumber;
- private SIMFileHandler mSimFH = null;
+ private IccFileHandler mSimFH = null;
private Message mEndMsg = null;
private byte[] mIconData = null;
// multi icons state members
@@ -68,19 +68,19 @@ class IconLoader extends Handler {
private static final int CLUT_ENTRY_SIZE = 3;
- private IconLoader(Looper looper , SIMFileHandler fh) {
+ private IconLoader(Looper looper , IccFileHandler fh) {
super(looper);
mSimFH = fh;
mIconsCache = new HashMap<Integer, Bitmap>(50);
}
- static IconLoader getInstance(Handler caller, SIMFileHandler fh) {
+ static IconLoader getInstance(Handler caller, IccFileHandler fh) {
if (sLoader != null) {
return sLoader;
}
if (fh != null) {
- HandlerThread thread = new HandlerThread("Stk Icon Loader");
+ HandlerThread thread = new HandlerThread("Cat Icon Loader");
thread.start();
return new IconLoader(thread.getLooper(), fh);
}
@@ -163,7 +163,7 @@ class IconLoader extends Handler {
break;
}
} catch (Exception e) {
- StkLog.d(this, "Icon load failed");
+ CatLog.d(this, "Icon load failed");
// post null icon back to the caller.
postIcon();
}
@@ -254,7 +254,7 @@ class IconLoader extends Handler {
}
if (pixelIndex != numOfPixels) {
- StkLog.d("IconLoader", "parseToBnW; size error");
+ CatLog.d("IconLoader", "parseToBnW; size error");
}
return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888);
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
index 880b9e5..711d977 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java
+++ b/telephony/java/com/android/internal/telephony/cat/ImageDescriptor.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
* {@hide}
@@ -69,7 +69,7 @@ public class ImageDescriptor {
d.length = ((rawData[valueIndex++] & 0xff) << 8 | (rawData[valueIndex++] & 0xff));
} catch (IndexOutOfBoundsException e) {
- StkLog.d("ImageDescripter", "parse; failed parsing image descriptor");
+ CatLog.d("ImageDescripter", "parse; failed parsing image descriptor");
d = null;
}
return d;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java b/telephony/java/com/android/internal/telephony/cat/Input.java
index 19f724b..13a5ad4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java
+++ b/telephony/java/com/android/internal/telephony/cat/Input.java
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;
/**
- * Container class for STK GET INPUT, GET IN KEY commands parameters.
+ * Container class for CAT GET INPUT, GET IN KEY commands parameters.
*
*/
public class Input implements Parcelable {
@@ -36,6 +36,7 @@ public class Input implements Parcelable {
public boolean echo;
public boolean yesNo;
public boolean helpAvailable;
+ public Duration duration;
Input() {
text = "";
@@ -49,6 +50,7 @@ public class Input implements Parcelable {
echo = false;
yesNo = false;
helpAvailable = false;
+ duration = null;
}
private Input(Parcel in) {
@@ -63,6 +65,7 @@ public class Input implements Parcelable {
echo = in.readInt() == 1 ? true : false;
yesNo = in.readInt() == 1 ? true : false;
helpAvailable = in.readInt() == 1 ? true : false;
+ duration = in.readParcelable(null);
}
public int describeContents() {
@@ -81,6 +84,7 @@ public class Input implements Parcelable {
dest.writeInt(echo ? 1 : 0);
dest.writeInt(yesNo ? 1 : 0);
dest.writeInt(helpAvailable ? 1 : 0);
+ dest.writeParcelable(duration, 0);
}
public static final Parcelable.Creator<Input> CREATOR = new Parcelable.Creator<Input>() {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java b/telephony/java/com/android/internal/telephony/cat/Item.java
index b2f338c..d4702bb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java
+++ b/telephony/java/com/android/internal/telephony/cat/Item.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Parcel;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
index 302273c..af043d1 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java
+++ b/telephony/java/com/android/internal/telephony/cat/LaunchBrowserMode.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java b/telephony/java/com/android/internal/telephony/cat/Menu.java
index 331f69d..7bbae01 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java
+++ b/telephony/java/com/android/internal/telephony/cat/Menu.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Parcel;
@@ -24,7 +24,7 @@ import java.util.ArrayList;
import java.util.List;
/**
- * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters.
+ * Container class for CAT menu (SET UP MENU, SELECT ITEM) parameters.
*
*/
public class Menu implements Parcelable {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java b/telephony/java/com/android/internal/telephony/cat/PresentationType.java
index 71bdcdc..7c8cd8c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java
+++ b/telephony/java/com/android/internal/telephony/cat/PresentationType.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
index fab916e..95f0399 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResponseData.java
@@ -14,7 +14,7 @@
* the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.GsmAlphabet;
@@ -28,6 +28,16 @@ abstract class ResponseData {
* the ByteArrayOutputStream object.
*/
public abstract void format(ByteArrayOutputStream buf);
+
+ public static void writeLength(ByteArrayOutputStream buf, int length) {
+ // As per ETSI 102.220 Sec7.1.2, if the total length is greater
+ // than 0x7F, it should be coded in two bytes and the first byte
+ // should be 0x81.
+ if (length > 0x7F) {
+ buf.write(0x81);
+ }
+ buf.write(length);
+ }
}
class SelectItemResponseData extends ResponseData {
@@ -120,7 +130,7 @@ class GetInkeyInputResponseData extends ResponseData {
}
// length - one more for data coding scheme.
- buf.write(data.length + 1);
+ writeLength(buf, data.length + 1);
// data coding scheme
if (mIsUcs2) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java b/telephony/java/com/android/internal/telephony/cat/ResultCode.java
index b96a524..8544175 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResultCode.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java b/telephony/java/com/android/internal/telephony/cat/ResultException.java
index 2eb16c9..1c2cb63 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java
+++ b/telephony/java/com/android/internal/telephony/cat/ResultException.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
@@ -22,7 +22,7 @@ package com.android.internal.telephony.gsm.stk;
*
* {@hide}
*/
-public class ResultException extends StkException {
+public class ResultException extends CatException {
private ResultCode mResult;
private int mAdditionalInfo;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
index a82177c..a197c9a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java
+++ b/telephony/java/com/android/internal/telephony/cat/RilMessageDecoder.java
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
-import com.android.internal.telephony.gsm.SIMFileHandler;
+import com.android.internal.telephony.IccFileHandler;
import com.android.internal.telephony.IccUtils;
import android.os.Handler;
@@ -26,7 +26,7 @@ import android.os.Message;
/**
* Class used for queuing raw ril messages, decoding them into CommanParams
- * objects and sending the result back to the STK Service.
+ * objects and sending the result back to the CAT Service.
*/
class RilMessageDecoder extends HierarchicalStateMachine {
@@ -51,7 +51,7 @@ class RilMessageDecoder extends HierarchicalStateMachine {
* @param fh
* @return RilMesssageDecoder
*/
- public static synchronized RilMessageDecoder getInstance(Handler caller, SIMFileHandler fh) {
+ public static synchronized RilMessageDecoder getInstance(Handler caller, IccFileHandler fh) {
if (sInstance == null) {
sInstance = new RilMessageDecoder(caller, fh);
sInstance.start();
@@ -85,12 +85,12 @@ class RilMessageDecoder extends HierarchicalStateMachine {
}
private void sendCmdForExecution(RilMessage rilMsg) {
- Message msg = mCaller.obtainMessage(StkService.MSG_ID_RIL_MSG_DECODED,
+ Message msg = mCaller.obtainMessage(CatService.MSG_ID_RIL_MSG_DECODED,
new RilMessage(rilMsg));
msg.sendToTarget();
}
- private RilMessageDecoder(Handler caller, SIMFileHandler fh) {
+ private RilMessageDecoder(Handler caller, IccFileHandler fh) {
super("RilMessageDecoder");
addState(mStateStart);
@@ -108,7 +108,7 @@ class RilMessageDecoder extends HierarchicalStateMachine {
transitionTo(mStateCmdParamsReady);
}
} else {
- StkLog.d(this, "StateStart unexpected expecting START=" +
+ CatLog.d(this, "StateStart unexpected expecting START=" +
CMD_START + " got " + msg.what);
}
return true;
@@ -123,7 +123,7 @@ class RilMessageDecoder extends HierarchicalStateMachine {
sendCmdForExecution(mCurrentRilMessage);
transitionTo(mStateStart);
} else {
- StkLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
+ CatLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY="
+ CMD_PARAMS_READY + " got " + msg.what);
deferMessage(msg);
}
@@ -136,21 +136,21 @@ class RilMessageDecoder extends HierarchicalStateMachine {
mCurrentRilMessage = rilMsg;
switch(rilMsg.mId) {
- case StkService.MSG_ID_SESSION_END:
- case StkService.MSG_ID_CALL_SETUP:
+ case CatService.MSG_ID_SESSION_END:
+ case CatService.MSG_ID_CALL_SETUP:
mCurrentRilMessage.mResCode = ResultCode.OK;
sendCmdForExecution(mCurrentRilMessage);
decodingStarted = false;
break;
- case StkService.MSG_ID_PROACTIVE_COMMAND:
- case StkService.MSG_ID_EVENT_NOTIFY:
- case StkService.MSG_ID_REFRESH:
+ case CatService.MSG_ID_PROACTIVE_COMMAND:
+ case CatService.MSG_ID_EVENT_NOTIFY:
+ case CatService.MSG_ID_REFRESH:
byte[] rawData = null;
try {
rawData = IccUtils.hexStringToBytes((String) rilMsg.mData);
} catch (Exception e) {
// zombie messages are dropped
- StkLog.d(this, "decodeMessageParams dropping zombie messages");
+ CatLog.d(this, "decodeMessageParams dropping zombie messages");
decodingStarted = false;
break;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
index c5dd50e..7fb58a5 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextAlignment.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
index ace4300..0dea640 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextAttribute.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java b/telephony/java/com/android/internal/telephony/cat/TextColor.java
index 126fc62..6447e74 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextColor.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java b/telephony/java/com/android/internal/telephony/cat/TextMessage.java
index 3b6a09a..5ffd076 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java
+++ b/telephony/java/com/android/internal/telephony/cat/TextMessage.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.graphics.Bitmap;
import android.os.Parcel;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java b/telephony/java/com/android/internal/telephony/cat/Tone.java
index b64e777..27b4489 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java
+++ b/telephony/java/com/android/internal/telephony/cat/Tone.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
index 90cc6c1..6375afb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java
+++ b/telephony/java/com/android/internal/telephony/cat/ToneSettings.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java b/telephony/java/com/android/internal/telephony/cat/ValueParser.java
index 09a860e..34e4811 100644
--- a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java
+++ b/telephony/java/com/android/internal/telephony/cat/ValueParser.java
@@ -14,11 +14,11 @@
* the License.
*/
-package com.android.internal.telephony.gsm.stk;
+package com.android.internal.telephony.cat;
import com.android.internal.telephony.GsmAlphabet;
import com.android.internal.telephony.IccUtils;
-import com.android.internal.telephony.gsm.stk.Duration.TimeUnit;
+import com.android.internal.telephony.cat.Duration.TimeUnit;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -182,7 +182,7 @@ abstract class ValueParser {
*/
static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv)
throws ResultException {
- StkLog.d("ValueParser", "retrieveItemsIconId:");
+ CatLog.d("ValueParser", "retrieveItemsIconId:");
ItemsIconId id = new ItemsIconId();
byte[] rawValue = ctlv.getRawValue();
diff --git a/telephony/java/com/android/internal/telephony/cat/package.html b/telephony/java/com/android/internal/telephony/cat/package.html
new file mode 100644
index 0000000..5b6bfc6
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cat/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+Provides classes for ICC Toolkit Service (CAT).
+</BODY>
+</HTML>
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 7c4f337..1efae21 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -42,6 +42,7 @@ import android.telephony.SignalStrength;
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.CommandException;
@@ -108,7 +109,7 @@ public class CDMAPhone extends PhoneBase {
PhoneSubInfo mSubInfo;
EriManager mEriManager;
WakeLock mWakeLock;
-
+ CatService mCcatService;
// mNvLoadedRegistrants are informed after the EVENT_NV_READY
private RegistrantList mNvLoadedRegistrants = new RegistrantList();
@@ -160,6 +161,8 @@ public class CDMAPhone extends PhoneBase {
mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this, mSMS);
mSubInfo = new PhoneSubInfo(this);
mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML);
+ mCcatService = CatService.getInstance(mCM, mRuimRecords, mContext,
+ mIccFileHandler, mRuimCard);
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
mRuimRecords.registerForRecordsLoaded(this, EVENT_RUIM_RECORDS_LOADED, null);
@@ -220,6 +223,7 @@ public class CDMAPhone extends PhoneBase {
mCM.unregisterForNVReady(this); //EVENT_NV_READY
mSST.unregisterForNetworkAttach(this); //EVENT_REGISTERED_TO_NETWORK
mCM.unSetOnSuppServiceNotification(this);
+ removeCallbacks(mExitEcmRunnable);
mPendingMmis.clear();
@@ -235,6 +239,7 @@ public class CDMAPhone extends PhoneBase {
mRuimSmsInterfaceManager.dispose();
mSubInfo.dispose();
mEriManager.dispose();
+ mCcatService.dispose();
}
}
@@ -250,6 +255,8 @@ public class CDMAPhone extends PhoneBase {
this.mCT = null;
this.mSST = null;
this.mEriManager = null;
+ this.mCcatService = null;
+ this.mExitEcmRunnable = null;
}
protected void finalize() {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 2cad6cc..5b6bc1f 100644..100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -552,32 +552,53 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
@Override
- protected void powerOffRadioSafely(){
- // clean data connection
+ protected void powerOffRadioSafely() {
DataConnectionTracker dcTracker = phone.mDataConnection;
Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
- msg.arg1 = 1; // tearDown is true
msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
- dcTracker.sendMessage(msg);
- synchronized(this) {
- if (!mPendingRadioPowerOffAfterDataOff) {
- DataConnectionTracker.State currentState = dcTracker.getState();
- if (currentState != DataConnectionTracker.State.CONNECTED
- && currentState != DataConnectionTracker.State.DISCONNECTING
- && currentState != DataConnectionTracker.State.INITING) {
- if (DBG) log("Data disconnected, turn off radio right away.");
- hangupAndPowerOff();
- }
- else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
- if (DBG) {
- log("Wait up to 30 sec for data to disconnect, then turn off radio.");
+ synchronized (this) {
+ if (networkType == ServiceState.RADIO_TECHNOLOGY_1xRTT) {
+ /*
+ * In 1x CDMA , during radio power off modem will disconnect the
+ * data call and sends the power down registration message along
+ * with the data call release message to the network
+ */
+
+ msg.arg1 = 0; // tearDown is false since modem does it anyway for 1X
+ dcTracker.sendMessage(msg);
+
+ Log.w(LOG_TAG, "Turn off the radio right away");
+ hangupAndPowerOff();
+ } else {
+ if (!mPendingRadioPowerOffAfterDataOff) {
+ DataConnectionTracker.State currentState = dcTracker.getState();
+ if (currentState != DataConnectionTracker.State.CONNECTED
+ && currentState != DataConnectionTracker.State.DISCONNECTING
+ && currentState != DataConnectionTracker.State.INITING) {
+
+ msg.arg1 = 0; // tearDown is false as it is not needed.
+ dcTracker.sendMessage(msg);
+
+ if (DBG)
+ log("Data disconnected, turn off radio right away.");
+ hangupAndPowerOff();
+ } else {
+ // clean data connection
+ msg.arg1 = 1; // tearDown is true
+ dcTracker.sendMessage(msg);
+
+ if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 30000)) {
+ if (DBG) {
+ log("Wait upto 30s for data to disconnect, then turn off radio.");
+ }
+ mPendingRadioPowerOffAfterDataOff = true;
+ } else {
+ Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
+ hangupAndPowerOff();
+ }
}
- mPendingRadioPowerOffAfterDataOff = true;
- } else {
- Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
- hangupAndPowerOff();
}
}
}
@@ -653,8 +674,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
return;
}
- if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW &&
- err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
+ if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
Log.e(LOG_TAG,
"RIL implementation has returned an error where it must succeed",
ar.exception);
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
index 6e12f24..dd1efdf 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimPhoneBookInterfaceManager.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony.cdma;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import android.os.Message;
import android.util.Log;
@@ -56,14 +58,11 @@ public class RuimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager
recordSize = new int[3];
//Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
- Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE);
+ AtomicBoolean status = new AtomicBoolean(false);
+ Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- logd("interrupted while trying to load from the RUIM");
- }
+ waitForResult(status);
}
return recordSize;
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index 87b0c60..3429099 100644..100755
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -16,10 +16,13 @@
package com.android.internal.telephony.cdma;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.Registrant;
+import android.os.SystemProperties;
import android.util.Log;
import com.android.internal.telephony.AdnRecord;
@@ -59,6 +62,7 @@ public final class RuimRecords extends IccRecords {
private static final int EVENT_RUIM_READY = 1;
private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
+ private static final int EVENT_GET_IMSI_DONE = 3;
private static final int EVENT_GET_DEVICE_IDENTITY_DONE = 4;
private static final int EVENT_GET_ICCID_DONE = 5;
private static final int EVENT_GET_CDMA_SUBSCRIPTION_DONE = 10;
@@ -114,6 +118,9 @@ public final class RuimRecords extends IccRecords {
adnCache.reset();
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_NUMERIC, null);
+ phone.setSystemProperty(PROPERTY_ICC_OPERATOR_ISO_COUNTRY, null);
+
// recordsRequested is set to false indicating that the SIM
// read requests made so far are not valid. This is set to
// true only when fresh set of read requests are made.
@@ -201,6 +208,33 @@ public final class RuimRecords extends IccRecords {
break;
/* IO events */
+ case EVENT_GET_IMSI_DONE:
+ isRecordLoadResponse = true;
+
+ ar = (AsyncResult)msg.obj;
+ if (ar.exception != null) {
+ Log.e(LOG_TAG, "Exception querying IMSI, Exception:" + ar.exception);
+ break;
+ }
+
+ mImsi = (String) ar.result;
+
+ // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more
+ // than 15 (and usually 15).
+ if (mImsi != null && (mImsi.length() < 6 || mImsi.length() > 15)) {
+ Log.e(LOG_TAG, "invalid IMSI " + mImsi);
+ mImsi = null;
+ }
+
+ Log.d(LOG_TAG, "IMSI: " + mImsi.substring(0, 6) + "xxxxxxxxx");
+
+ String operatorNumeric = getRUIMOperatorNumeric();
+ if (operatorNumeric != null) {
+ if(operatorNumeric.length() <= 6){
+ MccTable.updateMccMncConfiguration(phone, operatorNumeric);
+ }
+ }
+ break;
case EVENT_GET_CDMA_SUBSCRIPTION_DONE:
ar = (AsyncResult)msg.obj;
@@ -291,6 +325,13 @@ public final class RuimRecords extends IccRecords {
// Further records that can be inserted are Operator/OEM dependent
+ String operator = getRUIMOperatorNumeric();
+ SystemProperties.set(PROPERTY_ICC_OPERATOR_NUMERIC, operator);
+
+ if (mImsi != null) {
+ SystemProperties.set(PROPERTY_ICC_OPERATOR_ISO_COUNTRY,
+ MccTable.countryCodeForMcc(Integer.parseInt(mImsi.substring(0,3))));
+ }
recordsLoadedRegistrants.notifyRegistrants(
new AsyncResult(null, null, null));
((CDMAPhone) phone).mRuimCard.broadcastIccStateChangedIntent(
@@ -317,6 +358,9 @@ public final class RuimRecords extends IccRecords {
Log.v(LOG_TAG, "RuimRecords:fetchRuimRecords " + recordsToLoad);
+ phone.mCM.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE));
+ recordsToLoad++;
+
phone.getIccFileHandler().loadEFTransparent(EF_ICCID,
obtainMessage(EVENT_GET_ICCID_DONE));
recordsToLoad++;
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index a1f20f8..676a828 100755..100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -30,8 +30,10 @@ import com.android.internal.telephony.SmsMessageBase;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.cdma.sms.BearerData;
import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
+import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
import com.android.internal.telephony.cdma.sms.UserData;
+import com.android.internal.util.BitwiseInputStream;
import com.android.internal.util.HexDump;
import java.io.BufferedInputStream;
@@ -72,6 +74,16 @@ public class SmsMessage extends SmsMessageBase {
static final String LOG_TAG = "CDMA";
static private final String LOGGABLE_TAG = "CDMA:SMS";
+ private final static byte TELESERVICE_IDENTIFIER = 0x00;
+ private final static byte SERVICE_CATEGORY = 0x01;
+ private final static byte ORIGINATING_ADDRESS = 0x02;
+ private final static byte ORIGINATING_SUB_ADDRESS = 0x03;
+ private final static byte DESTINATION_ADDRESS = 0x04;
+ private final static byte DESTINATION_SUB_ADDRESS = 0x05;
+ private final static byte BEARER_REPLY_OPTION = 0x06;
+ private final static byte CAUSE_CODES = 0x07;
+ private final static byte BEARER_DATA = 0x08;
+
/**
* Status of a previously submitted SMS.
* This field applies to SMS Delivery Acknowledge messages. 0 indicates success;
@@ -139,6 +151,7 @@ public class SmsMessage extends SmsMessageBase {
SmsMessage msg = new SmsMessage();
SmsEnvelope env = new SmsEnvelope();
CdmaSmsAddress addr = new CdmaSmsAddress();
+ CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress();
byte[] data;
byte count;
int countInt;
@@ -181,15 +194,24 @@ public class SmsMessage extends SmsMessageBase {
addr.origBytes = data;
- // ignore subaddress
- p.readInt(); //p_cur->sSubAddress.subaddressType
- p.readInt(); //p_cur->sSubAddress.odd
- count = p.readByte(); //p_cur->sSubAddress.number_of_digits
- //p_cur->sSubAddress.digits[digitCount] :
- for (int index=0; index < count; index++) {
- p.readByte();
+ subaddr.type = p.readInt(); // p_cur->sSubAddress.subaddressType
+ subaddr.odd = p.readByte(); // p_cur->sSubAddress.odd
+ count = p.readByte(); // p_cur->sSubAddress.number_of_digits
+
+ if (count < 0) {
+ count = 0;
+ }
+
+ // p_cur->sSubAddress.digits[digitCount] :
+
+ data = new byte[count];
+
+ for (int index = 0; index < count; ++index) {
+ data[index] = p.readByte();
}
+ subaddr.origBytes = data;
+
/* currently not supported by the modem-lib:
env.bearerReply
env.replySeqNo
@@ -211,6 +233,7 @@ public class SmsMessage extends SmsMessageBase {
// link the the filled objects to the SMS
env.origAddress = addr;
+ env.origSubaddress = subaddr;
msg.originatingAddress = addr;
msg.mEnvelope = env;
@@ -256,6 +279,7 @@ public class SmsMessage extends SmsMessageBase {
System.arraycopy(data, 2, pdu, 0, size);
// the message has to be parsed before it can be displayed
// see gsm.SmsMessage
+ msg.parsePduFromEfRecord(pdu);
return msg;
} catch (RuntimeException ex) {
Log.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
@@ -528,6 +552,143 @@ public class SmsMessage extends SmsMessageBase {
}
/**
+ * Decodes 3GPP2 sms stored in CSIM/RUIM cards As per 3GPP2 C.S0015-0
+ */
+ private void parsePduFromEfRecord(byte[] pdu) {
+ ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
+ DataInputStream dis = new DataInputStream(bais);
+ SmsEnvelope env = new SmsEnvelope();
+ CdmaSmsAddress addr = new CdmaSmsAddress();
+ CdmaSmsSubaddress subAddr = new CdmaSmsSubaddress();
+
+ try {
+ env.messageType = dis.readByte();
+
+ while (dis.available() > 0) {
+ int parameterId = dis.readByte();
+ int parameterLen = dis.readByte();
+ byte[] parameterData = new byte[parameterLen];
+
+ switch (parameterId) {
+ case TELESERVICE_IDENTIFIER:
+ /*
+ * 16 bit parameter that identifies which upper layer
+ * service access point is sending or should receive
+ * this message
+ */
+ env.teleService = dis.readUnsignedShort();
+ Log.i(LOG_TAG, "teleservice = " + env.teleService);
+ break;
+ case SERVICE_CATEGORY:
+ /*
+ * 16 bit parameter that identifies type of service as
+ * in 3GPP2 C.S0015-0 Table 3.4.3.2-1
+ */
+ env.serviceCategory = dis.readUnsignedShort();
+ break;
+ case ORIGINATING_ADDRESS:
+ case DESTINATION_ADDRESS:
+ dis.read(parameterData, 0, parameterLen);
+ BitwiseInputStream addrBis = new BitwiseInputStream(parameterData);
+ addr.digitMode = addrBis.read(1);
+ addr.numberMode = addrBis.read(1);
+ int numberType = 0;
+ if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
+ numberType = addrBis.read(3);
+ addr.ton = numberType;
+
+ if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK)
+ addr.numberPlan = addrBis.read(4);
+ }
+
+ addr.numberOfDigits = addrBis.read(8);
+
+ byte[] data = new byte[addr.numberOfDigits];
+ byte b = 0x00;
+
+ if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
+ /* As per 3GPP2 C.S0005-0 Table 2.7.1.3.2.4-4 */
+ for (int index = 0; index < addr.numberOfDigits; index++) {
+ b = (byte) (0xF & addrBis.read(4));
+ // convert the value if it is 4-bit DTMF to 8
+ // bit
+ data[index] = convertDtmfToAscii(b);
+ }
+ } else if (addr.digitMode == CdmaSmsAddress.DIGIT_MODE_8BIT_CHAR) {
+ if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_NOT_DATA_NETWORK) {
+ for (int index = 0; index < addr.numberOfDigits; index++) {
+ b = (byte) (0xFF & addrBis.read(8));
+ data[index] = b;
+ }
+
+ } else if (addr.numberMode == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK) {
+ if (numberType == 2)
+ Log.e(LOG_TAG, "TODO: Originating Addr is email id");
+ else
+ Log.e(LOG_TAG,
+ "TODO: Originating Addr is data network address");
+ } else {
+ Log.e(LOG_TAG, "Originating Addr is of incorrect type");
+ }
+ } else {
+ Log.e(LOG_TAG, "Incorrect Digit mode");
+ }
+ addr.origBytes = data;
+ Log.i(LOG_TAG, "Originating Addr=" + addr.toString());
+ break;
+ case ORIGINATING_SUB_ADDRESS:
+ case DESTINATION_SUB_ADDRESS:
+ dis.read(parameterData, 0, parameterLen);
+ BitwiseInputStream subAddrBis = new BitwiseInputStream(parameterData);
+ subAddr.type = subAddrBis.read(3);
+ subAddr.odd = subAddrBis.readByteArray(1)[0];
+ int subAddrLen = subAddrBis.read(8);
+ byte[] subdata = new byte[subAddrLen];
+ for (int index = 0; index < subAddrLen; index++) {
+ b = (byte) (0xFF & subAddrBis.read(4));
+ // convert the value if it is 4-bit DTMF to 8 bit
+ subdata[index] = convertDtmfToAscii(b);
+ }
+ subAddr.origBytes = subdata;
+ break;
+ case BEARER_REPLY_OPTION:
+ dis.read(parameterData, 0, parameterLen);
+ BitwiseInputStream replyOptBis = new BitwiseInputStream(parameterData);
+ env.bearerReply = replyOptBis.read(6);
+ break;
+ case CAUSE_CODES:
+ dis.read(parameterData, 0, parameterLen);
+ BitwiseInputStream ccBis = new BitwiseInputStream(parameterData);
+ env.replySeqNo = ccBis.readByteArray(6)[0];
+ env.errorClass = ccBis.readByteArray(2)[0];
+ if (env.errorClass != 0x00)
+ env.causeCode = ccBis.readByteArray(8)[0];
+ break;
+ case BEARER_DATA:
+ dis.read(parameterData, 0, parameterLen);
+ env.bearerData = parameterData;
+ break;
+ default:
+ throw new Exception("unsupported parameterId (" + parameterId + ")");
+ }
+ }
+ bais.close();
+ dis.close();
+ } catch (Exception ex) {
+ Log.e(LOG_TAG, "parsePduFromEfRecord: conversion from pdu to SmsMessage failed" + ex);
+ }
+
+ // link the filled objects to this SMS
+ originatingAddress = addr;
+ env.origAddress = addr;
+ env.origSubaddress = subAddr;
+ mEnvelope = env;
+ mPdu = pdu;
+
+ parseSms();
+ }
+
+ /**
* Parses a SMS message from its BearerData stream. (mobile-terminated only)
*/
protected void parseSms() {
@@ -824,6 +985,8 @@ public class SmsMessage extends SmsMessageBase {
output.write(mEnvelope.teleService);
output.write(mEnvelope.origAddress.origBytes, 0, mEnvelope.origAddress.origBytes.length);
output.write(mEnvelope.bearerData, 0, mEnvelope.bearerData.length);
+ output.write(mEnvelope.origSubaddress.origBytes, 0,
+ mEnvelope.origSubaddress.origBytes.length);
return output.toByteArray();
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index 5b21ec1..58b0355 100755
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -585,7 +585,6 @@ public final class BearerData {
uData.payload = new byte[0];
uData.numFields = 0;
} else {
- uData.payload = uData.payload;
uData.numFields = uData.payload.length;
}
} else {
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java
new file mode 100644
index 0000000..f9cebf5
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/CdmaSmsSubaddress.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project. All rights reserved.
+ * Copyright (C) 2010 Code Aurora Forum. All rights reserved.
+ *
+ * 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.cdma.sms;
+
+public class CdmaSmsSubaddress {
+ public int type;
+
+ public byte odd;
+
+ public byte[] origBytes;
+}
+
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
index 0dcacc1..4f00163 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
@@ -17,6 +17,8 @@
package com.android.internal.telephony.cdma.sms;
+import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
+
public final class SmsEnvelope{
/**
* Message Types
@@ -74,17 +76,23 @@ public final class SmsEnvelope{
/**
* The origination address identifies the originator of the SMS message.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
*/
public CdmaSmsAddress origAddress;
/**
* The destination address identifies the target of the SMS message.
- * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.3)
*/
public CdmaSmsAddress destAddress;
/**
+ * The origination subaddress identifies the originator of the SMS message.
+ * (See 3GPP2 C.S0015-B, v2, 3.4.3.4)
+ */
+ public CdmaSmsSubaddress origSubaddress;
+
+ /**
* The 6-bit bearer reply parameter is used to request the return of a
* SMS Acknowledge Message.
* (See 3GPP2 C.S0015-B, v2, 3.4.3.5)
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index f128f5b..c5be856 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -49,6 +49,7 @@ import static com.android.internal.telephony.CommandsInterface.CF_REASON_UNCONDI
import static com.android.internal.telephony.CommandsInterface.SERVICE_CLASS_VOICE;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION;
+import com.android.internal.telephony.cat.CatService;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallForwardInfo;
import com.android.internal.telephony.CallStateException;
@@ -68,7 +69,6 @@ import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.PhoneSubInfo;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.gsm.stk.StkService;
import com.android.internal.telephony.test.SimulatedRadioControl;
import com.android.internal.telephony.IccVmNotSupportedException;
@@ -102,7 +102,7 @@ public class GSMPhone extends PhoneBase {
GsmSMSDispatcher mSMS;
SIMRecords mSIMRecords;
SimCard mSimCard;
- StkService mStkService;
+ CatService mStkService;
ArrayList <GsmMmiCode> mPendingMMIs = new ArrayList<GsmMmiCode>();
SimPhoneBookInterfaceManager mSimPhoneBookIntManager;
SimSmsInterfaceManager mSimSmsIntManager;
@@ -150,7 +150,7 @@ public class GSMPhone extends PhoneBase {
mSimSmsIntManager = new SimSmsInterfaceManager(this, mSMS);
mSubInfo = new PhoneSubInfo(this);
}
- mStkService = StkService.getInstance(mCM, mSIMRecords, mContext,
+ mStkService = CatService.getInstance(mCM, mSIMRecords, mContext,
(SIMFileHandler)mIccFileHandler, mSimCard);
mCM.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
@@ -968,7 +968,9 @@ public class GSMPhone extends PhoneBase {
}
public void getCallWaiting(Message onComplete) {
- mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
+ //As per 3GPP TS 24.083, section 1.6 UE doesn't need to send service
+ //class parameter in call waiting interrogation to network
+ mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_NONE, onComplete);
}
public void setCallWaiting(boolean enable, Message onComplete) {
@@ -1221,7 +1223,8 @@ public class GSMPhone extends PhoneBase {
// Check if this is a different SIM than the previous one. If so unset the
// voice mail number.
String imsi = getVmSimImsi();
- if (imsi != null && !getSubscriberId().equals(imsi)) {
+ String imsiFromSIM = getSubscriberId();
+ if (imsi != null && imsiFromSIM != null && !imsiFromSIM.equals(imsi)) {
storeVoiceMailNumber(null);
setVmSimImsi(null);
}
@@ -1498,4 +1501,8 @@ public class GSMPhone extends PhoneBase {
Log.e(LOG_TAG, "[GSMPhone] setCellBroadcastSmsConfig() is obsolete; use SmsManager");
response.sendToTarget();
}
+
+ public boolean isCspPlmnEnabled() {
+ return mSIMRecords.isCspPlmnEnabled();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 5c7ce2f..2962e0f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -44,6 +44,13 @@ public final class GsmMmiCode extends Handler implements MmiCode {
//***** Constants
+ // Max Size of the Short Code (aka Short String from TS 22.030 6.5.2)
+ static final int MAX_LENGTH_SHORT_CODE = 2;
+
+ // TS 22.030 6.5.2 Every Short String USSD command will end with #-key
+ // (known as #-String)
+ static final char END_OF_USSD_COMMAND = '#';
+
// From TS 22.030 6.5.2
static final String ACTION_ACTIVATE = "*";
static final String ACTION_DEACTIVATE = "#";
@@ -471,22 +478,69 @@ public final class GsmMmiCode extends Handler implements MmiCode {
}
/**
- * Helper function for newFromDialString. Returns true if dialString appears to be a short code
- * AND conditions are correct for it to be treated as such.
+ * Helper function for newFromDialString. Returns true if dialString appears
+ * to be a short code AND conditions are correct for it to be treated as
+ * such.
*/
static private boolean isShortCode(String dialString, GSMPhone phone) {
// Refer to TS 22.030 Figure 3.5.3.2:
- // A 1 or 2 digit "short code" is treated as USSD if it is entered while on a call or
- // does not satisfy the condition (exactly 2 digits && starts with '1').
- return ((dialString != null && dialString.length() <= 2)
- && !PhoneNumberUtils.isEmergencyNumber(dialString)
- && (phone.isInCall()
- || !((dialString.length() == 2 && dialString.charAt(0) == '1')
- /* While contrary to TS 22.030, there is strong precedence
- * for treating "0" and "00" as call setup strings.
- */
- || dialString.equals("0")
- || dialString.equals("00"))));
+ if (dialString == null) {
+ return false;
+ }
+
+ // Illegal dial string characters will give a ZERO length.
+ // At this point we do not want to crash as any application with
+ // call privileges may send a non dial string.
+ // It return false as when the dialString is equal to NULL.
+ if (dialString.length() == 0) {
+ return false;
+ }
+
+ if (PhoneNumberUtils.isEmergencyNumber(dialString)) {
+ return false;
+ } else {
+ return isShortCodeUSSD(dialString, phone);
+ }
+ }
+
+ /**
+ * Helper function for isShortCode. Returns true if dialString appears to be
+ * a short code and it is a USSD structure
+ *
+ * According to the 3PGG TS 22.030 specification Figure 3.5.3.2: A 1 or 2
+ * digit "short code" is treated as USSD if it is entered while on a call or
+ * does not satisfy the condition (exactly 2 digits && starts with '1'), there
+ * are however exceptions to this rule (see below)
+ *
+ * Exception (1) to Call initiation is: If the user of the device is already in a call
+ * and enters a Short String without any #-key at the end and the length of the Short String is
+ * equal or less then the MAX_LENGTH_SHORT_CODE [constant that is equal to 2]
+ *
+ * The phone shall initiate a USSD/SS commands.
+ *
+ * Exception (2) to Call initiation is: If the user of the device enters one
+ * Digit followed by the #-key. This rule defines this String as the
+ * #-String which is a USSD/SS command.
+ *
+ * The phone shall initiate a USSD/SS command.
+ */
+ static private boolean isShortCodeUSSD(String dialString, GSMPhone phone) {
+ if (dialString != null) {
+ if (phone.isInCall()) {
+ // The maximum length of a Short Code (aka Short String) is 2
+ if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
+ return true;
+ }
+ }
+
+ // The maximum length of a Short Code (aka Short String) is 2
+ if (dialString.length() <= MAX_LENGTH_SHORT_CODE) {
+ if (dialString.charAt(dialString.length() - 1) == END_OF_USSD_COMMAND) {
+ return true;
+ }
+ }
+ }
+ return false;
}
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 6ddb312..18ef121 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -643,8 +643,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
return;
}
- if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW &&
- err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
+ if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
Log.e(LOG_TAG,
"RIL implementation has returned an error where it must succeed" +
ar.exception);
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
index 206e62f..e8d10f9 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java
@@ -81,6 +81,7 @@ public final class SIMFileHandler extends IccFileHandler implements IccConstants
case EF_SPN_CPHS:
case EF_SPN_SHORT_CPHS:
case EF_INFO_CPHS:
+ case EF_CSP_CPHS:
return MF_SIM + DF_GSM;
case EF_PBR:
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index e214061..3b133da 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -73,6 +73,7 @@ public final class SIMRecords extends IccRecords {
* mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
*/
private byte[] mCphsInfo = null;
+ boolean mCspPlmnEnabled = true;
byte[] efMWIS = null;
byte[] efCPHS_MWI =null;
@@ -93,6 +94,7 @@ public final class SIMRecords extends IccRecords {
static final int SPN_RULE_SHOW_PLMN = 0x02;
// From TS 51.011 EF[SPDI] section
+ static final int TAG_SPDI = 0xA3;
static final int TAG_SPDI_PLMN_LIST = 0x80;
// Full Name IEI from TS 24.008
@@ -140,6 +142,7 @@ public final class SIMRecords extends IccRecords {
private static final int EVENT_SET_MSISDN_DONE = 30;
private static final int EVENT_SIM_REFRESH = 31;
private static final int EVENT_GET_CFIS_DONE = 32;
+ private static final int EVENT_GET_CSP_CPHS_DONE = 33;
// Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
@@ -589,6 +592,13 @@ public final class SIMRecords extends IccRecords {
break;
case EVENT_GET_CPHS_MAILBOX_DONE:
case EVENT_GET_MBDN_DONE:
+ //Resetting the voice mail number and voice mail tag to null
+ //as these should be updated from the data read from EF_MBDN.
+ //If they are not reset, incase of invalid data/exception these
+ //variables are retaining their previous values and are
+ //causing invalid voice mailbox info display to user.
+ voiceMailNum = null;
+ voiceMailTag = null;
isRecordLoadResponse = true;
ar = (AsyncResult)msg.obj;
@@ -1035,6 +1045,22 @@ public final class SIMRecords extends IccRecords {
((GSMPhone) phone).notifyCallForwardingIndicator();
break;
+ case EVENT_GET_CSP_CPHS_DONE:
+ isRecordLoadResponse = true;
+
+ ar = (AsyncResult)msg.obj;
+
+ if (ar.exception != null) {
+ Log.e(LOG_TAG,"Exception in fetching EF_CSP data " + ar.exception);
+ break;
+ }
+
+ data = (byte[])ar.result;
+
+ Log.i(LOG_TAG,"EF_CSP: " + IccUtils.bytesToHexString(data));
+ handleEfCspData(data);
+ break;
+
}}catch (RuntimeException exc) {
// I don't want these exceptions to be fatal
Log.w(LOG_TAG, "Exception parsing SIM record", exc);
@@ -1058,6 +1084,12 @@ public final class SIMRecords extends IccRecords {
new AdnRecordLoader(phone).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
break;
+ case EF_CSP_CPHS:
+ recordsToLoad++;
+ Log.i(LOG_TAG, "[CSP] SIM Refresh for EF_CSP_CPHS");
+ phone.getIccFileHandler().loadEFTransparent(EF_CSP_CPHS,
+ obtainMessage(EVENT_GET_CSP_CPHS_DONE));
+ break;
default:
// For now, fetch all records if this is not a
// voicemail number.
@@ -1288,6 +1320,9 @@ public final class SIMRecords extends IccRecords {
iccFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
recordsToLoad++;
+ iccFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
+ recordsToLoad++;
+
// XXX should seek instead of examining them all
if (false) { // XXX
iccFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
@@ -1467,8 +1502,12 @@ public final class SIMRecords extends IccRecords {
byte[] plmnEntries = null;
- // There should only be one TAG_SPDI_PLMN_LIST
for ( ; tlv.isValidObject() ; tlv.nextObject()) {
+ // Skip SPDI tag, if existant
+ if (tlv.getTag() == TAG_SPDI) {
+ tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length);
+ }
+ // There should only be one TAG_SPDI_PLMN_LIST
if (tlv.getTag() == TAG_SPDI_PLMN_LIST) {
plmnEntries = tlv.getData();
break;
@@ -1505,4 +1544,53 @@ public final class SIMRecords extends IccRecords {
Log.d(LOG_TAG, "[SIMRecords] " + s);
}
+ /**
+ * Return true if "Restriction of menu options for manual PLMN selection"
+ * bit is set or EF_CSP data is unavailable, return false otherwise.
+ */
+ public boolean isCspPlmnEnabled() {
+ return mCspPlmnEnabled;
+ }
+
+ /**
+ * Parse EF_CSP data and check if
+ * "Restriction of menu options for manual PLMN selection" is
+ * Enabled/Disabled
+ *
+ * @param data EF_CSP hex data.
+ */
+ private void handleEfCspData(byte[] data) {
+ // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined
+ // 18 bytes (i.e 9 service groups info) and additional data specific to
+ // operator. The valueAddedServicesGroup is not part of standard
+ // services. This is operator specific and can be programmed any where.
+ // Normally this is programmed as 10th service after the standard
+ // services.
+ int usedCspGroups = data.length / 2;
+ // This is the "Servive Group Number" of "Value Added Services Group".
+ byte valueAddedServicesGroup = (byte)0xC0;
+
+ mCspPlmnEnabled = true;
+ for (int i = 0; i < usedCspGroups; i++) {
+ if (data[2 * i] == valueAddedServicesGroup) {
+ Log.i(LOG_TAG, "[CSP] found ValueAddedServicesGroup, value "
+ + data[(2 * i) + 1]);
+ if ((data[(2 * i) + 1] & 0x80) == 0x80) {
+ // Bit 8 is for
+ // "Restriction of menu options for manual PLMN selection".
+ // Operator Selection menu should be enabled.
+ mCspPlmnEnabled = true;
+ } else {
+ mCspPlmnEnabled = false;
+ // Operator Selection menu should be disabled.
+ // Operator Selection Mode should be set to Automatic.
+ Log.i(LOG_TAG,"[CSP] Set Automatic Network Selection");
+ phone.setNetworkSelectionModeAutomatic(null);
+ }
+ return;
+ }
+ }
+
+ Log.w(LOG_TAG, "[CSP] Value Added Service Group (0xC0), not found!");
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
index feb508a..001e1bd 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java
@@ -16,6 +16,8 @@
package com.android.internal.telephony.gsm;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import android.os.Message;
import android.util.Log;
@@ -56,14 +58,11 @@ public class SimPhoneBookInterfaceManager extends IccPhoneBookInterfaceManager {
recordSize = new int[3];
//Using mBaseHandler, no difference in EVENT_GET_SIZE_DONE handling
- Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE);
+ AtomicBoolean status = new AtomicBoolean(false);
+ Message response = mBaseHandler.obtainMessage(EVENT_GET_SIZE_DONE, status);
phone.getIccFileHandler().getEFLinearRecordSize(efid, response);
- try {
- mLock.wait();
- } catch (InterruptedException e) {
- logd("interrupted while trying to load from the SIM");
- }
+ waitForResult(status);
}
return recordSize;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
index c2e3008..6e87f21 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java
@@ -17,6 +17,7 @@
package com.android.internal.telephony.gsm;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.AsyncResult;
import android.os.Binder;
import android.os.Handler;
@@ -50,6 +51,8 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
private final Object mLock = new Object();
private boolean mSuccess;
private List<SmsRawData> mSms;
+ private HashMap<Integer, HashSet<String>> mCellBroadcastSubscriptions =
+ new HashMap<Integer, HashSet<String>>();
private CellBroadcastRangeManager mCellBroadcastRangeManager =
new CellBroadcastRangeManager();
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index d16d426..0be9466 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -24,6 +24,7 @@ import android.util.Log;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.GsmAlphabet;
+import com.android.internal.telephony.SimRegionCache;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
@@ -46,6 +47,12 @@ import static android.telephony.SmsMessage.MessageClass;
public class SmsMessage extends SmsMessageBase{
static final String LOG_TAG = "GSM";
+ /**
+ * Used with the ENCODING_ constants from {@link android.telephony.SmsMessage}
+ * Not a part of the public API, therefore not in order with those constants.
+ */
+ private static final int ENCODING_KSC5601 = 4000;
+
private MessageClass messageClass;
/**
@@ -730,6 +737,28 @@ public class SmsMessage extends SmsMessageBase{
return ret;
}
+ /**
+ * Interprets the user data payload as KSC5601 characters, and
+ * decodes them into a String
+ *
+ * @param byteCount the number of bytes in the user data payload
+ * @return a String with the decoded characters
+ */
+ String getUserDataKSC5601(int byteCount) {
+ String ret;
+
+ try {
+ ret = new String(pdu, cur, byteCount, "KSC5601");
+ } catch (UnsupportedEncodingException ex) {
+ // Should return same as ENCODING_UNKNOWN on error.
+ ret = null;
+ Log.e(LOG_TAG, "implausible UnsupportedEncodingException", ex);
+ }
+
+ cur += byteCount;
+ return ret;
+ }
+
boolean moreDataPresent() {
return (pdu.length > cur);
}
@@ -867,6 +896,8 @@ public class SmsMessage extends SmsMessageBase{
// TP-Message-Type-Indicator
// 9.2.3
case 0:
+ case 3: //GSM 03.40 9.2.3.1: MTI == 3 is Reserved.
+ //This should be processed in the same way as MTI == 0 (Deliver)
parseSmsDeliver(p, firstByte);
break;
case 2:
@@ -1045,6 +1076,10 @@ public class SmsMessage extends SmsMessageBase{
} else {
Log.w(LOG_TAG, "3 - Unsupported SMS data coding scheme "
+ (dataCodingScheme & 0xff));
+ if (SimRegionCache.getRegion() == SimRegionCache.MCC_KOREAN) {
+ Log.w(LOG_TAG, "Korean SIM, using KSC5601 for decoding.");
+ encodingType = ENCODING_KSC5601;
+ }
}
// set both the user data and the user data header.
@@ -1068,6 +1103,10 @@ public class SmsMessage extends SmsMessageBase{
case ENCODING_16BIT:
messageBody = p.getUserDataUCS2(count);
break;
+
+ case ENCODING_KSC5601:
+ messageBody = p.getUserDataKSC5601(count);
+ break;
}
if (Config.LOGV) Log.v(LOG_TAG, "SMS message body (raw): '" + messageBody + "'");
diff --git a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
index 6458fda..ec3d20a 100644..100755
--- a/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
+++ b/telephony/java/com/android/internal/telephony/gsm/UsimPhoneBookManager.java
@@ -53,6 +53,7 @@ public class UsimPhoneBookManager extends Handler implements IccConstants {
private ArrayList<byte[]> mIapFileRecord;
private ArrayList<byte[]> mEmailFileRecord;
private Map<Integer, ArrayList<String>> mEmailsForAdnRec;
+ private boolean mRefreshCache = false;
private static final int EVENT_PBR_LOAD_DONE = 1;
private static final int EVENT_USIM_ADN_LOAD_DONE = 2;
@@ -91,11 +92,19 @@ public class UsimPhoneBookManager extends Handler implements IccConstants {
mEmailFileRecord = null;
mPbrFile = null;
mIsPbrPresent = true;
+ mRefreshCache = false;
}
public ArrayList<AdnRecord> loadEfFilesFromUsim() {
synchronized (mLock) {
- if (!mPhoneBookRecords.isEmpty()) return mPhoneBookRecords;
+ if (!mPhoneBookRecords.isEmpty()) {
+ if (mRefreshCache) {
+ mRefreshCache = false;
+ refreshCache();
+ }
+ return mPhoneBookRecords;
+ }
+
if (!mIsPbrPresent) return null;
// Check if the PBR file is present in the cache, if not read it
@@ -116,6 +125,20 @@ public class UsimPhoneBookManager extends Handler implements IccConstants {
return mPhoneBookRecords;
}
+ private void refreshCache() {
+ if (mPbrFile == null) return;
+ mPhoneBookRecords.clear();
+
+ int numRecs = mPbrFile.mFileIds.size();
+ for (int i = 0; i < numRecs; i++) {
+ readAdnFileAndWait(i);
+ }
+ }
+
+ public void invalidateCache() {
+ mRefreshCache = true;
+ }
+
private void readPbrFileAndWait() {
mPhone.getIccFileHandler().loadEFLinearFixedAll(EF_PBR, obtainMessage(EVENT_PBR_LOAD_DONE));
try {
diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/package.html b/telephony/java/com/android/internal/telephony/gsm/stk/package.html
deleted file mode 100644
index c285b57..0000000
--- a/telephony/java/com/android/internal/telephony/gsm/stk/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<HTML>
-<BODY>
-Provides classes for SIM Toolkit Service.
-</BODY>
-</HTML>
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 461e4fb..e37afda 100755..100644
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -41,6 +41,7 @@ import com.android.internal.telephony.UUSInfo;
import java.text.ParseException;
import java.util.List;
+import java.util.regex.Pattern;
/**
* {@hide}
@@ -383,8 +384,8 @@ public class SipPhone extends SipPhoneBase {
Connection dial(String originalNumber) throws SipException {
String calleeSipUri = originalNumber;
if (!calleeSipUri.contains("@")) {
- calleeSipUri = mProfile.getUriString().replaceFirst(
- mProfile.getUserName() + "@",
+ String replaceStr = Pattern.quote(mProfile.getUserName() + "@");
+ calleeSipUri = mProfile.getUriString().replaceFirst(replaceStr,
calleeSipUri + "@");
}
try {