1

我开发了自己的 STK 小程序并安装在 SIM 卡中。但是,当我在智能手机中插入 SIM 卡时,SET_UP_MENU 主动命令不会发送到终端。我的小程序代码如下。

package com.example.ToolkitAppletExample;

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

public class MyToolkitApplet extends javacard.framework.Applet implements ToolkitInterface, uicc.toolkit.ToolkitConstants
{
    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 byte buffer[] = new byte[10];
    private byte itemId;
    private byte result;


    // Allocate 500 bytes for the reception buffer
    private static final short BUFFER_SIZE = (short)0x01F4;    
    // TLVs overhead in the Terminal Response in case of Receice Data: 
    //      Command details size: 5 bytes
    //      Device identities size : 4 bytes
    //      Result size : 3 bytes (in success case)
    //      Channel data length size : 3 bytes
    //      Channel data TL size : 3 bytes
    private static final short MAX_TLV_OVERHEAD = (short)0x0012;
    // Maximum response handler capacity to be used for the receive data 
    private static short myRspHdlrCapacity;
    
    // Port number : integer
    private static byte[] portNumber = {(byte)0x00,(byte)0x23};
    // Channel Identifier given by the ME after the OPEN CHANNEL proactive command
    private static byte channelID = 0x00;
    // Byte array where data from the ME buffer is stored
    private static byte[] channelData = new byte [BUFFER_SIZE];
    // IP Address of the Server 
    private static byte[] IPAddress = {(byte)163,(byte)187,(byte)203,(byte)1};

    /**
    * Constructor of the applet
    */
    public MyToolkitApplet(byte bArray[], short bOffset, byte bLength) {
        
        register();
        
        // register to the SIM Toolkit Framework
        reg = ToolkitRegistrySystem.getEntry();

        // Define the applet Menu Entry and register to the EVENT_MENU_SELECTION
        itemId = reg.initMenuEntry(menuEntry, (short)0x0000, (short)menuEntry.length, 
                                   PRO_CMD_DISPLAY_TEXT, false, (byte) 0x00, (short) 0x0000);
        
        reg.enableMenuEntry((byte)itemId);
    }

    /**
    * Method called by the JCRE at the installation of the applet
    */
    public static void install(byte bArray[], short bOffset, byte bLength) {
        MyToolkitApplet MyApplet = new MyToolkitApplet(bArray, bOffset, bLength);       
    }

    /**
    * Method called by the GSM Framework
    */
    public Shareable getShareableInterfaceObject(AID aid, byte p) {
         if (aid == null && p == (byte)1) {
            return this ; 
         }
         return null;
    }

    /**
    * Method called by the SIM Toolkit Framework
    */
    public void processToolkit(short event) {

        // get the handler references
        EnvelopeHandler          envHdlr = EnvelopeHandlerSystem.getTheHandler();
        ProactiveHandler         proHdlr = ProactiveHandlerSystem.getTheHandler();
        ProactiveResponseHandler rspHdlr = ProactiveResponseHandlerSystem.getTheHandler();;
        boolean repeat;

        switch(event) {
            case EVENT_STATUS_COMMAND:
                reg.enableMenuEntry((byte)itemId);  

            
            case EVENT_PROFILE_DOWNLOAD:
                reg.enableMenuEntry((byte)itemId);               
            break;
            case EVENT_MENU_SELECTION:
                // Prepare the Select Item proactive command
                proHdlr.init(PRO_CMD_SELECT_ITEM,(byte)0x00,DEV_ID_TERMINAL);
                // Append the Menu Title
                proHdlr.appendTLV((byte) (TAG_ALPHA_IDENTIFIER | TAG_SET_CR),
                                 menuTitle,(short)0x0000,(short)menuTitle.length);
                // add all the Item
                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);
                }
                // ask the SIM Toolkit Framework to send the proactive command and check the result
                if((result = proHdlr.send()) == RES_CMD_PERF){

                    // SelectItem response handling
                    switch (rspHdlr.getItemIdentifier()) {
                        case 1: 
                            // DisplayText High Priority 
                            proHdlr.init(PRO_CMD_DISPLAY_TEXT, CMD_QUALIFIER,DEV_ID_DISPLAY);
                            proHdlr.appendTLV((byte)(TAG_TEXT_STRING| TAG_SET_CR), (byte)0x04,
                                                textDText,(short)0x0000, (short)textDText.length);
                            proHdlr.send();
                        break;

                        case 2: // Ask the user to enter data and display it
                            do {
                                repeat = false;
                                try {
                                    // GetInput asking the users name
                                    proHdlr.initGetInput((byte)0x01, (byte)0x04, textGInput,(byte)0x00,
                                                (short)textGInput.length,(short)0x0001,(short)0x0002);
                                    proHdlr.send();
                                    // Display the entered text
                                    rspHdlr.copyTextString(textDText,(short)0x0000);
                                    proHdlr.initDisplayText((byte)0x00, (byte)0x04, 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;
            
        }
    }

    /**
    * Method called by the JCRE, once selected
    */
    public void process(APDU apdu) {
        // Handle the Select AID apdu
        if(selectingApplet())
            return;

        switch(apdu.getBuffer()[1]) {
            // specific APDU for this applet to configure the MenuTitle from SelectItem
            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);
        }
    }
}

据我所知,方法 initMenuEntry 和 enableMenuEntry 触发发送 SET_UP_MENU 主动命令。但是当我插入 SIM 卡时,没有 SET_UP_MENU 命令。当SIM卡插入手机时,还有其他人如何发送SET_UP_MENU主动命令吗?请帮我...

4

1 回答 1

0
  1. 为什么在 initMenuEntry 中使用 PRO_CMD_DISPLAY_TEXT ???正确的方法是

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

  2. 您不需要在这里和那里使用 enableMenuEntry。initMenuEntry 就足够了。

  3. 由于第 2 页,它已过时,但如果您想使用它,您必须订阅 EVENT_PROFILE_DOWNLOAD (reg.setEvent(EVENT_PROFILE_DOWNLOAD);)。以及将轮询间隔设置为 30 秒 (reg.requestPollInterval((short)30);) 以确保 EVENT_STATUS_COMMAND 可用。

于 2020-10-01T22:15:22.520 回答