Java卡的应用开发其实并不难(6)-toolkit app demo

package ToolkitAppletExample;

import sim.toolkit.*;
import sim.access.*;
import javacard.framework.*;

public class MyToolkitApplet extends javacard.framework.Applet implements ToolkitInterface, ToolkitConstants
{
    // BIP Constants
    private static final byte TAG_DATA_DESTINATION_ADDRESS           = (byte) 0x3E;
 

    private static byte[] myAPN = {(byte)0x0A,(byte)'m',(byte)'y',(byte)'o',(byte)'p',(byte)'e',(byte)'r',(byte)'a',(byte)'t',(byte)'o',
                             (byte)'r',(byte)0x09,(byte)'m',(byte)'y',(byte)'c',(byte)'o',(byte)'u',(byte)'n',(byte)'t',
                             (byte)'r',(byte)'y'};
   
    //GPRS = 0x02
    private static final byte BEARER_TYPE_GPRS                       = (byte) 0x02;

    // The service precedence class indicates the relative priority of maintaining the service
    //Precedence Class n? => High priority.
    private static final byte BEARER_PARAMETER_PRECEDENCE_CLASS1     = (byte) 0x01;
   
 
    private static final byte BEARER_PARAMETER_DELAY_CLASS1          = (byte) 0x01;


    private static final byte BEARER_PARAMETER_RELIABILITY_CLASS1    = (byte) 0x01;


    private static final byte BEARER_PARAMETER_PEAK_THROUGHPUT_CLASS1= (byte) 0x01;
   

    private static final byte BEARER_PARAMETER_MEAN_THROUGHPUT_CLASS1    = (byte) 0x01;

    // PDP Type --> IP
    private static final byte BEARER_PARAMETER_PDP_IP                    = (byte) 0x02;

    // Define parameters necessary to launch a PDP context
    private static byte[] BearerParameters=    {(byte) BEARER_TYPE_GPRS, (byte) BEARER_PARAMETER_PRECEDENCE_CLASS1,
        (byte) BEARER_PARAMETER_DELAY_CLASS1, (byte) BEARER_PARAMETER_RELIABILITY_CLASS1,
        (byte) BEARER_PARAMETER_PEAK_THROUGHPUT_CLASS1, (byte) BEARER_PARAMETER_MEAN_THROUGHPUT_CLASS1,
        (byte) BEARER_PARAMETER_PDP_IP };

    // Type of Address IPV4=21,
    private static final byte TYPE_OF_ADDRESS_IPV4      = (byte) 0x21;
    // SIM/ME interface transport level UDP=01
    private static final byte TRANSPORT_PROTOCOL_TYPE   = (byte) 0x01;

    // --> ... end GPRS case

    public static final byte MY_INSTRUCTION         = (byte)0x46;
    public static final byte SERVER_OPERATION       = (byte)0x0F;
    public static final byte CMD_QUALIFIER          = (byte)0x80;
    public static final byte EXIT_REQUESTED_BY_USER = (byte)0x10;

    private byte[] menuEntry =    {(byte)'0',(byte)'3',(byte)'.',(byte)'1',(byte)'9',(byte)' ',(byte)'A',(byte)'p',(byte)'p',(byte)'l',(byte)'e',(byte)'t'};
   
    private byte[] menuTitle=     {(byte)'M',(byte)'y',(byte)'M',(byte)'e',(byte)'n' ,(byte)'u'};
    private byte[] item1 =        {(byte)'I',(byte)'T',(byte)'E',(byte)'M',(byte)'1' };
    private byte[] item2 =        {(byte)'I',(byte)'T',(byte)'E',(byte)'M',(byte)'2' };
    private byte[] item3 =        {(byte)'I',(byte)'T',(byte)'E',(byte)'M',(byte)'3' };
    private byte[] item4 =        {(byte)'I',(byte)'T',(byte)'E',(byte)'M',(byte)'4' };
    private Object[] ItemList =   { item1, item2, item3, item4 };
    private byte[] textDText =    {(byte)'H',(byte)'e',(byte)'l',(byte)'l',(byte)'o',(byte)' ',
      (byte)'w',(byte)'o',(byte)'r',(byte)'l',(byte)'d',(byte)'2'};
    private byte[] textGInput =    {(byte)'Y',(byte)'o',(byte)'u',(byte)'r',(byte)' ',(byte)'n',
      (byte)'a',(byte)'m',(byte)'e',(byte)'?'};

    private byte[]  baGSMAID =    {(byte)0xA0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09, (byte)0x00, (byte)0x01};
    private ToolkitRegistry reg;
    private SIMView gsmFile;
    private byte buffer[] = new byte[10];
    private byte itemId;
    private byte result;


    private static final short BUFFER_SIZE = (short)0x01F4;   
  
    private static final short MAX_TLV_OVERHEAD = (short)0x0012;

    private static short myRspHdlrCapacity;
   
    private static byte[] portNumber = {(byte)0x00,(byte)0x23};

    private static byte channelID = 0x00;

    private static byte[] channelData = new byte [BUFFER_SIZE];

    private static byte[] IPAddress = {(byte)163,(byte)187,(byte)203,(byte)1};

   
    public MyToolkitApplet() {


        gsmFile = SIMSystem.getTheSIMView();


        reg = ToolkitRegistry.getEntry();


        itemId = reg.initMenuEntry(menuEntry, (short)0x0000, (short)menuEntry.length,
                                   PRO_CMD_DISPLAY_TEXT, false, (byte) 0x00, (short) 0x0000);

        reg.setEvent(EVENT_UNFORMATTED_SMS_PP_ENV);
       

        reg.setEvent(EVENT_EVENT_DOWNLOAD_DATA_AVAILABLE);
    }

   
    public static void install(byte bArray[], short bOffset, byte bLength) {
        MyToolkitApplet MyApplet = new MyToolkitApplet();
        MyApplet.register();
    }

   
    public Shareable getShareableInterfaceObject(AID clientAID, byte parameter){
        if (parameter == (byte) 0x00){
            if ( clientAID.partialEquals(baGSMAID, (byte) 0x00, (byte) baGSMAID.length) == true )
                return((Shareable) this);
        }
        return(null);
    }

   
    public void processToolkit(byte event) {


        EnvelopeHandler          envHdlr = EnvelopeHandler.getTheHandler();
        ProactiveHandler         proHdlr = ProactiveHandler.getTheHandler();
        ProactiveResponseHandler rspHdlr ;
        boolean repeat;

        switch(event) {

            case EVENT_MENU_SELECTION:

                proHdlr.init(PRO_CMD_SELECT_ITEM,(byte)0x00,DEV_ID_ME);

                proHdlr.appendTLV((byte) (TAG_ALPHA_IDENTIFIER | TAG_SET_CR),
                                 menuTitle,(short)0x0000,(short)menuTitle.length);
 
                for (short i=(short) 0x0000; i<(short) 0x0004; i++) {
                    proHdlr.appendTLV((byte) (TAG_ITEM | TAG_SET_CR),(byte) (i+1),
                                      (byte[])ItemList[i],(short) 0x0000,
                                      (short)((byte[])ItemList[i]).length);
                }
 
                if((result = proHdlr.send()) == RES_CMD_PERF){
                    rspHdlr = ProactiveResponseHandler.getTheHandler();


                    switch (rspHdlr.getItemIdentifier()) {
                        case 1:
                        case 2:
                       
                            proHdlr.init(PRO_CMD_OPEN_CHANNEL,(byte)0x00, DEV_ID_ME);
 
                            proHdlr.appendTLV((byte)(TAG_BEARER_DESCRIPTION | TAG_SET_CR),(byte)BEARER_TYPE_GPRS,
                                                BearerParameters, (short)0x0000, (short)BearerParameters.length);
 
                            proHdlr.appendTLV((byte)(TAG_BUFFER_SIZE | TAG_SET_CR),(byte)(BUFFER_SIZE>>(byte)8),(byte)BUFFER_SIZE);
 
                            proHdlr.appendTLV((byte)(TAG_NETWORK_ACCESS_NAME | TAG_SET_CR),myAPN,(short)0,(short)myAPN.length);
 
                            proHdlr.appendTLV((byte) (TAG_SIM_ME_INTERFACE_TRANSPORT_LEVEL | TAG_SET_CR),TRANSPORT_PROTOCOL_TYPE,
                                                portNumber, (short)0, (short)portNumber.length);
 
 
                            proHdlr.appendTLV((byte) (TAG_DATA_DESTINATION_ADDRESS | TAG_SET_CR),TYPE_OF_ADDRESS_IPV4,
                                                IPAddress,(short)0, (short) IPAddress.length);

                            result = proHdlr.send();


                            if (result == RES_CMD_PERF){
                                rspHdlr = ProactiveResponseHandler.getTheHandler();
                                channelID = rspHdlr.getChannelIdentifier();

                                myRspHdlrCapacity = rspHdlr.getCapacity();
                   
                            }
                            else {
                                channelID = 0x00;
                            }

                        break;

                        case 3:

                            proHdlr.init(PRO_CMD_DISPLAY_TEXT, CMD_QUALIFIER,DEV_ID_DISPLAY);
                            proHdlr.appendTLV((byte)(TAG_TEXT_STRING| TAG_SET_CR), DCS_8_BIT_DATA,
                                                textDText,(short)0x0000, (short)textDText.length);
                            proHdlr.send();
                        break;

                        case 4: // Ask the user to enter data and display it
                            do {
                                repeat = false;
                                try {

                                    proHdlr.initGetInput((byte)0x01, DCS_8_BIT_DATA, textGInput,(byte)0x00,
                                                (short)textGInput.length,(short)0x0001,(short)0x0002);
                                    proHdlr.send();

                                    rspHdlr.copyTextString(textDText,(short)0x0000);
                                    proHdlr.initDisplayText((byte)0x00,DCS_8_BIT_DATA, textDText,
                                                            (short)0x0000,(short) textDText.length);
                                    proHdlr.send();
                                }
                                catch (ToolkitException MyException) {
                                    if (MyException.getReason() == ToolkitException.UNAVAILABLE_ELEMENT ){
                                        if (rspHdlr.getGeneralResult() != EXIT_REQUESTED_BY_USER)
                                            repeat = true;
                                        break;
                                    }
                                }
                            }
                            while(repeat);
                        break;
                    }
                }
            break;

            case EVENT_UNFORMATTED_SMS_PP_ENV:

                short TPUDOffset = (short) (envHdlr.getTPUDLOffset() + SERVER_OPERATION);


                switch (envHdlr.getValueByte((short)TPUDOffset) ) {
                    case 0x41 : // Update of a gsm file

                        envHdlr.copyValue((short)(TPUDOffset+1),buffer,(short)0x0000,(short)0x0003);

                        gsmFile.select(SIMView.FID_DF_GSM);
                        gsmFile.select(SIMView.FID_EF_PUCT);
                        gsmFile.updateBinary((short)0x0000,buffer,(short)0x0000,(short)0x0003);
                    break;

                    case 0x36 : // change the MenuTitle for the SelectItem
                        envHdlr.copyValue((short)(TPUDOffset+1), menuTitle,(short)0x0000,(short)0x0006);
                    break;
                }
            break;
               
            case EVENT_EVENT_DOWNLOAD_DATA_AVAILABLE:


                if ( channelID == envHdlr.getChannelIdentifier()) {

                    byte channelDataRemainingLgth;

                    short channelDataOffset = 0;

                    envHdlr.findTLV(TAG_CHANNEL_DATA_LENGTH ,(byte)0x01);
                    channelDataRemainingLgth = envHdlr.getValueByte((short)0x0000);
                                                   
                    do {
                       
   
                        if ( (short)(myRspHdlrCapacity - MAX_TLV_OVERHEAD) < (short)(( (short)(channelDataRemainingLgth) & (short)0x00FF))) {
                            channelDataRemainingLgth = (byte)((short)(myRspHdlrCapacity - MAX_TLV_OVERHEAD));
                        }
                           
   
                        proHdlr.init(PRO_CMD_RECEIVE_DATA,(byte)0,channelID);
                        proHdlr.appendTLV((byte)(TAG_CHANNEL_DATA_LENGTH | TAG_SET_CR),channelDataRemainingLgth);
                        result = proHdlr.send();

            
                        if ( result == RES_CMD_PERF ) {
                            rspHdlr = ProactiveResponseHandler.getTheHandler();
                            rspHdlr.findTLV(TAG_CHANNEL_DATA,(byte)0x01);
                            channelDataOffset = rspHdlr.copyChannelData(channelData,channelDataOffset, rspHdlr.getValueLength() );
                           
                          
                            rspHdlr.findTLV(TAG_CHANNEL_DATA_LENGTH ,(byte)0x01);
                            channelDataRemainingLgth = rspHdlr.getValueByte((short)0x0000);
                           
                        }

                    } while( channelDataRemainingLgth != (byte)0);

                   
                    proHdlr.initCloseChannel(channelID);
                    proHdlr.send();

                    // Process the data received in channelData
                    //.....
                    //....
                }

            break;

        }
    }

   
    public void process(APDU apdu) {
   
        if(selectingApplet())
            return;

        switch(apdu.getBuffer()[1]) {

            case (byte)MY_INSTRUCTION:
                if(apdu.setIncomingAndReceive() > (short)0) {
                    Util.arrayCopy(apdu.getBuffer(),(short)0x0005,menuTitle,(short)0x0000,(short)0x0006);
                }
            break;

            default:
                ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }
    }
}


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值