blob: 13db926763a4a90ce0768537260770a7bd55019b [file] [log] [blame]
Oliver Smith4e5e5162020-02-21 08:47:36 +01001package org.osmocom.IMSIPseudo;
2
Oliver Smith4eee13d2020-02-24 11:28:39 +01003import sim.access.*;
4import sim.toolkit.*;
5import javacard.framework.*;
Oliver Smith4e5e5162020-02-21 08:47:36 +01006
7public class IMSIPseudo extends Applet implements ToolkitInterface, ToolkitConstants {
8 // DON'T DECLARE USELESS INSTANCE VARIABLES! They get saved to the EEPROM,
9 // which has a limited number of write cycles.
Oliver Smith4e5e5162020-02-21 08:47:36 +010010
Oliver Smithca866fe2020-02-24 09:56:30 +010011 private byte STKServicesMenuId;
Oliver Smith2259cb92020-02-24 11:36:31 +010012 private SIMView gsmFile;
Oliver Smith1e5cc462020-02-21 15:39:14 +010013 static byte[] LUCounter = new byte[] { '0', 'x', ' ', 'L', 'U' };
Oliver Smithca866fe2020-02-24 09:56:30 +010014
15 /* Main menu */
Oliver Smith2dcbfab2020-02-21 15:40:21 +010016 static byte[] title = new byte[] { 'I', 'M', 'S', 'I', ' ', 'P', 's', 'e', 'u', 'd', 'o', 'n', 'y', 'm',
17 'i', 'z', 'a', 't', 'i', 'o', 'n'};
Oliver Smithca866fe2020-02-24 09:56:30 +010018 static byte[] showLU = new byte[] {'S', 'h', 'o', 'w', ' ', 'L', 'U', ' ', 'c', 'o', 'u', 'n', 't', 'e', 'r'};
19 static byte[] showIMSI = new byte[] {'S', 'h', 'o', 'w', ' ', 'I', 'M', 'S', 'I'};
20 static byte[] changeIMSI = new byte[] {'C', 'h', 'a', 'n', 'g', 'e', ' ', 'I', 'M', 'S', 'I', ' '};
21 private Object[] itemListMain = {title, showLU, showIMSI, changeIMSI};
22
23 /* Change IMSI menu */
24 static byte[] setDigit1 = new byte[] {'S', 'e', 't', ' ', '1', ' ', 'a', 's', ' ', 'l', 'a', 's', 't', ' ',
25 'd', 'i', 'g', 'i', 't'};
26 static byte[] setDigit2 = new byte[] {'S', 'e', 't', ' ', '2', ' ', 'a', 's', ' ', 'l', 'a', 's', 't', ' ',
27 'd', 'i', 'g', 'i', 't'};
28 private Object[] itemListChangeIMSI = {changeIMSI, setDigit1, setDigit2};
Oliver Smith4e5e5162020-02-21 08:47:36 +010029
30 private IMSIPseudo() {
Oliver Smith2259cb92020-02-24 11:36:31 +010031 gsmFile = SIMSystem.getTheSIMView();
32
Oliver Smithca866fe2020-02-24 09:56:30 +010033 /* Register menu and trigger on location updates */
Oliver Smith4e5e5162020-02-21 08:47:36 +010034 ToolkitRegistry reg = ToolkitRegistry.getEntry();
Oliver Smithca866fe2020-02-24 09:56:30 +010035 STKServicesMenuId = reg.initMenuEntry(title, (short)0, (short)title.length, PRO_CMD_SELECT_ITEM, false,
36 (byte)0, (short)0);
Oliver Smithe28705a2020-02-21 10:06:14 +010037 reg.setEvent(EVENT_EVENT_DOWNLOAD_LOCATION_STATUS);
Oliver Smith4e5e5162020-02-21 08:47:36 +010038 }
39
Oliver Smith4e5e5162020-02-21 08:47:36 +010040 public static void install(byte[] bArray, short bOffset, byte bLength) {
41 IMSIPseudo applet = new IMSIPseudo();
42 applet.register();
43 }
44
Oliver Smith4e5e5162020-02-21 08:47:36 +010045 public void process(APDU arg0) throws ISOException {
Oliver Smith4e5e5162020-02-21 08:47:36 +010046 if (selectingApplet())
47 return;
48 }
49
Oliver Smith4e5e5162020-02-21 08:47:36 +010050 public void processToolkit(byte event) throws ToolkitException {
51 EnvelopeHandler envHdlr = EnvelopeHandler.getTheHandler();
52
53 if (event == EVENT_MENU_SELECTION) {
54 byte selectedItemId = envHdlr.getItemIdentifier();
55
Oliver Smithca866fe2020-02-24 09:56:30 +010056 if (selectedItemId == STKServicesMenuId) {
57 showMenu(itemListMain, (byte)4);
58 handleMenuResponseMain();
Oliver Smith4e5e5162020-02-21 08:47:36 +010059 }
60 }
Oliver Smithe28705a2020-02-21 10:06:14 +010061
62 if (event == EVENT_EVENT_DOWNLOAD_LOCATION_STATUS) {
Oliver Smith1e5cc462020-02-21 15:39:14 +010063 LUCounter[0]++;
Oliver Smith234ab542020-02-24 08:25:43 +010064 showMsg(LUCounter);
Oliver Smithe28705a2020-02-21 10:06:14 +010065 }
Oliver Smith4e5e5162020-02-21 08:47:36 +010066 }
67
Oliver Smithca866fe2020-02-24 09:56:30 +010068 private void showMenu(Object[] itemList, byte itemCount) {
69 ProactiveHandler proHdlr = ProactiveHandler.getTheHandler();
70 proHdlr.init((byte) PRO_CMD_SELECT_ITEM,(byte)0,DEV_ID_ME);
71
72 for (byte i=(byte)0;i<itemCount;i++) {
73 if (i == 0) {
74 /* Title */
75 proHdlr.appendTLV((byte)(TAG_ALPHA_IDENTIFIER | TAG_SET_CR), (byte[])itemList[i],
76 (short)0, (short)((byte[])itemList[i]).length);
77
78 } else {
79 /* Menu entry */
80 proHdlr.appendTLV((byte)(TAG_ITEM | TAG_SET_CR), (byte)i, (byte[])itemList[i], (short)0,
81 (short)((byte[])itemList[i]).length);
82 }
83 }
84 proHdlr.send();
85 }
86
Oliver Smithcef081c2020-02-24 10:02:14 +010087 private void showMsg(byte[] msg) {
88 ProactiveHandler proHdlr = ProactiveHandler.getTheHandler();
89 proHdlr.initDisplayText((byte)0, DCS_8_BIT_DATA, msg, (short)0, (short)(msg.length));
90 proHdlr.send();
91 return;
92 }
93
Oliver Smithd7f18922020-02-24 12:24:38 +010094 private void showError(short code) {
95 byte[] msg = new byte[] {'E', '?', '?'};
96 msg[1] = (byte)('0' + code / 10);
97 msg[2] = (byte)('0' + code % 10);
98 showMsg(msg);
99 }
100
Oliver Smith2259cb92020-02-24 11:36:31 +0100101 private void showIMSI() {
102 /* 3GPP TS 31.102 4.2.2: IMSI */
103 byte[] IMSI = new byte[9];
104 byte[] msg = {'C', 'u', 'r', 'r', 'e', 'n', 't', ' ', 'I', 'M', 'S', 'I', ':', ' ',
105 '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_'};
106
107 gsmFile.select((short) SIMView.FID_DF_GSM);
108 gsmFile.select((short) SIMView.FID_EF_IMSI);
Oliver Smithd7f18922020-02-24 12:24:38 +0100109
110 try {
111 gsmFile.readBinary((short)0, IMSI, (short)0, (short)9);
112 } catch (SIMViewException e) {
113 showError(e.getReason());
114 }
Oliver Smith2259cb92020-02-24 11:36:31 +0100115
116 for (byte i = (byte)0; i < (byte)15; i++) {
117 byte msg_i = (byte)(14 + i);
118 if (i >= IMSI[0]) {
119 msg[msg_i] = ' ';
120 } else if (i % (byte)2 == (byte)0) {
121 msg[msg_i] = (byte)('0' + (IMSI[i / (byte)2] & 0x0f));
122 } else {
123 msg[msg_i] = (byte)('0' + (IMSI[i / (byte)2] >>> 4));
124 }
Oliver Smithd7f18922020-02-24 12:24:38 +0100125 showMsg(msg); /* DEBUG */
Oliver Smith2259cb92020-02-24 11:36:31 +0100126 }
127 showMsg(msg);
128 }
129
Oliver Smithca866fe2020-02-24 09:56:30 +0100130 private void handleMenuResponseMain() {
131 ProactiveResponseHandler rspHdlr = ProactiveResponseHandler.getTheHandler();
132
133 switch (rspHdlr.getItemIdentifier()) {
134 case 1: /* Show LU counter */
135 showMsg(LUCounter);
136 break;
137 case 2: /* Show IMSI */
Oliver Smith2259cb92020-02-24 11:36:31 +0100138 showIMSI();
Oliver Smithca866fe2020-02-24 09:56:30 +0100139 break;
140 case 3: /* Change IMSI */
141 showMenu(itemListChangeIMSI, (byte)3);
142 handleMenuResponseChangeIMSI();
143 break;
144 }
145 }
146
147 private void handleMenuResponseChangeIMSI() {
148 /* TODO */
149 }
Oliver Smith4e5e5162020-02-21 08:47:36 +0100150}