
„Most je cijeli posao.“
Čipovi pasoša i platni terminali, iz React Nativea
Dva angažmana, dvije vrste hardvera, jedan pristup: napiši protokol nativno, izloži ga jednom, i pusti JavaScript da ostane neupućen u oboje.
Dvaput smo morali natjerati React Native da razgovara sa hardverom za koji nije postojala biblioteka vrijedna upotrebe: NFC čip u njemačkom pasošu, i kineski platni terminal na Androidu.
Oba puta odgovor je imao isti oblik — implementiraj protokol u jeziku platforme, izloži uzak sloj JavaScriptu, i ne daj detalju platforme da se prelije naviše. Razlikuje se ono što je hardver zahtijevao.
Problem
Ograničenje
Šta smo uradili
Protokol čipa u Javi, isti u Swiftu
Implementiran za Android, pa prenesen na iOS i izložen React Nativeu kroz Turbo Module — tada još eksperimentalni dio nove arhitekture, sa ručnom registracijom i tankom dokumentacijom.
Jedan protokol, dvije platformePort je važniji od implementacije
Dvije nezavisne implementacije takvog protokola se razilaze: počnu različito tretirati granične slučajeve, i onda isti pasoš prođe na jednom telefonu a padne na drugom. U verifikaciji identiteta to nije kozmetička nekonzistentnost — to je nejednako postupanje prema osobi koja drži dokument.
Isti pasoš, isti ishodTerminal izložen, pa zaključan
Kartica, štampač i hardver izloženi kroz Turbo Module u Javi. Onda launcher u Kotlinu koji je zamijenio Android početni ekran i zaključao uređaj na jednu aplikaciju. Na uređaju koji isplaćuje novac to je odluka o kontroli, ne o izgledu: osoba za šalterom ne smije moći otvoriti pregledač, instalirati nešto ili promijeniti postavku.
Jedna aplikacija, bez izlazaIsplatilo se dvaput — ažuriranje preko mreže
Uređaj zaključan na aplikaciju koju kontrolišete može se ažurirati na daljinu. Preko sto terminala ažurirano je bez ijednog izlaska na terensku lokaciju — aplikacija provjeri objektno skladište za novu verziju, a ako ažuriranje padne ne dogodi se ništa: nastavi raditi i ponovi pokušaj svakih pet minuta dok ne uspije. Svaki terminal je registrovan u admin ploči koja prikazuje njegovu aktivnost od trenutka povezivanja do toga ko je izdao koji kupon.
100+ terminala, nula izlazakaTermalni ispis: štampač ne zna za slike
Štampač računa ne zna za slike, fontove ni raspored — prima tačke. Logo mora postati bitmapa i biti pozicioniran ručno, u jedinicama papira, bez ikakvog pregleda. Zvuči trivijalno dok ne probaš, i može se odraditi samo štampanjem i mjerenjem.
Štampaj i mjeri
ICAO 9303 sa autentikacijskim rukovanjem prije nego čip bilo šta izgovori. Implementiran u Javi, prenesen u Swift, izložen kroz Turbo Module. Dekodiranje pročitanih podataka radio je vanjski servis — naše je bilo čitanje sa čipa.
Rezultat
- Kriptografski potpisani podaci pasoša pročitani sa čipa, na obje platforme, iz jedne implementacije protokola
- Preko 100 platnih terminala zaključanih na jednu aplikaciju i ažuriranih preko mreže
- Neuspjelo ažuriranje ne košta ništa: terminal nastavlja raditi i ponavlja pokušaj
Šta bismo uradili drugačije
Java implementaciju smo na Swift prenijeli ručno i provjerili testiranjem. Ono što je trebalo napraviti jesu dijeljeni testni vektori protokola — poznati ulazi i očekivani izlazi — pušteni protiv obje implementacije. Testirati da se ponašaju isto nije isto što i testirati da su ispravne, a mi smo uradili prvo vjerujući da smo uradili drugo.
- Java
- Kotlin
- Swift
- Turbo Modules
- React Native
- Android
- NFC / ICAO 9303