Android通过OMA获得ESE的CPLC

摘要】随着NFC支付的不断发展,以及NFC城市一卡通的不断普及,越来越多的大众开始接触到NFC技术带来的安全以及便捷,本文主要针对ANDROID如何通过OMA获取ESE的CPLC作下简单的介绍

OMA调用的流程图如下:
Android通过OMA获得ESE的CPLC_第1张图片

public class OMASEServiceCallBack implements SEService.CallBack {
        @Override
        public void serviceConnected(SEService seService) {
            Log.d(TAG, "connect to SEService");
            mSEservice = seService;
       }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = getApplicationContext();
        setContentView(R.layout.activity_cplc_layout);
        mBtn_sendCommand = (Button) findViewById(R.id.bt_sendCommand);
        mBtn_sendCommand.setOnClickListener(this);
        mTxtShowCplc = (TextView) findViewById(R.id.txt_showCplc);

        getSEService();
    }

首先我们得获取SEService的对象,上述的代码实现了这一点,当我们new SEService(mContext, mCallBack)时,会提供一个callback,在SEService的构造函数里面,会去bind SmartcardService,一旦bind成功,会通过callback回调上面的serviceConnected方法,这时候,就可以拿到SEService对象了,这个操作一般方法onCreate()方法里面执行。

private Reader getEseReader(Reader[] readers){
        Reader eseReader = null;
        Log.d(TAG, "getReader start");
        if(readers != null && readers.length >= 1){
            int idx = 0;
            for(Reader reader : readers){
                if(reader.getName().startsWith("eSE")){
                    break;
                }
                idx++;
            }
            if(idx < readers.length){
                eseReader = readers[idx];
            }else{
                Log.d(TAG, "eSE reader not exist");
            }
        }else{
            Log.d(TAG, "_readers is null");
        }
        Log.d(TAG,"getReader end");
        return eseReader;
    }

接下来,我们需要获得eSEReader,通过SEService的getReaders()方法,我们可以获得一个Readers的数组,这里用reader.getName().startsWith(“eSE”)筛选出来。

private Session initSession(Reader[] readers) {
        Log.d(TAG, "initSession start");
        Session session = null;
        try {
            session = getEseReader(readers).openSession();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.d(TAG, "initSession end");
        if (session == null){
            Log.d(TAG, "session null, re-connect");
            if (mSEservice != null && mSEservice.isConnected())
                mSEservice.shutdown();
            SEService seService = getSEService();
            if (seService == null){
                return null;
            }
            mReaders = seService.getReaders();
            try {
                session = getEseReader(mReaders).openSession();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Log.d(TAG, "re-connect end session is " + session);
        }
        return session;
    }

拿到eSEReader之后,接下来就是openSession的操作了,这里我们加入了一个re-connect机制,如果第一次get失败了,会重新get一次。

public static final String openChannelCommand = "A000000151000000";

public static final String getCplcCommand = "80CA9F7F00";

 synchronized private boolean sendCommand() {
        boolean result = true;
        Session session = null;
        Channel channel = null;

        if (mSEservice == null) {
            Log.d(TAG, "init failed !!!");
            return false;
        }
        try {
            if (mReaders == null) {
                mReaders = mSEservice.getReaders();
            }
            session = initSession(mReaders);
            if (session == null) {
                return false;
            }
            byte[] openChannelAidByte = CplcUtils.hexStringToBytes(openChannelCommand);
            channel = session.openBasicChannel(openChannelAidByte);
            Log.d(TAG, "sendCommand openBasicChannel");
            if (channel != null) {
                byte[] respSetstatus =       channel.transmit(CplcUtils.hexStringToBytes(getCplcCommand));
                mStrCplc = CplcUtils.bytesToHexString(respSetstatus);
                Log.d(TAG, "aid response" + mStrCplc);
                channel.close();
            }
            session.close();
        }
        catch (IOException e) {
            e.printStackTrace();
            return false;
        } catch (Exception e1) {
            e1.printStackTrace();
            return false;
        } finally {
            if (channel != null && !channel.isClosed()) {
            channel.close();
        }
            if (session != null && !session.isClosed()) {
                session.close();
            }
        }
        return true;
    }

最后就是openChannel以及sendCommand了,对于Ese来说,basicChannel和logicChannel都可以,我们这里打开的是BasicChannel,select的Aid为”A000000151000000”,当然如果我们把参数设置为null的话,也会用默认的Aid去执行,效果是一样的。Channel打开之后,通过transmit方法,就可以把查询CPLC的命令发送过去,正常情况下会成功返回9000结尾的一串数字,解析之后就是我们最终需要的CPLC了

完整的代码请见这里: http://download.csdn.net/download/shaoyuan1314520/10176536

你可能感兴趣的:(oma)