|
| 1 | +<!doctype html> |
| 2 | +<html lang="ja"> |
| 3 | + |
| 4 | +<head> |
| 5 | + <meta charset="utf-8" /> |
| 6 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 7 | + <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.min.css"> |
| 8 | + <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> |
| 9 | + <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> |
| 10 | + <script crossorigin src="https://unpkg.com/@babel/standalone/babel.min.js"></script> |
| 11 | + |
| 12 | + <style> |
| 13 | + label.config { |
| 14 | + display: flex; |
| 15 | + align-items: baseline; |
| 16 | + } |
| 17 | + label.config > div:first-child { |
| 18 | + padding-right: 0.5rem; |
| 19 | + } |
| 20 | + </style> |
| 21 | +</head> |
| 22 | + |
| 23 | +<body> |
| 24 | + <div id="app"></div> |
| 25 | + <script type="text/babel"> |
| 26 | + const App = (props) => { |
| 27 | + const [priority, setPriority] = React.useState(255); |
| 28 | + const [timer, setTimer] = React.useState(5); |
| 29 | + const [channel, setChannel] = React.useState(5); |
| 30 | + const [menuCount, setMenuCount] = React.useState(1); |
| 31 | + const [entryLabelLength, setEntryLabelLength] = React.useState(32); |
| 32 | + const [useUiccFs, setUseUiccFs] = React.useState(false); |
| 33 | + const [adf1Aid, setAdf1Aid] = React.useState(""); |
| 34 | + |
| 35 | + const [generatedUssp, setGeneratedUssp] = React.useState(""); |
| 36 | + |
| 37 | + const toHex = (val) => val.toString(16).padStart(2, "0").toUpperCase(); |
| 38 | + |
| 39 | + const generateUssp = () => { |
| 40 | + let ussp = ""; |
| 41 | + |
| 42 | + ussp += "80"; |
| 43 | + |
| 44 | + let utasp = ""; |
| 45 | + utasp += toHex(priority); |
| 46 | + utasp += toHex(timer); |
| 47 | + utasp += toHex(entryLabelLength); |
| 48 | + utasp += toHex(menuCount); |
| 49 | + for (let i = 0; i < menuCount; i++) { |
| 50 | + utasp += toHex(i+1); |
| 51 | + utasp += "00"; |
| 52 | + } |
| 53 | + utasp += toHex(channel); |
| 54 | + utasp += "00"; |
| 55 | + ussp += toHex(utasp.length / 2); |
| 56 | + ussp += utasp; |
| 57 | + |
| 58 | + if (useUiccFs) { |
| 59 | + ussp += "81"; |
| 60 | + |
| 61 | + let uiccFs = ""; |
| 62 | + uiccFs += "00"; |
| 63 | + uiccFs += "01"; |
| 64 | + uiccFs += "00"; |
| 65 | + uiccFs += "00"; |
| 66 | + uiccFs += toHex(adf1Aid.length / 2); |
| 67 | + uiccFs += adf1Aid; |
| 68 | + uiccFs += "01"; |
| 69 | + uiccFs += "00"; |
| 70 | + uiccFs += "00"; |
| 71 | + ussp += toHex(uiccFs.length / 2); |
| 72 | + ussp += uiccFs; |
| 73 | + } |
| 74 | + |
| 75 | + setGeneratedUssp(ussp); |
| 76 | + } |
| 77 | + |
| 78 | + React.useEffect(() => { |
| 79 | + generateUssp(); |
| 80 | + }, [priority, timer, channel, menuCount, entryLabelLength, useUiccFs, adf1Aid]); |
| 81 | + |
| 82 | + return ( |
| 83 | + <div> |
| 84 | + <h1>UICC system specific parameters generator</h1> |
| 85 | + |
| 86 | + <h2>設定</h2> |
| 87 | + <div> |
| 88 | + <label className="config"> |
| 89 | + <div>Toolkit アプリケーション インスタンスの優先度: </div> |
| 90 | + <div> |
| 91 | + <input type="number" value={priority} onChange={(e) => setPriority(parseInt(e.target.value, 10))} min={0} max={255} /> |
| 92 | + </div> |
| 93 | + </label> |
| 94 | + <label className="config"> |
| 95 | + <div>タイマーの数: </div> |
| 96 | + <div> |
| 97 | + <input type="number" value={timer} onChange={(e) => setTimer(parseInt(e.target.value, 10))} min={0} max={255} /> |
| 98 | + </div> |
| 99 | + </label> |
| 100 | + <label className="config"> |
| 101 | + <div>チャネルの数: </div> |
| 102 | + <div> |
| 103 | + <input type="number" value={channel} onChange={(e) => setChannel(parseInt(e.target.value, 10))} min={0} max={255} /> |
| 104 | + </div> |
| 105 | + </label> |
| 106 | + <label className="config"> |
| 107 | + <div>メニューに表示するエントリーの数: </div> |
| 108 | + <div> |
| 109 | + <input type="number" value={menuCount} onChange={(e) => setMenuCount(parseInt(e.target.value, 10))} min={0} max={255} /> |
| 110 | + </div> |
| 111 | + </label> |
| 112 | + <label className="config"> |
| 113 | + <div>メニュー エントリーの文字数: </div> |
| 114 | + <div> |
| 115 | + <input type="number" value={entryLabelLength} onChange={(e) => setEntryLabelLength(parseInt(e.target.value, 10))} min={0} max={255} /> |
| 116 | + </div> |
| 117 | + </label> |
| 118 | + <label className="config"> |
| 119 | + <div> |
| 120 | + <input type="checkbox" checked={useUiccFs} onChange={(e) => setUseUiccFs(e.target.checked)} /> |
| 121 | + </div> |
| 122 | + <div>UICC AIDファイルシステムを使用する</div> |
| 123 | + </label> |
| 124 | + {useUiccFs && ( |
| 125 | + <> |
| 126 | + <label className="config"> |
| 127 | + <div>ADF#1 AID (hex): </div> |
| 128 | + <div style={{ flex: 1 }}> |
| 129 | + <input style={{ width: "80%" }} value={adf1Aid} onChange={(e) => setAdf1Aid(e.target.value)} /> |
| 130 | + </div> |
| 131 | + </label> |
| 132 | + </> |
| 133 | + )} |
| 134 | + </div> |
| 135 | + |
| 136 | + <h2>UICC_SYSTEM_SPECIFIC_PARAMETERS</h2> |
| 137 | + <code>{generatedUssp}</code> |
| 138 | + </div> |
| 139 | + ); |
| 140 | + }; |
| 141 | + |
| 142 | + ReactDOM.createRoot(document.querySelector("#app")).render(<App />); |
| 143 | + </script> |
| 144 | +</body> |
| 145 | + |
| 146 | +</html> |
0 commit comments