44< head >
55 < meta charset ="utf-8 " />
66 < 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 ">
7+
8+ <!-- Tailwind CSS -->
9+ < script src ="https://cdn.tailwindcss.com "> </ script >
10+
11+ <!-- React -->
812 < script crossorigin src ="https://unpkg.com/react@18/umd/react.production.min.js "> </ script >
913 < 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 >
14+
15+ <!-- Flowbite -->
16+ < link href ="https://cdn.jsdelivr.net/npm/flowbite@2.5.2/dist/flowbite.min.css " rel ="stylesheet " />
17+
18+ < title > UICC system specific parameters generator</ title >
2119</ head >
2220
23- < body >
21+ < body class =" bg-gray-50 dark:bg-gray-900 " >
2422 < div id ="app "> </ div >
25- < script type ="text/babel ">
26- const params = new URLSearchParams ( location . search ) ;
27-
28- const toHex = ( val ) => val . toString ( 16 ) . padStart ( 2 , "0" ) . toUpperCase ( ) ;
29- const strToHexStream = ( str ) => str . split ( "" ) . map ( ( c ) => c . charCodeAt ( 0 ) . toString ( 16 ) ) . join ( "" ) . toUpperCase ( ) ;
30- // expose to devtool
31- window . toHex = toHex ;
32- window . strToHexStream = strToHexStream ;
33-
34- const copyToClipboard = ( text ) => {
35- const p = document . createElement ( "p" ) ;
36- p . style . opacity = "0" ;
37- p . style . position = "absolute" ;
38- p . style . top = "0" ;
39- p . style . left = "0" ;
40- document . body . appendChild ( p ) ;
41- p . innerHTML = text ;
42-
43- let result ;
44- try {
45- const range = document . createRange ( ) ;
46- range . selectNode ( p ) ;
47- window . getSelection ( ) . removeAllRanges ( ) ;
48- window . getSelection ( ) . addRange ( range ) ;
49- result = document . execCommand ( "copy" ) ;
50- window . getSelection ( ) . removeAllRanges ( ) ;
51- } finally {
52- document . body . removeChild ( p ) ;
53- }
54- return result ;
55- }
56-
57- const App = ( props ) => {
58- const [ priority , setPriority ] = React . useState ( 255 ) ;
59- const [ timer , setTimer ] = React . useState ( 5 ) ;
60- const [ channel , setChannel ] = React . useState ( 5 ) ;
61- const [ menuCount , setMenuCount ] = React . useState ( 6 ) ;
62- const [ entryLabelLength , setEntryLabelLength ] = React . useState ( 32 ) ;
63- const [ useUiccFs , setUseUiccFs ] = React . useState ( ( params . get ( "useuiccfs" ) == null ) || ( params . get ( "useuiccfs" ) === "true" ) || false ) ;
64- const [ adf1Aid , setAdf1Aid ] = React . useState ( params . get ( "adf1aid" ) || "" ) ;
65-
66- const [ generatedUssp , setGeneratedUssp ] = React . useState ( "" ) ;
67- const [ generatedUsspWithTag , setGeneratedUsspWithTag ] = React . useState ( "" ) ;
68-
69- const [ ramQuota , setRAMQuota ] = React . useState ( 1 ) ;
70- const [ nvramQuota , setNVRAMQuota ] = React . useState ( 1 ) ;
71-
72- const [ generatedSspWithTag , setGeneratedSspWithTag ] = React . useState ( "" ) ;
73-
74- const [ serverFQDN , setServerFQDN ] = React . useState ( params . get ( "serverfqdn" ) || "proxy.develop.sim-applet.com" ) ;
75- const [ serverPort , setServerPort ] = React . useState ( 80 ) ;
76- const [ connectInterval , setConnectInterval ] = React . useState ( "005132" ) ;
77- const [ encrypt , setEncrypt ] = React . useState ( "01" ) ;
78- const [ strOemEncKey , setStrOemEncKey ] = React . useState ( "PlsCngThisEncKey" ) ;
79- const [ hexOemEncKey , setHexOemEncKey ] = React . useState ( strToHexStream ( strOemEncKey ) ) ;
80- const [ oemEncKeyType , setOemEncKeyType ] = React . useState ( "str" ) ;
81- const [ useDigestAuth , setUseDigestAuth ] = React . useState ( false ) ;
82- const [ changeOemEncKey , setChangeOemEncKey ] = React . useState ( false ) ;
83-
84- const [ generatedAsp , setGeneratedAsp ] = React . useState ( "" ) ;
85- const [ generatedAspWithTag , setGeneratedAspWithTag ] = React . useState ( "" ) ;
86-
87- const generateSsp = ( ) => {
88- let ssp = "" ;
89- ssp += "C702" + ramQuota . toString ( 16 ) . padStart ( 4 , "0" )
90- ssp += "C802" + nvramQuota . toString ( 16 ) . padStart ( 4 , "0" )
91- ssp = "EF" + toHex ( ssp . length / 2 ) + ssp ;
92- ssp = ssp . toUpperCase ( ) ;
93-
94- setGeneratedSspWithTag ( ssp ) ;
95- }
96-
97- const generateAsp = ( ) => {
98- let asp = "" ;
99- asp += "80" + toHex ( serverFQDN . length ) + strToHexStream ( serverFQDN )
100- asp += "8102" + serverPort . toString ( 16 ) . padStart ( 4 , "0" )
101- if ( changeOemEncKey ) {
102- if ( oemEncKeyType === "hex" ) {
103- asp += "82" + toHex ( hexOemEncKey . length / 2 ) + hexOemEncKey ;
104- } else {
105- const tmpOemEncKey = strToHexStream ( strOemEncKey ) ;
106- asp += "82" + toHex ( tmpOemEncKey . length / 2 ) + tmpOemEncKey ;
107- }
108- }
109- asp += "8303" + connectInterval ;
110- asp += "8401" + encrypt ;
111- asp = asp . toUpperCase ( ) ;
112- setGeneratedAsp ( asp ) ;
113-
114- asp = "C9" + toHex ( asp . length / 2 ) + asp
115- setGeneratedAspWithTag ( asp ) ;
116- }
117-
118- const generateUssp = ( ) => {
119- let ussp = "" ;
120-
121- ussp += "80" ; // Tag of **UICC Toolkit** Application specific parameters field
122-
123- let utasp = "" ;
124- utasp += toHex ( priority ) ; // Priority level of the Toolkit application instance
125- utasp += toHex ( timer ) ; // Maximum number of timers allowed for this application instance
126- utasp += toHex ( entryLabelLength ) ; // Maximum text length for a menu entry
127- utasp += toHex ( menuCount ) ; // Maximum number of menu entries allowed for this application instance
128- for ( let i = 0 ; i < menuCount ; i ++ ) {
129- utasp += toHex ( i + 1 ) ; // Position of the n-th menu entry
130- utasp += "00" ; // Identifier of the n-th menu entry ('00' means do not care)
131- }
132- utasp += toHex ( channel ) ; // Maximum number of channels for this application instance
133- utasp += "00" ; // Length of Minimum Security Level field
134-
135- ussp += toHex ( utasp . length / 2 ) ; // Length of UICC Toolkit Application specific parameters field
136- ussp += utasp ;
137-
138- if ( useUiccFs ) {
139- ussp += "81" ; // Tag of **UICC Access** Application specific parameters field
140-
141- let uiccFs = "" ;
142- uiccFs += "00" ; // Length of UICC file system AID
143- uiccFs += "01" ; // Length of Access Domain for UICC file system
144- uiccFs += "00" ; // Access Domain for UICC file system
145- uiccFs += "00" ; // Length of Access Domain DAP
146- uiccFs += toHex ( adf1Aid . length / 2 ) ; // Length of ADF#1 AID
147- uiccFs += adf1Aid ;
148- uiccFs += "01" ; // Length of Access Domain for ADF#1
149- uiccFs += "00" ; // Access Domain for ADF#1
150- uiccFs += "00" ; // Length of Access Domain DAP#1
151-
152- ussp += toHex ( uiccFs . length / 2 ) ; // Length of UICC Access Application specific parameters field
153- ussp += uiccFs ;
154- }
155- ussp = ussp . toUpperCase ( ) ;
156-
157- setGeneratedUssp ( ussp ) ;
158-
159- let usspWithTag = "EA" + toHex ( ussp . length / 2 ) + ussp ;
160- setGeneratedUsspWithTag ( usspWithTag ) ;
161-
162- }
163-
164- React . useEffect ( ( ) => {
165- generateUssp ( ) ;
166- generateSsp ( ) ;
167- generateAsp ( ) ;
168- } , [ priority , timer , channel , menuCount , entryLabelLength , useUiccFs , adf1Aid ,
169- ramQuota , nvramQuota ,
170- serverFQDN , serverPort , connectInterval , encrypt , hexOemEncKey , strOemEncKey , useDigestAuth , changeOemEncKey ] ) ;
171-
172- React . useEffect ( ( ) => {
173- if ( oemEncKeyType === "hex" ) {
174- setHexOemEncKey ( strToHexStream ( strOemEncKey ) ) ;
175- } else {
176- setStrOemEncKey ( hexOemEncKey . match ( / .{ 1 , 2 } / g) ?. map ( ( hex ) => String . fromCharCode ( parseInt ( hex , 16 ) ) ) . join ( "" ) || "" ) ;
177- }
178- } , [ oemEncKeyType ] ) ;
179-
180- const gpParams = generatedAspWithTag + generatedSspWithTag + generatedUsspWithTag ;
181-
182- return (
183- < div >
184- < h1 > UICC system specific parameters generator</ h1 >
185-
186- < h2 > 設定</ h2 >
187- < div >
188- < label className = "config" >
189- < div > Toolkit アプリケーション インスタンスの優先度: </ div >
190- < div >
191- < input type = "number" value = { priority } onChange = { ( e ) => setPriority ( parseInt ( e . target . value , 10 ) ) } min = { 0 } max = { 255 } />
192- </ div >
193- </ label >
194- < label className = "config" >
195- < div > タイマーの数: </ div >
196- < div >
197- < input type = "number" value = { timer } onChange = { ( e ) => setTimer ( parseInt ( e . target . value , 10 ) ) } min = { 0 } max = { 255 } />
198- </ div >
199- </ label >
200- < label className = "config" >
201- < div > チャネルの数: </ div >
202- < div >
203- < input type = "number" value = { channel } onChange = { ( e ) => setChannel ( parseInt ( e . target . value , 10 ) ) } min = { 0 } max = { 255 } />
204- </ div >
205- </ label >
206- < label className = "config" >
207- < div > メニューに表示するエントリーの数: </ div >
208- < div >
209- < input type = "number" value = { menuCount } onChange = { ( e ) => setMenuCount ( parseInt ( e . target . value , 10 ) ) } min = { 0 } max = { 255 } />
210- </ div >
211- </ label >
212- < label className = "config" >
213- < div > メニュー エントリーの文字数: </ div >
214- < div >
215- < input type = "number" value = { entryLabelLength } onChange = { ( e ) => setEntryLabelLength ( parseInt ( e . target . value , 10 ) ) } min = { 0 } max = { 255 } />
216- </ div >
217- </ label >
218- < label className = "config" >
219- < div >
220- < input type = "checkbox" checked = { useUiccFs } onChange = { ( e ) => setUseUiccFs ( e . target . checked ) } />
221- </ div >
222- < div > UICC AIDファイルシステムを使用する</ div >
223- </ label >
224- { useUiccFs && (
225- < >
226- < label className = "config" >
227- < div > ADF#1 AID (hex): </ div >
228- < div style = { { flex : 1 } } >
229- < input style = { { width : "80%" } } value = { adf1Aid } onChange = { ( e ) => setAdf1Aid ( e . target . value ) } />
230- </ div >
231- </ label >
232- </ >
233- ) }
234- </ div >
235-
236- < h2 > 設定(System Specific Parameters)</ h2 >
237- < div >
238- < label className = "config" >
239- < div > Volatile Memory Quota(C7): </ div >
240- < div >
241- < input type = "number" value = { ramQuota } onChange = { ( e ) => setRAMQuota ( parseInt ( e . target . value , 10 ) ) } min = { 0 } max = { 65535 } />
242- </ div >
243- </ label >
244- < label className = "config" >
245- < div > Nonv-volatile Memory Quota(C8): </ div >
246- < div >
247- < input type = "number" value = { nvramQuota } onChange = { ( e ) => setNVRAMQuota ( parseInt ( e . target . value , 10 ) ) } min = { 0 } max = { 65535 } />
248- </ div >
249- </ label >
250- </ div >
251-
252- < h2 > 設定(Application Specific Parameters)</ h2 >
253- < div >
254- < label className = "config" >
255- < div > (tag80)server FQDN: </ div >
256- < div style = { { flex : 1 } } >
257- < input style = { { width : "80%" } } value = { serverFQDN } maxLength = "127" onChange = { ( e ) => setServerFQDN ( e . target . value ) } />
258- </ div >
259- </ label >
260- < label className = "config" >
261- < div > (tag81)Port: </ div >
262- < div >
263- < input type = "number" value = { serverPort } onChange = { ( e ) => setServerPort ( parseInt ( e . target . value , 10 ) ) } min = { 1 } max = { 65535 } />
264- </ div >
265- </ label >
266- < label className = "config" >
267- < div >
268- < input type = "checkbox" checked = { changeOemEncKey } onChange = { ( e ) => setChangeOemEncKey ( e . target . checked ) } />
269- </ div >
270- < div > (tag82)OEMEncKeyを指定する</ div >
271- </ label >
272- < div style = { { marginLeft : "2rem" , marginBottom : "0.5rem" } } > < i > ※telemetryの暗号化 と ダイジェスト認証時のPW として使用します</ i > </ div >
273- { changeOemEncKey && (
274- < label className = "config" style = { { marginLeft : "2rem" , marginBottom : "0.5rem" } } >
275- < div > OEMEncKey: </ div >
276- { [ "str" , "hex" ] . map ( type => {
277- return (
278- < label style = { { marginRight : "0.5rem" } } >
279- < input type = "radio" value = { type } checked = { type === oemEncKeyType } onChange = { ( e ) => setOemEncKeyType ( e . target . value ) } />
280- < span > { type } </ span >
281- </ label >
282- )
283- } ) }
284- < div style = { { flex : 1 , display : "flex" , alignItems : "baseline" } } >
285- { oemEncKeyType === "hex" ? (
286- < >
287- < input style = { { width : "80%" } } value = { hexOemEncKey } onChange = { ( e ) => setHexOemEncKey ( e . target . value ) } />
288- < span style = { { color : hexOemEncKey . length === 32 ? "inherit" : "red" } } > { hexOemEncKey . length } /32</ span >
289- </ >
290- ) : (
291- < >
292- < input style = { { width : "80%" } } value = { strOemEncKey } onChange = { ( e ) => setStrOemEncKey ( e . target . value ) } />
293- < span style = { { color : strOemEncKey . length === 16 ? "inherit" : "red" } } > { strOemEncKey . length } /16</ span >
294- </ >
295- ) }
296- </ div >
297- </ label >
298- ) }
299- < label className = "config" >
300- < div > (tag83)接続間隔: </ div >
301- < div >
302- < input type = "text" value = { connectInterval } onChange = { ( e ) => setConnectInterval ( e . target . value ) } pattern = "\d{6}" maxLength = "6" />
303- </ div > < div > hHmMsS(例:15分23秒)</ div >
304- </ label >
305-
306- < label className = "config" >
307- < div >
308- < input type = "checkbox" checked = { encrypt === "01" } onChange = { ( e ) => setEncrypt ( e . target . checked ? "01" : "00" ) } />
309- </ div >
310- < div > (tag84)テレメトリデータを暗号化する</ div >
311- </ label >
312- </ div >
313-
314- < h2 > UICC_SYSTEM_SPECIFIC_PARAMETERS</ h2 >
315- < code > { generatedUssp } </ code >
316- < div style = { { display : "flex" , justifyContent : "end" , marginTop : "0.5rem" } } >
317- < button onClick = { ( ) => copyToClipboard ( generatedUssp ) } > クリップボードにコピー</ button >
318- </ div >
319-
320- < h2 > APP_SPECIFIC_PARAMETERS (STORE DATA)</ h2 >
321- < code > { generatedAsp } </ code >
322- < div style = { { display : "flex" , justifyContent : "end" , marginTop : "0.5rem" } } >
323- < button onClick = { ( ) => copyToClipboard ( generatedAsp ) } > クリップボードにコピー</ button >
324- </ div >
325-
326- < h2 > --params for GlobalPlatformPro (C9)</ h2 >
327- < code > { gpParams } </ code >
328- < div style = { { display : "flex" , justifyContent : "end" , marginTop : "0.5rem" } } >
329- < div >
330- < div style = { { display : "flex" , justifyContent : "end" , color : gpParams . length > 255 ? "red" : "inherit" , marginBottom : "0.5rem" } } > { gpParams . length } /255</ div >
331- < button onClick = { ( ) => copyToClipboard ( gpParams ) } disabled = { gpParams . length > 255 } > クリップボードにコピー</ button >
332- </ div >
333- </ div >
334- </ div >
335- ) ;
336- } ;
337-
338- ReactDOM . createRoot ( document . querySelector ( "#app" ) ) . render ( < App /> ) ;
339- </ script >
23+ < script type ="module " src ="./script.mjs "> </ script >
24+ < script src ="https://cdn.jsdelivr.net/npm/flowbite@2.5.2/dist/flowbite.min.js "> </ script >
34025</ body >
34126
342- </ html >
27+ </ html >
0 commit comments