diff options
8 files changed, 374 insertions, 1 deletions
diff --git a/src/java/com/android/internal/telephony/BaseCommands.java b/src/java/com/android/internal/telephony/BaseCommands.java index 9a7be22dd..5459de51d 100644 --- a/src/java/com/android/internal/telephony/BaseCommands.java +++ b/src/java/com/android/internal/telephony/BaseCommands.java @@ -90,6 +90,7 @@ public abstract class BaseCommands implements CommandsInterface { protected Registrant mCatProCmdRegistrant; protected Registrant mCatEventRegistrant; protected Registrant mCatCallSetUpRegistrant; + protected Registrant mCatSendSmsResultRegistrant; protected Registrant mIccSmsFullRegistrant; protected Registrant mEmergencyCallbackModeRegistrant; protected Registrant mRingRegistrant; @@ -453,6 +454,15 @@ public abstract class BaseCommands implements CommandsInterface { } } + // For Samsung STK + public void setOnCatSendSmsResult(Handler h, int what, Object obj) { + mCatSendSmsResultRegistrant = new Registrant(h, what, obj); + } + + public void unSetOnCatSendSmsResult(Handler h) { + mCatSendSmsResultRegistrant.clear(); + } + @Override public void setOnIccSmsFull(Handler h, int what, Object obj) { mIccSmsFullRegistrant = new Registrant (h, what, obj); diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java index 2a4b2b826..5386efb6d 100644 --- a/src/java/com/android/internal/telephony/CommandsInterface.java +++ b/src/java/com/android/internal/telephony/CommandsInterface.java @@ -2118,4 +2118,16 @@ public interface CommandsInterface { * @param h Handler to be removed from the registrant list. */ public void unregisterForAdnRecordsInfo(Handler h); + + /** + * @hide + * samsung stk service implementation - set up registrant for sending + * sms send result from modem(RIL) to catService + */ + void setOnCatSendSmsResult(Handler h, int what, Object obj); + + /** + * @hide + */ + void unSetOnCatSendSmsResult(Handler h); } diff --git a/src/java/com/android/internal/telephony/cat/CallControlResult.java b/src/java/com/android/internal/telephony/cat/CallControlResult.java new file mode 100644 index 000000000..2dbc0d477 --- /dev/null +++ b/src/java/com/android/internal/telephony/cat/CallControlResult.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2007 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.cat; + + +public enum CallControlResult { + + CALL_CONTROL_NO_CONTROL(0x00), + CALL_CONTROL_ALLOWED_NO_MOD(0x01), + CALL_CONTROL_NOT_ALLOWED(0x02), + CALL_CONTROL_ALLOWED_WITH_MOD(0x03); + private int mValue; + + CallControlResult(int value) { + mValue = value; + } + + public static CallControlResult fromInt(int value) { + for (CallControlResult e : CallControlResult.values()) { + if (e.mValue == value) { + return e; + } + } + return null; + } + + public int value() { + return mValue; + } +} diff --git a/src/java/com/android/internal/telephony/cat/CatService.java b/src/java/com/android/internal/telephony/cat/CatService.java index 2c2a6974c..cf52d99bb 100644 --- a/src/java/com/android/internal/telephony/cat/CatService.java +++ b/src/java/com/android/internal/telephony/cat/CatService.java @@ -97,6 +97,10 @@ public class CatService extends Handler implements AppInterface { private UiccController mUiccController; private CardState mCardState = CardState.CARDSTATE_ABSENT; + // Samsung STK + private int mTimeoutDest = 0; + private int mCallControlResultCode = 0; + // Service constants. protected static final int MSG_ID_SESSION_END = 1; protected static final int MSG_ID_PROACTIVE_COMMAND = 2; @@ -110,6 +114,8 @@ public class CatService extends Handler implements AppInterface { protected static final int MSG_ID_ALPHA_NOTIFY = 9; static final int MSG_ID_RIL_MSG_DECODED = 10; + static final int MSG_ID_TIMEOUT = 11; // Samsung STK + static final int MSG_ID_SEND_SMS_RESULT = 12; // Samsung STK // Events to signal SIM presence or absent in the device. private static final int MSG_ID_ICC_RECORDS_LOADED = 20; @@ -128,6 +134,14 @@ public class CatService extends Handler implements AppInterface { private HandlerThread mHandlerThread; private int mSlotId; + // Samsung STK SEND_SMS + static final int WAITING_SMS_RESULT = 2; + static final int WAITING_SMS_RESULT_TIME = 60000; + + static final int SMS_SEND_OK = 0; + static final int SMS_SEND_FAIL = 32790; + static final int SMS_SEND_RETRY = 32810; + /* For multisim catservice should not be singleton */ private CatService(CommandsInterface ci, UiccCardApplication ca, IccRecords ir, Context context, IccFileHandler fh, UiccCard ic, int slotId) { @@ -155,6 +169,7 @@ public class CatService extends Handler implements AppInterface { 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.setOnCatSendSmsResult(this, MSG_ID_SEND_SMS_RESULT, null); // Samsung STK //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null); mCmdIf.registerForIccRefresh(this, MSG_ID_ICC_REFRESH, null); @@ -248,6 +263,7 @@ public class CatService extends Handler implements AppInterface { mCmdIf.unSetOnCatEvent(this); mCmdIf.unSetOnCatCallSetUp(this); mCmdIf.unSetOnCatCcAlphaNotify(this); + mCmdIf.unSetOnCatSendSmsResult(this); mCmdIf.unregisterForIccRefresh(this); if (mUiccController != null) { @@ -438,8 +454,17 @@ public class CatService extends Handler implements AppInterface { break; case SEND_DTMF: case SEND_SMS: + // Samsung STK + if (cmdParams instanceof SendSMSParams) { + handleProactiveCommandSendSMS((SendSMSParams) cmdParams); + } + // Fall through case SEND_SS: case SEND_USSD: + // Samsung STK + if (cmdParams instanceof SendUSSDParams) { + handleProactiveCommandSendUSSD((SendUSSDParams) cmdParams); + } if ((((DisplayTextParams)cmdParams).mTextMsg.text != null) && (((DisplayTextParams)cmdParams).mTextMsg.text.equals(STK_DEFAULT))) { message = mContext.getText(com.android.internal.R.string.sending); @@ -871,6 +896,82 @@ public class CatService extends Handler implements AppInterface { CatLog.d(this, "CAT Alpha message: msg.obj is null"); } break; + case MSG_ID_TIMEOUT: // Should only be called for Samsung STK + if (mTimeoutDest == WAITING_SMS_RESULT) { + CatLog.d(this, "SMS SEND TIMEOUT"); + if (CallControlResult.fromInt(mCallControlResultCode) == + CallControlResult.CALL_CONTROL_NOT_ALLOWED) { + sendTerminalResponse(mCurrntCmd.mCmdDet, + ResultCode.USIM_CALL_CONTROL_PERMANENT, true, 1, null); + } else { + sendTerminalResponse(mCurrntCmd.mCmdDet, + ResultCode.TERMINAL_CRNTLY_UNABLE_TO_PROCESS, false, 0, null); + } + } + break; + case MSG_ID_SEND_SMS_RESULT: // Samsung STK SEND_SMS + if (mContext.getResources(). + getBoolean(com.android.internal.R.bool.config_samsung_stk)) { + int[] sendResult; + AsyncResult ar; + CatLog.d(this, "handleMsg : MSG_ID_SEND_SMS_RESULT"); + cancelTimeOut(); + CatLog.d(this, "The Msg ID data:" + msg.what); + ar = (AsyncResult) msg.obj; + if (ar == null || ar.result == null || mCurrntCmd == null || mCurrntCmd.mCmdDet == null) { + break; + } + sendResult = (int[]) ar.result; + if (sendResult.length == 0) { + break; + } + switch (sendResult[0]) { + default: + CatLog.d(this, "SMS SEND GENERIC FAIL"); + if (CallControlResult.fromInt(mCallControlResultCode) == + CallControlResult.CALL_CONTROL_NOT_ALLOWED) { + sendTerminalResponse(mCurrntCmd.mCmdDet, + ResultCode.USIM_CALL_CONTROL_PERMANENT, true, 1, null); + } else { + sendTerminalResponse(mCurrntCmd.mCmdDet, + ResultCode.TERMINAL_CRNTLY_UNABLE_TO_PROCESS, false, 0, null); + } + break; + case SMS_SEND_OK: // '\0' + CatLog.d(this, "SMS SEND OK"); + if (CallControlResult.fromInt(mCallControlResultCode) == + CallControlResult.CALL_CONTROL_NOT_ALLOWED) { + sendTerminalResponse(mCurrntCmd.mCmdDet, + ResultCode.USIM_CALL_CONTROL_PERMANENT, true, 1, null); + } else { + sendTerminalResponse(mCurrntCmd.mCmdDet, ResultCode.OK, false, 0, null); + } + break; + case SMS_SEND_FAIL: + CatLog.d(this, "SMS SEND FAIL - MEMORY NOT AVAILABLE"); + if (CallControlResult.fromInt(mCallControlResultCode) == + CallControlResult.CALL_CONTROL_NOT_ALLOWED) { + sendTerminalResponse(mCurrntCmd.mCmdDet, + ResultCode.USIM_CALL_CONTROL_PERMANENT, true, 1, null); + } else { + sendTerminalResponse(mCurrntCmd.mCmdDet, + ResultCode.TERMINAL_CRNTLY_UNABLE_TO_PROCESS, false, 0, null); + } + break; + case SMS_SEND_RETRY: + CatLog.d(this, "SMS SEND FAIL RETRY"); + if (CallControlResult.fromInt(mCallControlResultCode) == + CallControlResult.CALL_CONTROL_NOT_ALLOWED) { + sendTerminalResponse(mCurrntCmd.mCmdDet, + ResultCode.USIM_CALL_CONTROL_PERMANENT, true, 1, null); + } else { + sendTerminalResponse(mCurrntCmd.mCmdDet, + ResultCode.NETWORK_CRNTLY_UNABLE_TO_PROCESS, false, 0, null); + } + break; + } + } + break; default: throw new AssertionError("Unrecognized CAT command: " + msg.what); } @@ -1151,4 +1252,36 @@ public class CatService extends Handler implements AppInterface { mCmdIf.reportStkServiceIsRunning(null); } } + + /** + * Samsung STK SEND_SMS + * @param cmdPar + */ + private void handleProactiveCommandSendSMS(SendSMSParams cmdPar) { + CatLog.d(this, "The smscaddress is: " + cmdPar.smscAddress); + CatLog.d(this, "The SMS tpdu is: " + cmdPar.pdu); + mCmdIf.sendSMS(cmdPar.smscAddress, cmdPar.pdu, null); + startTimeOut(WAITING_SMS_RESULT, WAITING_SMS_RESULT_TIME); + } + + /** + * Samsung STK SEND_USSD + * @param cmdPar + */ + private void handleProactiveCommandSendUSSD(SendUSSDParams cmdPar) { + CatLog.d(this, "The USSD is: " + cmdPar.ussdString); + mCmdIf.sendUSSD(cmdPar.ussdString, null); + // Sent USSD, let framework handle the rest + } + + private void cancelTimeOut() { + removeMessages(MSG_ID_TIMEOUT); + mTimeoutDest = 0; + } + + private void startTimeOut(int timeout, int delay) { + cancelTimeOut(); + mTimeoutDest = timeout; + sendMessageDelayed(obtainMessage(MSG_ID_TIMEOUT), delay); + } } diff --git a/src/java/com/android/internal/telephony/cat/CommandParams.java b/src/java/com/android/internal/telephony/cat/CommandParams.java index edb377211..b87b042be 100644 --- a/src/java/com/android/internal/telephony/cat/CommandParams.java +++ b/src/java/com/android/internal/telephony/cat/CommandParams.java @@ -234,3 +234,23 @@ class ActivateParams extends CommandParams { } } +// Samsung STK +class SendSMSParams extends DisplayTextParams { + String pdu; + String smscAddress; + + SendSMSParams(CommandDetails cmdDet, TextMessage textmessage, String smscaddress, String smsPdu) { + super(cmdDet, textmessage); + smscAddress = smscaddress; + pdu = smsPdu; + } +} + +class SendUSSDParams extends DisplayTextParams { + String ussdString; + + SendUSSDParams(CommandDetails cmdDet, TextMessage textmessage, String ussdstring) { + super(cmdDet, textmessage); + ussdString = ussdstring; + } +} diff --git a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java index 93525cd90..103847d7b 100755 --- a/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java +++ b/src/java/com/android/internal/telephony/cat/CommandParamsFactory.java @@ -16,6 +16,7 @@ package com.android.internal.telephony.cat; +import android.content.res.Resources; import android.graphics.Bitmap; import android.os.Handler; import android.os.Message; @@ -701,7 +702,49 @@ class CommandParamsFactory extends Handler { } textMsg.responseNeeded = false; - mCmdParams = new DisplayTextParams(cmdDet, textMsg); + // Samsung STK + if (Resources.getSystem().getBoolean(com.android.internal.R.bool.config_samsung_stk)) { + AppInterface.CommandType cmdType = AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); + if (cmdType == AppInterface.CommandType.SEND_SMS) { + String smscAddress = null; + String pdu = null; + + ctlv = searchForTag(ComprehensionTlvTag.ADDRESS, ctlvs); + if (ctlv != null) { + smscAddress = ValueParser.retrieveSMSCaddress(ctlv); + CatLog.d(this, "The smsc address is " + smscAddress); + } + else { + CatLog.d(this, "The smsc address is null"); + } + + ctlv = searchForTag(ComprehensionTlvTag.SMS_TPDU, ctlvs); + if (ctlv != null) { + pdu = ValueParser.retrieveSMSTPDU(ctlv); + CatLog.d(this, "The SMS tpdu is " + pdu); + } + else { + CatLog.d(this, "The SMS tpdu is null"); + } + mCmdParams = new SendSMSParams(cmdDet, textMsg, smscAddress, pdu); + } else if (cmdType == AppInterface.CommandType.SEND_USSD) { + String ussdString = null; + + ctlv = searchForTag(ComprehensionTlvTag.USSD_STRING, ctlvs); + if (ctlv != null) { + ussdString = ValueParser.retrieveUSSDString(ctlv); + CatLog.d(this, "The ussd string is " + ussdString); + } + else { + CatLog.d(this, "The ussd string is null"); + } + mCmdParams = new SendUSSDParams(cmdDet, textMsg, ussdString); + } else { + mCmdParams = new DisplayTextParams(cmdDet, textMsg); + } + } else { + mCmdParams = new DisplayTextParams(cmdDet, textMsg); + } if (iconId != null) { mloadIcon = true; diff --git a/src/java/com/android/internal/telephony/cat/ValueParser.java b/src/java/com/android/internal/telephony/cat/ValueParser.java index c6b16c783..666ee68fe 100644 --- a/src/java/com/android/internal/telephony/cat/ValueParser.java +++ b/src/java/com/android/internal/telephony/cat/ValueParser.java @@ -366,4 +366,105 @@ abstract class ValueParser { throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); } } + + /** + * Samsung STK: Read SMSC Address + * + * @param ctlv A SMSC Address COMPREHENSION-TLV object + * @return A Java String object decoded from the SMSC Address object + * @throws ResultException + */ + static String retrieveSMSCaddress(ComprehensionTlv ctlv) + throws ResultException { + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + int length = ctlv.getLength(); + byte[] outputValue = new byte[length + 1]; + + for (int k = 0; k <= length; k++) { + try { + outputValue[k] = rawValue[k + (valueIndex - 1)]; + } catch (IndexOutOfBoundsException indexoutofboundsexception) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } + if (length != 0) { + return IccUtils.bytesToHexString(outputValue); + } else { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } + + /** + * Samsung STK: Read SMS TPDU Address + * + * @param ctlv A SMS TPDU COMPREHENSION-TLV object + * @return A Java String object decoded from the SMS TPDU object + * @throws ResultException + */ + static String retrieveSMSTPDU(ComprehensionTlv ctlv) + throws ResultException { + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + int pduLength = ctlv.getLength(); + byte[] outputValue; + int k; + String result; + if (rawValue[valueIndex + 2] % 2 == 0) { + k = rawValue[valueIndex + 2] / 2; + } else { + k = (1 + rawValue[valueIndex + 2]) / 2; + } + + if (pduLength == k + 6) { + outputValue = new byte[pduLength + 1]; + } else { + outputValue = new byte[pduLength]; + } + + for (int l = 0; l < pduLength; l++) { + try { + outputValue[l] = rawValue[valueIndex + l]; + } catch (IndexOutOfBoundsException ex) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } + if (pduLength != 0) { + result = IccUtils.bytesToHexString(outputValue); + } else { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + + return result; + } + + /** + * Samsung STK: Read USSD String + * + * @param ctlv A USSD String COMPREHENSION-TLV object + * @return A String object decoded from the USSD String object + * @throws ResultException + */ + static String retrieveUSSDString(ComprehensionTlv ctlv) throws ResultException { + byte[] rawValue = ctlv.getRawValue(); + int valueIndex = ctlv.getValueIndex(); + int length = ctlv.getLength(); + + // If length is 0 (shouldn't be), return null + if (length == 0) { + return null; + } + + // Should be 0x0f + if (rawValue[valueIndex] != 0x0f) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + + try { + return GsmAlphabet.gsm7BitPackedToString(rawValue, + valueIndex + 1, ((length - 1) * 8) / 7); + } catch (IndexOutOfBoundsException e) { + throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); + } + } } diff --git a/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java b/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java index 475e5b061..e7c12c99d 100644 --- a/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java +++ b/src/java/com/android/internal/telephony/test/SimulatedCommandsVerifier.java @@ -1415,4 +1415,14 @@ public class SimulatedCommandsVerifier implements CommandsInterface { } + @Override + public void unSetOnCatSendSmsResult(Handler h) { // Samsung STK + + } + + @Override + public void setOnCatSendSmsResult(Handler h, int what, Object obj) { // Samsung STK + + } + } |