Semua masalah dalam ilmu komputer dapat diselesaikan dengan tingkat tipuan yang lain, kecuali tentu saja untuk masalah tipuan yang terlalu banyak.
David Wheeler

Kutipan yang bagus dan pengantar yang bagus untuk postingan blog ini! Kami ingin memberi Anda wawasan tentang Antarmuka Jaringan Internal (INI) Server Web Tertanam Mongoose.

Latar belakang

Awalnya, Mongoose menggunakan API soket BSD dan banyak fungsi soket serta mode non-pemblokiran. Artinya, ini hanya portabel untuk platform yang mendukung API ini. Ini berfungsi untuk platform yang mendukung soket. Namun, kami menemukan bahwa sebagian besar platform memberikan dukungan dengan caranya sendiri. Pembuat SDK Perangkat Keras “lupa” fungsi pilih. Mereka juga suka menggabungkan fungsi pilihdan terima. Hal ini membuat solusi API soket BSD asli kami sulit digunakan. Kami memiliki dua opsi untuk memperbaikinya:

  1. Jangan melakukan porting ke platform yang tidak hanya mendukung API soket lengkap
  2. Terapkan fungsi apa pun yang hilang untuk setiap platform

Gerakan heroik

Opsi pertama bukanlah cara yang heroik dalam melakukan sesuatu, bukan? ? Kami menyukai kompleksitas.

Microchip pertama yang di-porting Mongoose adalah Arduino (Mega). Dan, itu diterapkan dengan menggunakan cara kedua. Kami mengembangkan lapisan soket BSD di atas Arduino Socket Library. Ini bekerja dengan baik dengan beberapa cegukan.

Platform berikutnya adalah ESP8266. Di sini, kami harus memutuskan apa yang sebenarnya ingin kami capai. Kami mulai bekerja dengan ESP8266 sejak lama. Tidak ada RTOS SDK dengan LWIP (dan soket BSD). Selain itu, kami ingin mem-porting Mongoose ke lebih banyak platform tertanam dan mulai memahami, bahwa sebagian besar dari mereka akan memiliki masalah dengan soket BSD.

Ini adalah waktu untuk membagi Server Web Tertanam Mongoose menjadi tingkat protokol dan tingkat jaringan. Ya, David Wheeler, saatnya menambahkan tingkat tipuan lainnya.

Merencanakan Antarmuka Jaringan Internal kami

Antarmuka Jaringan Internal kami (INI) seharusnya melakukan hal tersebut

  1. berorientasi pada koneksi (bukan soket!) — Mongoose berorientasi pada koneksi, jadi, penggunaan antarmuka berorientasi koneksi harus lebih sederhana.
  2. mendukung TCP dan UDP (protokol lain yang didukung didasarkan pada keduanya).
  3. menjadi async, berbasis panggilan balik.
  4. menjadi sederhana!

Anda sudah dapat menebaknya, hal yang paling bermasalah adalah: bersikaplah sederhana. Teka-teki kami:

Di satu sisi, mudah untuk merancang antarmuka yang sulit digunakan, tapi lalu siapa yang akan menggunakannya?

Di sisi lain, Mongoose memiliki begitu banyak fitur, termasuk fitur terkait jaringan, sehingga penting untuk menemukan keseimbangan antara fungsionalitas dan kesederhanaan.

Hasilnya, Antarmuka Jaringan Internal Mongoose memiliki ~20 fungsi.

Ikhtisar INI

Ada beberapa kelompok fungsi di INI API:

  1. Manajemen koneksi
  2. Pengiriman dan penerimaan data
  3. Fungsi klien
  4. Fungsi server
  5. Kumpulan kecil fungsi utilitas.

Sebagian besar fungsi (kecuali fungsi manajemen koneksi) memiliki dua versi: satu untuk TCP dan satu lagi untuk UDP.

Yang terakhir namun tidak kalah pentingnya: ada serangkaian panggilan balik. INI kami memiliki antarmuka berbasis panggilan balik. Singkatnya, artinya, fungsi tersebut, seperti connectreturn secara perantara dan memanggil callback. Kemudian, koneksi dibuat (atau terjadi kesalahan).

Skema interaksi lapisan cukup tradisional: protokol tingkat aplikasi menggunakan API protokol transport, sedangkan protokol transport menggunakan implementasi INI untuk berkomunikasi dengan API spesifik platform (atau perangkat).

Saat ini, kami memiliki 3 implementasi INI:

  1. Soket BSD
  2. LWIP
  3. SimpleLink (Instrumen Texas CC3100/C3200)

Implementasi spesifik INIdipilih pada waktu kompilasi dengan mendefinisikan makro CS_PLATFORM (makro ini dapat ditentukan secara manual, menggunakan opsi compiler, atau sekumpulan #ifdef #elsedalam kode Mongoose akan mencoba melakukannya untuk Anda).

Bagaimana itu bekerja

Implementasi INI yang spesifik harus mengimplementasikan serangkaian fungsi untuk membuat koneksi, mengirim data, menerimanya, dll. Inti memanggil fungsi-fungsi ini untuk membuat koneksi, mengirim data, dll. Jika INIingin menyampaikan segala jenis informasi ke inti, ia memanggil panggilan balik yang sebagian besar diimplementasikan di Mongoose Coredaripada di INI, yaitu pelaksana INI tidak boleh menyediakan implementasi fungsi-fungsi tersebut (di sebagian besar kasus yang mereka sebutkan diakhiri dengan _cb). Namun, INI juga harus mengimplementasikan satu callback (mg_if_recved,lihat di bawah).

Berikut adalah diagram kecil dari urutan eksekusi:

Fungsi

Sekarang, mari kita lakukan ikhtisar singkat fungsi INI (deskripsi lengkap dapat ditemukan dalam dokumentasi Mongoose di sini):

Fungsi manajemen koneksi:

Sebagian besar aktivitas terkait manajemen koneksi dilakukan oleh Mongoose sendiri, sehingga INImemiliki fungsi untuk memenuhi tindakan spesifik platform. Misalnya, “Socket INI” membuat soket dalam implementasi mg_if_create_conn.

  • mg_if_create_conn
  • mg_if_destroy_conn
  • mg_close_conn

Fungsi klien dan server:

  • mg_if_connect_tcp
  • mg_if_connect_udp

Setelah koneksi dibuat, fungsi mg_if_connect_cbharus dipanggil.

  • mg_if_listen_tcp
  • mg_if_listen_udp
  • mg_if_accept_new_conn

Kemudian INI menerima koneksi baru dan harus memanggil mg_if_accept_tcp_cb

Kirim dan terima fungsi:

  • mg_if_tcp_send, mg_if_udp_send dan panggilan balik yang sesuai mg_if_sent_cb

Saat diterima, INIharus memanggil callback mg_if_recv_tcp_cbdan mg_if_recv_udp_cb. Jika inti mengakui konsumsi, maka akan memanggil mg_if_recved.

Misi selesai?

Apakah kita mencapai apa yang ingin kita lakukan? Berikut pengingat tentang apa yang kami inginkan:

Antarmuka Jaringan Internal (INI) kami seharusnya

  1. berorientasi pada koneksi (bukan soket!) — Mongoose berorientasi pada koneksi, jadi, penggunaan antarmuka berorientasi koneksi harus lebih sederhana.
  2. mendukung TCP dan UDP (protokol lain yang didukung didasarkan pada keduanya).
  3. menjadi async, berbasis panggilan balik.
  4. menjadi sederhana!

Kami pikir kami mendapatkannya. Sekarang ada cara untuk mem-porting Mongoose ke berbagai platform. Ini mungkin tidak selalu super sederhana, tapi mungkin dan kita tidak perlu membuat jalan pintas dan hal-hal seperti itu untuk mewujudkannya.

Melihat ke masa depan, kami berencana untuk mem-porting Mongoose ke lebih banyak platform tertanam. Jadi kita akan mendapatkan 5–6 implementasi INI yang berbeda. Nantikan terus!

Awalnya diterbitkan di blog.cesanta.com.