am 076d0654: Merge "SIM toolkit enhancements and bug fixes"

Merge commit '076d06547f90c480a4ed19da6f4b3d1270f57ec9' into gingerbread-plus-aosp

* commit '076d06547f90c480a4ed19da6f4b3d1270f57ec9':
  SIM toolkit enhancements and bug fixes
This commit is contained in:
Jean-Baptiste Queru
2010-08-11 09:44:27 -07:00
committed by Android Git Automerger
5 changed files with 151 additions and 47 deletions

View File

@@ -58,7 +58,8 @@ public interface AppInterface {
SET_UP_EVENT_LIST(0x05), SET_UP_EVENT_LIST(0x05),
SET_UP_IDLE_MODE_TEXT(0x28), SET_UP_IDLE_MODE_TEXT(0x28),
SET_UP_MENU(0x25), SET_UP_MENU(0x25),
SET_UP_CALL(0x10); SET_UP_CALL(0x10),
PROVIDE_LOCAL_INFORMATION(0x26);
private int mValue; private int mValue;

View File

@@ -22,6 +22,7 @@ import android.os.AsyncResult;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.Message; import android.os.Message;
import android.os.SystemProperties;
import com.android.internal.telephony.IccUtils; import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.CommandsInterface;
@@ -251,27 +252,25 @@ public class CatService extends Handler implements AppInterface {
} else { } else {
mMenuCmd = cmdMsg; mMenuCmd = cmdMsg;
} }
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
null);
break; break;
case DISPLAY_TEXT: case DISPLAY_TEXT:
// when application is not required to respond, send an immediate // when application is not required to respond, send an immediate response.
// response.
if (!cmdMsg.geTextMessage().responseNeeded) { if (!cmdMsg.geTextMessage().responseNeeded) {
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
0, null);
} }
break; break;
case REFRESH: case REFRESH:
// ME side only handles refresh commands which meant to remove IDLE // ME side only handles refresh commands which meant to remove IDLE
// MODE TEXT. // MODE TEXT.
cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
.value();
break; break;
case SET_UP_IDLE_MODE_TEXT: case SET_UP_IDLE_MODE_TEXT:
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
0, null);
break; break;
case PROVIDE_LOCAL_INFORMATION:
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
return;
case LAUNCH_BROWSER: case LAUNCH_BROWSER:
case SELECT_ITEM: case SELECT_ITEM:
case GET_INPUT: case GET_INPUT:
@@ -315,6 +314,11 @@ public class CatService extends Handler implements AppInterface {
} }
ByteArrayOutputStream buf = new ByteArrayOutputStream(); ByteArrayOutputStream buf = new ByteArrayOutputStream();
Input cmdInput = null;
if (mCurrntCmd != null) {
cmdInput = mCurrntCmd.geInput();
}
// command details // command details
int tag = ComprehensionTlvTag.COMMAND_DETAILS.value(); int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
if (cmdDet.compRequired) { if (cmdDet.compRequired) {
@@ -327,7 +331,13 @@ public class CatService extends Handler implements AppInterface {
buf.write(cmdDet.commandQualifier); buf.write(cmdDet.commandQualifier);
// device identities // 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(tag);
buf.write(0x02); // length buf.write(0x02); // length
buf.write(DEV_ID_TERMINAL); // source device id buf.write(DEV_ID_TERMINAL); // source device id
@@ -348,6 +358,8 @@ public class CatService extends Handler implements AppInterface {
// Fill optional data for each corresponding command // Fill optional data for each corresponding command
if (resp != null) { if (resp != null) {
resp.format(buf); resp.format(buf);
} else {
encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
} }
byte[] rawData = buf.toByteArray(); byte[] rawData = buf.toByteArray();
@@ -359,6 +371,52 @@ public class CatService extends Handler implements AppInterface {
mCmdIf.sendTerminalResponse(hexString, null); 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) { private void sendMenuSelection(int menuId, boolean helpRequired) {

View File

@@ -52,6 +52,9 @@ class CommandParamsFactory extends Handler {
static final int REFRESH_NAA_INIT = 0x03; static final int REFRESH_NAA_INIT = 0x03;
static final int REFRESH_UICC_RESET = 0x04; 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, static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller,
IccFileHandler fh) { IccFileHandler fh) {
if (sInstance != null) { if (sInstance != null) {
@@ -112,7 +115,10 @@ class CommandParamsFactory extends Handler {
AppInterface.CommandType cmdType = AppInterface.CommandType AppInterface.CommandType cmdType = AppInterface.CommandType
.fromInt(cmdDet.typeOfCommand); .fromInt(cmdDet.typeOfCommand);
if (cmdType == null) { 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; return;
} }
@@ -155,10 +161,13 @@ class CommandParamsFactory extends Handler {
case PLAY_TONE: case PLAY_TONE:
cmdPending = processPlayTone(cmdDet, ctlvs); cmdPending = processPlayTone(cmdDet, ctlvs);
break; break;
case PROVIDE_LOCAL_INFORMATION:
cmdPending = processProvideLocalInfo(cmdDet, ctlvs);
break;
default: default:
// unsupported proactive commands // unsupported proactive commands
mCmdParams = new CommandParams(cmdDet); mCmdParams = new CommandParams(cmdDet);
sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
return; return;
} }
} catch (ResultException e) { } catch (ResultException e) {
@@ -380,6 +389,12 @@ class CommandParamsFactory extends Handler {
iconId = ValueParser.retrieveIconId(ctlv); iconId = ValueParser.retrieveIconId(ctlv);
} }
// parse duration
ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
if (ctlv != null) {
input.duration = ValueParser.retrieveDuration(ctlv);
}
input.minLen = 1; input.minLen = 1;
input.maxLen = 1; input.maxLen = 1;
@@ -863,4 +878,20 @@ class CommandParamsFactory extends Handler {
} }
return false; 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;
}
} }

View File

@@ -36,6 +36,7 @@ public class Input implements Parcelable {
public boolean echo; public boolean echo;
public boolean yesNo; public boolean yesNo;
public boolean helpAvailable; public boolean helpAvailable;
public Duration duration;
Input() { Input() {
text = ""; text = "";
@@ -49,6 +50,7 @@ public class Input implements Parcelable {
echo = false; echo = false;
yesNo = false; yesNo = false;
helpAvailable = false; helpAvailable = false;
duration = null;
} }
private Input(Parcel in) { private Input(Parcel in) {
@@ -63,6 +65,7 @@ public class Input implements Parcelable {
echo = in.readInt() == 1 ? true : false; echo = in.readInt() == 1 ? true : false;
yesNo = in.readInt() == 1 ? true : false; yesNo = in.readInt() == 1 ? true : false;
helpAvailable = in.readInt() == 1 ? true : false; helpAvailable = in.readInt() == 1 ? true : false;
duration = in.readParcelable(null);
} }
public int describeContents() { public int describeContents() {
@@ -81,6 +84,7 @@ public class Input implements Parcelable {
dest.writeInt(echo ? 1 : 0); dest.writeInt(echo ? 1 : 0);
dest.writeInt(yesNo ? 1 : 0); dest.writeInt(yesNo ? 1 : 0);
dest.writeInt(helpAvailable ? 1 : 0); dest.writeInt(helpAvailable ? 1 : 0);
dest.writeParcelable(duration, 0);
} }
public static final Parcelable.Creator<Input> CREATOR = new Parcelable.Creator<Input>() { public static final Parcelable.Creator<Input> CREATOR = new Parcelable.Creator<Input>() {

View File

@@ -28,6 +28,16 @@ abstract class ResponseData {
* the ByteArrayOutputStream object. * the ByteArrayOutputStream object.
*/ */
public abstract void format(ByteArrayOutputStream buf); 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 { class SelectItemResponseData extends ResponseData {
@@ -120,7 +130,7 @@ class GetInkeyInputResponseData extends ResponseData {
} }
// length - one more for data coding scheme. // length - one more for data coding scheme.
buf.write(data.length + 1); writeLength(buf, data.length + 1);
// data coding scheme // data coding scheme
if (mIsUcs2) { if (mIsUcs2) {