|
|
@@ -16,7 +16,7 @@
|
|
|
|
<div class="max-w-7xl mx-auto px-6 py-4">
|
|
|
|
<div class="max-w-7xl mx-auto px-6 py-4">
|
|
|
|
|
|
|
|
|
|
|
|
<div class="flex items-center justify-between mb-6">
|
|
|
|
<div class="flex items-center justify-between mb-6">
|
|
|
|
<h1 class="text-2xl font-bold text-heading">OTAMan <span id="slogan" class="text-sm font-normal text-gray-500 dark:text-slate-400 ml-2" data-l10n="SIM OTA with a Human Face">SIM OTA with a Human Face</span> <span class="text-xs text-gray-400 dark:text-slate-500 ml-1">v1.4.1</span></h1>
|
|
|
|
<h1 class="text-2xl font-bold text-heading">OTAMan <span id="slogan" class="text-sm font-normal text-gray-500 dark:text-slate-400 ml-2" data-l10n="SIM OTA with a Human Face">SIM OTA with a Human Face</span> <span class="text-xs text-gray-400 dark:text-slate-500 ml-1">v1.4.2</span></h1>
|
|
|
|
<div class="flex items-center gap-4">
|
|
|
|
<div class="flex items-center gap-4">
|
|
|
|
<button id="install-btn" class="px-2 py-1 text-xs rounded border border-gray-300 dark:border-slate-600 hover:bg-gray-200 dark:hover:bg-slate-700" style="display:none">INSTALL PWA [for offline use]</button>
|
|
|
|
<button id="install-btn" class="px-2 py-1 text-xs rounded border border-gray-300 dark:border-slate-600 hover:bg-gray-200 dark:hover:bg-slate-700" style="display:none">INSTALL PWA [for offline use]</button>
|
|
|
|
<a href="https://github.com/anttro/otaman" target="_blank" class="text-xs text-gray-400 hover:text-gray-600 dark:text-slate-500 dark:hover:text-slate-300">github</a>
|
|
|
|
<a href="https://github.com/anttro/otaman" target="_blank" class="text-xs text-gray-400 hover:text-gray-600 dark:text-slate-500 dark:hover:text-slate-300">github</a>
|
|
|
@@ -34,50 +34,8 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="tab-c-apdu" class="tab-content">
|
|
|
|
<div id="tab-c-apdu" class="tab-content">
|
|
|
|
<div class="border border-gray-300 dark:border-slate-600 rounded p-3 bg-gray-50 dark:bg-slate-800 mb-3">
|
|
|
|
<div class="flex gap-4">
|
|
|
|
<div class="flex gap-3 items-end">
|
|
|
|
<div class="flex-1">
|
|
|
|
<div class="flex-1">
|
|
|
|
|
|
|
|
<div class="mb-2">
|
|
|
|
|
|
|
|
<select id="conv-type" onchange="updateConvFields()" class="w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800">
|
|
|
|
|
|
|
|
<option value="nibswap">Nibble swap</option>
|
|
|
|
|
|
|
|
<option value="imsi">IMSI → EF.IMSI</option>
|
|
|
|
|
|
|
|
<option value="msisdn">MSISDN → BCD</option>
|
|
|
|
|
|
|
|
<option value="iccid">ICCID → hex</option>
|
|
|
|
|
|
|
|
<option value="spn">Provider Name → SPN</option>
|
|
|
|
|
|
|
|
<option value="plmn">MCC,MNC → PLMNsel</option>
|
|
|
|
|
|
|
|
<option value="plmnwact">MCC,MNC,AcT → PLMNwAcT</option>
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex gap-2 mb-2">
|
|
|
|
|
|
|
|
<input id="conv-input" class="font-mono flex-1 border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800">
|
|
|
|
|
|
|
|
<button onclick="genConvert()" class="px-3 py-1.5 bg-blue-600 text-white text-xs font-medium rounded hover:bg-blue-700" data-l10n="Convert">Convert</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="conv-plmn-fields" class="" style="display:none">
|
|
|
|
|
|
|
|
<div class="flex gap-2 mb-2">
|
|
|
|
|
|
|
|
<div class="flex-1">
|
|
|
|
|
|
|
|
<input id="conv-mcc" maxlength="3" class="font-mono w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800" placeholder="MCC">
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex-1">
|
|
|
|
|
|
|
|
<input id="conv-mnc" maxlength="3" class="font-mono w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800" placeholder="MNC">
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="conv-act-row" class="" style="display:none">
|
|
|
|
|
|
|
|
<select id="conv-act" class="w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800">
|
|
|
|
|
|
|
|
<option value="8000">GSM (8000)</option>
|
|
|
|
|
|
|
|
<option value="4000">UTRAN (4000)</option>
|
|
|
|
|
|
|
|
<option value="2000">E-UTRAN (2000)</option>
|
|
|
|
|
|
|
|
<option value="1000">NGRAN (1000)</option>
|
|
|
|
|
|
|
|
<option value="C000">GSM + UTRAN (C000)</option>
|
|
|
|
|
|
|
|
<option value="6000">UTRAN + E-UTRAN (6000)</option>
|
|
|
|
|
|
|
|
<option value="E000">GSM + UTRAN + E-UTRAN (E000)</option>
|
|
|
|
|
|
|
|
<option value="F000">All (F000)</option>
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<textarea id="conv-result" rows="2" readonly class="flex-1 font-mono border border-gray-300 dark:border-slate-600 text-xs rounded px-2 py-1.5 bg-white dark:bg-slate-800"></textarea>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex justify-center gap-2 mb-3">
|
|
|
|
<div class="flex justify-center gap-2 mb-3">
|
|
|
|
<button class="c-apdu-subtab px-4 py-1.5 text-sm rounded-full bg-blue-600 text-white" data-sub="sim" onclick="cApduSwitchSubtab('sim')">SIM RFM</button>
|
|
|
|
<button class="c-apdu-subtab px-4 py-1.5 text-sm rounded-full bg-blue-600 text-white" data-sub="sim" onclick="cApduSwitchSubtab('sim')">SIM RFM</button>
|
|
|
|
<button class="c-apdu-subtab px-4 py-1.5 text-sm rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-sub="usim" onclick="cApduSwitchSubtab('usim')">USIM RFM</button>
|
|
|
|
<button class="c-apdu-subtab px-4 py-1.5 text-sm rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-sub="usim" onclick="cApduSwitchSubtab('usim')">USIM RFM</button>
|
|
|
@@ -565,7 +523,49 @@
|
|
|
|
<textarea id="ram-result" rows="3" readonly class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-3 py-2.5 bg-gray-100 dark:bg-slate-800"></textarea>
|
|
|
|
<textarea id="ram-result" rows="3" readonly class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-3 py-2.5 bg-gray-100 dark:bg-slate-800"></textarea>
|
|
|
|
<button onclick="packToSp('ram-result')" id="ram-pack-btn" disabled class="mb-3 px-5 py-2.5 bg-emerald-600 text-white text-sm font-medium rounded hover:bg-emerald-700 disabled:opacity-40 disabled:cursor-not-allowed" data-l10n="Pack into Secured packet">Pack into Secured packet</button>
|
|
|
|
<button onclick="packToSp('ram-result')" id="ram-pack-btn" disabled class="mb-3 px-5 py-2.5 bg-emerald-600 text-white text-sm font-medium rounded hover:bg-emerald-700 disabled:opacity-40 disabled:cursor-not-allowed" data-l10n="Pack into Secured packet">Pack into Secured packet</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="w-1/4">
|
|
|
|
|
|
|
|
<div class="border border-gray-300 dark:border-slate-600 rounded p-3 bg-gray-50 dark:bg-slate-800">
|
|
|
|
|
|
|
|
<select id="conv-type" onchange="updateConvFields()" class="w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800 mb-2">
|
|
|
|
|
|
|
|
<option value="nibswap">Nibble swap</option>
|
|
|
|
|
|
|
|
<option value="imsi">IMSI → EF.IMSI</option>
|
|
|
|
|
|
|
|
<option value="msisdn">MSISDN → BCD</option>
|
|
|
|
|
|
|
|
<option value="iccid">ICCID → hex</option>
|
|
|
|
|
|
|
|
<option value="spn">Provider Name → SPN</option>
|
|
|
|
|
|
|
|
<option value="plmn">MCC,MNC → PLMNsel</option>
|
|
|
|
|
|
|
|
<option value="plmnwact">MCC,MNC,AcT → PLMNwAcT</option>
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
<div class="flex flex-col gap-2 mb-2">
|
|
|
|
|
|
|
|
<input id="conv-input" class="font-mono flex-1 border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800">
|
|
|
|
|
|
|
|
<button onclick="genConvert()" class="px-3 py-1.5 bg-blue-600 text-white text-xs font-medium rounded hover:bg-blue-700" data-l10n="Convert">Convert</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="conv-plmn-fields" class="" style="display:none">
|
|
|
|
|
|
|
|
<div class="flex gap-2 mb-2">
|
|
|
|
|
|
|
|
<div class="flex-1">
|
|
|
|
|
|
|
|
<input id="conv-mcc" maxlength="3" class="font-mono w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800" placeholder="MCC">
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex-1">
|
|
|
|
|
|
|
|
<input id="conv-mnc" maxlength="3" class="font-mono w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800" placeholder="MNC">
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="conv-act-row" class="" style="display:none">
|
|
|
|
|
|
|
|
<select id="conv-act" class="w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800">
|
|
|
|
|
|
|
|
<option value="8000">GSM (8000)</option>
|
|
|
|
|
|
|
|
<option value="4000">UTRAN (4000)</option>
|
|
|
|
|
|
|
|
<option value="2000">E-UTRAN (2000)</option>
|
|
|
|
|
|
|
|
<option value="1000">NGRAN (1000)</option>
|
|
|
|
|
|
|
|
<option value="C000">GSM + UTRAN (C000)</option>
|
|
|
|
|
|
|
|
<option value="6000">UTRAN + E-UTRAN (6000)</option>
|
|
|
|
|
|
|
|
<option value="E000">GSM + UTRAN + E-UTRAN (E000)</option>
|
|
|
|
|
|
|
|
<option value="F000">All (F000)</option>
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<textarea id="conv-result" rows="3" readonly class="w-full font-mono border border-gray-300 dark:border-slate-600 text-xs rounded px-2 py-1.5 mt-2 bg-white dark:bg-slate-800"></textarea>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="tab-sp" class="tab-content hidden">
|
|
|
|
<div id="tab-sp" class="tab-content hidden">
|
|
|
|
<div class="mb-3">
|
|
|
|
<div class="mb-3">
|
|
|
@@ -863,6 +863,7 @@
|
|
|
|
<button class="pysim-subtab px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-pysim-sub="custom" data-l10n="Custom files">Custom files</button>
|
|
|
|
<button class="pysim-subtab px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-pysim-sub="custom" data-l10n="Custom files">Custom files</button>
|
|
|
|
<button class="pysim-subtab px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-pysim-sub="cmd" data-l10n="pySim command line">pySim command line</button>
|
|
|
|
<button class="pysim-subtab px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-pysim-sub="cmd" data-l10n="pySim command line">pySim command line</button>
|
|
|
|
<button class="pysim-subtab px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-pysim-sub="apdu" data-l10n="Raw APDU">Raw APDU</button>
|
|
|
|
<button class="pysim-subtab px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-pysim-sub="apdu" data-l10n="Raw APDU">Raw APDU</button>
|
|
|
|
|
|
|
|
<button class="pysim-subtab px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-pysim-sub="proactive">Proactive UICC</button>
|
|
|
|
<button id="stk-menu-btn" onclick="stkMenuOpen()" class="pysim-subtab px-3 py-1 text-xs rounded-full bg-emerald-600 text-white hover:bg-emerald-700" style="display:none">STK: <span id="stk-menu-title"></span></button>
|
|
|
|
<button id="stk-menu-btn" onclick="stkMenuOpen()" class="pysim-subtab px-3 py-1 text-xs rounded-full bg-emerald-600 text-white hover:bg-emerald-700" style="display:none">STK: <span id="stk-menu-title"></span></button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
@@ -924,6 +925,10 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<textarea id="pysim-apdu-output" rows="5" readonly class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-3 py-2.5 bg-gray-100 dark:bg-slate-800"></textarea>
|
|
|
|
<textarea id="pysim-apdu-output" rows="5" readonly class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-3 py-2.5 bg-gray-100 dark:bg-slate-800"></textarea>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="pysim-sub-proactive" class="hidden">
|
|
|
|
|
|
|
|
<div class="mb-2 text-xs text-gray-500 dark:text-slate-400" data-l10n="Events that the card monitors (SET UP EVENT LIST):">Events that the card monitors (SET UP EVENT LIST):</div>
|
|
|
|
|
|
|
|
<div id="pysim-event-list" class="text-xs font-mono text-gray-600 dark:text-slate-400"></div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="stk-menu-panel" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center hidden">
|
|
|
|
<div id="stk-menu-panel" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center hidden">
|
|
|
@@ -935,9 +940,9 @@
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div id="stk-menu-panel-content" class="flex-1 overflow-auto"></div>
|
|
|
|
<div id="stk-menu-panel-content" class="flex-1 overflow-auto"></div>
|
|
|
|
<div id="stk-menu-buttons" class="flex justify-between mt-3 pt-3 border-t border-gray-200 dark:border-slate-700 hidden">
|
|
|
|
<div id="stk-menu-buttons" class="flex justify-between mt-3 pt-3 border-t border-gray-200 dark:border-slate-700 hidden">
|
|
|
|
<button onclick="stkMenuRespond('timeout')" class="px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-l10n="Timeout">Timeout</button>
|
|
|
|
<button id="stk-timeout-btn" onclick="stkMenuRespond('timeout')" class="px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-l10n="Timeout">Timeout</button>
|
|
|
|
<button onclick="stkMenuRespond('cancel')" class="px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-l10n="Cancel">Cancel</button>
|
|
|
|
<button id="stk-cancel-btn" onclick="stkMenuRespond('cancel')" class="px-3 py-1 text-xs rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-l10n="Cancel">Cancel</button>
|
|
|
|
<button onclick="stkMenuRespond('ok')" class="px-4 py-1 text-xs rounded-full bg-blue-600 text-white hover:bg-blue-700" data-l10n="OK">OK</button>
|
|
|
|
<button id="stk-ok-btn" onclick="stkMenuRespond('ok')" class="px-4 py-1 text-xs rounded-full bg-blue-600 text-white hover:bg-blue-700" data-l10n="OK">OK</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
@@ -2854,6 +2859,7 @@ function stkMenuHandleResponse(data) {
|
|
|
|
if (data.type === 'display_text') {
|
|
|
|
if (data.type === 'display_text') {
|
|
|
|
content.innerHTML = '<div class="text-sm whitespace-pre-wrap p-2 bg-gray-50 dark:bg-slate-700 rounded">' + esc(data.text) + '</div>';
|
|
|
|
content.innerHTML = '<div class="text-sm whitespace-pre-wrap p-2 bg-gray-50 dark:bg-slate-700 rounded">' + esc(data.text) + '</div>';
|
|
|
|
backBtn.style.display = '';
|
|
|
|
backBtn.style.display = '';
|
|
|
|
|
|
|
|
document.getElementById('stk-ok-btn').style.display = '';
|
|
|
|
btns.classList.remove('hidden');
|
|
|
|
btns.classList.remove('hidden');
|
|
|
|
} else if (data.type === 'select_item') {
|
|
|
|
} else if (data.type === 'select_item') {
|
|
|
|
stkMenuStack.push(data.items);
|
|
|
|
stkMenuStack.push(data.items);
|
|
|
@@ -2866,6 +2872,7 @@ function stkMenuHandleResponse(data) {
|
|
|
|
html += '</div>';
|
|
|
|
html += '</div>';
|
|
|
|
content.innerHTML = html;
|
|
|
|
content.innerHTML = html;
|
|
|
|
backBtn.style.display = '';
|
|
|
|
backBtn.style.display = '';
|
|
|
|
|
|
|
|
document.getElementById('stk-ok-btn').style.display = 'none';
|
|
|
|
btns.classList.remove('hidden');
|
|
|
|
btns.classList.remove('hidden');
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
content.innerHTML = '<span class="text-gray-500 text-sm">SW: ' + esc(data.sw || '?') + '</span>';
|
|
|
|
content.innerHTML = '<span class="text-gray-500 text-sm">SW: ' + esc(data.sw || '?') + '</span>';
|
|
|
@@ -3054,10 +3061,11 @@ function pysimSwitchSubtab(name) {
|
|
|
|
btn.classList.toggle('text-gray-700', !isActive);
|
|
|
|
btn.classList.toggle('text-gray-700', !isActive);
|
|
|
|
btn.classList.toggle('dark:text-slate-300', !isActive);
|
|
|
|
btn.classList.toggle('dark:text-slate-300', !isActive);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
['cmd', 'apdu', 'files', 'custom'].forEach(s => {
|
|
|
|
['cmd', 'apdu', 'files', 'custom', 'proactive'].forEach(s => {
|
|
|
|
document.getElementById('pysim-sub-' + s).classList.toggle('hidden', s !== name);
|
|
|
|
document.getElementById('pysim-sub-' + s).classList.toggle('hidden', s !== name);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
if (name === 'custom') pysimCustomRender();
|
|
|
|
if (name === 'custom') pysimCustomRender();
|
|
|
|
|
|
|
|
if (name === 'proactive') pysimEventsRender();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function pysimCmdKeydown(e) {
|
|
|
|
function pysimCmdKeydown(e) {
|
|
|
@@ -3525,6 +3533,46 @@ function pysimFsResetEdit() {
|
|
|
|
document.getElementById('pysim-fs-cancel-btn').classList.add('hidden');
|
|
|
|
document.getElementById('pysim-fs-cancel-btn').classList.add('hidden');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ===== proactive UICC events =====
|
|
|
|
|
|
|
|
const EVENT_NAMES = {
|
|
|
|
|
|
|
|
0x00: 'MT call', 0x01: 'Call connected', 0x02: 'Call disconnected',
|
|
|
|
|
|
|
|
0x03: 'Location status', 0x04: 'User activity', 0x05: 'Idle screen available',
|
|
|
|
|
|
|
|
0x06: 'Card reader status', 0x07: 'Language selection',
|
|
|
|
|
|
|
|
0x08: 'Browser termination', 0x09: 'Data available',
|
|
|
|
|
|
|
|
0x0A: 'Channel status', 0x0B: 'Access Technology Change',
|
|
|
|
|
|
|
|
0x0C: 'Display parameters changed', 0x0D: 'Local connection',
|
|
|
|
|
|
|
|
0x0E: 'Network Search Mode Change', 0x0F: 'Browsing status',
|
|
|
|
|
|
|
|
0x10: 'Frames Information Change', 0x11: 'I-WLAN Access Status',
|
|
|
|
|
|
|
|
0x12: 'Network Rejection', 0x13: 'HCI Connectivity',
|
|
|
|
|
|
|
|
0x14: 'Change of UICC Access', 0x15: 'CSG Cell Change',
|
|
|
|
|
|
|
|
0x16: 'Contactless state request', 0x17: 'Profile Container',
|
|
|
|
|
|
|
|
0x18: 'LTE D2D Discovery Monitoring', 0x19: 'LTE D2D Communication Monitoring',
|
|
|
|
|
|
|
|
0x1A: 'LTE D2D Announcement Response', 0x1B: 'LTE D2D Revocation',
|
|
|
|
|
|
|
|
0x1C: 'LTE D2D Application Port', 0x1D: 'LTE D2D Security Recovery',
|
|
|
|
|
|
|
|
0x1E: 'Off-net Emergency Call', 0x1F: 'ECall Over IMS',
|
|
|
|
|
|
|
|
0x20: 'EARFCN Update', 0x21: 'SCEF Channel Status',
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function pysimEventsRender() {
|
|
|
|
|
|
|
|
const el = document.getElementById('pysim-event-list');
|
|
|
|
|
|
|
|
el.innerHTML = '<span class="text-gray-400">' + t('Loading...') + '</span>';
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const events = await pysimFetch('/api/events');
|
|
|
|
|
|
|
|
if (!events || !events.length) {
|
|
|
|
|
|
|
|
el.innerHTML = '<span class="text-gray-400">' + t('No events configured.') + '</span>';
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let html = '';
|
|
|
|
|
|
|
|
events.forEach(e => {
|
|
|
|
|
|
|
|
const name = EVENT_NAMES[e] || ('Event 0x' + e.toString(16).padStart(2, '0').toUpperCase());
|
|
|
|
|
|
|
|
html += '<div class="flex items-center gap-2 py-0.5"><span class="w-6 text-right text-gray-400">' + e.toString(16).padStart(2, '0').toUpperCase() + '</span> ' + esc(name) + '</div>';
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
el.innerHTML = html;
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
el.innerHTML = '<span class="text-red-500">Error: ' + esc(e.message) + '</span>';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ===== custom files =====
|
|
|
|
// ===== custom files =====
|
|
|
|
let pysimCustomFiles = [];
|
|
|
|
let pysimCustomFiles = [];
|
|
|
|
|
|
|
|
|
|
|
@@ -3747,6 +3795,9 @@ const LANG_RU = {
|
|
|
|
'Verifying against pySim reference...': 'Сверка с эталоном pySim...',
|
|
|
|
'Verifying against pySim reference...': 'Сверка с эталоном pySim...',
|
|
|
|
'Verify vs pySim': 'Проверить в pySim',
|
|
|
|
'Verify vs pySim': 'Проверить в pySim',
|
|
|
|
'Send to Card': 'Отправить на карту',
|
|
|
|
'Send to Card': 'Отправить на карту',
|
|
|
|
|
|
|
|
'Proactive UICC': 'Проактивный UICC',
|
|
|
|
|
|
|
|
'Events that the card monitors (SET UP EVENT LIST):': 'События, отслеживаемые картой (SET UP EVENT LIST):',
|
|
|
|
|
|
|
|
'No events configured.': 'Нет настроенных событий.',
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let currentLang = 'en';
|
|
|
|
let currentLang = 'en';
|
|
|
|
|
|
|
|
|
|
|
|