Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Halo.

Kami, Viktor Antipov dan Ilya Aleshin, hari ini akan berbicara tentang pengalaman kami bekerja dengan perangkat USB melalui Python PyUSB dan sedikit tentang rekayasa balik.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

prasejarah

Pada tahun 2019, Keputusan Pemerintah Federasi Rusia No. 224 “Atas persetujuan Aturan pelabelan produk tembakau dengan alat identifikasi dan fitur penerapan sistem informasi negara untuk memantau peredaran barang yang wajib diberi label dengan alat identifikasi sehubungan dengan produk tembakau” mulai berlaku.
Dokumen tersebut menjelaskan, mulai 1 Juli 2019, produsen wajib memberi label pada setiap bungkus tembakau. Dan distributor langsung harus menerima produk tersebut dengan dibuatnya universal transfer document (UDD). Toko, pada gilirannya, perlu mendaftarkan penjualan produk berlabel melalui mesin kasir.

Selain itu, mulai 1 Juli 2020, peredaran produk tembakau tanpa label dilarang. Artinya semua bungkus rokok harus ditandai dengan barcode khusus Datamatrix. Apalagi - poin penting - ternyata Datamatrixnya tidak biasa, melainkan terbalik. Artinya, bukan kode hitam di atas putih, melainkan sebaliknya.

Kami menguji pemindai kami, dan ternyata sebagian besar pemindai perlu di-reflash/dilatih ulang, jika tidak, pemindai tersebut tidak akan dapat bekerja secara normal dengan kode batang ini. Pergantian peristiwa ini membuat kami sangat pusing, karena perusahaan kami memiliki banyak toko yang tersebar di wilayah yang sangat luas. Beberapa puluh ribu mesin kasir – dan waktu yang sangat singkat.

Apa yang harus dilakukan? Ada dua pilihan. Pertama: teknisi di lokasi secara manual melakukan reflash dan menyesuaikan pemindai. Kedua: kami bekerja dari jarak jauh dan, sebaiknya, mencakup banyak pemindai sekaligus dalam satu iterasi.

Opsi pertama, jelas, tidak cocok untuk kami: kami harus mengeluarkan uang untuk mengunjungi para insinyur, dan dalam hal ini akan sulit untuk mengontrol dan mengoordinasikan prosesnya. Tapi yang terpenting orang mau bekerja, artinya kita berpotensi banyak kesalahan dan kemungkinan besar tidak memenuhi tenggat waktu.

Pilihan kedua baik untuk semua orang, jika bukan karena satu hal. Beberapa vendor tidak memiliki alat flashing jarak jauh yang kami perlukan untuk semua sistem operasi yang diperlukan. Dan karena tenggat waktu hampir habis, saya harus berpikir sendiri.

Selanjutnya, kami akan memberi tahu Anda bagaimana kami mengembangkan alat pemindai genggam untuk OS Debian 9.x (semua mesin kasir kami menggunakan Debian).

Pecahkan teka-teki: cara mem-flash pemindai

Victor Antipov melaporkan.

Utilitas resmi yang disediakan oleh vendor berfungsi di Windows, dan hanya dengan IE. Utilitas ini dapat mem-flash dan mengkonfigurasi pemindai.

Karena sistem target kami adalah Debian, kami menginstal server usb-redirector di Debian dan klien usb-redirector di Windows. Dengan menggunakan utilitas usb-redirector, kami meneruskan pemindai dari mesin Linux ke mesin Windows.

Utilitas dari vendor Windows melihat pemindai dan bahkan mem-flash-nya secara normal. Jadi, kami membuat kesimpulan pertama: tidak ada yang bergantung pada OS, ini masalah protokol flashing.

OKE. Kami menjalankan flashing pada mesin Windows, dan menghapus dump pada mesin Linux.

Kami memasukkan dump tersebut ke WireShark dan... menjadi sedih (saya akan menghilangkan beberapa detail dari dump tersebut, mereka tidak menarik).

Apa yang ditunjukkan tempat pembuangan sampah itu kepada kita:

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Alamat 0000-0030, menurut Wireshark, adalah informasi layanan USB.

Kami tertarik pada bagian 0040-0070.

Tidak ada yang jelas dari satu frame transmisi kecuali karakter MOCFT. Karakter-karakter ini ternyata merupakan karakter dari file firmware, serta karakter yang tersisa hingga akhir frame (file firmware disorot):

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Apa maksud dari simbol fd 3e 02 01 fe, saya pribadi, seperti Ilya, tidak tahu.

Saya melihat bingkai berikut (informasi layanan telah dihapus di sini, file firmware telah disorot):

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Apa yang menjadi jelas? Bahwa dua byte pertama adalah semacam konstanta. Semua blok berikutnya mengkonfirmasi hal ini, tetapi sebelum akhir blok transmisi:

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Bingkai ini juga menakjubkan, karena konstanta telah berubah (disorot) dan, anehnya, ada bagian dari file tersebut. Ukuran byte file yang ditransfer menunjukkan bahwa 1024 byte ditransfer. Saya sekali lagi tidak tahu apa arti sisa byte.

Pertama-tama, sebagai nama panggilan BBS lama, saya meninjau protokol transmisi standar. Tidak ada protokol yang mengirimkan 1024 byte. Saya mulai mempelajari perangkat keras dan menemukan protokol 1K Xmodem. Ini mengizinkan transmisi 1024, tetapi dengan peringatan: pada awalnya hanya 128, dan hanya jika tidak ada kesalahan, protokol meningkatkan jumlah byte yang dikirimkan. Saya langsung mendapat transfer 1024 byte. Saya memutuskan untuk mempelajari protokol transmisi, dan khususnya X-modem.

Ada dua variasi modem.

Pertama, format paket XMODEM dengan dukungan CRC8 (XMODEM asli):

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Kedua, format paket XMODEM dengan dukungan CRC16 (XmodemCRC):

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Kelihatannya serupa, kecuali SOH, nomor paket dan CRC serta panjang paket.

Saya melihat awal blok transmisi kedua (dan sekali lagi melihat file firmware, tetapi sudah menjorok 1024 byte):

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Saya melihat header yang familiar fd 3e 02, tetapi dua byte berikutnya telah berubah: tadinya 01 fe, dan menjadi 02 fd. Kemudian saya perhatikan bahwa blok kedua sekarang diberi nomor 02 dan dengan demikian saya mengerti: di depan saya ada penomoran blok transmisi. Gigi 1024 yang pertama adalah 01, yang kedua adalah 02, yang ketiga adalah 03 dan seterusnya (tetapi dalam hex tentunya). Tapi apa arti perubahan dari fe ke fd? Mata melihat penurunan sebesar 1, otak mengingatkan bahwa programmer menghitung dari 0, bukan 1. Tapi mengapa blok pertama 1, dan bukan 0? Saya masih belum menemukan jawaban atas pertanyaan ini. Tapi saya mengerti bagaimana blok kedua dihitung. Blok kedua tidak lebih dari FF – (dikurangi) nomor blok pertama. Jadi, blok kedua ditetapkan sebagai = 02 (FF-02) = 02 FD. Pembacaan dump selanjutnya mengkonfirmasi dugaan saya.

Kemudian gambaran transmisi berikut mulai muncul:

Mulai transmisi
fd 3e 02 – Mulai
01 FE – penghitung transmisi
Transfer (34 blok, 1024 byte ditransfer)
fd 3e 1024 byte data (dibagi menjadi 30 byte blok).
Akhir transmisi
fd 25

Data yang tersisa untuk disejajarkan menjadi 1024 byte.

Seperti apa bentuk rangka ujung transmisi blok:

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

fd 25 – sinyal untuk mengakhiri transmisi blok. Berikutnya 2f 52 – sisa file berukuran hingga 1024 byte. 2f 52, dilihat dari protokolnya, adalah checksum CRC 16-bit.

Demi masa lalu, saya membuat program dalam C yang menarik 1024 byte dari sebuah file dan menghitung CRC 16-bit. Peluncuran program menunjukkan bahwa ini bukan CRC 16-bit. Pingsan lagi - sekitar tiga hari. Selama ini saya mencoba memahami apa yang bisa terjadi, jika bukan checksum. Saat mempelajari situs berbahasa Inggris, saya menemukan bahwa X-modem menggunakan perhitungan checksumnya sendiri - CRC-CCITT (XModem). Saya tidak menemukan implementasi C dari penghitungan ini, tetapi saya menemukan situs yang menghitung checksum ini secara online. Setelah mentransfer 1024 byte file saya ke halaman web, situs tersebut menunjukkan kepada saya sebuah checksum yang sepenuhnya cocok dengan checksum dari file tersebut.

Hore! Teka-teki terakhir terpecahkan, sekarang saya perlu membuat firmware sendiri. Selanjutnya, saya meneruskan pengetahuan saya (dan itu hanya tinggal di kepala saya) kepada Ilya, yang akrab dengan toolkit Python yang kuat.

Membuat sebuah program

Ilya Aleshin melaporkan.

Setelah menerima instruksi yang tepat, saya sangat “senang.”

Di mana memulainya? Itu benar, dari awal.  Dari mengambil dump dari port USB.

Luncurkan USB-pcap https://desowin.org/usbpcap/tour.html

Pilih port tempat perangkat terhubung dan file tempat kita akan menyimpan dump.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Kami menghubungkan pemindai ke mesin tempat perangkat lunak EZConfigScanning asli untuk Windows diinstal.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Di dalamnya kami menemukan item untuk mengirimkan perintah ke perangkat. Tapi bagaimana dengan tim? Dimana saya bisa mendapatkannya?
Saat program dimulai, peralatan disurvei secara otomatis (kita akan melihatnya nanti). Dan ada barcode pelatihan dari dokumen peralatan resmi. DEFALT. Ini adalah tim kami.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Data yang diperlukan telah diterima. Buka dump.pcap melalui wireshark.

Blokir saat memulai EZConfigScanning. Tempat-tempat yang perlu Anda perhatikan ditandai dengan warna merah.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Melihat semua ini untuk pertama kalinya, aku putus asa. Tidak jelas ke mana harus menggali selanjutnya.

Sedikit bertukar pikiran dan-dan-dan... Aha! Di tempat pembuangan sampah di luar - adalah inDan in ini di luar.

Saya mencari di Google apa itu URB_INTERRUPT. Saya menemukan bahwa ini adalah metode transfer data. Dan ada 4 metode seperti itu: kontrol, interupsi, isochronous, massal. Anda dapat membacanya secara terpisah.

Dan alamat titik akhir di antarmuka perangkat USB dapat diperoleh melalui perintah “lsusb –v” atau menggunakan pyusb.

Sekarang kita perlu menemukan semua perangkat dengan VID ini. Anda dapat mencari secara spesifik berdasarkan VID:PID.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Terlihat seperti ini:

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Jadi, kami memiliki informasi yang diperlukan: perintah P_INFO. atau DEFALT, alamat tempat menulis perintah titik akhir=03 dan tempat mendapatkan titik akhir respons=86. Yang tersisa hanyalah mengubah perintah menjadi hex.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Karena kita sudah menemukan perangkatnya, mari kita putuskan sambungannya dari kernel...

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

...dan menulis ke titik akhir dengan alamat 0x03,

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

... dan kemudian membaca respon dari titik akhir dengan alamat 0x86.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Jawaban terstruktur:

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

Kami melihat data ini di dump.pcap.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Besar! Ubah kode batang sistem menjadi hex. Selesai, fungsi pelatihan sudah siap.

Bagaimana dengan firmwarenya? Segalanya tampak sama, tetapi ada nuansanya.

Setelah sepenuhnya membuang proses flashing, kami secara kasar memahami apa yang kami hadapi. Berikut adalah artikel tentang XMODEM yang sangat membantu dalam memahami bagaimana komunikasi ini terjadi, meskipun secara umum: http://microsin.net/adminstuff/others/xmodem-protocol-overview.html Saya sarankan membaca.

Melihat dump, Anda dapat melihat bahwa ukuran frame adalah 1024, dan ukuran data URB adalah 64.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Oleh karena itu – 1024/64 – kita mendapatkan 16 baris dalam satu blok, membaca file firmware 1 karakter sekaligus dan membentuk satu blok. Melengkapi 1 baris dalam satu blok dengan karakter khusus fd3e02 + nomor blok.
14 baris berikutnya dilengkapi dengan fd25 +, menggunakan XMODEM.calc_crc() kami menghitung checksum seluruh blok (butuh banyak waktu untuk memahami bahwa "FF – 1" adalah CSUM) dan baris ke-16 yang terakhir ditambahkan dengan fd3e.

Tampaknya itu saja, baca file firmware, tekan blok, putuskan sambungan pemindai dari kernel dan kirimkan ke perangkat. Tapi itu tidak sesederhana itu. Pemindai perlu dialihkan ke mode firmware,
отправив ему NEWAPP = ‘\xfd\x0a\x16\x4e\x2c\x4e\x45\x57\x41\x50\x50\x0d’.
Dari mana tim ini?? Dari tempat pembuangan sampah.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Namun kami tidak dapat mengirim seluruh blok ke pemindai karena batas 64:

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Nah, pemindai dalam mode flashing NEWAPP tidak menerima hex. Oleh karena itu, Anda harus menerjemahkan setiap baris bytes_array

[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]

Dan kemudian kirimkan data ini ke pemindai.

Kami mendapatkan jawabannya:

[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]

Jika Anda memeriksa artikel tentang XMODEM, akan menjadi jelas: data telah diterima.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Setelah semua blok ditransfer, kami menyelesaikan transfer END_TRANSFER = 'xfdx01x04'.

Karena blok ini tidak membawa informasi apa pun untuk orang biasa, kami akan menginstal firmware dalam mode tersembunyi secara default. Dan untuk berjaga-jaga, kami akan mengatur bilah kemajuan melalui tqdm.

Sebuah tugas untuk pengembang, atau bagaimana kami mem-flash pemindai genggam tanpa vendor

Sebenarnya, ini masalah hal kecil. Yang tersisa hanyalah membungkus solusi dalam skrip untuk replikasi massal pada waktu yang ditentukan dengan jelas, agar tidak memperlambat proses kerja di kasir, dan menambahkan logging.

Total

Setelah menghabiskan banyak waktu dan tenaga, kami mampu mengembangkan solusi yang kami butuhkan, dan juga memenuhi tenggat waktu. Pada saat yang sama, pemindai sekarang di-reflash dan dilatih ulang secara terpusat, kami mengontrol seluruh proses dengan jelas. Perusahaan menghemat waktu dan uang, dan kami memperoleh pengalaman berharga dalam peralatan rekayasa balik jenis ini.

Sumber: www.habr.com

Tambah komentar