Skip to content

Commit 076d065

Browse files
Jean-Baptiste QueruAndroid Code Review
authored andcommitted
Merge "SIM toolkit enhancements and bug fixes"
2 parents 6061af1 + e4866d0 commit 076d065

File tree

5 files changed

+151
-47
lines changed

5 files changed

+151
-47
lines changed

telephony/java/com/android/internal/telephony/cat/AppInterface.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public static enum CommandType {
5858
SET_UP_EVENT_LIST(0x05),
5959
SET_UP_IDLE_MODE_TEXT(0x28),
6060
SET_UP_MENU(0x25),
61-
SET_UP_CALL(0x10);
61+
SET_UP_CALL(0x10),
62+
PROVIDE_LOCAL_INFORMATION(0x26);
6263

6364
private int mValue;
6465

telephony/java/com/android/internal/telephony/cat/CatService.java

Lines changed: 101 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.os.Handler;
2323
import android.os.HandlerThread;
2424
import android.os.Message;
25+
import android.os.SystemProperties;
2526

2627
import com.android.internal.telephony.IccUtils;
2728
import com.android.internal.telephony.CommandsInterface;
@@ -245,48 +246,46 @@ private void handleProactiveCommand(CommandParams cmdParams) {
245246

246247
CatCmdMessage cmdMsg = new CatCmdMessage(cmdParams);
247248
switch (cmdParams.getCommandType()) {
248-
case SET_UP_MENU:
249-
if (removeMenu(cmdMsg.getMenu())) {
250-
mMenuCmd = null;
251-
} else {
252-
mMenuCmd = cmdMsg;
253-
}
254-
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0,
255-
null);
256-
break;
257-
case DISPLAY_TEXT:
258-
// when application is not required to respond, send an immediate
259-
// response.
260-
if (!cmdMsg.geTextMessage().responseNeeded) {
261-
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false,
262-
0, null);
263-
}
264-
break;
265-
case REFRESH:
266-
// ME side only handles refresh commands which meant to remove IDLE
267-
// MODE TEXT.
268-
cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT
269-
.value();
270-
break;
271-
case SET_UP_IDLE_MODE_TEXT:
272-
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false,
273-
0, null);
274-
break;
275-
case LAUNCH_BROWSER:
276-
case SELECT_ITEM:
277-
case GET_INPUT:
278-
case GET_INKEY:
279-
case SEND_DTMF:
280-
case SEND_SMS:
281-
case SEND_SS:
282-
case SEND_USSD:
283-
case PLAY_TONE:
284-
case SET_UP_CALL:
285-
// nothing to do on telephony!
286-
break;
287-
default:
288-
CatLog.d(this, "Unsupported command");
289-
return;
249+
case SET_UP_MENU:
250+
if (removeMenu(cmdMsg.getMenu())) {
251+
mMenuCmd = null;
252+
} else {
253+
mMenuCmd = cmdMsg;
254+
}
255+
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
256+
break;
257+
case DISPLAY_TEXT:
258+
// when application is not required to respond, send an immediate response.
259+
if (!cmdMsg.geTextMessage().responseNeeded) {
260+
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
261+
}
262+
break;
263+
case REFRESH:
264+
// ME side only handles refresh commands which meant to remove IDLE
265+
// MODE TEXT.
266+
cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT.value();
267+
break;
268+
case SET_UP_IDLE_MODE_TEXT:
269+
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
270+
break;
271+
case PROVIDE_LOCAL_INFORMATION:
272+
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
273+
return;
274+
case LAUNCH_BROWSER:
275+
case SELECT_ITEM:
276+
case GET_INPUT:
277+
case GET_INKEY:
278+
case SEND_DTMF:
279+
case SEND_SMS:
280+
case SEND_SS:
281+
case SEND_USSD:
282+
case PLAY_TONE:
283+
case SET_UP_CALL:
284+
// nothing to do on telephony!
285+
break;
286+
default:
287+
CatLog.d(this, "Unsupported command");
288+
return;
290289
}
291290
mCurrntCmd = cmdMsg;
292291
Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
@@ -315,6 +314,11 @@ private void sendTerminalResponse(CommandDetails cmdDet,
315314
}
316315
ByteArrayOutputStream buf = new ByteArrayOutputStream();
317316

317+
Input cmdInput = null;
318+
if (mCurrntCmd != null) {
319+
cmdInput = mCurrntCmd.geInput();
320+
}
321+
318322
// command details
319323
int tag = ComprehensionTlvTag.COMMAND_DETAILS.value();
320324
if (cmdDet.compRequired) {
@@ -327,7 +331,13 @@ private void sendTerminalResponse(CommandDetails cmdDet,
327331
buf.write(cmdDet.commandQualifier);
328332

329333
// device identities
330-
tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value();
334+
// According to TS102.223/TS31.111 section 6.8 Structure of
335+
// TERMINAL RESPONSE, "For all SIMPLE-TLV objects with Min=N,
336+
// the ME should set the CR(comprehension required) flag to
337+
// comprehension not required.(CR=0)"
338+
// Since DEVICE_IDENTITIES and DURATION TLVs have Min=N,
339+
// the CR flag is not set.
340+
tag = ComprehensionTlvTag.DEVICE_IDENTITIES.value();
331341
buf.write(tag);
332342
buf.write(0x02); // length
333343
buf.write(DEV_ID_TERMINAL); // source device id
@@ -348,6 +358,8 @@ private void sendTerminalResponse(CommandDetails cmdDet,
348358
// Fill optional data for each corresponding command
349359
if (resp != null) {
350360
resp.format(buf);
361+
} else {
362+
encodeOptionalTags(cmdDet, resultCode, cmdInput, buf);
351363
}
352364

353365
byte[] rawData = buf.toByteArray();
@@ -359,6 +371,52 @@ private void sendTerminalResponse(CommandDetails cmdDet,
359371
mCmdIf.sendTerminalResponse(hexString, null);
360372
}
361373

374+
private void encodeOptionalTags(CommandDetails cmdDet,
375+
ResultCode resultCode, Input cmdInput, ByteArrayOutputStream buf) {
376+
switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) {
377+
case GET_INKEY:
378+
// ETSI TS 102 384,27.22.4.2.8.4.2.
379+
// If it is a response for GET_INKEY command and the response timeout
380+
// occured, then add DURATION TLV for variable timeout case.
381+
if ((resultCode.value() == ResultCode.NO_RESPONSE_FROM_USER.value()) &&
382+
(cmdInput != null) && (cmdInput.duration != null)) {
383+
getInKeyResponse(buf, cmdInput);
384+
}
385+
break;
386+
case PROVIDE_LOCAL_INFORMATION:
387+
if ((cmdDet.commandQualifier == CommandParamsFactory.LANGUAGE_SETTING) &&
388+
(resultCode.value() == ResultCode.OK.value())) {
389+
getPliResponse(buf);
390+
}
391+
break;
392+
default:
393+
CatLog.d(this, "encodeOptionalTags() Unsupported Cmd:" + cmdDet.typeOfCommand);
394+
break;
395+
}
396+
}
397+
398+
private void getInKeyResponse(ByteArrayOutputStream buf, Input cmdInput) {
399+
int tag = ComprehensionTlvTag.DURATION.value();
400+
401+
buf.write(tag);
402+
buf.write(0x02); // length
403+
buf.write(cmdInput.duration.timeUnit.SECOND.value()); // Time (Unit,Seconds)
404+
buf.write(cmdInput.duration.timeInterval); // Time Duration
405+
}
406+
407+
private void getPliResponse(ByteArrayOutputStream buf) {
408+
409+
// Locale Language Setting
410+
String lang = SystemProperties.get("persist.sys.language");
411+
412+
if (lang != null) {
413+
// tag
414+
int tag = ComprehensionTlvTag.LANGUAGE.value();
415+
buf.write(tag);
416+
ResponseData.writeLength(buf, lang.length());
417+
buf.write(lang.getBytes(), 0, lang.length());
418+
}
419+
}
362420

363421
private void sendMenuSelection(int menuId, boolean helpRequired) {
364422

telephony/java/com/android/internal/telephony/cat/CommandParamsFactory.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ class CommandParamsFactory extends Handler {
5252
static final int REFRESH_NAA_INIT = 0x03;
5353
static final int REFRESH_UICC_RESET = 0x04;
5454

55+
// Command Qualifier values for PLI command
56+
static final int LANGUAGE_SETTING = 0x04;
57+
5558
static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller,
5659
IccFileHandler fh) {
5760
if (sInstance != null) {
@@ -112,7 +115,10 @@ void make(BerTlv berTlv) {
112115
AppInterface.CommandType cmdType = AppInterface.CommandType
113116
.fromInt(cmdDet.typeOfCommand);
114117
if (cmdType == null) {
115-
sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
118+
// This PROACTIVE COMMAND is presently not handled. Hence set
119+
// result code as BEYOND_TERMINAL_CAPABILITY in TR.
120+
mCmdParams = new CommandParams(cmdDet);
121+
sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
116122
return;
117123
}
118124

@@ -155,10 +161,13 @@ void make(BerTlv berTlv) {
155161
case PLAY_TONE:
156162
cmdPending = processPlayTone(cmdDet, ctlvs);
157163
break;
164+
case PROVIDE_LOCAL_INFORMATION:
165+
cmdPending = processProvideLocalInfo(cmdDet, ctlvs);
166+
break;
158167
default:
159168
// unsupported proactive commands
160169
mCmdParams = new CommandParams(cmdDet);
161-
sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD);
170+
sendCmdParams(ResultCode.BEYOND_TERMINAL_CAPABILITY);
162171
return;
163172
}
164173
} catch (ResultException e) {
@@ -380,6 +389,12 @@ private boolean processGetInkey(CommandDetails cmdDet,
380389
iconId = ValueParser.retrieveIconId(ctlv);
381390
}
382391

392+
// parse duration
393+
ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs);
394+
if (ctlv != null) {
395+
input.duration = ValueParser.retrieveDuration(ctlv);
396+
}
397+
383398
input.minLen = 1;
384399
input.maxLen = 1;
385400

@@ -863,4 +878,20 @@ private boolean processSetupCall(CommandDetails cmdDet,
863878
}
864879
return false;
865880
}
881+
882+
private boolean processProvideLocalInfo(CommandDetails cmdDet, List<ComprehensionTlv> ctlvs)
883+
throws ResultException {
884+
CatLog.d(this, "process ProvideLocalInfo");
885+
switch (cmdDet.commandQualifier) {
886+
case LANGUAGE_SETTING:
887+
CatLog.d(this, "PLI [LANGUAGE_SETTING]");
888+
mCmdParams = new CommandParams(cmdDet);
889+
break;
890+
default:
891+
CatLog.d(this, "PLI[" + cmdDet.commandQualifier + "] Command Not Supported");
892+
mCmdParams = new CommandParams(cmdDet);
893+
throw new ResultException(ResultCode.BEYOND_TERMINAL_CAPABILITY);
894+
}
895+
return false;
896+
}
866897
}

telephony/java/com/android/internal/telephony/cat/Input.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class Input implements Parcelable {
3636
public boolean echo;
3737
public boolean yesNo;
3838
public boolean helpAvailable;
39+
public Duration duration;
3940

4041
Input() {
4142
text = "";
@@ -49,6 +50,7 @@ public class Input implements Parcelable {
4950
echo = false;
5051
yesNo = false;
5152
helpAvailable = false;
53+
duration = null;
5254
}
5355

5456
private Input(Parcel in) {
@@ -63,6 +65,7 @@ private Input(Parcel in) {
6365
echo = in.readInt() == 1 ? true : false;
6466
yesNo = in.readInt() == 1 ? true : false;
6567
helpAvailable = in.readInt() == 1 ? true : false;
68+
duration = in.readParcelable(null);
6669
}
6770

6871
public int describeContents() {
@@ -81,6 +84,7 @@ public void writeToParcel(Parcel dest, int flags) {
8184
dest.writeInt(echo ? 1 : 0);
8285
dest.writeInt(yesNo ? 1 : 0);
8386
dest.writeInt(helpAvailable ? 1 : 0);
87+
dest.writeParcelable(duration, 0);
8488
}
8589

8690
public static final Parcelable.Creator<Input> CREATOR = new Parcelable.Creator<Input>() {

telephony/java/com/android/internal/telephony/cat/ResponseData.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ abstract class ResponseData {
2828
* the ByteArrayOutputStream object.
2929
*/
3030
public abstract void format(ByteArrayOutputStream buf);
31+
32+
public static void writeLength(ByteArrayOutputStream buf, int length) {
33+
// As per ETSI 102.220 Sec7.1.2, if the total length is greater
34+
// than 0x7F, it should be coded in two bytes and the first byte
35+
// should be 0x81.
36+
if (length > 0x7F) {
37+
buf.write(0x81);
38+
}
39+
buf.write(length);
40+
}
3141
}
3242

3343
class SelectItemResponseData extends ResponseData {
@@ -120,7 +130,7 @@ public void format(ByteArrayOutputStream buf) {
120130
}
121131

122132
// length - one more for data coding scheme.
123-
buf.write(data.length + 1);
133+
writeLength(buf, data.length + 1);
124134

125135
// data coding scheme
126136
if (mIsUcs2) {

0 commit comments

Comments
 (0)