Perjuangan Memprogram Sebuah device … (kisah teknis)

Warning: Kisah ini teknis banget :p

Selama tiga hari ini aku lagi menyelesaikan apa yang sudah aku mulai sejak beberapa bulan yang lalu: memprogram sebuah device wireless point of sales (Lipman Nurit). Karakteristik device ini: punya thermal printer, punya touch screen, punya magnetic card reader, punya smart card reader, bisa buat nelpon dan SMS.

Secara teknis pemrograman alat ini:
– punya memori sekitar 300 kilo byte (dengan memory layout yang gak jelas)
– punya stack sekitar 20 kb
– punya media penyimpanan (record based/tanpa filesystem) sekitar 1 Mb
– memakai processor ARM

Dan dari segi kelengkapan:
– compiler yang dipake untuk project ini adalah versi trial yang udah abis sejak januari lalu, jadi tanggal komputernya perlu dimundurin 🙁
– debugger untuk device ini tidak dibelikan
– tidak ada emulator untuk device ini

Kelengkapan API:
– tidak ada malloc/free/realloc
– hanya ada blocking API untuk TCP/IP

Perjuangan awal

Awalnya memprogram device ini memakai kompilator yang disarankan dokumentasi, di Windows. Setiap habis compile, program didownload ke device. Siklus compile sampai upload kira-kira butuh semenit (dan tambah lama dengan semakin besarnya program).

Kompilator untuk benda ini sangat jelek, versi yang dipakai harus yang versi lama karena library yang disediakan oleh device ini hanya kompatibel dengan format library versi lama. Kompilatornya juga aneh: jika ada fungsi yang ada di library bawaan kompilator, tapi tidak ada di library (misalnya fungsi time() yang standar di Unix) maka program akan sukses di kompilasi, tapi jika fungsi itu sampai dipanggil di device, akan muncul fatal error dan akan mencetak stack trace di thermal printernya, sekitar 1/2 meter.

Stack tracenya pun gak berguna, karena gak tau gimana caranya mencari alamatnya di file yang sebenarnya (format file executablenya gak standar).

Tidak ada bounds checker untuk kompilator tersebut, dan pemeriksaan kesalahan statiknya jelek banget, dibawah -Wall-nya gcc. Jadi sering sekali nemu error yang bikin stress 🙁

Membuat Emulator

Untuk mempercepat pembuatan program, supaya nggak perlu siklus, compile-download-run, maka yang dilakukan adalah: mengemulasikan API device teryang dipakai di Linux (dengan kompilator gcc) ini langkah yang cukup melelahkan, tapi untungnya kompilator jelek itu mendukung ANSI C jadi cukup cepat coding ulang API device tersebut di Linux.

Membuat memory manager

Karena device ini nggak punya memory management, maka perlu diimplementasikan juga malloc/realloc dan free (dengan buffer statik).Sebenarnya mungkin aja mbikin program tanpa memory manager, tapi library SSL (lihat bagian berikut) butuh implementasi malloc/realloc/free.

Mengimplementasikan SSL

Device ini juga perlu ssl, jadi pake matrixSSL dan setelah susah payah porting (bagian OS dependantnya_ ternyata banyak banget bugnya, ntar kalo sempat ngirim patch deh ke mereka.

Waktu testing: gagal. Jadi perlu diselidiki kenapa gagal? ternyata enkripsi public yang didukung device ini cuma RSA, dan server yang dipakai memakai DSA. Entah kenapa jetty yang dipakai gak bisa mendebug handshaking ssl, yang terlihat dari sisi client (sisiku), cuma client mengirim SSL HELO dan ditolak oleh server (tanpa alasan/tidak terlihat di ssldump). Setelah menebak bahwa servernya hanya mendukung DSA, maka key di server di ganti pake RSA, tapi setelah itu ternyata ada bug di programku, jadi perlu menebak lagi salahnya.

Supaya lebih mudah melihat apa salahnya, maka perlu di-sniff isi trafficnya, tapi untuk bisa melakukan ini perlu key milik server. Tapi program untuk mengsniff ini hanya menerima format PEM sedangkan servernya memakai format keystore. Jadi akhirnya harus mencari-cari dulu cara untuk mengkonvert antar dua format ini. Setelah agak lama, akhirnya ketemu juga salahnya: buffer penerimanya kurang besar. Akhirnya buffernya dinaikkan jadi 16Kb, dan semua pun bahagia.

Tools pembantu: valgrind dan tcc

Untuk mendeteksi segala macam memory leak, ada program yang bernama valgrind yang jalan di Linux. Sialnya valgrind ini gak bisa meriksa heap overflow, ataupun stack overflow selama memori yang ditimpa masih valid.

Akhirnya dicobalah tcc (tiny c compiler) yang punya kemampuan untuk menghasilkan kode dengan bounds checking. Tapi entah mengapa, compiler ini rada aneh, misalnya hasil program kalo tcc *.c dengan mengkompile masing-masing .c lalu dilink beda, atau program yang dicompile dengan -g (debugging info), gak bisa didebug dgn gdb (mungkin karena library C Fedora 3 yang sudah kebanyakan dioprek). Dan ada satu lagi keanehan, kalo variabel array of character yang sifatnya static (private) di-pass menjadi parameter untuk fungsi di file lain, dianggapnya terjadi array index of bounds).

Tapi meskipun demikian TCC ini akhirnya berhasil menemukan bug-bug yang tidak ditemukan Valgrind.

Dan akhirnya semua berakhir bahagia

Dan Lega bisa menceritakan ini semua :p

3 thoughts on “Perjuangan Memprogram Sebuah device … (kisah teknis)”

  1. yakin lo berakhir? :p, paling tar ditambahin projeknya.
    Trus duitnya mo dipake beli device apa? kabar-kabarin ya

  2. Fren…

    mw tanya ne,,,

    1. beda smartcard ma rfid apa??
    2.gmana cara memprogram smartcard?

    thx before.

Leave a Reply

Your email address will not be published. Required fields are marked *