Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public interface AppInterface {
* Enumeration for representing "Type of Command" of proactive commands.
* Those are the only commands which are supported by the Telephony. Any app
* implementation should support those.
* Refer to ETSI TS 102.223 section 9.4
*/
public static enum CommandType {
DISPLAY_TEXT(0x21),
Expand All @@ -59,7 +60,11 @@ public static enum CommandType {
SET_UP_IDLE_MODE_TEXT(0x28),
SET_UP_MENU(0x25),
SET_UP_CALL(0x10),
PROVIDE_LOCAL_INFORMATION(0x26);
PROVIDE_LOCAL_INFORMATION(0x26),
OPEN_CHANNEL(0x40),
CLOSE_CHANNEL(0x41),
RECEIVE_DATA(0x42),
SEND_DATA(0x43);

private int mValue;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ public class CallSettings {
mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).confirmMsg;
mCallSettings.callMsg = ((CallSetupParams) cmdParams).callMsg;
break;
case OPEN_CHANNEL:
case CLOSE_CHANNEL:
case RECEIVE_DATA:
case SEND_DATA:
BIPClientParams param = (BIPClientParams) cmdParams;
mTextMsg = param.textMsg;
break;
}
}

Expand Down
77 changes: 67 additions & 10 deletions telephony/java/com/android/internal/telephony/cat/CatService.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.HandlerThread;
Expand All @@ -32,6 +34,7 @@


import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Locale;

class RilMessage {
Expand Down Expand Up @@ -72,6 +75,7 @@ public class CatService extends Handler implements AppInterface {
private CatCmdMessage mMenuCmd = null;

private RilMessageDecoder mMsgDecoder = null;
private boolean mStkAppInstalled = false;

// Service constants.
static final int MSG_ID_SESSION_END = 1;
Expand Down Expand Up @@ -125,7 +129,10 @@ private CatService(CommandsInterface ci, IccRecords ir, Context context,
mCmdIf.registerForNVReady(this, MSG_ID_SIM_READY, null);
mIccRecords.registerForRecordsLoaded(this, MSG_ID_ICC_RECORDS_LOADED, null);

CatLog.d(this, "Is running");
// Check if STK application is availalbe
mStkAppInstalled = isStkAppInstalled();

CatLog.d(this, "Running CAT service. STK app installed:" + mStkAppInstalled);
}

public void dispose() {
Expand Down Expand Up @@ -154,7 +161,7 @@ private void handleRilMsg(RilMessage rilMsg) {
if (rilMsg.mResCode == ResultCode.OK) {
cmdParams = (CommandParams) rilMsg.mData;
if (cmdParams != null) {
handleProactiveCommand(cmdParams);
handleCommand(cmdParams, false);
}
}
break;
Expand All @@ -170,7 +177,7 @@ private void handleRilMsg(RilMessage rilMsg) {
}
if (cmdParams != null) {
if (rilMsg.mResCode == ResultCode.OK) {
handleProactiveCommand(cmdParams);
handleCommand(cmdParams, true);
} else {
// for proactive commands that couldn't be decoded
// successfully respond with the code generated by the
Expand All @@ -183,7 +190,7 @@ private void handleRilMsg(RilMessage rilMsg) {
case MSG_ID_REFRESH:
cmdParams = (CommandParams) rilMsg.mData;
if (cmdParams != null) {
handleProactiveCommand(cmdParams);
handleCommand(cmdParams, false);
}
break;
case MSG_ID_SESSION_END:
Expand All @@ -197,11 +204,13 @@ private void handleRilMsg(RilMessage rilMsg) {
}

/**
* Handles RIL_UNSOL_STK_PROACTIVE_COMMAND unsolicited command from RIL.
* Handles RIL_UNSOL_STK_EVENT_NOTIFY or RIL_UNSOL_STK_PROACTIVE_COMMAND command
* from RIL.
* Sends valid proactive command data to the application using intents.
*
* RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE will be send back if the command is
* from RIL_UNSOL_STK_PROACTIVE_COMMAND.
*/
private void handleProactiveCommand(CommandParams cmdParams) {
private void handleCommand(CommandParams cmdParams, boolean isProactiveCmd) {
CatLog.d(this, cmdParams.getCommandType().name());

CharSequence message;
Expand Down Expand Up @@ -235,15 +244,16 @@ private void handleProactiveCommand(CommandParams cmdParams) {
case CommandParamsFactory.DTTZ_SETTING:
resp = new DTTZResponseData(null);
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp);
return;
break;
case CommandParamsFactory.LANGUAGE_SETTING:
resp = new LanguageResponseData(Locale.getDefault().getLanguage());
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, resp);
return;
break;
default:
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
return;
}
// No need to start STK app here.
return;
case LAUNCH_BROWSER:
if ((((LaunchBrowserParams) cmdParams).confirmMsg.text != null)
&& (((LaunchBrowserParams) cmdParams).confirmMsg.text.equals(STK_DEFAULT))) {
Expand Down Expand Up @@ -274,6 +284,42 @@ private void handleProactiveCommand(CommandParams cmdParams) {
((CallSetupParams) cmdParams).confirmMsg.text = message.toString();
}
break;
case OPEN_CHANNEL:
case CLOSE_CHANNEL:
case RECEIVE_DATA:
case SEND_DATA:
BIPClientParams cmd = (BIPClientParams) cmdParams;
if (cmd.bHasAlphaId && (cmd.textMsg.text == null)) {
CatLog.d(this, "cmd " + cmdParams.getCommandType() + " with null alpha id");
// If alpha length is zero, we just respond with OK.
if (isProactiveCmd) {
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
}
return;
}
// Respond with permanent failure to avoid retry if STK app is not present.
if (!mStkAppInstalled) {
CatLog.d(this, "No STK application found.");
if (isProactiveCmd) {
sendTerminalResponse(cmdParams.cmdDet,
ResultCode.BEYOND_TERMINAL_CAPABILITY,
false, 0, null);
return;
}
}
/*
* CLOSE_CHANNEL, RECEIVE_DATA and SEND_DATA can be delivered by
* either PROACTIVE_COMMAND or EVENT_NOTIFY.
* If PROACTIVE_COMMAND is used for those commands, send terminal
* response here.
*/
if (isProactiveCmd &&
((cmdParams.getCommandType() == CommandType.CLOSE_CHANNEL) ||
(cmdParams.getCommandType() == CommandType.RECEIVE_DATA) ||
(cmdParams.getCommandType() == CommandType.SEND_DATA))) {
sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, null);
}
break;
default:
CatLog.d(this, "Unsupported command");
return;
Expand Down Expand Up @@ -684,6 +730,7 @@ private void handleCmdResponse(CatResponseMessage resMsg) {
case NO_RESPONSE_FROM_USER:
case UICC_SESSION_TERM_BY_USER:
case BACKWARD_MOVE_BY_USER:
case USER_NOT_ACCEPT:
resp = null;
break;
default:
Expand All @@ -692,4 +739,14 @@ private void handleCmdResponse(CatResponseMessage resMsg) {
sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp);
mCurrntCmd = null;
}

private boolean isStkAppInstalled() {
Intent intent = new Intent(AppInterface.CAT_CMD_ACTION);
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> broadcastReceivers =
pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA);
int numReceiver = broadcastReceivers == null ? 0 : broadcastReceivers.size();

return (numReceiver > 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,29 @@ boolean setIcon(Bitmap icon) {
}
}

/*
* BIP (Bearer Independent Protocol) is the mechanism for SIM card applications
* to access data connection through the mobile device.
*
* SIM utilizes proactive commands (OPEN CHANNEL, CLOSE CHANNEL, SEND DATA and
* RECEIVE DATA to control/read/write data for BIP. Refer to ETSI TS 102 223 for
* the details of proactive commands procedures and their structures.
*/
class BIPClientParams extends CommandParams {
TextMessage textMsg;
boolean bHasAlphaId;

BIPClientParams(CommandDetails cmdDet, TextMessage textMsg, boolean has_alpha_id) {
super(cmdDet);
this.textMsg = textMsg;
this.bHasAlphaId = has_alpha_id;
}

boolean setIcon(Bitmap icon) {
if (icon != null && textMsg != null) {
textMsg.icon = icon;
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ void make(BerTlv berTlv) {
case PROVIDE_LOCAL_INFORMATION:
cmdPending = processProvideLocalInfo(cmdDet, ctlvs);
break;
case OPEN_CHANNEL:
case CLOSE_CHANNEL:
case RECEIVE_DATA:
case SEND_DATA:
cmdPending = processBIPClient(cmdDet, ctlvs);
break;
default:
// unsupported proactive commands
mCmdParams = new CommandParams(cmdDet);
Expand Down Expand Up @@ -893,4 +899,43 @@ private boolean processProvideLocalInfo(CommandDetails cmdDet, List<Comprehensio
}
return false;
}

private boolean processBIPClient(CommandDetails cmdDet,
List<ComprehensionTlv> ctlvs) throws ResultException {
AppInterface.CommandType commandType =
AppInterface.CommandType.fromInt(cmdDet.typeOfCommand);
if (commandType != null) {
CatLog.d(this, "process "+ commandType.name());
}

TextMessage textMsg = new TextMessage();
IconId iconId = null;
ComprehensionTlv ctlv = null;
boolean has_alpha_id = false;

// parse alpha identifier
ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs);
if (ctlv != null) {
textMsg.text = ValueParser.retrieveAlphaId(ctlv);
CatLog.d(this, "alpha TLV text=" + textMsg.text);
has_alpha_id = true;
}

// parse icon identifier
ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs);
if (ctlv != null) {
iconId = ValueParser.retrieveIconId(ctlv);
textMsg.iconSelfExplanatory = iconId.selfExplanatory;
}

textMsg.responseNeeded = false;
mCmdParams = new BIPClientParams(cmdDet, textMsg, has_alpha_id);

if (iconId != null) {
mIconLoadState = LOAD_SINGLE_ICON;
mIconLoader.loadIcon(iconId.recordNumber, this.obtainMessage(MSG_ID_LOAD_ICON_DONE));
return true;
}
return false;
}
}