クマは森で用を足しますか?

アウトプットは重要です。

SET UP MENU コマンドと DISPLAY TEXT コマンド

sysmoUSIM-SJS1 4FF を久しぶりに引っ張り出してきて、SIM ツールキット用の Java Card アプレットを作ってみることにします。SIM 側の実装を知ることで、SIM ツールキットの理解も深められるのではないかと考えています。

いわゆる "Hello World" 相当の、このコミットからスタートです。

github.com

ちなみに、sysmoUSIM-SJS1 4FF を購入した当時の話はこちら。

cheerio-the-bear.hatenablog.com

SET UP MENU コマンド

SET UP MENU コマンドをサポートするアプレットを SIM カードにインストールすることで、そのカードが装着された端末のユーザーインターフェースから SIM ツールキットアプリケーションを起動できるようになります。上記のコミットで対応した SET UP MENU コマンドの場合、次のスクリーンショットのようなメニューが表示されます。

f:id:cheerio-the-bear:20190211124614p:plain
SET UP MENU コマンド

sim.toolkit.ToolkitRegistry クラスの initMenuEntry() メソッドを利用することで、SIM ツールキットメニューを構成する要素を追加することができます。GSM 03.19 v2.0.0 Annex A から API 書式を引用してみましょう。

public byte initMenuEntry(byte[] menuEntry,
                          short offset,
                          short length,
                          byte nextAction,
                          boolean helpSupported,
                          byte iconQualifier,
                          short iconIdentifier)
                   throws java.lang.NullPointerException,
                          java.lang.ArrayIndexOutOfBoundsException,
                          ToolkitException

SET UP MENU コマンドの BER-TLV データオブジェクトの構成要素 (ETSI TS 102 223 6.6.7 参照) と比較すると、下記の情報に不足があります。追加するメニュー項目にアイコンを付加する必要がない場合には、この initMenuEntry() の利用で充分そうです。

  • Command Details (selection using soft key preferred)
  • Alpha Identifier
  • Icon Identifier
  • Item Icon Identifier List
  • Text Attribute
  • Item Text Attribute List

EF_SUME (ETSI ETSI TS 131 102 4.5.4 参照) をサポートしているカードであれば、Alpha Identifier やメニュー自体に付加するアイコンもそちらで変更できるんでしょう。

DISPLAY TEXT コマンド

DISPLAY TEXT コマンドを使って、SIM カードが装着された端末のユーザーインターフェース上にメッセージを表示することができます。上記のコミットで対応した DISPLAY TEXT コマンドの場合、次のスクリーンショットのようなダイアログがポップアップ表示されます。

f:id:cheerio-the-bear:20190211124719p:plain
DISPLAY TEXT コマンド

今回は、sim.toolkit.ProactiveHandler の initDisplayText() を使って実装してみました。GSM 03.19 v2.0.0 Annex A から引用した API 書式がこちら。

public void initDisplayText(byte qualifier,
                            byte dcs,
                            byte[] buffer,
                            short offset,
                            short length)
                     throws java.lang.NullPointerException,
                            java.lang.ArrayIndexOutOfBoundsException,
                            ToolkitException

SET UP MENU コマンドの BER-TLV データオブジェクトの構成要素 (ETSI TS 102 223 6.6.1 参照) と比較すると、下記の情報に不足があります。Icon Identifier はさておいても、Immediate Response や Duration を指定できないのは痛いかもしれません。

  • Icon Identifier
  • Immediate response
  • Duration
  • Text Attribute
  • Frame Identifier

この DISPLAY TEXT コマンドをしっかり使うアプレットを書く場合には、appendTLV() を使ってそれらの要素を追加できそうな API 仕様ですね。また別の機会にやってみることにしましょうか。

ビルドからインストールまで

Java Cardアプレットを書くのは久しぶりなので、今後の作業のためにビルドやインストールの方法をまとめておきます。

ツールのダウンロードとビルド

OSMOCOM 提供ツールを Python 3 で動くようにしたものと、作成中のアプレットソースコードgithub からクローンし、make コマンドを実行します。

$ git clone https://github.com/cheeriotb/osmocom-sim-tools.git
$ git clone https://github.com/cheeriotb/sim-toolkit-input.git
$ cd sim-toolkit-input
$ make

うまくビルドできれば、下記のように出力されます。

$ make
mkdir -p ./build/classes
mkdir -p ./build/javacard
javac -target 1.1 -source 1.3 -J-Duser.language=en -g -d ./build/classes -classpath "../osmocom-sim-tools/javacard/lib/api21.jar;../osmocom-sim-tools/javacard/lib/sim.jar" src/com/github/cheeriotb/toolkit/*.java
warning: [options] bootstrap class path not set in conjunction with -source 1.3
warning: [options] source value 1.3 is obsolete and will be removed in a future release
warning: [options] target value 1.1 is obsolete and will be removed in a future release
warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
4 warnings
java -jar ../osmocom-sim-tools/javacard/bin/converter.jar    \
        -d ./build/javacard                          \
        -classdir ./build/classes                    \
        -exportpath ../osmocom-sim-tools/javacard/api21_export_files                \
        -applet 0xD0:0x70:0x02:0xCA:0x44:0x90:0x01:0x01 com.github.cheeriotb.toolkit.InputApplet              \
        com.github.cheeriotb.toolkit 0xD0:0x70:0x02:0xCA:0x44:0x90:0x01 1.00

Java Card 2.1.2 Class File Converter (version 1.2)
Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved.

conversion completed with 0 errors and 0 warnings.

ロードとインストール

SIM カードへのパッケージのロードとアプレットのインストールは、下記のコマンドでまとめて実行します。

$ python ../osmocom-sim-tools/shadysim/shadysim.py --pcsc -l ./build/javacard/com/github/cheeriotb/toolkit/input/javacard/input.cap -i ./build/javacard/com/github/cheeriotb/toolkit/input/javacard/input.cap --enable-sim-toolkit --module-aid D07002CA44900101 --instance-aid D07002CA44900101 --nonvolatile-memory-required 0100 --volatile-memory-for-install 0100 --max-menu-entry-text 15 --max-menu-entries 05 --kic 3F9EA33B0DBEFEEE6FA90533FE22113E --kid 62C724DFFD165CB9CFF78778B49AB003

アプレットの動作確認に利用している SIM カードの KIc/KID は、下記の通り。KIc/KID は、使用するカードによって異なります。適切なものに適宜変更してからコマンドを実行しないと、二度と使えないカードにしてしまうかもしれないのでご注意ください。

  • KIc: 3F9EA33B0DBEFEEE6FA90533FE22113E
  • KID: 62C724DFFD165CB9CFF78778B49AB003

パッケージを SIM カードから削除するコマンドは、これでいいはず。

$ python ../osmocom-sim-tools/shadysim/shadysim.py --pcsc -d D07002CA449001 --kic 3F9EA33B0DBEFEEE6FA90533FE22113E --kid 62C724DFFD165CB9CFF78778B49AB003

GET STATUS コマンドで確認

パッケージのロードとアプレットのインストールを正しく実行できたかどうか、GET STATUS コマンドを使って確認してみましょう。

$ python ../osmocom-sim-tools/shadysim/shadysim.py --pcsc --list-applets --kic 3F9EA33B0DBEFEEE6FA90533FE22113E --kid 62C724DFFD165CB9CFF78778B49AB003
...
AID: a0000000090001ffffffff8900, State: 01, Privs: 00
        Instance AID: a0000000090001ffffffff8900000000
        Instance AID: a0000000090001ffffffff89b00010
AID: a0000000871002ff49ffff8900, State: 01, Privs: 00
        Instance AID: a0000000871002ff49ffff89040b0000
AID: ff434e52581040040203, State: 01, Privs: 00
        Instance AID: ff434e52581040040203000000000000
AID: d07002ca449001, State: 01, Privs: 00
        Instance AID: d07002ca44900101

末尾のパッケージおよびアプレットが、今回追加したものですね。問題ありません。