73ff6a60bd
Three fixes found while filling the ETSI/3GPP registry gaps against the SIMalliance Stepping Stones R7: - SCP80 builder/verification parity (TS 31.115 Table 1 NOTE / 4.2 / 4.3): the CPL is now transmitted whenever the packet is ciphered or carries RC/CC/DS - it is part of their input - and whenever the packet needs SMS concatenation; a single unprotected SM keeps pySim's CHL-first form. Before, the JS dropped the CPL for every unciphered packet while the server reference re-added it, so "Verify vs pySim" reported a false MISMATCH for every unciphered RC/CC packet (SPI1 01/02/0A/12/1A...). All ten offered SPI1 values now match the server reference byte-for-byte. - RC (SPI1 b2b1 = 01) was offered but not built: the JS now computes CRC-32 (TS 102 225 5.1.3.2, pySim zlib.crc32 parity) over the same CPL frame as the CC; the packet no longer silently omits the 4-byte RC field. - Server: _build_secured_packet/_ota_reference add the CPL to a concatenated unprotected packet too (Table 1 NOTE / 4.3). - fcpLifeCycle: unlisted values with b8 clear are RFU, b8 set is proprietary (Table 11.7b); previously all unmatched values were labelled proprietary. - EF.ARR decoder now decodes the expanded format (AM_DO/SC_DO per ISO 7816-4 5.4.3.2 + TS 102 221 9.2.7): operation bit masks, INCREASE/RESIZE AM_DO 0x84, OR/AND/NOT templates, PIN key references with usage qualifiers. - FCP 'C6' PS template DO decoded (PS_DO bitmap + key references + usage qualifiers, TS 102 221 11.1.1.4.10/9.5.2) with a shared key-reference map. Tests: sp.test.js (CPL/RC vectors + crc32 known answer), ef_decode.test.js (expanded-format ARR vectors), profiler.test.js (LCSI RFU/proprietary, C6), test_ota_helpers.py (RC reference, unprotected single-SM vs concatenated). Help EN/RU and READMEs: CPL size 2 (SMS), RC/CC/DS 4-8, RC bullet, CPL rule. 547 frontend / 397 Python green; version 3.5.1; sw cache simple-v253.
71 lines
1.8 KiB
JavaScript
71 lines
1.8 KiB
JavaScript
const CACHE = 'simple-v253';
|
|
const URLS = [
|
|
'index.html',
|
|
'help.html',
|
|
'help-ru.html',
|
|
'style.css',
|
|
'sim.png',
|
|
'favicon.svg',
|
|
'icon-192.png',
|
|
'icon-512.png',
|
|
'manifest.json',
|
|
'des-bundle.js',
|
|
'aes-bundle.js',
|
|
'sim.svg',
|
|
'sim_anim.svg',
|
|
'nosim.svg',
|
|
'uicc_files.json',
|
|
];
|
|
|
|
self.addEventListener('install', e => {
|
|
e.waitUntil(
|
|
caches.open(CACHE).then(c => c.addAll(URLS))
|
|
);
|
|
self.skipWaiting();
|
|
});
|
|
|
|
self.addEventListener('activate', e => {
|
|
e.waitUntil(
|
|
caches.keys().then(keys =>
|
|
Promise.all(keys.filter(k => k !== CACHE).map(k => caches.delete(k)))
|
|
).then(() => clients.claim())
|
|
);
|
|
});
|
|
|
|
const OFFLINE_RESPONSE = new Response('Offline: page not cached', {
|
|
status: 503,
|
|
statusText: 'Offline',
|
|
headers: { 'Content-Type': 'text/plain' },
|
|
});
|
|
|
|
self.addEventListener('fetch', e => {
|
|
if (!e.request.url.startsWith('http')) return;
|
|
const path = new URL(e.request.url).pathname;
|
|
if (path.startsWith('/api/')) return; // live data, never cache
|
|
if (e.request.method !== 'GET') return;
|
|
const isNavigate = e.request.mode === 'navigate';
|
|
const isSwScript = path.endsWith('/sw.js');
|
|
if (isNavigate) {
|
|
e.respondWith(
|
|
fetch(e.request).then(res => {
|
|
const clone = res.clone();
|
|
caches.open(CACHE).then(c => c.put(e.request, clone));
|
|
return res;
|
|
}).catch(() =>
|
|
caches.match(e.request)
|
|
.then(r => r || caches.match('index.html'))
|
|
.then(r => r || OFFLINE_RESPONSE)
|
|
)
|
|
);
|
|
} else if (isSwScript) {
|
|
e.respondWith(fetch(e.request).catch(() => OFFLINE_RESPONSE));
|
|
} else {
|
|
e.respondWith(
|
|
caches.match(e.request).then(r => r || fetch(e.request).then(res => {
|
|
const clone = res.clone();
|
|
caches.open(CACHE).then(c => c.put(e.request, clone));
|
|
return res;
|
|
}))
|
|
);
|
|
}
|
|
}); |