C代码
int AppEmvAppSelect(int Slot, unsigned long TransNo)
{
unsigned char aucPDOL[256] = {0}, ucTransType = 0;
int InmputAmt=0;
unsigned int nPDOLLen = 0, nLen=0;
int nRet =0 ;
EMV_CANDLIST atCandAppList[MAX_APP_ITEMS];
EMV_CANDLIST atCandAppList_old[MAX_APP_ITEMS];
int nAppNum = 0, i=0;
int nSelTryCnt=0;
int nAppSelNo=0;
unsigned char buf[20] = {0}, buff[100] = {0};
DBG1(cDebugPortStr("%s %s %d -------- AppEmvAppSelect" , __FILE__ , __FUNCTION__, __LINE__););
gl_nEnableConfirmAmt = 0;
DEV_SetIccSlot((unsigned char)Slot);
nRet = DEV_IccReset();
if (nRet)
{
return ICC_RESET_ERR;
}
AppLoadALLtoKernel();
memset(atCandAppList, 0, sizeof(atCandAppList));
nAppNum = 0;
DBG1(cDebugPortStr("%s %s %d -------- EMV_AppSelect" , __FILE__ , __FUNCTION__, __LINE__););
if (gl_ucSkipCreCandiListFlg == 0) //Skip creating candidate list for AppEmvAppSelect
{
nRet = EMV_AppSelect(atCandAppList,&nAppNum);
}
else
{
nRet = EMV_GetCandList(atCandAppList,&nAppNum);// use the Candidate list set by application
}
if(nRet)
{
return nRet;
}
DBG1(cDebugPortStr("%s %s %d -------- nRet = %d" , __FILE__ , __FUNCTION__, __LINE__, nRet););
nSelTryCnt=0;
while(1)
{
if ((nAppNum == 1) && (!nSelTryCnt) && !(atCandAppList[0].ucPriority & 0x80)&& (gl_ucAppConfimMethod == 0))
{
nAppSelNo=0;
nRet=EMV_FinalSelect(0,atCandAppList, &nAppNum);
DBG1(cDebugPortStr("%s %d -------- nRet = %d" , __FUNCTION__, __LINE__, nRet););
}
else while(2)
{
memset(atCandAppList_old, 0, sizeof(atCandAppList_old));
for (i=0;i
整个逻辑来看,三个while()循环,细看其实就是一个continue.
1.上下文类,用于存储数据结构。
2.一个抽象状态类,
3.实现抽象类的类
4.调用这个状态模式
public class ContextAppSelete {
public ContextAppSelete(){
MAX_APP_ITEMS = 22;
nSelTryCnt = 0;
nAppNum = 0;
nAppSelNo = 0;
candListArray = new EMV_CANDLIST[MAX_APP_ITEMS];
for (int i = 0; i < candListArray.length; i++) {
candListArray[i] = new EMV_CANDLIST();
}
appNum = new int[1];
}
private AppSelectState state; //维持一个对抽象状态对象的引用
public int MAX_APP_ITEMS;
private int nSelTryCnt;
private int[] appNum;
private EMV_CANDLIST[] candListArray;
private int nAppNum ;
private int nAppSelNo ;
public int getnAppSelNo() {
return nAppSelNo;
}
public void setnAppSelNo(int nAppSelNo) {
this.nAppSelNo = nAppSelNo;
}
public void executeSelectFinalApp() {
state.executeAppSelete();
}
public AppSelectState getState() {
return state;
}
public int getnSelTryCnt() {
return nSelTryCnt;
}
public void setnSelTryCnt(int nSelTryCnt) {
this.nSelTryCnt = nSelTryCnt;
}
public int[] getAppNum() {
return appNum;
}
public void setAppNum(int[] appNum) {
this.appNum = appNum;
}
public int getMAX_APP_ITEMS() {
return MAX_APP_ITEMS;
}
public void setState(AppSelectState state) {
this.state = state;
}
public EMV_CANDLIST[] getCandListArray() {
return candListArray;
}
public void setCandListArray(EMV_CANDLIST[] candListArray) {
this.candListArray = candListArray;
}
public int getnAppNum() {
return nAppNum;
}
public void setnAppNum(int nAppNum) {
this.nAppNum = nAppNum;
}
}
public abstract class AppSelectState {
protected ContextAppSelete contextAppSelete;
public AppSelectState(ContextAppSelete contextAppSelete) {
this.contextAppSelete = contextAppSelete;
}
public abstract void executeAppSelete();
}
public class FinalAppState extends AppSelectState {
static final String TAG = FinalAppState.class.getSimpleName();
private int ret = -1;
private int nSelTryCnt =0;
public FinalAppState(ContextAppSelete contextAppSelete) {
super(contextAppSelete);
}
@Override
public void executeAppSelete() {
if ((contextAppSelete.getnAppNum() == 1) &&
(contextAppSelete.getnSelTryCnt()!=0) &&
((contextAppSelete.getCandListArray()[0].priority & 0x80) == 0x00)) {
ret = EMV_FinalSelect((byte)0,contextAppSelete.getCandListArray(),
contextAppSelete.getAppNum());
if(ret !=0){
contextAppSelete.setState(new QuitFinalAppState(contextAppSelete));
}else {
contextAppSelete.setState(new InitializeAppState(contextAppSelete));
}
} else {
if ((contextAppSelete.getnAppNum() == 1) &&
((contextAppSelete.getCandListArray()[0].priority & 0x80) == 0x00)) {
contextAppSelete.setnAppNum(0);
ret = EMV_FinalSelect((byte)contextAppSelete.getnAppNum(),
contextAppSelete.getCandListArray(),contextAppSelete.getAppNum());
Logs.d(TAG,"ret" + ret);
if( ret !=0 ){
contextAppSelete.setState(new QuitFinalAppState(contextAppSelete));
}else {
contextAppSelete.setState(new InitializeAppState(contextAppSelete));
}
//contextAppSelete.setState(new QuitFinalAppState(contextAppSelete));
}
InitializeAppState(contextAppSelete));
}
}
}
public boolean Appselect() {
ContextAppSelete contextAppSelete = new ContextAppSelete();
contextAppSelete.setState(new SelectAppState(contextAppSelete));
try {
while (true) {
contextAppSelete.executeSelectFinalApp();
if (contextAppSelete.getState() instanceof QuitFinalAppState) {
// Logic for quitting CVM
Logs.d(TAG, "QuitFinalAppState");
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}