Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Hei kaikki

Tänään Viktor Antipov ja Ilya Aleshin jakavat kokemuksiaan USB-laitteiden kanssa työskentelystä Python PyUSB:n kautta ja hieman käänteisestä suunnittelusta.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

esihistoria

Vuonna 2019 tuli voimaan Venäjän hallituksen päätöslauselma nro 224 "Tupakkatuotteiden tunnistusvälineillä merkitsemistä koskevien sääntöjen hyväksymisestä ja tupakkatuotteiden tunnistusvälineillä merkitsemisen alaisten tavaroiden liikkuvuuden valvontaa koskevan valtion tietojärjestelmän käyttöönoton yksityiskohdista".
Asiakirjassa selitetään, että 1. heinäkuuta 2019 alkaen valmistajien on merkittävä jokainen tupakkapakkaus. Suorien jakelijoiden on vastaanotettava nämä tuotteet yleisellä siirtoasiakirjalla (UTD). Kauppojen on puolestaan ​​rekisteröitävä merkittyjen tuotteiden myynti kassalla.

Myös merkitsemättömien tupakkatuotteiden levitys on kielletty 1. heinäkuuta 2020 alkaen. Tämä tarkoittaa, että kaikki savukepakkaukset on merkittävä erityisellä Datamatrix-viivakoodilla. Tärkeää on, että on paljastunut, että Datamatrix ei ole standardiviivakoodi, vaan käänteinen. Eli ei mustaa koodia valkoisella, vaan päinvastoin.

Testasimme skannereitamme, ja kävi ilmi, että useimmat niistä piti ohjelmoida tai opettaa uudelleen, muuten ne eivät yksinkertaisesti toimisi kunnolla tämän viivakoodin kanssa. Tämä käänne takasi meille suuren päänsäryn, sillä yrityksellämme on valtava määrä myymälöitä hajallaan laajalla alueella. Kymmeniä tuhansia kassoja – ja hyvin vähän aikaa.

Mitä meidän pitäisi tehdä? On kaksi vaihtoehtoa. Ensinnäkin paikan päällä olevat insinöörit voivat manuaalisesti päivittää skannerien asetukset ja hienosäätää ne. Toiseksi voimme työskennellä etänä ja mieluiten käsitellä useita skannereita yhdellä kertaa.

Ensimmäinen vaihtoehto oli meille ilmiselvästi sopimaton: meidän olisi pitänyt käyttää rahaa insinöörien käynteihin, ja prosessin seuranta ja koordinointi olisi ollut vaikeaa. Mutta mikä tärkeintä, se olisi koskenut ihmisiä, mikä olisi tarkoittanut, että olisimme mahdollisesti kohdanneet lukuisia virheitä ja todennäköisesti myöhästyneet määräajasta.

Toinen vaihtoehto olisi ollut täydellinen, paitsi että yksi asia puuttui. Joillakin toimittajilla ei ollut tarvitsemiamme etäflashaustyökaluja kaikille vaadituille käyttöjärjestelmille. Ja koska aikataulut olivat tiukat, meidän piti selvittää se itse.

Seuraavaksi kerromme, kuinka kehitimme työkaluja Debian 9.x:ää käyttäville kannettaville skannereille (kaikki kassatyömme ovat Debianilla).

Ratkaise arvoitus: kuinka skanneri salataan

Viktor Antipov kertoo tarinan.

Valmistajan toimittama virallinen apuohjelma toimii Windowsissa, mutta vain Internet Explorerilla. Se voi flashata ja määrittää skannerin.

Koska kohdejärjestelmämme on Debian, asensimme USB-redirector-palvelimen Debianiin ja USB-redirector-asiakasohjelman Windowsiin. USB-redirector-apuohjelmien avulla ohjasimme skannerin uudelleen Linux-koneelta Windows-koneelle.

Valmistajan Windows-apuohjelma tunnisti skannerin ja jopa flashasi sen onnistuneesti. Ensimmäinen johtopäätöksemme siis: käyttöjärjestelmällä ei ole mitään tekemistä asian kanssa; ongelma on flashausprotokollassa.

OK. Aloitimme laiteohjelmistopäivityksen Windows-koneella ja teimme vedoksen Linux-koneella.

Työnsimme vedoksen WireSharkiin ja... tunsimme olomme surulliseksi (ohitan joitakin vedoksen yksityiskohtia, ne eivät ole kiinnostavia).

Mitä kaatopaikka meille näytti:

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Wiresharkin mukaan osoitteet 0000-0030 ovat USB-palvelutietoja.

Olimme kiinnostuneita osista 0040-0070.

Yksittäisestä lähetyskehyksestä ei ollut selvää mitään lukuun ottamatta MOCFT-symboleita. Nämä symbolit osoittautuivat laiteohjelmistotiedostosta, kuten myös muut symbolit kehyksen loppuun asti (laiteohjelmistotiedosto on korostettu):

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Henkilökohtaisesti minulla, kuten Iljallakaan, ei ollut aavistustakaan, mitä symbolit fd 3e 02 01 fe tarkoittivat.

Katsoin seuraavaa kehystä (huoltotiedot on poistettu tästä, laiteohjelmistotiedosto on korostettu):

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Mikä kävi selväksi? Että kaksi ensimmäistä tavua ovat jonkinlainen vakio. Kaikki seuraavat lohkot vahvistivat tämän, mutta vasta lähetyslohkon lopussa:

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Tämä kehys hämmensi minua myös, koska vakio (korostettu) oli muuttunut ja kumma kyllä, osa tiedostosta oli jäljellä. Siirrettyjen tavujen koko osoitti, että 1024 tavua oli siirretty. Mitä loput tavut tarkoittivat – taaskaan minulla ei ollut aavistustakaan.

Ensimmäiseksi kokeneena BBS-käyttäjänä tarkastelin standardinmukaisia ​​siirtoprotokollia. Yksikään niistä ei pystynyt siirtämään 1024 tavua. Aloin tutkia laitteistoa ja törmäsin 1K Xmodem-protokollaan. Se salli 1024 tavua, mutta siinä oli yksi haittapuoli: aluksi vain 128 tavua, ja vain jos virheitä ei ollut, protokolla lisäsi siirrettävien tavujen määrää. Lähetin heti 1024 tavua. Päätin tutkia siirtoprotokollia, erityisesti Xmodemia.

Modeemista oli kaksi versiota.

Ensin XMODEM-pakettimuoto CRC8-tuella (alkuperäinen XMODEM):

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Toiseksi, XMODEM-pakettimuoto CRC16-tuella (XmodemCRC):

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Näyttää samankaltaiselta lukuun ottamatta SOH:ta, pakettinumeroa, CRC:tä ja paketin pituutta.

Katsoin toisen lähetyslohkon alkua (ja näin jälleen laiteohjelmistotiedoston, mutta 1024 tavun sisennyksellä):

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Näin tutun otsikon, fd 3e 02, mutta seuraavat kaksi tavua olivat jo muuttuneet: se oli 01 fe, nyt 02 fd. Sitten huomasin, että toinen lohko oli nyt numeroitu 02, ja tajusin siten: tämä oli siirtolohkon numerointi. Ensimmäinen 1024 siirto on 01, toinen on 02, kolmas on 03 ja niin edelleen (mutta tietenkin heksadesimaalina). Mutta mitä muutos fe:stä fd:ksi tarkoittaa? Silmäni näkivät yhden pienenemisen, aivoni muistuttivat minua siitä, että ohjelmoijat laskevat nollasta, eivät ykkösestä. Mutta miksi ensimmäinen lohko sitten on 1, ei 0? En koskaan löytänyt vastausta tähän kysymykseen. Mutta ymmärsin, miten toinen lohko lasketaan. Toinen lohko ei ole muuta kuin FF – (miinus) ensimmäisen lohkon numero. Näin ollen toinen lohko nimettiin = 02 (FF-02) = 02 FD. Vedoksen myöhempi lukeminen vahvisti arvaukseni.

Sitten alkoi hahmottua seuraava kuva lähetyksestä:

Lähetyksen alku
fd 3e 02 – Aloitus
01 FE – lähetyslaskuri
Lähetys (34 lohkoa, 1024 tavua siirretty)
fd 3e 1024 tavua dataa (jaettuna 30 tavun lohkoihin).
Lähetyksen loppu
fd 25

Data on vielä yhdenmukaistettava 1024 tavuun.

Miltä näyttää lohkon lähetyskehyksen loppuosa:

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

fd 25 on lohkon lähetyksen lopetussignaali. Sitten 2f 52 on tiedoston loppuosa 1024 tavuun asti. Protokollan mukaan 2f 52 on 16-bittinen CRC-tarkistussumma.

Tapani vuoksi tein C-ohjelman, joka haki tiedostosta 1024 tavua ja laski 16-bittisen CRC:n. Ohjelman suorittaminen paljasti, ettei se ollutkaan 16-bittinen CRC. Jälleen kerran olin ymmälläni – noin kolme päivää. Koko tämän ajan yritin selvittää, mikä se voisi olla, ellei tarkistussumma. Tutkiessani englanninkielisiä verkkosivustoja huomasin, että X-modem käyttää omaa tarkistussummalaskentaansa – CRC-CCITT (XModem). En löytänyt mitään C-toteutuksia tästä laskutoimituksesta, mutta löysin verkkosivuston, joka laski tämän tarkistussumman verkosta. Ladattuani 1024 tavua tiedostostaan ​​verkkosivulle, verkkosivusto näytti minulle tarkistussumman, joka vastasi täysin tiedoston tarkistussummaa.

Hurraa! Viimeinenkin pulma oli ratkaistu, nyt minun piti luoda oma laiteohjelmisto. Seuraavaksi jaoin tietoni (joka oli jäänyt vain päähäni) Iljalle, joka tuntee tehokkaan työkalupakin – Pythonin.

Ohjelman luominen

Ilja Alešin kertoo tarinan.

Saatuaani asiaankuuluvat ohjeet olin erittäin "iloinen".

Mistä aloittaa? Aivan, aivan alusta.  Irrota USB-portti.

Käynnistä USB-pcap https://desowin.org/usbpcap/tour.html

Valitse portti, johon laite on kytketty, ja tiedosto, johon tallennamme vedoksen.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Yhdistämme skannerin koneeseen, johon on asennettu Windowsin natiivi EZConfigScanning-ohjelmisto.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Sieltä löytyy vaihtoehto lähettää komentoja laitteelle. Mutta entä sitten komennot? Mistä saan ne?
Kun ohjelma käynnistyy, laitteistolle tehdään automaattisesti kysely (näemme tämän hieman myöhemmin). Laitteen virallisesta dokumentaatiosta löytyivät myös harjoitusviivakoodit. OLETUS. Tämä on meidän tiimimme.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Tarvittavat tiedot on hankittu. Avaa dump.pcap Wiresharkilla.

Estä, kun EZConfigScanning käynnistyy. Huomiota vaativat alueet on korostettu punaisella.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Nähdessäni kaiken tämän ensimmäistä kertaa olin lannistunut. Oli epäselvää, mistä kaivaa seuraavaksi.

Vähän ideointia ja... Ahaa! Kaatopaikalla ulos - Onko inJa in это ulos.

Googlasin URB_INTERRUPTin ja selvisi, että se on tiedonsiirtomenetelmä. Näitä menetelmiä on neljä: control, interrupt, isokroninen ja bulk. Voit lukea niistä erikseen.

Ja USB-laiteliitännän päätepisteen osoite voidaan saada joko komennolla "lsusb –v" tai käyttämällä komentoa pyusb.

Nyt meidän on löydettävä kaikki laitteet, joilla on tämä VID. Voit hakea erityisesti VID:PID:n perusteella.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Näyttää siltä:

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Eli meillä on tarvittavat tiedot: P_INFO- tai DEFALT-komennot, osoitteet, joihin komennot kirjoitetaan (päätepiste=03) ja mihin vastaus vastaanotetaan (päätepiste=86). Jäljelle jää enää komennon muuntaminen heksadesimaalimuotoon.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Koska olemme jo löytäneet laitteen, irrotetaan se kernelista...

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

...ja kirjoita päätepisteeseen, jonka osoite on 0x03,

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

... ja sitten luemme vastauksen päätepisteestä, jonka osoite on 0x86.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Strukturoitu vastaus:

P_INFOfmt: 1
mode: app
app-present: 1
boot-present: 1
hw-sn: 18072B44CA
hw-rev: 0x20
cbl: 4
app-sw-rev: CP000116BBA
boot-sw-rev: CP000014BAD
flash: 3
app-m_name: Voyager 1450g
boot-m_name: Voyager 1450g
app-p_name: 1450g
boot-p_name: 1450g
boot-time: 16:56:02
boot-date: Oct 16 2014
app-time: 08:49:30
app-date: Mar 25 2019
app-compat: 289
boot-compat: 288
csum: 0x6986

Näemme nämä tiedot tiedostossa dump.pcap.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Erinomaista! Muunnamme järjestelmän viivakoodeja heksakoodimuotoon. Siinä kaikki, koulutustoiminto on valmis.

Entä laiteohjelmisto? Se näyttää olevan sama, mutta siinä on yksi vivahde.

Tallentettuamme täydellisen tiedoston laiteohjelmiston päivitysprosessista saimme karkean käsityksen siitä, minkä kanssa olimme tekemisissä. Tässä on artikkeli XMODEMista, joka auttoi meitä todella ymmärtämään, miten tämä tiedonsiirto toimii, vaikkakin yleisesti ottaen: http://microsin.net/adminstuff/others/xmodem-protocol-overview.html Suosittelen sen lukemista.

Katsomalla vedosta näet, että kehyksen koko on 1024 ja URB-datan koko on 64.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Siksi – 1024/64 – lohkossa on 16 riviä, luemme laiteohjelmistotiedoston merkki kerrallaan ja muodostamme lohkon. Lisäämme lohkoon yhden rivin erikoismerkeillä fd3e02 + lohkonumero.
Täydennämme seuraavia 14 riviä muuttujalla fd25 +, laskemme koko lohkon tarkistussumman XMODEM.calc_crc() -funktiolla (kesti kauan ymmärtää, että "FF - 1" on CSUM) ja täydennämme viimeistä, 16. riviä muuttujalla fd3e.

Näyttäisi siltä, ​​että siinä kaikki: lue laiteohjelmistotiedosto, käynnistä lohkot, irrota skanneri ytimestä ja lähetä se laitteelle. Mutta se ei ole niin yksinkertaista. Skanneri on asetettava laiteohjelmistotilaan.
отправив ему NEWAPP = ‘\xfd\x0a\x16\x4e\x2c\x4e\x45\x57\x41\x50\x50\x0d’.
Mistä tämä komento tulee? Kaatopaikalta.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Mutta emme voi lähettää koko lohkoa skannerille 64-rajoituksen vuoksi:

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Ja skanneri ei hyväksy heksadesimaalimuotoa NEWAPP:n vilkkumistilassa. Joten sinun on käännettävä jokainen bytes_array-rivi.

[253, 10, 22, 78, 44, 78, 69, 87, 65, 80, 80, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Ja sitten lähetä nämä tiedot skanneriin.

Saamme vastauksen:

[2, 1, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Jos tarkistat XMODEMia käsittelevän artikkelin, käy selväksi: tiedot on vastaanotettu.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Kun kaikki lohkot on siirretty, suoritamme siirron loppuun END_TRANSFER = 'xfdx01x04'.

Koska nämä lohkot eivät tarjoa mitään tietoa tavallisille ihmisille, ajamme laiteohjelmistoa oletuksena piilotilassa. Ja varmuuden vuoksi määritämme edistymispalkin käyttämällä tqdm:ää.

Tehtävä kehittäjälle, tai kuinka välähtimme käsiskannereita ilman myyjää

Nyt jäljellä on enää vain paketoida ratkaisu skripteihin, jotka voidaan ottaa käyttöön massakäyttöön selkeästi määriteltynä ajankohtana, jotta uloskirjausprosessi ei hidastuisi, ja lisätä lokikirjaus.

Koko

Panostettuamme valtavasti aikaa, vaivaa ja työtä, pystyimme kehittämään tarvitsemamme ratkaisut ja pysyimme aikataulussa. Lisäksi skannerit on nyt uudelleenohjelmoitu ja -koulutettu keskitetysti, mikä antaa meille tarkan hallinnan koko prosessiin. Yritys säästi aikaa ja rahaa, ja saimme arvokasta kokemusta tällaisten laitteiden käänteisestä suunnittelusta.

Lähde: will.com